Dzięki bezpośredniemu dostępowi do modelu w ML Kit możesz używać wywoływania funkcji, aby umożliwić modelom Gemini Nano generowanie ustrukturyzowanych żądań wykonania funkcji (wywołań narzędzi) zamiast odpowiedzi w formie zwykłego tekstu. Wywoływanie funkcji umożliwia łączenie modeli generatywnej AI na urządzeniu z zewnętrznymi narzędziami, interfejsami API i funkcjami aplikacji lokalnych.
Najważniejsze funkcje
Wywoływanie funkcji zapewnia te kluczowe możliwości:
- Wywoływanie funkcji w jednej turze: Gemini Nano przewiduje jedno lub więcej wywołań narzędzi (
FunctionCall), aplikacja wykonuje funkcje lokalnie, a proces kończy się bez konieczności uzyskania odpowiedzi modelu. - Wieloturowe wywoływanie funkcji: Gemini Nano przewiduje co najmniej 1 wywołanie narzędzia (
FunctionCall), aplikacja wykonuje funkcje lokalnie i przekazuje wyniki (FunctionResponsePart), aby pobrać więcej wywołań narzędzi lub ostateczną, zsyntetyzowaną odpowiedź tekstową.
Podczas implementowania wywoływania funkcji możesz korzystać z tych rozwiązań:
- Definicje narzędzi automatycznych: twórz dynamiczne definicje narzędzi
FunctionDeclarationiFunctionSchemaw czasie działania za pomocą interfejsu ML Kit GenAI Schema API (com.google.mlkit:genai-schema). - Analiza argumentów strukturalnych: otrzymuj silnie typowane wartości argumentów bezpośrednio z odpowiedzi modelu kandydującego, aby wykonywać lokalną logikę aplikacji.
Przykładowe wyniki
Wywoływanie funkcji obsługuje zarówno przepływy jednoetapowe, jak i wieloetapowe. W obu przypadkach model przewiduje co najmniej 1 wywołanie narzędzia, które składa się z nazwy funkcji i argumentów. W przypadku wieloetapowych procesów po otrzymaniu wyników wykonania aplikacja może wysłać do modelu kolejną prośbę z pełną historią rozmowy, aby uzyskać więcej wywołań narzędzi lub ostateczną odpowiedź tekstową dla użytkownika.
| Przepływ wykonywania | Prompt użytkownika | Dane wyjściowe modelu |
|---|---|---|
| Jednoetapowe | „Ustaw jasność światła w salonie na 80%”. |
Wywołanie narzędzia:turn_on_light(room="living room", brightness=80)
|
| Jednoetapowe | „Otwórz aplikację Aparat”. |
Wywołanie narzędzia:open_app(appName="Camera")
|
| Wieloetapowe | „Jaka jest pogoda w San Francisco w stopniach Celsjusza?” |
Wywołanie narzędzia pośredniego:get_current_weather(location="San Francisco, CA", unit="celsius")
Ostateczne dane wyjściowe modelu wyświetlane użytkownikowi: In SF it's currently 25 degrees Celsius.
|
Wymagania wstępne
Aby korzystać z wywoływania funkcji, musisz spełniać te wymagania dotyczące urządzenia i konta:
- Twoje urządzenie obsługuje Prompt API.
- Konto Google na Twoim urządzeniu jest objęte programem AICore w wersji przedpremierowej dla programistów.
Aby sprawdzić, czy spełniasz te wymagania, upewnij się, że model Gemini Nano 4 Fast jest dostępny w aplikacji AICore: otwórz aplikację AICore, kliknij menu Wybierz model i sprawdź, czy na liście znajduje się Gemini Nano 4 Fast. Jeśli modelu nie ma na liście, oznacza to, że wystąpił problem z obsługą urządzenia lub rejestracją konta i wywoływanie funkcji nie będzie działać.
Projekt musi też spełniać te wymagania:
- Kotlin w wersji 2.3.0 lub nowszej,
- Minimalna wersja pakietu SDK (
minSdk): 26
Rozpocznij
Aby zacząć korzystać z wywoływania funkcji, wykonaj te czynności.
W pliku
settings.gradle.kts(lubsettings.gradle) na poziomie projektu dodajmavenCentral()do blokurepositories {}.dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }W pliku
build.gradle.kts(lubbuild.gradle) na poziomie modułu dodaj interfejs ML Kit Prompt API i zależności schematu: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") }Zakręcony
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' }W pliku
build.gradle(lubbuild.gradle.kts) na poziomie modułu ustaw wersjęminSdkna26lub nowszą.Kotlin
android { defaultConfig { // ... minSdk = 26 // ... } }Zakręcony
android { defaultConfig { // ... minSdk 26 // ... } }
Jak korzystać z interfejsu Function Calling API
Aby wdrożyć wywoływanie funkcji, wykonaj te czynności:
- Określ narzędzia.
- Wybierz model.
- Dołącz narzędzia do prośby.
- obsługiwać wywołania narzędzi (jedno- lub wieloetapowe);
W kolejnych sekcjach znajdziesz przykład, który ilustruje te kroki.
Definiowanie narzędzi
Twórz schematy narzędzi automatycznie, używając FunctionDeclaration, FunctionSchema i FunctionType z pakietu com.google.mlkit.genai.schema.tools. (Aby zdefiniować narzędzia deklaratywnie w czasie kompilacji za pomocą adnotacji @AppFunction na Androidzie z automatycznym wykonywaniem, zapoznaj się z artykułem Definiowanie narzędzi).
Możesz na przykład zdefiniować narzędzie zorientowane na działanie (takie jak włączenie inteligentnego oświetlenia w ramach pojedynczego wykonania):
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")
)
)
Możesz też zdefiniować narzędzie do pobierania danych (np. pobieranie aktualnej pogody na potrzeby syntezy wieloetapowej):
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")
)
)
Wybierz model.
Wywoływanie funkcji wymaga Gemini Nano 4. Aby uzyskać dostęp do Gemini Nano 4, użyj interfejsu API do wyboru modelu i skonfiguruj instancję GenerativeModel tak, aby była kierowana na ModelReleaseStage.PREVIEW ORAZ 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)
Dołącz narzędzia do prośby
Podczas tworzenia obiektu GenerateContentRequest przekaż listę FunctionDeclaration do setTools() w kreatorze żądań.
Aby na przykład dołączyć narzędzie do prośby o działanie w jednej turze z instrukcją systemową:
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)
Możesz też dołączyć listę FunctionDeclaration w przypadku zapytania wieloetapowego:
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)
Obsługa wywołań narzędzi
Gdy Gemini Nano zdecyduje się wywołać narzędzie, odpowiedź modelu zawiera co najmniej 1 obiekt FunctionCall w candidate.functionCalls. Aby obsłużyć wywołania narzędzi, aplikacja musi najpierw sprawdzić kandydata odpowiedzi, aby zweryfikować, czy zostały przewidziane jakieś wywołania narzędzi:
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
}
Jednoetapowe wywoływanie funkcji
Używaj wywoływania funkcji w jednej turze w przypadku zadań zorientowanych na działanie, w których aplikacja bezpośrednio realizuje żądanie (np. „Otwórz aplikację aparatu” lub „Włącz światła w Living Room”). Gdy aplikacja wykona funkcję lokalnie, proces jest zakończony. Nie jest wymagana żadna dalsza odpowiedź modelu.
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")
}
}
Wieloetapowe wywoływanie funkcji
Używaj wieloetapowego wywoływania funkcji, gdy użytkownik oczekuje odpowiedzi w języku naturalnym na podstawie danych pobranych przez narzędzie (np. „Jaka jest pogoda w San Francisco?”).
W przepływie wieloetapowym aplikacja wykonuje te czynności:
- Wykonuje żądaną funkcję lokalnie.
- Pakuje wynik w obiekt
FunctionResponsePart. - Dołącza do historii rozmowy zarówno wywołanie modelu (rola
MODEL), jak i wynik wykonania (rolaUSER). - wysyła do Gemini Nano prośbę o dalsze działania, aby wygenerować ostateczną odpowiedź w języku naturalnym.
// 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")
Przykładowy kod
Pełny, działający przykład wywoływania funkcji w aplikacji na Androida znajdziesz w tej przykładowej aplikacji ML Kit.
Znane problemy
- AndroidX AppFunctions (
@AppFunction) w ramach bezpośredniego dostępu do modelu (genai-prompt): wykrywanie i wykonywanie narzędzi@AppFunctionw czasie kompilacji bezpośrednio za pomocą interfejsu Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) nie jest jeszcze dostępne. Narzędzia w bibliotecegenai-promptmuszą być definiowane programowo za pomocą klasyFunctionDeclaration. Aby korzystać z narzędzi@AppFunction, używaj Agentic Workflows (com.google.mlkit:genai-agent). - W przypadku żądań strumieniowych (
generateContentStream) wywołania narzędzi nie są przesyłane strumieniowo token po tokenie. Zamiast tego po zakończeniu generowania wywołania narzędzia przez model emitowane są kompletne obiektyFunctionCall(za pomocąStreamingCallback.onNewFunctionCalllub w końcowym strumieniuGenerateContentResponse.candidates[0].functionCalls).