Благодаря прямому доступу к модели ML Kit вы можете использовать вызов функций, чтобы модели Gemini Nano выводили структурированные запросы на выполнение функций (вызовы инструментов) вместо обычных текстовых ответов. Вызов функций позволяет подключать встроенные модели генеративного ИИ к внешним инструментам, API и функциям локальных приложений.
Основные возможности
Вызов функций предоставляет следующие ключевые возможности:
- Одноэтапный вызов функций. Gemini Nano прогнозирует один или несколько вызовов инструментов (
FunctionCall), ваше приложение выполняет функции локально, и процесс завершается без необходимости последующего ответа модели. - Многоэтапный вызов функций. Gemini Nano прогнозирует один или несколько вызовов инструментов (
FunctionCall), ваше приложение выполняет функции локально и передает результаты обратно (FunctionResponsePart), чтобы получить больше вызовов инструментов или окончательный синтезированный текстовый ответ.
При реализации вызова функций вы можете воспользоваться следующими возможностями:
- Программные определения инструментов. Создавайте динамические определения инструментов
FunctionDeclarationиFunctionSchemaво время выполнения с помощью ML Kit GenAI Schema API (com.google.mlkit:genai-schema). - Структурированный синтаксический анализ аргументов. Получайте строго типизированные значения аргументов непосредственно из ответа модели, чтобы выполнять логику локального приложения.
Пример результатов
Вызов функций поддерживает как одноэтапные, так и многоэтапные процессы. В обоих случаях модель прогнозирует один или несколько вызовов инструментов, состоящих из имени функции и аргументов. В многоэтапных процессах после получения результатов выполнения приложение может отправить модели ещё один запрос с полной историей разговора, чтобы получить больше вызовов инструментов или окончательный текстовый ответ для пользователя.
| Процесс выполнения | Запрос пользователя | Выходные данные модели |
|---|---|---|
| Один поворот | "Включи свет в гостиной на 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.
Чтобы проверить, выполнены ли эти требования, убедитесь, что модель Gemini Nano 4 Fast доступна в приложении AICore. Для этого откройте приложение 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 вызова функций
Чтобы реализовать вызов функций, выполните следующие действия:
- Определите инструменты.
- Выберите модель.
- Прикрепите инструменты к запросу.
- Обработка вызовов инструментов (одно- или многоэтапных).
В следующих разделах приведен пример, демонстрирующий эти шаги.
Определите инструменты
Создавайте схемы инструментов программно, используя FunctionDeclaration, FunctionSchema и FunctionType из пакета com.google.mlkit.genai.schema.tools. Чтобы определить инструменты декларативно во время компиляции с помощью аннотации @AppFunction в Android и автоматического выполнения, ознакомьтесь с разделом Определение инструментов.
Например, вы можете определить инструмент, ориентированный на действие (например, включение умного светильника за один шаг):
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 решает вызвать инструмент, ответ модели содержит один или несколько объектов FunctionCall в candidate.functionCalls. Чтобы обработать вызовы инструментов, ваше приложение должно сначала проверить вариант ответа и убедиться, что в нем есть вызовы инструментов.
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.
Известные проблемы
- AndroidX AppFunctions (
@AppFunction) в прямом доступе к модели (genai-prompt). Обнаружение и выполнение инструментов@AppFunctionвремени компиляции напрямую через Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) пока недоступно. Инструменты в библиотекеgenai-promptдолжны быть определены программно с помощью классаFunctionDeclaration. Чтобы использовать инструменты@AppFunction, используйте агентные рабочие процессы (com.google.mlkit:genai-agent). - При использовании потоковых запросов (
generateContentStream) вызовы инструментов не передаются по токенам. Вместо этого полные объектыFunctionCallпередаются (черезStreamingCallback.onNewFunctionCallили в последнем потоковомGenerateContentResponse.candidates[0].functionCalls), как только модель завершает генерирование вызова инструмента.