Con el acceso directo al modelo de ML Kit, puedes usar la llamada a funciones para permitir que los modelos de Gemini Nano generen solicitudes de ejecución de funciones estructuradas (llamadas a herramientas) en lugar de respuestas de texto sin formato. La llamada a función te permite conectar modelos de IA generativa integrados en el dispositivo con herramientas externas, APIs y funciones de apps locales.
Funciones clave
La llamada a funciones proporciona las siguientes capacidades clave:
- Llamada a función de un solo turno: Gemini Nano predice una o más llamadas a herramientas
(
FunctionCall), tu app ejecuta las funciones de forma local y el flujo se completa sin necesidad de una respuesta de modelo de seguimiento. - Llamada a funciones de varios turnos: Gemini Nano predice una o más llamadas a herramientas
(
FunctionCall), tu app ejecuta las funciones de forma local y devuelve los resultados (FunctionResponsePart) para recuperar más llamadas a herramientas o una respuesta de texto sintetizada final.
Cuando implementas la llamada a funciones, puedes aprovechar lo siguiente:
- Definiciones de herramientas programáticas: Construye definiciones de herramientas
FunctionDeclarationyFunctionSchemadinámicas en el entorno de ejecución con la API de esquema de IA generativa de ML Kit (com.google.mlkit:genai-schema). - Análisis de argumentos estructurados: Recibe valores de argumentos con tipos de datos definidos directamente desde el candidato de respuesta del modelo para ejecutar la lógica de tu app local.
Resultados de ejemplo
La llamada a funciones admite flujos de un solo turno y de varios turnos. En ambos casos, el modelo predice una o más llamadas a herramientas que consisten en el nombre de la función y los argumentos. En el caso de los flujos de varios turnos, después de recibir los resultados de la ejecución de la app, esta puede enviar otra solicitud al modelo con el historial de conversaciones completo para obtener más llamadas a herramientas o una respuesta de texto final para el usuario.
| Flujo de ejecución | Instrucción del usuario | Resultado del modelo |
|---|---|---|
| Un solo turno | "Enciende las luces de la sala de estar al 80% de brillo". |
Llamada a la herramienta:turn_on_light(room="living room", brightness=80)
|
| Un solo turno | "Abre la app de Cámara". |
Llamada a la herramienta:open_app(appName="Camera")
|
| Varios turnos | "¿Cómo está el clima en San Francisco en grados Celsius?" |
Llamada a la herramienta intermedia:get_current_weather(location="San Francisco, CA", unit="celsius")
Resultado final del modelo que se muestra al usuario: In SF it's currently 25 degrees Celsius.
|
Requisitos previos
Para usar la llamada a función, debes cumplir con los siguientes requisitos de dispositivo y cuenta:
- Tu dispositivo admite la API de Prompt.
- La Cuenta de Google de tu dispositivo forma parte del programa de Versión preliminar para desarrolladores de AICore.
Para verificar que cumpliste con estos requisitos, comprueba que el modelo Gemini Nano 4 Fast esté disponible en la app de AICore: abre la app de AICore, haz clic en el menú desplegable Select a model y verifica que aparezca Gemini Nano 4 Fast. Si el modelo no está allí, hay un problema con la compatibilidad del dispositivo o la inscripción de la cuenta, y la llamada a función no funcionará.
Además, tu proyecto debe cumplir con los siguientes requisitos:
- Kotlin versión 2.3.0 o posterior
- Versión mínima del SDK (
minSdk) 26 o posterior
Comenzar
Estos son los pasos para comenzar a usar la llamada a funciones.
En el archivo
settings.gradle.kts(osettings.gradle) a nivel del proyecto, agregamavenCentral()al bloquerepositories {}.dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }En el archivo
build.gradle.kts(obuild.gradle) a nivel del módulo, agrega las dependencias de la API de Prompt y el esquema de ML Kit: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' }En el archivo
build.gradle(obuild.gradle.kts) a nivel del módulo, establece la versión deminSdken26o una posterior.Kotlin
android { defaultConfig { // ... minSdk = 26 // ... } }Groovy
android { defaultConfig { // ... minSdk 26 // ... } }
Cómo usar la API de llamada a funciones
Para implementar la llamada a funciones, sigue estos pasos:
- Define tus herramientas.
- Selecciona el modelo.
- Adjunta herramientas a tu solicitud.
- Controlar las llamadas a herramientas (de un solo turno o de varios turnos)
En las próximas secciones, se muestra un ejemplo de estos pasos.
Define tus herramientas
Crea esquemas de herramientas de forma programática con FunctionDeclaration,
FunctionSchema y FunctionType del
paquete com.google.mlkit.genai.schema.tools. (Para definir herramientas de forma declarativa en
el tiempo de compilación con la anotación @AppFunction de Android con ejecución automática,
consulta Cómo definir herramientas).
Por ejemplo, puedes definir una herramienta orientada a la acción (como encender una lámpara inteligente para la ejecución de un solo turno):
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")
)
)
O define una herramienta de recuperación de datos (como recuperar el clima actual para la síntesis de varios turnos):
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")
)
)
Selecciona el modelo
La llamada a funciones requiere Gemini Nano 4. Para acceder a Gemini Nano 4, usa la
API de selección de modelos para configurar
tu instancia de GenerativeModel para que se oriente a ModelReleaseStage.PREVIEW Y
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)
Adjunta herramientas a tu solicitud
Cuando crees un objeto GenerateContentRequest, pasa tu lista de FunctionDeclaration a setTools() en el compilador de solicitudes.
Por ejemplo, para adjuntar una herramienta para una solicitud de acción de un solo turno con una instrucción del sistema, haz lo siguiente:
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)
O bien, para adjuntar tu lista de FunctionDeclaration para una consulta de varios turnos, haz lo siguiente:
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)
Controla las llamadas a herramientas
Cuando Gemini Nano decide invocar una herramienta, la respuesta candidata del modelo
contiene uno o más objetos FunctionCall en candidate.functionCalls. Para
controlar las llamadas a herramientas, tu app primero debe inspeccionar el candidato de respuesta para verificar
si se predijeron llamadas a herramientas:
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
}
Llamada a funciones de un solo turno
Usa la llamada a función de un solo turno para tareas orientadas a la acción en las que la app cumple directamente con la solicitud (por ejemplo, "Abre la app de la cámara" o "Enciende las luces de la sala de estar"). Una vez que tu app ejecuta la función de forma local, el flujo se completa; no se requiere una respuesta de seguimiento del modelo.
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")
}
}
Llamada a funciones de varios turnos
Usa la llamada a funciones de varios turnos cuando el usuario espere una respuesta en lenguaje natural basada en los datos que recuperó la herramienta (por ejemplo, "¿Cómo está el clima en San Francisco?").
En un flujo de varios turnos, tu app hace lo siguiente:
- Ejecuta la función solicitada de forma local.
- Empaqueta el resultado en un objeto
FunctionResponsePart. - Agrega la llamada del modelo (rol
MODEL) y el resultado de la ejecución (rolUSER) al historial de conversaciones. - Envía una solicitud de seguimiento a Gemini Nano para sintetizar la respuesta final en lenguaje natural.
// 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")
Código de muestra
Para ver un ejemplo completo de la llamada a funciones en una app para Android, consulta esta app de ejemplo de ML Kit.
Problemas conocidos
- AppFunctions de AndroidX (
@AppFunction) en el acceso directo al modelo (genai-prompt): El descubrimiento y la ejecución de herramientas de@AppFunctionen tiempo de compilación directamente a través de la API de Prompt (com.google.mlkit:genai-prompt:1.0.0-beta5) aún no están disponibles. Las herramientas de la bibliotecagenai-promptse deben definir de forma programática con la claseFunctionDeclaration. Para usar las herramientas de@AppFunctionhoy, usa flujos de trabajo de agentes (com.google.mlkit:genai-agent). - Cuando se usan solicitudes de transmisión (
generateContentStream), las llamadas a funciones no se transmiten token por token. En cambio, se emiten objetosFunctionCallcompletos (a través deStreamingCallback.onNewFunctionCallo en elGenerateContentResponse.candidates[0].functionCallstransmitido final) una vez que el modelo termina de generar la llamada a función.