Mit dem direkten Modellzugriff von ML Kit können Sie Funktionsaufrufe verwenden, damit Gemini Nano-Modelle strukturierte Anfragen zur Funktionsausführung (Toolaufrufe) anstelle von Nur-Text-Antworten ausgeben. Mit Funktionsaufrufen können Sie generative KI-Modelle auf dem Gerät mit externen Tools, APIs und lokalen App-Funktionen verbinden.
Hauptmerkmale
Funktionsaufrufe bieten die folgenden Hauptfunktionen:
- Funktionsaufruf in einer einzelnen Runde: Gemini Nano sagt einen oder mehrere Toolaufrufe (
FunctionCall) vorher, Ihre App führt die Funktionen lokal aus und der Ablauf wird ohne eine weitere Modellantwort abgeschlossen. - Funktionsaufrufe in mehreren Runden: Gemini Nano sagt einen oder mehrere Toolaufrufe (
FunctionCall) vorher, Ihre App führt die Funktionen lokal aus und gibt die Ergebnisse zurück (FunctionResponsePart), um weitere Toolaufrufe oder eine endgültige synthetisierte Textantwort abzurufen.
Bei der Implementierung von Funktionsaufrufen können Sie die folgenden Vorteile nutzen:
- Programmatische Tooldefinitionen: Erstellen Sie dynamische
FunctionDeclaration- undFunctionSchema-Tooldefinitionen zur Laufzeit mit der ML Kit GenAI Schema API (com.google.mlkit:genai-schema). - Strukturiertes Argument-Parsing: Sie erhalten stark typisierte Argumentwerte direkt aus dem Modellantwortkandidaten, um Ihre lokale Anwendungslogik auszuführen.
Beispielergebnisse
Funktionsaufrufe unterstützen sowohl Einzelrunden- als auch Mehrrunden-Abläufe. In beiden Fällen sagt das Modell einen oder mehrere Toolaufrufe voraus, die aus dem Funktionsnamen und den Argumenten bestehen. Bei Multi-Turn-Abläufen kann die Anwendung nach Erhalt der Ausführungsergebnisse eine weitere Anfrage mit dem vollständigen Unterhaltungsverlauf an das Modell senden, um weitere Toolaufrufe oder eine endgültige Textantwort für den Nutzer zu erhalten.
| Ablauf der Ausführung | Nutzer-Prompt | Modellausgabe |
|---|---|---|
| In einem Schritt | „Stelle die Helligkeit der Wohnzimmerbeleuchtung auf 80 %.“ |
Toolaufruf:turn_on_light(room="living room", brightness=80)
|
| In einem Schritt | „Öffne die Kamera.“ |
Toolaufruf:open_app(appName="Camera")
|
| In mehreren Schritten | „Wie ist das Wetter in San Francisco in Celsius?“ |
Zwischenaufruf des Tools:get_current_weather(location="San Francisco, CA", unit="celsius")
Endgültige Modellausgabe, die dem Nutzer angezeigt wird: In SF it's currently 25 degrees Celsius.
|
Vorbereitung
Damit Sie Funktionsaufrufe verwenden können, müssen die folgenden Geräte- und Kontoanforderungen erfüllt sein:
- Ihr Gerät unterstützt die Prompt API.
- Das Google-Konto auf deinem Gerät ist Teil der AICore-Entwicklervorschau.
Prüfen Sie, ob das Modell Gemini Nano 4 Fast in der AICore App verfügbar ist, um sicherzustellen, dass Sie diese Anforderungen erfüllen: Öffnen Sie die AICore App, klicken Sie auf das Drop-down-Menü Modell auswählen und prüfen Sie, ob Gemini Nano 4 Fast aufgeführt ist. Wenn das Modell nicht vorhanden ist, liegt ein Problem mit der Geräteunterstützung oder der Kontoanmeldung vor und Funktionsaufrufe funktionieren nicht.
Außerdem muss Ihr Projekt die folgenden Anforderungen erfüllen:
- Kotlin-Version 2.3.0 oder höher
- Mindest-SDK-Version (
minSdk) 26 oder höher
Jetzt starten
So verwenden Sie Funktionsaufrufe:
Fügen Sie in der Datei
settings.gradle.kts(odersettings.gradle) auf ProjektebenemavenCentral()zum Blockrepositories {}hinzu.dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }Fügen Sie in der Datei
build.gradle.kts(oderbuild.gradle) auf Modulebene die Abhängigkeiten für die ML Kit Prompt API und das Schema hinzu: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' }Legen Sie in der Datei
build.gradle(oderbuild.gradle.kts) auf Modulebene für dieminSdk-Version26oder höher fest.Kotlin
android { defaultConfig { // ... minSdk = 26 // ... } }Groovy
android { defaultConfig { // ... minSdk 26 // ... } }
Function Calling API verwenden
So implementieren Sie Funktionsaufrufe:
- Tools definieren
- Wählen Sie das Modell aus.
- Tools an Ihre Anfrage anhängen.
- Toolaufrufe verarbeiten (einzelner oder mehrere Schritte)
In den nächsten Abschnitten wird ein Beispiel für diese Schritte gezeigt.
Tools definieren
Erstellen Sie Toolschemas programmatisch mit FunctionDeclaration, FunctionSchema und FunctionType aus dem Paket com.google.mlkit.genai.schema.tools. (Informationen zum deklarativen Definieren von Tools zur Kompilierzeit mit der Android-Annotation @AppFunction und automatischer Ausführung finden Sie unter Tools definieren.)
Sie können beispielsweise ein aktionsorientiertes Tool definieren (z. B. das Einschalten einer smarten Lampe für die Ausführung in einem Schritt):
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")
)
)
Sie können auch ein Tool zum Abrufen von Daten definieren (z. B. zum Abrufen des aktuellen Wetters für die Multi-Turn-Synthese):
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")
)
)
Modell auswählen
Für Funktionsaufrufe ist Gemini Nano 4 erforderlich. Wenn Sie auf Gemini Nano 4 zugreifen möchten, verwenden Sie die Model Selection API, um Ihre GenerativeModel-Instanz so zu konfigurieren, dass sie auf ModelReleaseStage.PREVIEW UND ModelPreference.FAST abzielt.
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)
Tools an Ihre Anfrage anhängen
Übergeben Sie beim Erstellen eines GenerateContentRequest-Objekts die FunctionDeclaration-Liste an setTools() im Request Builder.
So hängen Sie beispielsweise ein Tool für eine Aktionsanfrage mit einer Systemanweisung an:
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)
Oder um Ihre FunctionDeclaration-Liste für eine Anfrage mit mehreren Durchgängen anzuhängen:
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)
Toolaufrufe verarbeiten
Wenn Gemini Nano entscheidet, ein Tool aufzurufen, enthält der Antwortkandidat des Modells ein oder mehrere FunctionCall-Objekte in candidate.functionCalls. Damit Ihre Anwendung Toolaufrufe verarbeiten kann, muss sie zuerst den Antwortkandidaten prüfen, um festzustellen, ob Toolaufrufe vorhergesagt wurden:
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
}
Einzelrunden-Funktionsaufruf
Verwenden Sie Funktionsaufrufe mit einer einzelnen Runde für aktionsorientierte Aufgaben, bei denen die App die Anfrage direkt erfüllt (z. B. „Öffne die Kamera-App“ oder „Schalte das Licht im Wohnzimmer ein“). Sobald Ihre Anwendung die Funktion lokal ausführt, ist der Ablauf abgeschlossen. Es ist keine weitere Modellantwort erforderlich.
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")
}
}
Funktionsaufrufe in mehreren Runden
Verwenden Sie Funktionsaufrufe mit mehreren Durchgängen, wenn der Nutzer eine Antwort in natürlicher Sprache erwartet, die auf den vom Tool abgerufenen Daten basiert (z. B. „Wie ist das Wetter in San Francisco?“).
In einem Multi-Turn-Ablauf führt Ihre Anwendung die folgenden Schritte aus:
- Führt die angeforderte Funktion lokal aus.
- Verpackt das Ergebnis in ein
FunctionResponsePart-Objekt. - Hängt sowohl den Aufruf des Modells (Rolle
MODEL) als auch das Ausführungsergebnis (RolleUSER) an den Unterhaltungsverlauf an. - Sendet eine Folgeanfrage an Gemini Nano, um die endgültige Antwort in natürlicher Sprache zu generieren.
// 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")
Beispielcode
Ein vollständiges, funktionierendes Beispiel für Funktionsaufrufe in einer Android-App finden Sie in dieser ML Kit-Beispiel-App.
Bekannte Probleme
- AndroidX AppFunctions (
@AppFunction) im direkten Modellzugriff (genai-prompt): Das Erkennen und Ausführen von@AppFunction-Tools zur Kompilierzeit direkt über die Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) ist noch nicht verfügbar. Tools in dergenai-prompt-Bibliothek müssen programmatisch mit der KlasseFunctionDeclarationdefiniert werden. Wenn Sie@AppFunction-Tools verwenden möchten, nutzen Sie agentische Workflows (com.google.mlkit:genai-agent). - Bei Streaminganfragen (
generateContentStream) werden Toolaufrufe nicht Token für Token gestreamt. Stattdessen werden vollständigeFunctionCall-Objekte (überStreamingCallback.onNewFunctionCalloder im endgültigen gestreamtenGenerateContentResponse.candidates[0].functionCalls) ausgegeben, sobald das Modell die Generierung des Toolaufrufs abgeschlossen hat.