跳到正文
Google Developers Blog·· 29 天前精选AI 评分60

Google 发布 ADK for Kotlin 1.0,面向 Kotlin、Android 的生产级 AI 智能体开发工具包

Announcing ADK for Kotlin 1.0: Building Production-Ready AI Agents in Kotlin, Android, and Beyond

AI 导读

Google 宣布 Agent Development Kit(ADK)for Kotlin 1.0 正式可用,与 ADK 1.0 Core 实现完整功能对齐,并加入面向 Android 的端侧扩展。

推荐理由

官方给出 ADK for Kotlin 1.0 与 ADK Python、Java 核心对齐的能力清单,以及 Android 端侧扩展的接入方式,便于判断 Kotlin 技术栈能否承接生产级智能体。

正文 · AI 翻译

2026年9月9日

今天,我们非常激动地宣布面向 Kotlin 的 Agent Development Kit(ADK)正式发布 1.0 通用版本!请查看 GitHub 仓库,深入了解代码并立即构建你的第一个 agent,同时探索文档。

当我们推出 ADK for Kotlin 0.1.0 时,我们的使命是为 Kotlin、Java 和 Android 开发者带来符合语言习惯、轻量且可组合的 AI agent 开发体验。在过去的几个月里,我们一直致力于将该框架演进为一个可用于生产环境的工具包。

在 1.0 版本中,ADK for Kotlin 实现了与 ADK 1.0 Core 的完整功能对等,同时提供了一套丰富的Android 优先、端侧扩展。无论你是想使用 LiteRT-LM 和 ML Kit(beta)运行快速、私密的端侧 agent,还是想通过 Firebase AI Logic 编排混合云工作流,抑或是想借助 Room 和 AppSearch 在进程重启后持久化 agent 状态,ADK for Kotlin 1.0 都能提供你所需的一切。

ADK for Kotlin 不仅适用于 Android,服务端 Kotlin 开发者同样能够编写符合语言习惯的 Kotlin 代码,来创建他们的企业级 agent和智能应用。

🚀 ADK for Kotlin 1.0 有哪些新特性?

ADK for Kotlin 围绕一个Kotlin Multiplatform(KMP)核心构建,该核心对具体的模型后端、会话提供程序或记忆系统完全保持无关。1.0 版本结合了面向本地和云场景的核心多 agent 编排能力,以及面向移动设备开发者的即插即用 Android 扩展。

完整的 ADK 1.0 核心对等

ADK for Kotlin 1.0 实现了与 ADK Python 和 Java 的完全对齐,将高级多 agent 协调模式引入符合语言习惯的 Kotlin:

  • 分层多 agent 系统:串联 agent 并将任务委托给专门的子 agent。
  • 上下文压缩与多轮对话:通过总结历史记录来管理上下文,以保持在 token 限制之内。
  • 人在回路(HITL)与确认流程:暂停执行,针对敏感操作请求用户确认,然后恢复执行。
  • 长时间运行与基于注解的工具:使用 @Tool 和 @Param 注解,为用 Kotlin 编写的工具自动生成 schema。
  • 会话可恢复性:跨用户会话暂停、序列化和恢复活跃的 agent 交互。
  • 一方 Java 互操作性:直接从现有 Java 应用程序调用 ADK Kotlin agent。
  • 企业级 Agent 平台(VertexAI)集成:VertexAiSessionService、VertexAiRagMemoryService、VertexAiMemoryBankService。

⛑️ 数据库事件响应 agent 示例

让我们来试用一下 ADK for Kotlin 1.0,构建一个事件分诊与诊断 agent,用于调查生产数据库告警。我们的 agent 将利用 ADK 的函数调用和 agent 技能能力:

  1. 工具(@Tool):可执行、类型安全的能力(调用 API、查询指标、执行操作)。
  2. 技能(SkillToolset):按需提供的过程性知识和领域操作手册,通过渐进式披露动态加载(SKILL.md、检查清单、模板)。

