Cuando se crean agentes de voz en tiempo real, algunas llamadas a funciones pueden bloquear la ejecución del modelo, lo que hace que la transmisión de audio se silencie y el usuario quede esperando en silencio. Con la API de Gemini Live, todas las llamadas a funciones no son de bloqueo de forma predeterminada, lo que te permite ejecutar funciones en paralelo con el flujo de conversación principal. Este proceso se denomina llamada a función asíncrona. Tu backend puede procesar tareas pesadas, como buscar precios de vuelos en vivo o consultar APIs externas complejas en segundo plano, mientras el modelo sigue escuchando, hablando y conversando con naturalidad con el usuario. La API de Gemini Live permite que las llamadas a funciones se procesen en segundo plano sin interrumpir la interacción del usuario con el modelo, lo que permite interacciones más fluidas y en tiempo real.
La llamada a funciones asíncrona te permite completar tareas como reservar citas, establecer recordatorios o recuperar datos sin pausar la conversación. Por ejemplo, un usuario puede solicitar reservar un vuelo y, de inmediato, pedir información sobre el clima mientras se procesa la reserva en segundo plano.
Ejemplo de llamada a función asíncrona
En este ejemplo, se muestra a un usuario que reserva un vuelo y pregunta la hora en
Nueva York mientras la función book_ticket se ejecuta de forma asíncrona en segundo plano:
User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The "book_ticket" function call is sent to the client.)
//(Right after the "book_ticket" function call is received, the client sends a text message to the model: "repeat this sentence 'I'm booking your ticket now, please wait.'")
//(The client runs the function call asynchronously in the background.)
Model: I'm booking your ticket now, please wait.
User: What is the current time in New York?
Model: The current time in New York is 12:00pm.
//(Once the book_ticket function finishes, the client sends the result.)
Function_response: {name: "book_ticket", response: {booking_status: "booked"}}
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.
Implementa la llamada a funciones asíncrona
En esta sección, se proporcionan varios ejemplos en los que se usa la versión para Python del SDK de Agent Platform para compilar una arquitectura simultánea y con alta capacidad de respuesta que usa la capacidad de llamada a funciones asíncrona de la API de Gemini Live. Los ejemplos se desglosan en las siguientes tareas:
- Define tus herramientas
- Controla las llamadas a funciones desde el flujo de mensajes
- Administra las expectativas de los usuarios
Define tus herramientas
Para controlar cómo se ejecuta cada herramienta, configura el campo behavior de su
FunctionDeclaration:
NON_BLOCKING(predeterminado cuando no se establecebehavior): El modelo sigue conversando mientras se ejecuta la herramienta. Usa este parámetro de configuración para búsquedas de solo lectura o tareas en segundo plano cuyos resultados se puedan entregar más tarde.BLOCKING: El modelo se detiene y espera tuFunctionResponseantes de generar más resultados. Usa este parámetro de configuración para operaciones irreversibles o que cambian de estado (como pagos, reservas o actualizaciones de cuentas) en las que el modelo no debe confirmar un resultado antes de conocerlo. Si llega una entrada de usuario nueva mientras se ejecuta una llamada de bloqueo, el servidor cancela la llamada, lo que requiere idempotencia del backend.
Si usas un framework sobre la API de Gemini Live, verifica que el framework
transmita behavior en el mensaje de configuración de la sesión. Si se omite, las herramientas se ejecutan como
NON_BLOCKING de forma predeterminada.
En el siguiente ejemplo de Python, se muestra cómo declarar herramientas de bloqueo y no bloqueo:
from google import genai
from google.genai import types
client = genai.Client()
# 1. A read-only lookup: safe to run in the background
search_live_flights = types.FunctionDeclaration(
name="search_live_flights",
description="Searches airlines for current flight prices. Can take up to 10 seconds.",
behavior=types.Behavior.NON_BLOCKING,
)
# 2. A state-changing operation: the model waits for the result before continuing
book_flight = types.FunctionDeclaration(
name="book_flight",
description="Books a flight ticket. Irreversible.",
behavior=types.Behavior.BLOCKING,
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"flight_id": types.Schema(type=types.Type.STRING),
},
required=["flight_id"],
),
)
tools = [types.Tool(function_declarations=[search_live_flights, book_flight])]
Controla las llamadas a función desde el flujo de mensajes
Cuando el modelo debe llamar a una o más funciones,
la API de Gemini Live envía un evento tool_call a través del flujo de mensajes en tiempo real.
Tu backend no debe bloquear la transmisión porque el modelo espera seguir
ejecutándose. Cuando recibes una llamada para una función lenta (como search_live_flights), debes pasarla a un trabajador en segundo plano. Si usas un
await directamente en tu bucle de mensajes principal para una tarea de 10 segundos, se
congelará la conexión. Las tareas rápidas (como get_current_weather)
se pueden esperar de forma segura.
import asyncio
async def handle_stream(session):
async for response in session.receive():
# Check if the model is asking to use a tool
if response.tool_call is not None:
for fc in response.tool_call.function_calls:
if fc.name == "search_live_flights":
# Pass to a background task so we don't block the receive loop!
asyncio.create_task(background_flight_search(fc.id, fc.args, session))
elif fc.name == "get_current_weather":
# Instant lookups can be safely awaited directly
await instant_weather_lookup(fc.id, fc.args, session)
Controlar las expectativas de los usuarios
Para administrar las expectativas durante las llamadas a funciones asíncronas de larga duración, envía un mensaje de texto desde el cliente que le indique al sistema que informe al usuario que se está procesando la solicitud y que tenga paciencia. Por ejemplo, después de que el cliente recibe una llamada a función, puede enviar un mensaje de texto al modelo, como: "repite esta oración: 'Estoy reservando tu boleto ahora, espera'".
En el siguiente diálogo de ejemplo, se muestra este intercambio:
User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The "book_ticket" function call is sent to the client.)
//(Right after the "book_ticket" function call is received, the client sends a text message to the model: "repeat this sentence 'I'm booking your ticket now, please wait.'")
//(The client runs the function call asynchronously in the background.)
Model: I'm booking your ticket now, please wait.
User: What is the current time in New York?
Model: The current time in New York is 12:00pm.
//(Once the "book_ticket" function call finishes, the client sends in the response.)
Function_response: {name: "book_ticket", response: {booking_status: "booked"}}
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.
Esta estrategia de mensajería proactiva tiene los siguientes beneficios:
- Informa al usuario sobre las operaciones actuales del sistema, lo que administra las expectativas durante las llamadas a funciones de larga duración.
- Reduce la frecuencia de instrucciones breves y redundantes de los usuarios, como "¿hola?" o "¿estás ahí?". Suelen ocurrir durante períodos prolongados de silencio del sistema mientras se procesan las llamadas a funciones asíncronas. Esto puede minimizar el riesgo de llamadas a funciones duplicadas que se activan por estas consultas repetidas de los usuarios.
- Proporcionar una instrucción del sistema adicional puede reducir la probabilidad de crear llamadas duplicadas en interacciones posteriores.
Controla las llamadas a funciones duplicadas
Existe una pequeña posibilidad de que el modelo genere llamadas a funciones duplicadas antes de recibir una respuesta para la primera llamada. Si tu caso de uso lo permite, tu aplicación puede ignorar las llamadas a funciones duplicadas si aún está pendiente una respuesta para la misma llamada a función.
En el siguiente ejemplo, se muestra cómo un cliente puede ignorar una llamada a función duplicada:
User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The "book_ticket" function call is sent to the client. It is running asynchronously in the background.)
User: What is the current time in New York?
Model: The current time in New York is 12:00pm. + function_call: {name: "book_ticket"}
//(The duplicated "book_ticket" can be ignored by the client since the response for the first "book_ticket" has not been sent to the model yet.)
//(The first "book_ticket" function call finishes, and client sends in the response.)
Function_response: {name: "book_ticket", response: {booking_status: "booked"}}
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.
Controla las respuestas de funciones asíncronas
Cuando se completa una llamada a función asíncrona, tu aplicación envía el
resultado al modelo en un function_response. Mientras tu backend procesa
una llamada a función, como buscar vuelos, el usuario puede hacerle al modelo una
pregunta completamente diferente, como "¿Cómo está el clima en
Londres?". El modelo responde a la solicitud en tiempo real, en paralelo con la ejecución de la llamada a función. Como el usuario podría estar en una interacción en curso con el modelo
cuando se complete la ejecución de la función, puedes especificar una política que defina cómo
debe controlar el modelo esta respuesta entrante. Puedes especificar una de las
siguientes políticas:
Para especificar una política, incluye el campo scheduling en la carga útil de
function_response:
{
"name": "book_ticket",
"scheduling": "WHEN_IDLE",
"response": {
"booking_status": "booked"
}
}
La compatibilidad de modelos para FunctionResponse.scheduling varía según el modelo:
Gemini 3.8 Live: Admitescheduling(SILENT,WHEN_IDLEyINTERRUPT).gemini-3.8-live-extended-thinking-preview: No admite parámetros de configuración de programación explícitos. El envío deschedulinghace que la sesión se cierre con el error 1007 de WebSocket. Para este modelo, omite el camposcheduling.
Cuando se omite scheduling en los modelos compatibles, la API de Gemini Live usa de forma predeterminada
WHEN_IDLE. Cada respuesta de función entrante activa un nuevo turno del modelo después de que el usuario termina de hablar.
En el siguiente ejemplo de Python, se muestra cómo dar formato y enviar un function_response
con scheduling="WHEN_IDLE" para esperar una pausa natural en la conversación
antes de anunciar los resultados:
async def background_flight_search(call_id, args, session):
# 1. Simulate a slow API call taking 5 seconds
await asyncio.sleep(5)
flight_data = ["Air Canada AC758: $350", "WestJet WS12: $290"]
# 2. Format the response
function_response = types.FunctionResponse(
id=call_id,
name="search_live_flights",
response={ "status": "success", "flights": flight_data },
scheduling="WHEN_IDLE" # Wait for a moment to tell the user
)
# 3. Send it back into the live session
await session.send_tool_response(function_responses=[function_response])
Las siguientes políticas se pueden especificar en el campo scheduling para administrar
las respuestas de las funciones:
Política de respuesta SILENT
Con la política SILENT, la respuesta de la función se agrega al contexto del modelo,
pero el modelo no genera una respuesta para ella, y no se interrumpe ninguna interacción
en curso del usuario.
User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The book_ticket function call is sent to the client and starts running asynchronously in the background.)
User: What is the current time in New York?
Model: The current time in New York is 12:00pm.
//(The book_ticket function finishes, and client sends the result with scheduling: "SILENT".)
Function_response: {name: "book_ticket", scheduling: "SILENT", response: {booking_status: "booked"}}
//(The model doesn't generate a response for the function response.)
User: Is my flight ticket booked?
Model: Yes. Your flight has been booked.
Política de respuesta WHEN_IDLE
Con la política WHEN_IDLE, el modelo genera una respuesta a la respuesta de la función
solo cuando no hay interacción activa del usuario. Si hay una interacción del usuario
en curso, el modelo espera a que se complete antes de generar una respuesta
para evitar interrupciones.
User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The book_ticket function call is sent to the client and starts running asynchronously in the background.)
User: What is the current time in New York?
//(The book_ticket function finishes, and client sends the result with scheduling: "WHEN_IDLE".)
Function_response: {name: "book_ticket", scheduling: "WHEN_IDLE", response: {booking_status: "booked"}}
//(The ongoing interaction about the time is not interrupted.)
Model: The current time in New York is 12:00pm.
//(After responding to the user's time query, the model issues the response for the book_ticket function.)
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.
Política de respuesta INTERRUPT
Con la política INTERRUPT, el modelo genera una respuesta a la función
de inmediato, lo que interrumpe cualquier interacción del usuario en curso.
User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The book_ticket function call is sent to the client and starts running asynchronously in the background.)
User: What is the current time in New York?
//(The book_ticket function finishes, and client sends the result with scheduling: "INTERRUPT".)
Function_response: {name: "book_ticket", scheduling: "INTERRUPT", response: {booking_status: "booked"}}
//(The ongoing interaction about the time is interrupted, and model skips responding to it.)
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.
Agrega varias respuestas no bloqueantes
Cuando el modelo llama a varias herramientas no bloqueantes de forma simultánea (como búsquedas de datos paralelas), enviar cada resultado de forma individual con WHEN_IDLE hace que el modelo genere varios turnos de voz independientes. Para entregar una sola
respuesta consolidada, aplica uno de los siguientes patrones:
- Usa SILENT para los resultados intermedios: Envía todas las respuestas intermedias de la herramienta
con
scheduling="SILENT". Envía la respuesta final conscheduling="WHEN_IDLE"para que el modelo resuma todos los datos recopilados en un turno. - Respuestas por lotes: Espera a que se completen todas las tareas de herramientas simultáneas y
entrégalas juntas en una sola llamada a
send_tool_responseconfunction_responses=[...].
Prácticas recomendadas
- Declara el comportamiento de la herramienta de forma explícita: Configura las herramientas irreversibles o que cambian de estado en
BLOCKINGy las búsquedas en segundo plano o de solo lectura enNON_BLOCKING. - Diseña para la simultaneidad: Siempre descarga las herramientas lentas (como consultar APIs externas o ejecutar canalizaciones de RAG) en tareas en segundo plano en tu backend. Permite que el modelo siga controlando la transmisión de audio activa.
- Programa respuestas sin bloqueo de forma deliberada: Usa
SILENTpara las respuestas intermedias,WHEN_IDLEpara el resultado final que debería activar la salida de voz yINTERRUPTsolo para las alertas críticas. Si dejasschedulingsin configurar, se establece de forma predeterminada enWHEN_IDLEy se inicia un turno del modelo para cada respuesta. - Turnos de chat independientes: En la API de Gemini Live, la ejecución de herramientas es completamente independiente de los turnos de chat. La conversación puede ramificarse, continuar y fluir de forma natural mientras tu herramienta se procesa en segundo plano.
- La advertencia "Silencioso": Es posible que el modelo aún intente narrar
verbalmente la ejecución de una herramienta, incluso si está programada como
SILENT. Para aplicar el silencio verdadero, agrega instrucciones de seguridad explícitas a tus instrucciones del sistema (por ejemplo, "Cuando uses [nombre de la herramienta], realiza una EJECUCIÓN SILENCIOSA y no digas nada") o usa un patrón de backend de "disparar y olvidar" en el que no envíes unFunctionResponsede vuelta al modelo.
¿Qué sigue?
Descripción general de la API de Live
Obtén una descripción general de la API de Live.
Inicia y administra sesiones en vivo
Aprende a iniciar y administrar sesiones en vivo con la API de Live.
Configura las funciones de Gemini
Aprende a configurar las funciones de Gemini para la API de Live.