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 建立在完全与特定模型后端、会话提供者或记忆系统无关的 Kotlin Multiplatform(KMP)核心之上。1.0 版本结合了本地和云场景的核心多 Agent 编排能力,以及面向目标移动设备的即插即用 Android 扩展。
ADK for Kotlin 1.0 与 ADK Python 和 Java 完全对齐,将先进的多 Agent 协调模式带入惯用的 Kotlin:
@Tool 和 @Param 注解在 Kotlin 中自动生成工具模式。VertexAiSessionService、VertexAiRagMemoryService、VertexAiMemoryBankService。让我们来体验一下 ADK for Kotlin 1.0,构建一个调查生产数据库告警的事故分诊和诊断 Agent。我们的 Agent 将利用 ADK 的函数调用和 Agent 技能能力:
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 在结构化的轮次循环中自主执行:
getServiceMetrics() → 识别出 98.5% 的连接池饱和。fetchRecentDeployments() → 锁定 deploy-9842("Add unindexed batch query...",25 分钟前)为根本原因。#production-alerts 发布更新,并呈现一份事故后报告,建议立即回滚。在服务端生产级 Agent 之后,让我们回到 ADK for Kotlin 的移动端能力。现代移动 AI 需要在云端推理能力与设备端隐私、速度和离线可靠性之间取得平衡。ADK for Kotlin 1.0 为标准 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 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 体验:
无论你在服务端 JVM 上还是在 Android 移动设备上开发 Agent,我们都迫不及待地想看到你如何使用 ADK for Kotlin!给仓库点个 Star,尝试示例,并与我们分享你的反馈!