ADK for Kotlin 上手:Google 官方 AI Agent 开发指南

作者:袖梨 2026-09-14

当大模型需要从回答问题进一步走向调用工具、规划任务和执行操作时,应用就需要一套可控的 Agent 运行框架。ADK for Kotlin 将这些能力带入 Kotlin 与 Android 生态,既支持云端编排,也覆盖设备端推理、状态持久化和敏感操作确认。下面从架构、核心机制和基础代码入手展开说明。

前言

今日,Google 发布了 ADK for Kotlin 1.0 正式版。

这意味着:Android 开发者可以用 Kotlin 写生产级 AI Agent 了


? 它是什么

ADK 全称 Agent Development Kit,这是:Google 官方出品的 Kotlin AI Agent 开发框架

类比一下:如果 Retrofit 是"网络请求框架",那 ADK 就是"AI Agent 框架"。


? ADK 能干什么

普通的 LLM 调用,你问它一个问题,它给你一段文字。

但 Agent 不一样——它能调用工具、做决策、执行操作。ADK 解决的是一个核心问题:怎么让 AI 不只是"聊天",而是"干活",日常使用场景包括:

场景一:端侧智能助手

手机上跑一个助手 Agent:

  • 用户说"帮我转 500 块给张三";
  • Agent 调用 findContact 工具找到张三;
  • 调用 previewTransfer 生成预览;
  • 暂停,弹出确认 UI(人在回路);
  • 用户确认后,调用 executeTransfer 执行。

全程在 Android 上完成,敏感数据不出设备。

场景二:服务端事件分诊

生产数据库告警了,Agent 自动:

  • 调用 getServiceMetrics() → 发现连接池饱和 98.5%;
  • 调用 fetchRecentDeployments() → 定为25 分钟前的未索引批查询;
  • 向 Slack #production-alerts 发送分析报告 + 回滚建议。

从告警到定位根因,分钟级完成

场景三:混合编排

云端大模型做主编排器,设备端小模型处理隐私数据:

  • 云端 Gemini:理解用户意图、规划步骤;
  • 设备端 Gemini Nano:解析本地文档、提取敏感信息;
  • 数据不上传云端,结果回传给云端 Agent 继续推理。

ADK 不是一个聊天框架,而是一个 AI 执行引擎。它让 LLM 从"能说"变成"能做"。


? 底层架构是什么?

ADK for Kotlin 基于 Kotlin Multiplatform(KMP) 构建。

核心设计思路:不绑定任何模型、会话提供者或记忆系统

你可以只用核心层写服务端 Agent,也可以加上 Android 扩展写端侧 Agent。按需引入,不捆绑

层级模块职责
核心层google-adk-kotlin-coreAgent 引擎、工具系统、编排逻辑
处理器google-adk-kotlin-processorKSP 编译期 Schema 生成
Android 扩展google-adk-kotlin-core-androidAndroid 生命周期适配
设备端模型google-adk-kotlin-mlkit-androidML Kit + Gemini Nano
设备端推理google-adk-kotlin-litertlmLiteRT-LM(Gemma 等)
云端模型google-adk-kotlin-firebase-androidFirebase AI Logic

ADK for Kotlin 1.0 与 Python / JS 版本实现了完整功能对等。选 Kotlin 不再是功能妥协,而是语言偏好。

? 核心能力拆解

ADK具体的能力包括:

  • 定义 Agent 能调用哪些工具(函数);
  • 编排多个 Agent 协作完成复杂任务;
  • 管理对话状态、记忆、会话恢复;
  • 在 Android 设备端 / 云端 / 混合模式下运行。

@Tool 注解 + KSP 编译期生成

这是 ADK 最优雅的设计。

定义一个工具,就是写一个普通的 Kotlin 函数,加上 @Tool 注解:

