Google ADK for Kotlin 1.0发布
Google正式发布Kotlin版Agent开发套件,实现与Python/Java ADK的功能对等,基于KMP实现多平台开发,支持本地模型(LiteRT-LM)和Firebase云推理。
完整中文译文
今天,我们激动地宣布 Kotlin 版 Agent Development Kit(ADK)1.0 正式发布!欢迎访问 GitHub 仓库深入了解代码,并从今天开始构建你的第一个 Agent。也可以先查阅文档。
在推出 ADK for Kotlin 0.1.0 时,我们的使命是将惯用的、轻量的、可组合的 AI Agent 开发能力带给 Kotlin、Java 和 Android 开发者。过去几个月里,我们一直在努力将这个框架打磨成一个生产可用的工具包。
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 Core 对标
ADK for Kotlin 1.0 与 ADK Python 和 Java 完全对齐,将先进的多 Agent 协调模式带入惯用的 Kotlin:
- 层级式多 Agent 系统:将 Agent 链接起来,并向专业子 Agent 委托任务。
- 上下文压缩与多轮对话:通过总结历史来管理上下文,保持在 token 限制内。
- 人机交互(HITL)和确认流程:暂停执行,请求用户确认敏感操作,然后恢复执行。
- 长时运行与基于注解的工具:使用
@Tool和@Param注解在 Kotlin 中自动生成工具模式。 - 会话可恢复性:跨用户会话暂停、序列化和恢复活跃的 Agent 交互。
- 原生 Java 互操作:从现有 Java 应用直接调用 ADK Kotlin Agent。
- 企业 Agent 平台(VertexAI)集成:
VertexAiSessionService、VertexAiRagMemoryService、VertexAiMemoryBankService。
⛑️ 数据库事故响应 Agent 示例
让我们来体验一下 ADK for Kotlin 1.0,构建一个调查生产数据库告警的事故分诊和诊断 Agent。我们的 Agent 将利用 ADK 的函数调用和 Agent 技能能力:
- 工具(@Tool):可执行的、类型安全的功能(调用 API、查询指标、执行操作)。
- 技能(SkillToolset):通过渐进式Disclosure动态加载的按需程序性知识和领域剧本(SKILL.md、检查清单、模板)。
ADK 利用 KSP(Kotlin Symbol Processing)在编译时生成函数调用定义,为你提供类型安全的模式、对 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()。
不要将分诊指南硬编码在代码中,而是将标准操作程序放在 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 使用量保持在最低——这被称为渐进式Disclosure的机制。
现在是时候以声明式的方式为 Agent 配备工具和技能了:
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()))),
)
}
Agent 准备就绪后,让我们用 Kotlin Coroutines 和 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") }
}
}
告警触发后,Agent 在结构化的轮次循环中自主执行:
- 发现并加载 database-incident-triage 技能及其安全防护栏。
- 调用
getServiceMetrics()→ 识别出 98.5% 的连接池饱和。 - 调用
fetchRecentDeployments()→ 锁定 deploy-9842("Add unindexed batch query...",25 分钟前)为根本原因。 - 向
#production-alerts发布更新,并呈现一份事故后报告,建议立即回滚。
📱 面向 Android 的及设备端扩展
在服务端生产级 Agent 之后,让我们回到 ADK for Kotlin 的移动端能力。现代移动 AI 需要在云端推理能力与设备端隐私、速度和离线可靠性之间取得平衡。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()}"
}
}
以下是配置 Agent 的方式,使用通过 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()
)
}
我们用 Room 支持的会话服务和 AppSearch 驱动的记忆服务来配置 InMemoryRunner:
// 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)
)
}
是时候运行 Agent 了,包含请求转账和通过人工批准确认转账的两轮交互:
// 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)
}
📊 ADK for Kotlin 功能对比——Core 与 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")
}
🔗 资源与文档
探索仓库、查看示例应用,开始构建你的多 Agent 体验:
- 🎬 ADK 文档与入门:adk.dev
- 📖 GitHub 仓库:github.com/google/adk-kotlin
- 🧩 模块化架构指南:ADK Kotlin 模块文档
- 📱 设备端与云端指南:用 ADK 构建 Android Agent
- 🛠️ 功能展示:所有 Kotlin 示例
- ☕ Java 互操作示例:ADK Kotlin Java 示例
无论你在服务端 JVM 上还是在 Android 移动设备上开发 Agent,我们都迫不及待地想看到你如何使用 ADK for Kotlin!给仓库点个 Star,尝试示例,并与我们分享你的反馈!