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

发布时间 2026-09-22 9 天前
来源 Google Developers Blog
字数 5,324 字
查看原文

AI智能总结

谷歌开发者布道师 Guillaume Laforge 于 2026 年 9 月 9 日宣布 Agent Development Kit(ADK)for Kotlin 1.0 正式发布。

宣布 ADK for Kotlin 1.0:在 Kotlin、Android 及更多平台上构建可用于生产环境的 AI 智能体

2026 年 9 月 9 日  作者:Guillaume Laforge,开发者布道师

banner-1080p

今天,我们激动地宣布 Agent Development Kit(ADK)for Kotlin 1.0 正式发布(GA)!欢迎访问 GitHub 仓库 深入了解代码,并立即构建你的第一个智能体;也可以查阅 文档。

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

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

不过,ADK for Kotlin 并不仅限于 Android——服务端 Kotlin 开发者 同样可以使用符合 Kotlin 语言习惯的代码来构建 面向企业的智能体(enterprise-ready agents) 和智能应用。

🚀 ADK for Kotlin 1.0 的新特性

ADK for Kotlin 构建在一个 Kotlin Multiplatform(KMP) 核心之上,对具体的模型后端、会话提供者或记忆系统保持完全中立。1.0 版本既融合了面向本地与云端场景的核心多智能体编排能力,也为面向移动设备的开发者提供了即插即用的 Android 扩展。

与 ADK 1.0 Core 完全对等

ADK for Kotlin 1.0 实现了与 ADK Python 和 Java 的完全对齐,将先进的多智能体协作模式带入符合 Kotlin 语言习惯的开发体验中:

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

⛑️ 数据库故障响应智能体示例

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

  1. 工具(Tools)(@Tool):可执行的、类型安全的函数能力(调用 API、查询指标、执行动作)。
  2. 技能(Skills)(SkillToolset):按需加载的过程性领域知识与运维剧本,通过渐进式披露(progressive disclosure)动态加载(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,
)

并使用 @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 = "dev-team@example.com",
                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."
    }
}

在构建时,KSP 会自动为 InfrastructureDiagnosticsService() 生成扩展函数 generatedTools()。

与其将分诊指南硬编码到代码中,不如把标准操作流程(SOP)放到 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`.

技能(Skills)可以捆绑一些辅助资源(例如 assets/mitigation_rules.txt),这些资源只有在模型真正需要时才会被加载,从而最大限度地降低 token 消耗——这种机制被称为 渐进式披露(progressive disclosure)。

现在,让我们以声明式的方式将工具与技能装配到智能体中:

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 协程与 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") }
    }
}

当告警触发时,智能体会在结构化的回合循环中自主执行:

  1. 发现并加载 database-incident-triage 技能及其安全护栏规则。
  2. 调用 getServiceMetrics() → 识别出连接池使用率已达 98.5%。
  3. 调用 fetchRecentDeployments() → 将 25 分钟前发布的 deploy-9842(“Add unindexed batch query...”)定位为根本原因。
  4. 向 #production-alerts 频道发布告警更新,并输出一份分诊后报告,建议立即回滚该版本。