ADK 利用 KSP(Kotlin Symbol Processing)在编译时生成函数调用定义,为你提供类型安全的 schema、对 suspend 函数的支持,以及零运行时反射。

你使用常规的 Kotlin 数据类来定义服务:

data class ServiceMetrics(
    val serviceName: String,
    val cpuUsagePercent: Double,
    val connectionPoolUsagePercent: Double,
    val activeConnections: Int,
    val maxConnections: Int,
    val p99LatencyMs: Int,
    val errorRatePercent: Double,
)

data class DeploymentInfo(
    val deploymentId: String,
    val serviceName: String,
    val gitCommit: String,
    val author: String,
    val deployedMinutesAgo: Int,
    val description: String,
)

Kotlin

已复制

以及使用 @Tool 和 @Param 注解的函数:

class InfrastructureDiagnosticsService {

    @Tool
    suspend fun getServiceMetrics(
        @Param("Target service or database cluster") serviceName: String,
        @Param("Time window in minutes") windowMinutes: Int? = 15,
    ): ServiceMetrics {
        // Query monitoring backends (Datadog, Prometheus, Cloud Monitoring)
        return ServiceMetrics(
            serviceName = serviceName,
            cpuUsagePercent = 91.4,
            connectionPoolUsagePercent = 98.5,
            activeConnections = 492,
            maxConnections = 500,
            p99LatencyMs = 2450,
            errorRatePercent = 4.2,
        )
    }

    @Tool
    fun fetchRecentDeployments(
        @Param("Target service identifier") serviceName: String
    ): List<DeploymentInfo> {
        return listOf(
            DeploymentInfo(
                deploymentId = "deploy-9842",
                serviceName = serviceName,
                gitCommit = "a1b2c3d",
                author = "[email protected]",
                deployedMinutesAgo = 25,
                description = "Add unindexed batch query to user profile sync job",
            )
        )
    }

    @Tool
    fun notifyOnCall(
        @Param("Channel to notify, e.g. '#production-alerts'") channel: String,
        @Param("Diagnostic summary message") message: String,
        @Param("Severity: INFO, WARNING, CRITICAL") severity: String? = "WARNING",
    ): String {
        println(">>> [CHAT-OPS] Broadcasting [$severity] to $channel: $message")
        return "Notification posted successfully."
    }
}

Kotlin

已复制

在构建时,KSP 会自动创建扩展函数 InfrastructureDiagnosticsService().generatedTools()。

与其在代码中硬编码分诊指南,不如将标准操作流程放在 src/main/resources/skills/database-incident-triage/SKILL.md 中:

---
name: database-incident-triage
description: Standard operating procedure for diagnosing database latency spikes and connection pool saturation.
allowed-tools: [getServiceMetrics, fetchRecentDeployments, notifyOnCall]
---

# Database Incident Triage SOP

1. **Telemetry**: Call `getServiceMetrics` to inspect CPU, latency, and pool saturation.
2. **Correlation**: Call `fetchRecentDeployments` to check for recent code/schema changes.
3. **Safety Rules**: Inspect `assets/mitigation_rules.txt` with `load_skill_resource` before taking action. Never restart primary nodes during peak hours.
4. **Notify**: Broadcast root-cause diagnosis to `#production-alerts` with `notifyOnCall`.

纯文本

已复制

技能可以捆绑辅助资源(例如 assets/mitigation_rules.txt),模型仅在需要时才会获取这些资源,从而将 token 使用量降至最低——这种机制称为渐进式披露。

现在,是时候以声明式的方式为我们的智能体配备工具和技能了:

object IncidentTriageDemoAgent {

