重磅:繼 SDK、NDK 後,Google 新推出 ADK!

Google 發布了 `ADK for Kotlin` 和 `ADK for Android` 的 `0.1.0` 版本。

以後不只有 SDK、NDK,還有 ADK。

ADK for Kotlin 用在 Kotlin 後端和通用 JVM 場景,ADK for Android 用在 Android App 裡,主要處理端側模型和 App 內上下文。

添加依賴

在 Android 工程裡先加這個依賴:

bash 体验AI代码助手 代码解读复制代码dependencies {
    implementation("com.google.adk:google-adk-kotlin-core-android:0.1.0")
}

如果是一般 Kotlin 後端或 JVM 專案,用的是 google-adk-kotlin-core。需要透過註解生成工具程式碼時,還要加 KSP processor:

bash 体验AI代码助手 代码解读复制代码dependencies {
    implementation("com.google.adk:google-adk-kotlin-core:0.1.0")
    ksp("com.google.adk:google-adk-kotlin-processor:0.1.0")
}

0.1.0 還是實驗版本。它現在更像 Demo 專案裡的嘗鮮依賴,不適合直接接正式業務。Agent 呼叫失敗以後回傳什麼、模型不可用時怎麼降級、工具有沒有權限,這些都要在 App 程式碼裡處理。

Agent 寫法

寫 Agent 時會用到 LlmAgent。一個 Agent 裡會放模型、名稱、描述、系統指令、工具和子 Agent。下面是一個簡化後的旅遊助理。

旅遊助理裡有一個雲端 orchestrator,它先理解使用者的旅遊問題,再把訂票確認、飯店資訊、租車資訊這類任務交給裝置上的子 Agent 處理。訂票確認可能來自使用者本機文件,這一步可以交給 Gemini Nano 這類端側模型解析。程式碼只看核心欄位:

bash 体验AI代码助手 代码解读复制代码val orchestrator = LlmAgent(
    name = "trip_orchestrator",
    model = Gemini(apiKey = apiKey, name = MODEL_NAME),
    instruction = Instruction(
        """
        You are a travel assistant.
        Use get_trip_details to read the trip plan.
        Delegate booking checks to local sub agents when needed.
        """.trimIndent()
    ),
    tools = listOf(GetTripDetailsTool(tripId)),
    subAgents = listOf(carRentalPipeline, hotelPipeline),
    // 其他路由限制參數先省略,具體語義要看官方原始碼和 demo
)

這段程式碼裡,model 決定目前 Agent 要呼叫哪個模型,instruction 決定它怎麼理解任務,tools 是可呼叫能力,subAgents 是它可以轉交任務的下游 Agent。官方範例裡還有一些 transfer 相關參數,這裡不按名稱展開說明,等真的看原始碼或 demo 時再確認。

以前在 App 裡接一個大模型,很多時候只是把使用者輸入送到雲端介面,再把回覆顯示出來。換成 Agent 之後,ViewModel 裡那些「先查行程、再判斷訂單、最後組回覆」的分支會往 Agent 端挪,App 端更像是在等一個最終的 UI State。

放到 Android 裡之後,工具呼叫會碰到執行緒和生命週期。比如工具裡要讀取本地行程檔案,就要處理檔案不存在和讀取耗時;如果訂單資訊來自本地資料庫,也不要在主執行緒裡直接查詢。

工具呼叫

ADK for Kotlin 支援用 @Tool@Param 描述函式工具。工具本質上是把本地函式暴露給 Agent,讓模型在合適的時候呼叫它。

比如把一個訂單查詢能力交給 Agent,先看服務類:

bash 体验AI代码助手 代码解读复制代码class TripService {
    @Tool
    fun getBookingStatus(
        @Param("Booking id from the user's trip document")
        bookingId: String
    ): String {
        return repository.findBookingStatus(bookingId)
    }
}

@Tool@Param 只是描述工具,還不是完整接入。官方 Kotlin 範例裡會透過 google-adk-kotlin-processor 做 KSP 生成,然後才能在 Agent 裡使用類似 generatedTools() 的結果。

也就是說,如果程式碼裡寫成下面這樣還不夠:

bash 体验AI代码助手 代码解读复制代码dependencies {
    implementation("com.google.adk:google-adk-kotlin-core:0.1.0")
    ksp("com.google.adk:google-adk-kotlin-processor:0.1.0")
}

Android 工程還要配置 KSP 插件。實際專案裡一般會在根專案或版本目錄裡宣告 com.google.devtools.ksp,再在模組裡套用插件。KSP 版本要和 Kotlin 版本對齊,這裡不寫死版本,舊專案直接照搬很容易卡在 Gradle Sync。

再配置 Agent 時,generatedTools() 不是手寫出來的一般方法,而是註解處理後的產物。沒有 KSP 插件和 processor 這兩步,直接照抄這段程式碼大概率會編譯不過。

bash 体验AI代码助手 代码解读复制代码val bookingAgent = LlmAgent(
    name = "booking_agent",
    description = "Checks booking status from local trip data.",
    model = Gemini(apiKey = apiKey, name = "gemini-2.5-flash"),
    instruction = Instruction("Use tools to verify booking status."),
    tools = TripService().generatedTools()
)

這裡的 @Param 不只是給開發者看的註解,它會影響模型理解參數含義。參數從哪裡來、格式是什麼、失敗時回傳什麼,都要寫清楚。

如果工具函式裡要讀本地行程檔案,這些邏輯仍然走原本的 Android 程式碼。Agent 只拿工具回傳的結果,不應該跳過檔案不存在、讀取失敗和權限拒絕這些分支。

Session 和 Memory

這裡還有一個容易踩坑的地方:狀態。一個 Agent 問使用者補充資訊,另一個 Agent 要知道前面已經確認過什麼;工具呼叫失敗以後,後面的 Agent 也要知道這一步失敗了。否則上游吐了一個空結果,下游還繼續拼 prompt,最後使用者看到的就是一段像正常回答的幻覺回覆。

ADK 裡有 Session state 和 Memory service。Session state 更像短期狀態,服務於目前會話裡的上下文共享;Memory service 更偏長期記憶,可以保存跨會話的資訊。

在 Android 工程裡使用這些能力時,不要簡單理解成 SharedPreferences 或聊天紀錄。Agent 狀態可能包含使用者輸入、模型輸出、工具呼叫參數、本地資料摘要和錯誤資訊。哪些能落盤,哪些只能留在記憶體,哪些不能進日誌,需要先訂好規則。

最後

我真的學不動了。

#Android #Kotlin #ADK #GeminiNano #AI


原文出處:https://juejin.cn/post/7647438301877501978


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝6   💬2  
337
🥈
我愛JS
💬1  
3
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登