透過 ML Kit 的直接模型存取功能,您可以使用函式呼叫,讓 Gemini Nano 模型輸出結構化函式執行要求 (工具呼叫),而非純文字回覆。函式呼叫可讓您將裝置端生成式 AI 模型,連結至外部工具、API 和本機應用程式功能。
主要功能
呼叫函式提供下列主要功能:
- 單輪函式呼叫:Gemini Nano 預測一或多個工具呼叫 (
FunctionCall),應用程式在本機執行函式,流程完成,不需要後續模型回覆。 - 多輪函式呼叫:Gemini Nano 會預測一或多個工具呼叫 (
FunctionCall),應用程式會在本機執行函式,並將結果傳回 (FunctionResponsePart),以擷取更多工具呼叫或最終合成文字回應。
實作函式呼叫時,您可以善用下列功能:
- 程式輔助工具定義:使用 ML Kit GenAI Schema API (
com.google.mlkit:genai-schema),在執行階段建構動態FunctionDeclaration和FunctionSchema工具定義。 - 結構化引數剖析:直接從模型回覆候選項目接收強型別引數值,執行本機應用程式邏輯。
搜尋結果範例
函式呼叫支援單輪和多輪對話流程。無論是哪種情況,模型都會預測一或多個工具呼叫,其中包含函式名稱和引數。如果是多輪對話流程,應用程式收到執行結果後,可以將完整的對話記錄傳送給模型,取得更多工具呼叫或最終文字回覆,再提供給使用者。
| 執行流程 | 使用者提示詞 | 模型輸出 |
|---|---|---|
| 單輪 | 「將客廳燈光亮度調到 80%。」 |
工具呼叫:turn_on_light(room="living room", brightness=80)
|
| 單輪 | 「開啟『相機』應用程式。」 |
工具呼叫:open_app(appName="Camera")
|
| 多輪 | 「舊金山的天氣如何?請用攝氏回答。」 |
中繼工具呼叫:get_current_weather(location="San Francisco, CA", unit="celsius")
向使用者顯示的最終模型輸出內容: In SF it's currently 25 degrees Celsius.
|
必要條件
如要使用呼叫函式功能,裝置和帳戶必須符合下列條件:
- 裝置支援 Prompt API。
- 裝置上的 Google 帳戶已加入 AICore 開發人員預覽版計畫。
如要確認是否符合這些需求,請檢查 AICore 應用程式中是否有 Gemini Nano 4 Fast 模型:開啟 AICore 應用程式,按一下「Select a model」下拉式選單,然後確認清單中是否有「Gemini Nano 4 Fast」。如果沒有,表示裝置支援或帳戶註冊有問題,無法使用呼叫函式。
此外,專案必須符合下列規定:
- Kotlin 2.3.0 以上版本
- SDK (
minSdk) 最低版本為 26
開始使用
以下是開始使用函式呼叫功能的步驟。
在專案層級的
settings.gradle.kts(或settings.gradle) 檔案中,將mavenCentral()新增至repositories {}區塊。dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }在模組層級
build.gradle.kts(或build.gradle檔案) 中,新增 ML Kit Prompt API 和結構定義依附元件:Kotlin
plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } dependencies { // ML Kit GenAI Prompt and Schema SDKs implementation("com.google.mlkit:genai-prompt:1.0.0-beta5") implementation("com.google.mlkit:genai-schema:1.0.0-alpha2") }Groovy
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } dependencies { // ML Kit GenAI Prompt and Schema SDKs implementation 'com.google.mlkit:genai-prompt:1.0.0-beta5' implementation 'com.google.mlkit:genai-schema:1.0.0-alpha2' }在模組層級
build.gradle(或build.gradle.kts檔案) 中,將minSdk版本設為26以上。Kotlin
android { defaultConfig { // ... minSdk = 26 // ... } }Groovy
android { defaultConfig { // ... minSdk 26 // ... } }
如何使用呼叫函式 API
如要實作函式呼叫,請按照下列步驟操作:
- 定義工具。
- 選取模型。
- 在要求中附加工具。
- 處理工具呼叫 (單輪或多輪)。
接下來,我們將透過範例示範這些步驟。
定義工具
使用 com.google.mlkit.genai.schema.tools 套件中的 FunctionDeclaration、FunctionSchema 和 FunctionType,透過程式輔助方式建構工具結構定義。(如要在編譯時間使用 Android 的 @AppFunction 註解和自動執行功能,以宣告方式定義工具,請參閱「定義工具」)。
舉例來說,您可以定義動作導向工具 (例如開啟智慧型燈具,執行單一回合):
import com.google.mlkit.genai.schema.tools.FunctionDeclaration
import com.google.mlkit.genai.schema.tools.FunctionSchema
import com.google.mlkit.genai.schema.tools.FunctionType
val turnOnLightTool = FunctionDeclaration(
name = "turn_on_light",
description = "Turn on the lights in a room and set the brightness",
parameters = FunctionSchema(
type = FunctionType.OBJECT,
properties = mapOf(
"room" to FunctionSchema(
type = FunctionType.STRING,
description = "The room name"
),
"brightness" to FunctionSchema(
type = FunctionType.INTEGER,
description = "Brightness level from 0 to 100"
)
),
required = listOf("room")
)
)
或者,您也可以定義資料擷取工具 (例如擷取目前天氣資訊,用於多輪合成):
import com.google.mlkit.genai.schema.tools.FunctionDeclaration
import com.google.mlkit.genai.schema.tools.FunctionSchema
import com.google.mlkit.genai.schema.tools.FunctionType
val getWeatherTool = FunctionDeclaration(
name = "get_current_weather",
description = "Get the current weather for a location",
parameters = FunctionSchema(
type = FunctionType.OBJECT,
properties = mapOf(
"location" to FunctionSchema(
type = FunctionType.STRING,
description = "The city and state, e.g. San Francisco, CA"
),
"unit" to FunctionSchema(
type = FunctionType.STRING,
description = "The temperature unit, either 'celsius' or 'fahrenheit'"
)
),
required = listOf("location")
)
)
選取模型
呼叫函式需要 Gemini Nano 4。如要存取 Gemini Nano 4,請使用模型選取 API,將 GenerativeModel 執行個體設為指定 ModelReleaseStage.PREVIEW 和 ModelPreference.FAST。
import com.google.mlkit.genai.prompt.Generation
import com.google.mlkit.genai.prompt.ModelPreference
import com.google.mlkit.genai.prompt.ModelReleaseStage
import com.google.mlkit.genai.prompt.generationConfig
import com.google.mlkit.genai.prompt.modelConfig
// Target the preview fast model (Gemini Nano 4)
val config = generationConfig {
modelConfig = modelConfig {
releaseStage = ModelReleaseStage.PREVIEW
preference = ModelPreference.FAST
}
}
val generativeModel = Generation.getClient(config)
在要求中附加工具
建立 GenerateContentRequest 物件時,請將 FunctionDeclaration 清單傳遞至要求建構工具中的 setTools()。
舉例來說,如要為單一回合動作要求附加工具,並提供系統指令:
import com.google.mlkit.genai.prompt.SystemInstruction
import com.google.mlkit.genai.prompt.TextPart
import com.google.mlkit.genai.prompt.generateContentRequest
val requestText = "Turn on the living room lights and set brightness to 50"
val request = generateContentRequest(
SystemInstruction("You are a helpful home automation assistant."),
TextPart(requestText)
) {
// Attach the FunctionDeclaration tool schemas
setTools(listOf(turnOnLightTool))
temperature = 0.2f
}
// Run non-streaming inference
val response = generativeModel.generateContent(request)
或附加 FunctionDeclaration 清單,進行多輪查詢:
import com.google.mlkit.genai.prompt.SystemInstruction
import com.google.mlkit.genai.prompt.TextPart
import com.google.mlkit.genai.prompt.generateContentRequest
val availableTools = listOf(getWeatherTool)
// Use the generateContentRequest DSL
val request = generateContentRequest(
TextPart("What is the weather in San Francisco, CA in celsius?")
) {
setTools(availableTools)
}
val response = generativeModel.generateContent(request)
處理工具呼叫
當 Gemini Nano 決定叫用工具時,模型的回覆候選項目會在 candidate.functionCalls 中包含一或多個 FunctionCall 物件。如要處理工具呼叫,應用程式必須先檢查候選回覆,確認是否預測到任何工具呼叫:
import com.google.mlkit.genai.common.FunctionArgValue
import com.google.mlkit.genai.prompt.Content
import com.google.mlkit.genai.prompt.FunctionCallPart
import com.google.mlkit.genai.prompt.FunctionResponsePart
import com.google.mlkit.genai.prompt.GenerateContentRequest
import com.google.mlkit.genai.prompt.TextPart
import com.google.mlkit.genai.prompt.content
val candidate = response.candidates.firstOrNull()
val functionCalls = candidate?.functionCalls ?: emptyList()
if (functionCalls.isNotEmpty()) {
// Process tool calls using either the single-turn or multi-turn flow
// described in the following sections
}
單輪呼叫函式
如果應用程式可直接執行要求 (例如「開啟相機應用程式」或「開啟客廳燈」),請使用單輪函式呼叫。應用程式在本機執行函式後,流程即完成,不需要後續的模型回覆。
for (functionCall in functionCalls) {
val name = functionCall.name
val args = functionCall.arguments // Map<String, FunctionArgValue>
when (name) {
"open_app" -> {
val appName = (args["appName"] as? FunctionArgValue.StringValue)?.value
launchApp(appName)
}
"turn_on_light" -> {
val room = (args["room"] as? FunctionArgValue.StringValue)?.value
val brightness = (args["brightness"] as? FunctionArgValue.IntValue)?.value ?: 100
setLightState(room, brightness)
}
else -> Log.w(TAG, "Unhandled tool call: $name")
}
}
多輪呼叫函式
如果使用者預期根據工具擷取的資料,取得自然語言答案 (例如「舊金山天氣如何?」),請使用多輪呼叫函式。
在多輪對話流程中,應用程式會執行下列操作:
- 在本機執行要求的函式。
- 將結果封裝在
FunctionResponsePart物件中。 - 將模型的呼叫 (
MODEL角色) 和執行結果 (USER角色) 附加至對話記錄。 - 將後續要求傳回 Gemini Nano,合成最終的自然語言答案。
// 1. Execute each predicted tool call and collect results
val responseParts = mutableListOf<FunctionResponsePart>()
for (functionCall in functionCalls) {
val responsePart: FunctionResponsePart = when {
functionCall.name == "get_current_weather" -> {
val location = (functionCall.arguments["location"] as? FunctionArgValue.StringValue)?.value ?: ""
val unit = (functionCall.arguments["unit"] as? FunctionArgValue.StringValue)?.value ?: "celsius"
val weatherData = fetchWeather(location, unit) // Local network/API call
// Package the tool execution result as a key-value map
FunctionResponsePart(
id = functionCall.id,
name = functionCall.name,
response = mapOf("result" to weatherData)
)
}
else -> throw IllegalArgumentException("Unknown tool: ${functionCall.name}")
}
responseParts.add(responsePart)
}
// 2. Append turns to conversation history to construct the multi-turn context
val history = request.contents.toMutableList().apply {
// Turn 1: Model's request containing the predicted FunctionCallPart object
add(
content(Content.Role.MODEL) {
for (call in functionCalls) {
addPart(FunctionCallPart(call))
}
}
)
// Turn 2: User's response containing the executed FunctionResponsePart object
add(
content(Content.Role.USER) {
for (responsePart in responseParts) {
addPart(responsePart)
}
}
)
}
// 3. Send the updated history back to Gemini Nano for final text synthesis
val followUpRequest = GenerateContentRequest.Builder(history)
.setTools(availableTools) // Include tools in case the model requires subsequent tool calls
.build()
val finalResponse = generativeModel.generateContent(followUpRequest)
val answer = finalResponse.candidates.firstOrNull()?.text
Log.d(TAG, "Final Model Response: $answer")
程式碼範例
如需 Android 應用程式中函式呼叫的完整範例,請參閱這個 ML Kit 範例應用程式。
已知問題
- 直接存取模型 (
genai-prompt) 中的 AndroidX AppFunctions (@AppFunction):目前無法直接透過 Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) 探索及執行編譯時間@AppFunction工具;genai-prompt程式庫中的工具必須使用FunctionDeclaration類別,以程式輔助方式定義。如要立即使用@AppFunction工具,請使用Agentic Workflows (com.google.mlkit:genai-agent)。 - 使用串流要求 (
generateContentStream) 時,工具呼叫不會逐一串流詞元。模型產生工具呼叫後,會透過StreamingCallback.onNewFunctionCall或最終串流的GenerateContentResponse.candidates[0].functionCalls發出完整的FunctionCall物件。