class OrderTools(
    private val orders: OrderRepository
) {
    @Tool(description = "根据订单号查询订单")
    suspend fun findOrder(
        @Param("客户可见的订单号") orderNumber: String
    ): OrderSummary {
        require(orderNumber.length in 6..24) // ? 参数校验
        return orders.findByNumber(orderNumber)
            ?: throw ToolException("订单不存在")
    }
}

编译时,KSP 自动生成函数的 JSON Schema——零运行时反射

⚠️ 这里用的是 Kotlin Symbol Processing,不是运行时反射。性能开销为零,Schema 在编译期就确定了。

对比 Python ADK 的装饰器方案,Kotlin 版的优势很明显:

维度Python ADKKotlin ADK
Schema 生成运行时反射编译期 KSP
类型安全运行时检查编译期检查
性能开销有反射开销
IDE 支持一般完整补全 + 重构

@Tool + KSP 是 Kotlin ADK 相比 Python 版最大的技术优势。写工具就是写函数,编译器帮你搞定剩下的。


② 多 Agent 编排

复杂任务别塞给一个全能 Agent——拆成多个专职 Agent 协作。

ADK 支持层级化多 Agent 系统

         ┌─────────────┐
         │ Router Agent │  ← 分类请求,选择工作流
         └──────┬───────┘
       ┌────────┼────────┐
  ┌────▼───┐ ┌──▼────┐ ┌─▼────────┐
  │Research│ │Decision│ │Execution │
  │ Agent  │ │ Agent  │ │  Agent   │
  │ 检索引用│ │应用规则│ │审批后执行 │
  └────────┘ └───────┘ └──────────┘

代码实现很直觉——子 Agent 就是 subAgents 列表:

val rootAgent = LlmAgent(
    name = "MissionControl",
    model = Gemini(apiKey = apiKey, name = "gemini-2.5-flash"),
    instruction = Instruction("你是任务控制中心..."),
    subAgents = listOf(
        researchAgent,   // ? 检索子 Agent
        decisionAgent,   // ? 决策子 Agent
        executionAgent   // ? 执行子 Agent
    )
)

Router Agent 根据指令自动把任务分派给合适的子 Agent。

多 Agent 的好处不是"更强",而是"更可控"。每个 Agent 职责单一,出了问题一眼就能定位。


③ 人在回路(HITL)

Agent 自己做决策没问题,但涉及钱、数据、隐私的操作,必须让人确认

ADK 内置了完整的确认流程:

  • @Tool(requireConfirmation = true) 标记敏感工具;
  • Agent 调用到该工具时自动暂停;
  • 暂停状态可序列化、持久化(用户可以关掉 App 再回来);
  • 用户确认后恢复执行。
@Tool(requireConfirmation = true) // ? 标记需要确认
suspend fun transferFunds(
    @Param("目标账户") targetAccount: String,
    @Param("金额") amount: Double
): TransferResult {
    // 只有用户确认后才会执行到这里
    return bankService.transfer(targetAccount, amount)
}

在 Android 上,确认可以是一个 Compose 弹窗、一条通知、甚至一个深链接。

HITL 不是可选的"高级功能",是生产级 Agent 的底线。没有它,Agent 就是一颗定时炸弹。


④ Android 设备端扩展

这是 Kotlin ADK 独有的——Python / JS 版没有。

扩展作用
LiteRT-LM设备端跑 Gemma 等小模型,离线可用
ML Kit GenAI设备端 Gemini Nano,隐私优先
Firebase AI Logic云端 Gemini,适合复杂推理
Room 持久化会话状态存 SQLite,App 被杀也不丢
AppSearch 语义记忆设备端全文索引,Agent 的"长期记忆"
FileArtifactService管理 Agent 生成的文件产物

混合架构的典型用法:

// 云端模型做主编排
val orchestrator = LlmAgent(
    model = Firebase.create("gemini-3.8-flash", firebaseAi),
    subAgents = listOf(onDeviceAgent) // ? 设备端子 Agent
)

// 设备端模型处理隐私数据
val onDeviceAgent = LlmAgent(
    model = GenaiPrompt.create(generativeModel, name = "gemini-nano"),
    instruction = Instruction("你负责处理用户的本地文档...")
)

