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 que el usuario quede esperando en silencio. Con la API de Gemini Live, todas las llamadas a funciones son no bloqueantes de forma predeterminada, lo que te permite ejecutar funciones en paralelo con el flujo principal de la conversación. Este proceso se denomina llamada a funciones 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 de forma natural 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.
Las llamadas a funciones asíncronas te permiten 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 función asíncrona
En esta sección, se proporcionan una serie de ejemplos que usan la versión de Python del SDK de Agent Platform para compilar una arquitectura simultánea y altamente responsiva que usa la capacidad de llamadas a funciones asíncronas de la API de Gemini Live. Los ejemplos se dividen 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
La llamada a función asíncrona está habilitada a nivel del modelo, por lo que puedes especificar qué herramientas deseas usar en la configuración de la solicitud, como lo harías con cualquier llamada estándar a la API de Gemini. Esto permite que el modelo siga conversando mientras se ejecuta tu herramienta:
from google import genai
from google.genai import types
# 1. A tool that takes a long time to execute
search_live_flights = {
"name": "search_live_flights",
"description": "Searches airlines for current flight prices. Can take up to 10 seconds."
}
# 2. A tool that executes instantly
get_current_weather = {
"name": "get_current_weather",
"description": "Gets the current weather for a given city."
}
tools = [{"function_declarations": [search_live_flights, get_current_weather]}]
Cómo controlar las llamadas a funciones 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, ya que el modelo espera seguir ejecutándose. Cuando recibas 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 el 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)
Administra las expectativas de los usuarios
Para administrar las expectativas durante las llamadas a funciones asíncronas de larga duración, se recomienda que el cliente inicie un mensaje de texto. Este mensaje debería indicarle al sistema que informe al usuario que se está procesando la solicitud y que le pida que espere. Por ejemplo, después de que el cliente recibe una llamada a la función, puede enviarle un mensaje de texto al modelo, como: "Repite esta oración: "Estoy reservando tu boleto ahora, espera un momento"".
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 las instrucciones redundantes y breves del usuario, como "¿Hola?" o "¿Estás ahí?". A menudo, se producen durante largos períodos 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 del usuario.
- Proporcionar una instrucción del sistema adicional puede reducir la probabilidad de crear llamadas duplicadas en interacciones posteriores.
Cómo controlar las llamadas a funciones duplicadas
Existe una pequeña probabilidad de que el modelo genere llamadas a función 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.
Cómo controlar 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 una función, como la búsqueda de vuelos, el usuario podría hacerle al modelo una pregunta completamente diferente, como "¿Cómo está el clima en Londres?". El modelo responderá 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 tu carga útil de function_response:
{
"name": "book_ticket",
"scheduling": "WHEN_IDLE",
"response": {
"booking_status": "booked"
}
}
Si omites el campo scheduling, la API de Gemini Live usará su método original para controlar las respuestas de funciones por motivos de retrocompatibilidad.
En el siguiente ejemplo de Python, se muestra cómo dar formato a un objeto function_response con scheduling="WHEN_IDLE" para esperar una pausa natural en la conversación antes de anunciar los resultados y enviarlo:
aearcync 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 este no genera una respuesta para ella y no se interrumpe ninguna 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?
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 de 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 de INTERRUPT
Con la política INTERRUPT, el modelo genera una respuesta a la respuesta de 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.
Prácticas recomendadas
- 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.
- Evita INTERRUPT, a menos que sea necesario: Usa
INTERRUPTpara las alertas críticas. Para las tareas en segundo plano,SILENToWHEN_IDLEproporcionan una experiencia del usuario mucho más fluida y cortés. - 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 la herramienta se procesa en segundo plano.
- La advertencia "Silencio": Es posible que el modelo intente narrar verbalmente la ejecución de una herramienta, incluso si se programó como
SILENT. Para aplicar un silencio verdadero, agrega medidas de protección 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 unFunctionResponseal modelo.
¿Qué sigue?
Descripción general de la API de Live
Obtén una descripción general de la API de Live.
Cómo iniciar y administrar sesiones en vivo
Aprende a iniciar y administrar sesiones en vivo con la API de Live.
Configura las capacidades de Gemini
Aprende a configurar las capacidades de Gemini para la API de Live.