Saat membangun agen suara real-time, beberapa panggilan fungsi dapat memblokir eksekusi model, yang menyebabkan streaming audio menjadi sunyi dan pengguna menunggu dalam keheningan. Dengan Gemini Live API, semua panggilan fungsi bersifat non-pemblokiran secara default, sehingga Anda dapat mengeksekusi fungsi secara paralel dengan alur percakapan utama. Proses ini disebut pemanggilan fungsi asinkron. Backend Anda dapat memproses tugas berat seperti menelusuri harga penerbangan live atau membuat kueri API eksternal yang kompleks di latar belakang, sementara model terus mendengarkan, berbicara, dan bercakap-cakap secara alami dengan pengguna. Gemini Live API memungkinkan panggilan fungsi diproses di latar belakang tanpa mengganggu interaksi pengguna dengan model, sehingga memungkinkan interaksi yang lebih lancar dan real-time.
Pemanggilan fungsi asinkron memungkinkan Anda menyelesaikan tugas seperti membuat janji temu, menyetel pengingat, atau mengambil data tanpa menjeda percakapan. Misalnya, pengguna dapat meminta untuk memesan penerbangan dan langsung meminta informasi cuaca saat pemesanan diproses di latar belakang.
Contoh pemanggilan fungsi asinkron
Contoh ini menunjukkan pengguna yang memesan penerbangan dan menanyakan waktu di
New York saat fungsi book_ticket berjalan secara asinkron di latar belakang:
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.
Mengimplementasikan pemanggilan fungsi asinkron
Bagian ini memberikan serangkaian contoh penggunaan Agent Platform SDK versi Python untuk membangun arsitektur serentak yang sangat responsif dan menggunakan kemampuan panggilan fungsi asinkron Gemini Live API. Contohnya diuraikan ke dalam tugas-tugas berikut:
Menentukan alat Anda
Anda dapat mengontrol cara setiap alat dijalankan dengan menetapkan kolom behavior dari
FunctionDeclaration:
NON_BLOCKING(default jikabehaviortidak disetel): model akan terus bercakap-cakap saat alat Anda dijalankan. Gunakan setelan ini untuk pencarian hanya baca atau tugas latar belakang yang hasilnya dapat dikirimkan nanti.BLOCKING: model akan dijeda dan menungguFunctionResponseAnda sebelum menghasilkan output lebih lanjut. Gunakan setelan ini untuk operasi yang mengubah status atau tidak dapat diubah (seperti pembayaran, pemesanan, atau pembaruan akun) yang modelnya tidak boleh mengonfirmasi hasil sebelum mengetahui hasilnya. Jika input pengguna baru tiba saat panggilan pemblokiran sedang berjalan, server akan membatalkan panggilan, sehingga memerlukan idempotensi backend.
Jika Anda menggunakan framework di atas Gemini Live API, pastikan framework tersebut
mengirimkan behavior dalam pesan penyiapan sesi; jika dihilangkan, alat akan berjalan sebagai
NON_BLOCKING secara default.
Contoh Python berikut menunjukkan cara mendeklarasikan alat non-pemblokiran dan pemblokiran:
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])]
Menangani panggilan fungsi dari aliran pesan
Jika satu atau beberapa fungsi harus dipanggil oleh model,
Gemini Live API akan mengirimkan peristiwa tool_call melalui aliran pesan real-time.
Backend Anda tidak boleh memblokir streaming karena model diharapkan untuk terus
berjalan. Saat menerima panggilan untuk fungsi lambat (seperti
search_live_flights), Anda harus meneruskannya ke pekerja latar belakang. Jika Anda menggunakan
await langsung di loop pesan utama untuk tugas berdurasi 10 detik, Anda akan
membekukan koneksi. Tugas cepat (seperti get_current_weather)
dapat ditunggu dengan aman.
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)
Mengelola ekspektasi pengguna
Untuk mengelola ekspektasi selama panggilan fungsi asinkron yang berjalan lama, kirim pesan teks dari klien yang meminta sistem untuk memberi tahu pengguna bahwa permintaan sedang diproses dan meminta kesabaran mereka. Misalnya, setelah panggilan fungsi diterima oleh klien, klien dapat mengirim pesan teks ke model seperti: "ulangi kalimat ini: 'Saya sedang memesan tiket Anda, harap tunggu.'".
Contoh dialog berikut menunjukkan pertukaran ini:
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.
Strategi pesan proaktif ini memiliki manfaat berikut:
- Menginformasikan operasi sistem saat ini kepada pengguna, yang mengelola ekspektasi selama panggilan fungsi yang berjalan lama.
- Mengurangi frekuensi perintah singkat pengguna yang berlebihan, seperti "halo?" atau "apakah Anda di sana?". Hal ini sering terjadi selama periode panjang saat sistem tidak merespons selagi panggilan fungsi asinkron diproses. Hal ini dapat meminimalkan risiko panggilan fungsi duplikat yang dipicu oleh permintaan pengguna yang berulang ini.
- Memberikan perintah sistem tambahan dapat menurunkan kemungkinan pembuatan panggilan duplikat dalam interaksi berikutnya.
Menangani panggilan fungsi duplikat
Ada kemungkinan kecil bahwa model akan menghasilkan panggilan fungsi duplikat sebelum menerima respons untuk panggilan pertama. Jika kasus penggunaan Anda mengizinkan, aplikasi Anda dapat mengabaikan panggilan fungsi duplikat jika respons untuk panggilan fungsi yang sama masih tertunda.
Contoh berikut menunjukkan cara klien dapat mengabaikan panggilan fungsi duplikat:
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.
Menangani respons fungsi asinkron
Setelah panggilan fungsi asinkron selesai, aplikasi Anda akan mengirimkan hasilnya ke model dalam function_response. Saat backend Anda memproses
panggilan fungsi, seperti menelusuri penerbangan, pengguna mungkin mengajukan pertanyaan yang
sama sekali berbeda kepada model, seperti, "Bagaimana cuaca di
London?". Model merespons permintaan secara real-time, bersamaan dengan eksekusi panggilan fungsi. Karena pengguna mungkin sedang berinteraksi dengan model saat eksekusi fungsi selesai, Anda dapat menentukan kebijakan yang menentukan cara model menangani respons yang masuk ini. Anda dapat menentukan salah satu
kebijakan berikut:
Untuk menentukan kebijakan, sertakan kolom scheduling dalam payload function_response Anda:
{
"name": "book_ticket",
"scheduling": "WHEN_IDLE",
"response": {
"booking_status": "booked"
}
}
Dukungan model untuk FunctionResponse.scheduling bervariasi menurut model:
Gemini 3.8 Live: mendukungscheduling(SILENT,WHEN_IDLE, danINTERRUPT).gemini-3.8-live-extended-thinking-preview: tidak mendukung konfigurasi penjadwalan eksplisit. Mengirimschedulingakan menyebabkan sesi ditutup dengan error WebSocket 1007. Untuk model ini, hapus kolomscheduling.
Jika scheduling dihilangkan pada model yang didukung, Gemini Live API akan ditetapkan secara default ke
WHEN_IDLE. Setiap respons fungsi yang masuk akan memicu giliran model baru setelah
pengguna selesai berbicara.
Contoh Python berikut menunjukkan cara memformat dan mengirim function_response
dengan scheduling="WHEN_IDLE" untuk menunggu jeda alami dalam percakapan
sebelum mengumumkan hasil:
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])
Kebijakan berikut dapat ditentukan di kolom scheduling untuk mengelola respons fungsi:
Kebijakan respons SILENT
Dengan kebijakan SILENT, respons fungsi ditambahkan ke konteks model,
tetapi model tidak menghasilkan respons untuknya, dan interaksi pengguna
yang sedang berlangsung tidak akan terganggu.
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.
Kebijakan respons WHEN_IDLE
Dengan kebijakan WHEN_IDLE, model akan menghasilkan respons terhadap respons fungsi hanya jika tidak ada interaksi pengguna yang aktif. Jika interaksi pengguna
sedang berlangsung, model akan menunggu hingga interaksi selesai sebelum menghasilkan respons
untuk menghindari gangguan.
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.
Kebijakan respons INTERRUPT
Dengan kebijakan INTERRUPT, model akan segera menghasilkan respons terhadap respons fungsi, sehingga mengganggu interaksi pengguna yang sedang berlangsung.
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.
Menggabungkan beberapa respons non-pemblokiran
Saat model memanggil beberapa alat non-pemblokiran secara serentak (seperti pencarian data paralel), mengirimkan setiap hasil satu per satu dengan WHEN_IDLE akan menyebabkan model menghasilkan beberapa giliran bicara yang terpisah. Untuk memberikan satu
respons gabungan, terapkan salah satu pola berikut:
- Gunakan SILENT untuk hasil menengah: Kirim semua respons alat menengah dengan
scheduling="SILENT". Kirim respons akhir denganscheduling="WHEN_IDLE"agar model meringkas semua data yang dikumpulkan dalam satu giliran. - Respons batch: Tunggu hingga semua tugas alat serentak selesai dan
kirimkan bersama-sama dalam satu panggilan
send_tool_responsedenganfunction_responses=[...].
Praktik terbaik
- Deklarasikan perilaku alat secara eksplisit: Tetapkan alat yang mengubah status atau tidak dapat diubah ke
BLOCKING, dan tetapkan pencarian hanya baca atau latar belakang keNON_BLOCKING. - Desain untuk konkurensi: Selalu pindahkan alat yang lambat (seperti membuat kueri API eksternal atau menjalankan pipeline RAG) ke tugas latar belakang di backend Anda. Biarkan model terus menangani streaming audio aktif.
- Jadwalkan respons non-pemblokiran dengan sengaja: Gunakan
SILENTuntuk respons perantara,WHEN_IDLEuntuk hasil akhir yang akan memicu output lisan, danINTERRUPThanya untuk pemberitahuan penting. Jikaschedulingtidak ditetapkan, setelan defaultnya adalahWHEN_IDLEdan memulai giliran model untuk setiap respons. - Giliran chat independen: Di Gemini Live API, eksekusi alat sepenuhnya independen dari giliran chat. Percakapan dapat bercabang, berlanjut, dan mengalir secara alami saat alat Anda memproses di latar belakang.
- Peringatan "Senyap": Model mungkin masih sesekali mencoba
menceritakan eksekusi alat secara lisan meskipun dijadwalkan sebagai
SILENT. Untuk menerapkan keheningan sejati, tambahkan guardrail eksplisit ke System Instructions Anda (misalnya, "Saat menggunakan [Nama Alat], lakukan SILENT EXECUTION dan jangan katakan apa pun"), atau gunakan pola backend "fire-and-forget" di mana Anda tidak mengirimFunctionResponsekembali ke model sama sekali.
Langkah berikutnya
Memulai dan mengelola sesi live
Pelajari cara memulai dan mengelola sesi live dengan Live API.
Mengonfigurasi kemampuan Gemini
Pelajari cara mengonfigurasi kemampuan Gemini untuk Live API.