Funktionsaufrufe verwenden

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- und FunctionSchema-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:

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:

  1. Fügen Sie in der Datei settings.gradle.kts (oder settings.gradle) auf Projektebene mavenCentral() zum Block repositories {} hinzu.

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
        }
    }
    
  2. Fügen Sie in der Datei build.gradle.kts (oder build.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'
    }
    
  3. Legen Sie in der Datei build.gradle (oder build.gradle.kts) auf Modulebene für die minSdk-Version 26 oder höher fest.

    Kotlin

    android {
        defaultConfig {
            // ...
            minSdk = 26
            // ...
        }
    }
    

    Groovy

    android {
        defaultConfig {
            // ...
            minSdk 26
            // ...
        }
    }
    

Function Calling API verwenden

So implementieren Sie Funktionsaufrufe:

  1. Tools definieren
  2. Wählen Sie das Modell aus.
  3. Tools an Ihre Anfrage anhängen.
  4. 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:

  1. Führt die angeforderte Funktion lokal aus.
  2. Verpackt das Ergebnis in ein FunctionResponsePart-Objekt.
  3. Hängt sowohl den Aufruf des Modells (Rolle MODEL) als auch das Ausführungsergebnis (Rolle USER) an den Unterhaltungsverlauf an.
  4. 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 der genai-prompt-Bibliothek müssen programmatisch mit der Klasse FunctionDeclaration definiert 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ändige FunctionCall-Objekte (über StreamingCallback.onNewFunctionCall oder im endgültigen gestreamten GenerateContentResponse.candidates[0].functionCalls) ausgegeben, sobald das Modell die Generierung des Toolaufrufs abgeschlossen hat.