    val rootAgent = LlmAgent(
        name = "incident_triage_agent",
        model = Gemini(name = "gemini-3.8-flash"),
        instruction = Instruction(
            """
            You are an SRE on-call diagnostic assistant.
            When an alert is reported:
            1. Discover available triage playbooks and load the matching SOP using `load_skill`.
            2. Follow the playbook steps strictly, loading skill resources if needed.
            3. Use your diagnostics tools to inspect telemetry and notify the team.
            """.trimIndent()
        ),
        // 1. Compile-time generated function tools (zero reflection)
        tools = InfrastructureDiagnosticsService().generatedTools(),
        // 2. Dynamic skill toolset (provides list_skills, load_skill, load_skill_resource)
        toolsets = listOf(SkillToolset(NewFileSystemSource(resolveSkillsDir()))),
    )
}

Kotlin

已复制

智能体准备就绪后,让我们使用 Kotlin 协程和 InMemoryRunner 来执行它:

fun main() = runBlocking {
    val runner = InMemoryRunner(
        agent = IncidentTriageDemoAgent.rootAgent, 
        appName = "IncidentTriageApp"
    )

    val alert = "ALERT [P1]: Database latency spike detected on 'users-postgres-cluster'! "
              + "Active connections are surging and queries are timing out."

    val events = runner.runAsync(
        userId = "oncall-sre",
        sessionId = UUID.randomUUID().toString(),
        newMessage = Content.fromText(Role.USER, alert)
    ).toList()

    for (event in events) {
        event.content?.parts?.firstOrNull()?.text?.let { println("Agent: $it") }
    }
}

Kotlin

已复制

当警报触发时,智能体以结构化的回合循环自主执行:

  1. 发现并加载 database-incident-triage 技能及其安全护栏。
  2. 调用 getServiceMetrics() → 识别出 98.5% 的连接池饱和度。
  3. 调用 fetchRecentDeployments() → 定位到 deploy-9842(“添加未索引的批量查询……” 25 分钟前)为根本原因。
  4. 向 #production-alerts 发布更新,并提交分诊后报告,建议立即回滚。

📱 Android 优先与端侧扩展

在完成这个服务器端生产智能体之后,让我们回到 ADK for Kotlin 的移动端能力。现代移动 AI 需要在云端推理能力与端侧隐私、速度和离线可靠性之间取得平衡。ADK for Kotlin 1.0 为标准 Android 架构组件引入了模块化实现:

adk-capabilities

表 1:ADK for Kotlin 1.0 的 Android 优先与端侧扩展。

💻 Android 示例:金融助手

让我们看看 ADK for Kotlin 如何集成到生产级 Android 应用中。在以下示例中,我们通过 Firebase AI 构建一个由 Gemini 3.8 Flash 驱动的金融助手。它使用 KSP 生成的函数调用处理需要用户明确批准的敏感交易,同时充分利用一流的 Android 持久化服务,例如将聊天会话存储在 Room 中、将索引内存存储在 AppSearch 中,以及将文件直接存储在 Android 存储中:

让我们先定义银行转账工具(需要人工确认):

// 1. Sensitive Tool requiring human confirmation
class BankTransferTools {
    @Tool(
        name = "transferFunds",
        description = "Transfers money to another account. Requires explicit user approval.",
        requireConfirmation = true
    )
    fun transferFunds(
        @Param("Recipient account ID") recipientId: String,
        @Param("Amount in USD") amount: Double
    ): String {
        println(">>> [BANKING CORE] Executing transfer of \$$amount to $recipientId...")
        return "Successfully scheduled transfer of \$$amount to $recipientId. Ref: TX-${System.currentTimeMillis()}"
    }
}

Kotlin

已复制

以下是我们如何配置智能体:通过 Firebase AI 使用 Gemini 3.8 Flash,并配置我们刚刚定义的工具:

// 2. Define the Agent backed by Firebase AI (Gemini 3.8 Flash)
fun createFinancialAgent(): LlmAgent {
    val firebaseAi = FirebaseAI.getInstance(FirebaseApp.getInstance())
    return LlmAgent(
        name = "FinancialAgent",
        description = "Handles banking inquiries and scheduled fund transfers",
        model = Firebase.create("gemini-3.8-flash", firebaseAi),
        instruction = Instruction(
            "You are a secure banking assistant. Help users manage their accounts and transfer funds."
        ),
        tools = BankTransferTools().generatedTools()
    )
}

