Panggilan fungsi asinkron dengan Gemini Live API

Saat membangun agen suara real-time, beberapa panggilan fungsi dapat memblokir eksekusi model, yang menyebabkan aliran audio menjadi senyap dan pengguna harus menunggu dalam diam. Dengan Gemini Live API, semua panggilan fungsi secara default tidak memblokir, 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 langsung atau mengkueri API eksternal yang kompleks di latar belakang, sementara model terus mendengarkan, berbicara, dan berinteraksi 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.

Dengan panggilan fungsi asinkron, Anda dapat 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 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.

Menerapkan panggilan fungsi asinkron

Bagian ini memberikan serangkaian contoh menggunakan Agent Platform SDK versi Python untuk membangun arsitektur serentak yang sangat responsif yang menggunakan kemampuan panggilan fungsi asinkron Gemini Live API. Contohnya dibagi menjadi tugas-tugas berikut:

Tentukan alat Anda

Panggilan fungsi asinkron diaktifkan di tingkat model, sehingga Anda dapat menentukan alat yang ingin digunakan dalam konfigurasi permintaan seperti yang Anda lakukan untuk panggilan Gemini API standar di Platform Agen Gemini Enterprise. Hal ini memungkinkan model melanjutkan percakapan saat alat Anda dijalankan:

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]}]

Menangani panggilan fungsi dari aliran pesan

Saat satu atau beberapa fungsi harus dipanggil oleh model, Gemini Live API mengirimkan peristiwa tool_call melalui aliran pesan real-time.

Backend Anda tidak boleh memblokir streaming karena model diharapkan tetap berjalan. Saat menerima panggilan untuk fungsi yang lambat (seperti search_live_flights), Anda harus meneruskannya ke pekerja latar belakang. Jika Anda menggunakan await secara langsung dalam loop pesan utama untuk tugas 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, sebaiknya klien memulai pesan teks. Pesan ini akan mendorong 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 sebagai berikut:

  • Memberi tahu pengguna tentang operasi sistem saat ini, yang mengelola ekspektasi selama panggilan fungsi yang berjalan lama.
  • Mengurangi frekuensi perintah pengguna singkat yang berlebihan, seperti "halo?" atau "apakah Anda ada?". Hal ini sering terjadi selama periode panjang ketika sistem tidak ada aktivitas saat panggilan fungsi asinkron sedang diproses. Hal ini dapat meminimalkan risiko panggilan fungsi duplikat yang dipicu oleh pertanyaan pengguna yang berulang ini.
  • Memberikan perintah sistem tambahan dapat mengurangi kemungkinan pembuatan panggilan duplikat dalam interaksi berikutnya.

Menangani panggilan fungsi duplikat

Ada kemungkinan kecil model membuat panggilan fungsi duplikat sebelum menerima respons untuk panggilan pertama. Jika kasus penggunaan Anda memungkinkan, 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 hasil 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 akan merespons permintaan secara real-time, secara paralel dengan eksekusi panggilan fungsi. Karena pengguna mungkin sedang berinteraksi dengan model saat eksekusi fungsi selesai, Anda dapat menentukan kebijakan yang menentukan cara model harus 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"
  }
}

Jika Anda menghilangkan kolom scheduling, Gemini Live API akan menggunakan metode aslinya untuk menangani respons fungsi demi kompatibilitas mundur.

Contoh Python berikut menunjukkan cara memformat dan mengirim function_response dengan scheduling="WHEN_IDLE" untuk menunggu jeda alami dalam percakapan sebelum mengumumkan hasil:

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])

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 membuat respons untuknya, dan interaksi pengguna yang sedang berlangsung tidak 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 menghasilkan respons terhadap respons fungsi hanya jika tidak ada interaksi pengguna yang aktif. Jika interaksi pengguna sedang berlangsung, model akan menunggu hingga interaksi tersebut selesai sebelum membuat 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.

Praktik terbaik

  • Desain untuk konkurensi: Selalu alihkan alat yang lambat (seperti membuat kueri API eksternal atau menjalankan pipeline RAG) ke tugas latar belakang di backend Anda. Biarkan model terus menangani aliran audio aktif.
  • Hindari INTERRUPT kecuali jika diperlukan: Gunakan INTERRUPT untuk pemberitahuan penting. Untuk tugas latar belakang, SILENT atau WHEN_IDLE memberikan pengalaman pengguna yang jauh lebih lancar dan lebih baik.
  • Giliran percakapan yang independen: Di Gemini Live API, eksekusi alat sepenuhnya independen dari giliran percakapan. Percakapan dapat bercabang, berlanjut, dan mengalir secara alami saat alat Anda memproses di latar belakang.
  • Peringatan "Senyap": Model mungkin masih sesekali mencoba menceritakan secara verbal eksekusi alat meskipun dijadwalkan sebagai SILENT. Untuk menerapkan keheningan yang sebenarnya, tambahkan batasan yang jelas ke Petunjuk Sistem Anda (misalnya, "Saat menggunakan [Nama Alat], lakukan EKSEKUSI SENYAP dan jangan berbicara"), atau gunakan pola backend "fire-and-forget" di mana Anda tidak mengirim FunctionResponse kembali ke model sama sekali.

Langkah berikutnya

Ringkasan

Dapatkan ringkasan Live API.

Referensi

Panduan referensi untuk Live API.

Panduan

Pelajari cara memulai dan mengelola sesi live dengan Live API.

Panduan

Pelajari cara mengonfigurasi kemampuan Gemini untuk Live API.