Beim Erstellen von Echtzeit-Sprach-Agents können einige Funktionsaufrufe die Ausführung des Modells blockieren. Dadurch wird der Audiostream unterbrochen und der Nutzer muss in Stille warten. In der Gemini Live API sind alle Funktionsaufrufe standardmäßig nicht blockierend. So können Sie Funktionen parallel zum Hauptkonversationsablauf ausführen. Dieser Vorgang wird als asynchroner Funktionsaufruf bezeichnet. Ihr Backend kann rechenintensive Aufgaben wie die Suche nach Live-Flugpreisen oder das Abfragen komplexer externer APIs im Hintergrund ausführen, während das Modell weiterhin zuhört, spricht und sich auf natürliche Weise mit dem Nutzer unterhält. Mit der Gemini Live API können Funktionsaufrufe im Hintergrund verarbeitet werden, ohne die Interaktion des Nutzers mit dem Modell zu unterbrechen. So sind flüssigere und Echtzeit-Interaktionen möglich.
Mit asynchronen Funktionsaufrufen können Sie Aufgaben wie das Buchen von Terminen, das Festlegen von Erinnerungen oder das Abrufen von Daten erledigen, ohne das Gespräch zu unterbrechen. Ein Nutzer kann beispielsweise einen Flug buchen und sofort nach Wetterinformationen fragen, während die Buchung im Hintergrund verarbeitet wird.
Beispiel für asynchronen Funktionsaufruf
In diesem Beispiel bucht ein Nutzer einen Flug und fragt nach der Uhrzeit in New York, während die book_ticket-Funktion asynchron im Hintergrund ausgeführt wird:
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.
Asynchrone Funktionsaufrufe implementieren
In diesem Abschnitt finden Sie eine Reihe von Beispielen für die Verwendung der Python-Version des Agent Platform SDK, um eine hochreaktionsfähige, parallele Architektur zu erstellen, die die asynchrone Funktion der Gemini Live API nutzt. Die Beispiele sind in die folgenden Aufgaben unterteilt:
- Tools definieren
- Funktionsaufrufe aus dem Nachrichtenstream verarbeiten
- Erwartungen der Nutzer verwalten
Tools definieren
Asynchrone Funktionsaufrufe sind auf Modellebene aktiviert. Sie können also in der Anfragekonfiguration angeben, welche Tools Sie verwenden möchten, genau wie bei jedem Standard-Gemini API-Aufruf in der Gemini Enterprise Agent Platform. So kann das Modell die Unterhaltung fortsetzen, während Ihr Tool ausgeführt wird:
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]}]
Funktionsaufrufe aus dem Nachrichtenstream verarbeiten
Wenn das Modell eine oder mehrere Funktionen aufrufen soll, sendet die Gemini Live API ein tool_call-Ereignis über den Echtzeit-Nachrichtenstream.
Ihr Backend darf den Stream nicht blockieren, da das Modell weiter ausgeführt werden muss. Wenn Sie einen Aufruf für eine langsame Funktion (z. B. search_live_flights) erhalten, müssen Sie ihn an einen Hintergrund-Worker übergeben. Wenn Sie ein await direkt in Ihrem Hauptnachrichtendurchlauf für eine 10-Sekunden-Aufgabe verwenden, wird die Verbindung eingefroren. Bei schnellen Aufgaben (z. B. get_current_weather) kann sicher gewartet werden.
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)
Für realistische Erwartungen sorgen
Um die Erwartungen bei asynchronen Funktionsaufrufen mit langer Laufzeit zu erfüllen, wird empfohlen, dass der Client eine Nachricht initiiert. Diese Nachricht sollte das System dazu veranlassen, den Nutzer darüber zu informieren, dass die Anfrage bearbeitet wird, und ihn um Geduld zu bitten. Nachdem der Client beispielsweise einen Funktionsaufruf empfangen hat, kann er eine Nachricht an das Modell senden, z. B.: „Wiederhole diesen Satz: ‚Ich buche jetzt dein Ticket. Bitte warte.‘“.
Das folgende Beispiel zeigt diesen Austausch:
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.
Diese proaktive Messaging-Strategie bietet folgende Vorteile:
- Informiert den Nutzer über aktuelle Systemvorgänge, um Erwartungen bei Funktionsaufrufen mit langer Ausführungszeit zu steuern.
- Die Häufigkeit redundanter kurzer Nutzeraufforderungen wie „Hallo?“ oder „Bist du da?“ wird reduziert. Diese treten häufig bei längeren Phasen der Inaktivität des Systems auf, während asynchrone Funktionsaufrufe verarbeitet werden. So kann das Risiko minimiert werden, dass durch diese wiederholten Nutzeranfragen doppelte Funktionsaufrufe ausgelöst werden.
- Wenn Sie einen zusätzlichen Systemprompt angeben, kann die Wahrscheinlichkeit verringert werden, dass in nachfolgenden Interaktionen doppelte Aufrufe erstellt werden.
Doppelte Funktionsaufrufe verarbeiten
Es besteht eine geringe Wahrscheinlichkeit, dass das Modell doppelte Funktionsaufrufe generiert, bevor es eine Antwort auf den ersten Aufruf erhält. Wenn Ihr Anwendungsfall dies zulässt, kann Ihre Anwendung doppelte Funktionsaufrufe ignorieren, wenn eine Antwort für denselben Funktionsaufruf noch aussteht.
Das folgende Beispiel zeigt, wie ein Client einen doppelten Funktionsaufruf ignorieren kann:
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.
Asynchrone Funktionsantworten verarbeiten
Wenn ein asynchroner Funktionsaufruf abgeschlossen ist, sendet Ihre Anwendung das Ergebnis in einem function_response an das Modell. Während Ihr Backend einen Funktionsaufruf verarbeitet, z. B. die Suche nach Flügen, kann der Nutzer dem Modell eine ganz andere Frage stellen, z. B. Wie ist das Wetter in London?. Das Modell antwortet in Echtzeit auf die Anfrage, parallel zur Ausführung des Funktionsaufrufs. Da der Nutzer möglicherweise gerade mit dem Modell interagiert, wenn die Funktionsausführung abgeschlossen ist, können Sie eine Richtlinie angeben, die definiert, wie das Modell mit dieser eingehenden Antwort umgehen soll. Sie können eine der folgenden Richtlinien angeben:
Wenn Sie eine Richtlinie angeben möchten, fügen Sie das Feld scheduling in Ihre function_response-Nutzlast ein:
{
"name": "book_ticket",
"scheduling": "WHEN_IDLE",
"response": {
"booking_status": "booked"
}
}
Wenn Sie das Feld scheduling weglassen, verwendet die Gemini Live API aus Gründen der Abwärtskompatibilität die ursprüngliche Methode für die Verarbeitung von Funktionsantworten.
Das folgende Python-Beispiel zeigt, wie Sie eine function_response mit scheduling="WHEN_IDLE" formatieren und senden, um eine natürliche Gesprächspause abzuwarten, bevor Sie Ergebnisse ankündigen:
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])
Die folgenden Richtlinien können im Feld scheduling angegeben werden, um Funktionsantworten zu verwalten:
SILENT-Antwortrichtlinie
Bei der SILENT-Richtlinie wird die Funktionsantwort dem Kontext des Modells hinzugefügt, das Modell generiert jedoch keine Antwort darauf und laufende Nutzerinteraktionen werden nicht unterbrochen.
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.
Antwortrichtlinie WHEN_IDLE
Mit der Richtlinie WHEN_IDLE generiert das Modell nur dann eine Antwort auf die Funktionsantwort, wenn keine aktive Nutzerinteraktion stattfindet. Wenn eine Nutzerinteraktion läuft, wartet das Modell, bis sie abgeschlossen ist, bevor es eine Antwort generiert, um Unterbrechungen zu vermeiden.
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.
INTERRUPT-Antwortrichtlinie
Gemäß der INTERRUPT-Richtlinie generiert das Modell sofort eine Antwort auf die Funktionsantwort, wodurch alle laufenden Nutzerinteraktionen unterbrochen werden.
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 Practices
- Auf Nebenläufigkeit ausgelegt: Langsame Tools (z. B. das Abfragen externer APIs oder das Ausführen von RAG-Pipelines) sollten immer an Hintergrundaufgaben in Ihrem Backend ausgelagert werden. Das Modell soll den aktiven Audiostream weiterhin verarbeiten.
- Vermeiden Sie INTERRUPT, sofern nicht erforderlich: Verwenden Sie
INTERRUPTfür wichtige Benachrichtigungen. Für Hintergrundaufgaben bietetSILENToderWHEN_IDLEeine viel reibungslosere und nutzerfreundlichere Lösung. - Unabhängige Chat-Turns: In der Gemini Live API ist die Tool-Ausführung völlig unabhängig von Chat-Turns. Die Unterhaltung kann sich verzweigen, fortgesetzt werden und natürlich ablaufen, während Ihr Tool im Hintergrund arbeitet.
- Hinweis zu „Silent“: Das Modell kann gelegentlich versuchen, die Ausführung eines Tools verbal zu beschreiben, auch wenn es als
SILENTgeplant ist. Wenn Sie die Ausführung ohne Antwort erzwingen möchten, fügen Sie Ihren Systemanweisungen explizite Schutzmaßnahmen hinzu (z. B. „Führe bei der Verwendung von [Tool Name] eine SILENT EXECUTION durch und sage nichts“) oder verwenden Sie ein „Fire-and-Forget“-Backend-Muster, bei dem Sie überhaupt keineFunctionResponsean das Modell zurücksenden.
Nächste Schritte
Live-Sitzungen starten und verwalten
Hier erfährst du, wie du Live-Sitzungen mit der Live API startest und verwaltest.
Gemini-Funktionen konfigurieren
Informationen zum Konfigurieren von Gemini-Funktionen für die Live API