Quando crei agenti vocali in tempo reale, alcune chiamate di funzioni possono bloccare l'esecuzione del modello, il che fa sì che il flusso audio si interrompa e l'utente rimanga in attesa in silenzio. Con l'API Gemini Live, tutte le chiamate di funzioni sono non bloccanti per impostazione predefinita, il che ti consente di eseguire le funzioni in parallelo con il flusso principale della conversazione. Questo processo è chiamato chiamata di funzione asincrona. Il backend può elaborare attività pesanti come la ricerca dei prezzi dei voli in tempo reale o l'esecuzione di query su API esterne complesse in background, mentre il modello continua ad ascoltare, parlare e conversare in modo naturale con l'utente. L'API Gemini Live consente alle chiamate di funzione di essere elaborate in background senza interrompere l'interazione dell'utente con il modello, consentendo interazioni più fluide e in tempo reale.
La chiamata di funzioni asincrona ti consente di completare attività come prenotare appuntamenti, impostare promemoria o recuperare dati senza mettere in pausa la conversazione. Ad esempio, un utente può richiedere di prenotare un volo e chiedere immediatamente informazioni sul meteo mentre la prenotazione viene elaborata in background.
Esempio di chiamata di funzione asincrona
Questo esempio mostra un utente che prenota un volo e chiede l'ora a
New York mentre la funzione book_ticket viene eseguita in modo asincrono in background:
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.
Implementare la chiamata di funzioni asincrone
Questa sezione fornisce una serie di esempi che utilizzano la versione Python dell'SDK Agent Platform per creare un'architettura simultanea e altamente reattiva che utilizza la funzionalità di chiamata di funzione asincrona dell'API Gemini Live. Gli esempi sono suddivisi nelle seguenti attività:
- Definisci gli strumenti
- Gestire le chiamate di funzione dal flusso di messaggi
- Gestire le aspettative degli utenti
Definisci gli strumenti
La chiamata di funzione asincrona è abilitata a livello di modello, quindi puoi specificare gli strumenti che vuoi utilizzare nella configurazione della richiesta come faresti per qualsiasi chiamata API Gemini standard in Gemini Enterprise Agent Platform. Ciò consente al modello di continuare a conversare mentre lo strumento viene eseguito:
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]}]
Gestire le chiamate di funzione dal flusso di messaggi
Quando il modello deve chiamare una o più funzioni,
l'API Gemini Live invia un evento tool_call tramite il flusso di messaggi in tempo reale.
Il backend non deve bloccare lo stream perché il modello prevede di continuare
l'esecuzione. Quando ricevi una chiamata per una funzione lenta (come
search_live_flights), devi passarla a un worker in background. Se utilizzi un
await direttamente nel ciclo di messaggi principale per un'attività di 10 secondi, la connessione si bloccherà. Le attività veloci (come get_current_weather)
possono essere attese in sicurezza.
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)
Gestire le aspettative degli utenti
Per gestire le aspettative durante le chiamate di funzioni asincrone di lunga durata, è consigliabile che il client avvii un messaggio di testo. Questo messaggio deve chiedere al sistema di informare l'utente che la richiesta è in fase di elaborazione e di avere pazienza. Ad esempio, dopo che una chiamata di funzione viene ricevuta dal client, il client può inviare un messaggio di testo al modello, ad esempio: "Ripeti questa frase: 'Sto prenotando il tuo biglietto, attendi.'".
La seguente finestra di dialogo di esempio mostra questo scambio:
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.
Questa strategia di messaggistica proattiva offre i seguenti vantaggi:
- Informa l'utente delle operazioni di sistema correnti, il che gestisce le aspettative durante le chiamate di funzioni a lunga esecuzione.
- Riduce la frequenza di brevi prompt utente ridondanti, ad esempio "Pronto?" o "Ci sei?". Questi errori si verificano spesso durante lunghi periodi di silenzio del sistema mentre vengono elaborate le chiamate di funzioni asincrone. In questo modo, puoi ridurre al minimo il rischio di chiamate di funzioni duplicate attivate da queste richieste ripetute degli utenti.
- Fornire un prompt di sistema aggiuntivo può ridurre la probabilità di creare chiamate duplicate nelle interazioni successive.
Gestire le chiamate di funzione duplicate
Esiste una piccola possibilità che il modello generi chiamate di funzione duplicate prima di ricevere una risposta per la prima chiamata. Se il tuo caso d'uso lo consente, la tua applicazione può ignorare le chiamate di funzione duplicate se una risposta per la stessa chiamata di funzione è ancora in attesa.
Il seguente esempio mostra come un client può ignorare una chiamata di funzione duplicata:
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.
Gestire le risposte delle funzioni asincrone
Quando una chiamata di funzione asincrona viene completata, l'applicazione invia il risultato al modello in un function_response. Mentre il backend elabora una chiamata di funzione, ad esempio la ricerca di voli, l'utente potrebbe porre al modello una domanda completamente diversa, ad esempio "Che tempo fa a Londra?". Il modello risponderà alla richiesta in tempo reale, in parallelo con l'esecuzione della chiamata di funzione. Poiché l'utente potrebbe essere in un'interazione in corso con il modello al termine dell'esecuzione della funzione, puoi specificare un criterio che definisca il modo in cui il modello deve gestire questa risposta in arrivo. Puoi specificare uno dei seguenti criteri:
Per specificare una policy, includi il campo scheduling nel payload
function_response:
{
"name": "book_ticket",
"scheduling": "WHEN_IDLE",
"response": {
"booking_status": "booked"
}
}
Se ometti il campo scheduling, l'API Gemini Live utilizza il metodo originale
per la gestione delle risposte alle funzioni per la compatibilità con le versioni precedenti.
Il seguente esempio Python mostra come formattare e inviare un function_response
con scheduling="WHEN_IDLE" per attendere una pausa naturale nella conversazione
prima di annunciare i risultati:
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])
I seguenti criteri possono essere specificati nel campo scheduling per la gestione
delle risposte delle funzioni:
Policy di risposta SILENT
Con la policy SILENT, la risposta di funzione viene aggiunta al contesto del modello,
ma il modello non genera una risposta e l'interazione utente in corso non viene interrotta.
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.
Policy di risposta WHEN_IDLE
Con il criterio WHEN_IDLE, il modello genera una risposta alla risposta di funzione solo quando non è presente un'interazione utente attiva. Se è in corso un'interazione dell'utente, il modello attende il completamento prima di generare una risposta per evitare interruzioni.
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.
Policy di risposta INTERRUPT
Con il criterio INTERRUPT, il modello genera una risposta alla risposta della funzione
immediatamente, interrompendo qualsiasi interazione utente in corso.
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.
Best practice
- Progettazione per la concorrenza: scarica sempre gli strumenti lenti (come l'interrogazione di API esterne o l'esecuzione di pipeline RAG) nelle attività in background nel backend. Consente al modello di continuare a gestire lo stream audio attivo.
- Evita INTERRUPT se non necessario: utilizza
INTERRUPTper gli avvisi critici. Per le attività in background,SILENToWHEN_IDLEoffre un'esperienza utente molto più fluida e rispettosa. - Turni di chat indipendenti: nell'API Gemini Live, l'esecuzione degli strumenti è completamente indipendente dai turni di chat. La conversazione può ramificarsi, continuare e fluire in modo naturale mentre lo strumento viene elaborato in background.
- Avviso relativo alla modalità "Silenziosa": il modello potrebbe comunque tentare occasionalmente di
narrare verbalmente l'esecuzione di uno strumento anche se è pianificata come
SILENT. Per imporre il silenzio effettivo, aggiungi regole esplicite alle istruzioni di sistema (ad esempio, "Quando utilizzi [nome dello strumento], esegui un'ESECUZIONE SILENZIOSA e non dire nulla ") o utilizza un pattern di backend"fire-and-forget" in cui non inviare unFunctionResponseal modello.
Passaggi successivi
Avviare e gestire le sessioni live
Scopri come avviare e gestire sessioni live con l'API Live.
Configura le funzionalità di Gemini
Scopri come configurare le funzionalità di Gemini per l'API Live.