Android 扩展是 Kotlin ADK 的护城河。Python 写不了端侧 Agent,JS 也做不到 Room + AppSearch 级别的本地持久化。


? 选型:Kotlin vs Python vs JS

ADK 目前有三个语言版本。选哪个?

维度ADK KotlinADK PythonADK JS/TS
主战场Android + 服务端服务端 + 数据/MLWeb + Node.js
设备端推理✅ LiteRT-LM / ML Kit
类型安全✅ 编译期 KSP❌ 运行时部分(TS)
本地持久化✅ Room + AppSearch
生态集成Jetpack / Compose / CoroutinesPyTorch / NumPy / LangChainReact / Next.js
Java 互操作✅ 一等公民

选型建议

  • 你是 Android 开发者 → 选 Kotlin,没悬念;
  • 你做后端 ML / 数据流水线 → 选 Python;
  • 你做 Web 应用 → 选 JS/TS;
  • 你的产品同时有 Android 端 + 服务端 → 客户端 Kotlin ADK + 服务端 Python ADK,混合分工

不存在"最好的 ADK",只有"最适合你战场的 ADK"


? 实战上手:5 分钟跑通第一个 Agent

步骤 1:添加依赖

// build.gradle.kts
plugins {
    id("com.android.application")
    kotlin("android")
    id("com.google.devtools.ksp") version "2.1.20-2.0.1"
}

dependencies {
    // 核心引擎(Android 版)
    implementation("com.google.adk:google-adk-kotlin-core-android:1.0.0")
    // KSP 处理器(编译期生成 Tool Schema)
    ksp("com.google.adk:google-adk-kotlin-processor:1.0.0")
    // 云端模型(可选,按需引入)
    implementation("com.google.adk:google-adk-kotlin-firebase-android:1.0.0")
}

⚠️ Android 项目用 google-adk-kotlin-core-android,不是 google-adk-kotlin-core。别引错了。

步骤 2:定义工具

class TimeService {
    @Tool
    fun getCurrentTime(
        @Param("城市名称") city: String
    ): Map<String, String> {
        // 实际项目替换为真实时区查询
        return mapOf("city" to city, "time" to "10:30 AM")
    }
}

步骤 3:创建 Agent

val rootAgent = LlmAgent(
    name = "time_agent",
    description = "查询指定城市的当前时间",
    model = Gemini(name = "gemini-flash-latest", apiKey = API_KEY),
    instruction = Instruction("你是一个时间查询助手,用中文回答。"),
    tools = TimeService().generatedTools() // ? KSP 自动生成
)

步骤 4:运行

val runner = InMemoryRunner(
    agent = rootAgent,
    sessionService = InMemorySessionService()
)

scope.launch {
    runner.runAsync(
        userId = "user-123",
        sessionId = "session-001",
        newMessage = Content(
            role = Role.USER,
            parts = listOf(Part(text = "北京现在几点?"))
        )
    ).collect { event ->
        val text = event.content?.parts?.firstOrNull()?.text
        if (!text.isNullOrBlank()) {
            println(text) // ✅ 输出 Agent 回复
        }
    }
}

四步跑通。@Tool 定义能力,LlmAgent 组装智能体,InMemoryRunner 运行。

5 分钟从零到能跑,这是 ADK 上手体验最好的地方


最后

ADK for Kotlin 1.0 GA,这件事对 Android 开发者的意义在于:

  • AI Agent 不再是 Python 的专利——Kotlin 有了完整的、生产级的方案;
  • 端侧 Agent 是 Kotlin 独占优势——LiteRT-LM、Room、AppSearch,Python 做不到;
  • @Tool + KSP 是最优雅的工具定义方式——编译期生成,零反射,类型安全。

你会用 ADK 做什么 Agent?评论区聊聊!

? 参考资料:adk.dev/get-started…

相关文章

精彩推荐