Kotlin

已复制

我们为 InMemoryRunner 配置由 Room 支持的会话服务,以及由 AppSearch 提供支持的内存服务:

// 3. Configure the Runner with Persistent Android Storage Services
fun createAndroidRunner(applicationContext: Context, agent: LlmAgent): InMemoryRunner {
    return InMemoryRunner(
        agent = agent,
        appName = "AndroidFinancialApp",
        // SQLite persistence for chat history across reboots / process death
        sessionService = RoomSessionService.fromContext(applicationContext),
        // On-device full-text indexed memory with AndroidX AppSearch
        memoryService = AppSearchMemoryService.fromContext(applicationContext),
        // App-private file storage for generated statements/receipts
        artifactService = FileArtifactService.fromExternalFilesDir(applicationContext)
    )
}

Kotlin

已复制

是时候运行智能体了,通过两个回合分别请求转账和通过人工批准确认转账:

// 4. Multi-turn Human-in-the-Loop Execution
suspend fun runFinancialDemo(runner: InMemoryRunner) {
    val userId = "user-123"
    val sessionId = "session-${UUID.randomUUID()}"
    suspend fun sendTurn(message: Content): List<Event> {
        val events = runner.runAsync(userId = userId, sessionId = sessionId, newMessage = message).toList()
        for (event in events) {
            event.content?.parts?.firstOrNull()?.text?.let { println("Agent: $it") }
        }
        return events
    }

    // --- Turn 1: User requests transfer (Agent pauses execution)
    println("User: Please transfer $50 to account ACCT-9876.\n")
    val turn1Events = sendTurn(
            Content.fromText(Role.USER, "Please transfer $50 to account ACCT-9876."))

    // Intercept the synthetic confirmation request emitted by ADK
    val confirmationRequestId = turn1Events
        .flatMap { it.functionCalls() }
        .firstOrNull { it.name == FunctionCall.REQUEST_CONFIRMATION_FUNCTION_CALL_NAME }
        ?.id ?: return
    println("\n[UI]: Sensitive action detected. User tapped [Confirm Transfer].\n")

    // --- Turn 2: User confirms in the Android UI (Resumes & executes transferFunds)
    val approvalMessage = Content(
        role = Role.USER,
        parts = listOf(
            Part(
                functionResponse = FunctionResponse(
                    name = FunctionCall.REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
                    id = confirmationRequestId,
                    response = mapOf(ToolConfirmation.CONFIRMED_KEY to true)
                )
            )
        )
    )
    sendTurn(approvalMessage)
}

Kotlin

已复制

注意:此示例仅用于演示目的,并非为满足任何合规要求而设计。

📊 比较 ADK for Kotlin 功能——核心与 Android

adk-features

表 2:ADK for Kotlin 功能在核心(服务器)与 Android 之间的比较。

📦 快速开始

要开始使用 ADK for Kotlin 1.0,请将必要的依赖项添加到模块的 build.gradle.kts 中:

dependencies {
    // ADK Kotlin Core Engine + KSP Processor
    implementation("com.google.adk:google-adk-kotlin-core:1.0.0")
    ksp("com.google.adk:google-adk-kotlin-processor:1.0.0")

    // Optional Android-first extensions:
    implementation("com.google.adk:google-adk-kotlin-mlkit-android:1.0.0-beta")
    implementation("com.google.adk:google-adk-kotlin-litertlm:1.0.0")     
    implementation("com.google.adk:google-adk-kotlin-firebase-android:1.0.0")
}

Kotlin

已复制

🔗 资源与文档

探索代码仓库,查看示例应用,并开始构建你的多智能体体验:

无论你是在 JVM 上开发服务端智能体,还是为 Android 移动设备开发智能体,我们都迫不及待想看到你将如何利用 ADK for Kotlin!给仓库点个 Star,试用这些示例,并把你的反馈分享给我们!

上一页

下一页

来源:Google Developers Blog · developers.googleblog.com