Panggilan fungsi asinkron dengan Gemini Live API

Saat membangun agen suara real-time, beberapa panggilan fungsi dapat memblokir eksekusi model, yang menyebabkan streaming audio menjadi senyap dan pengguna harus menunggu dalam diam. Dengan Gemini Live API, semua panggilan fungsi tidak memblokir secara default, yang memungkinkan Anda menjalankan fungsi secara paralel dengan alur percakapan utama. Proses ini disebut panggilan 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 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.

Panggilan fungsi asinkron memungkinkan Anda menyelesaikan tugas seperti memesan janji temu, menetapkan 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 panggilan 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.

Mengimplementasikan panggilan fungsi asinkron

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

Menentukan alat

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 Gemini Enterprise Agent Platform. Hal ini memungkinkan model untuk terus bercakap-cakap 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

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 aliran karena model diharapkan terus berjalan. Saat menerima panggilan untuk fungsi yang lambat (seperti search_live_flights), Anda harus meneruskannya ke pekerja latar belakang. Jika Anda menggunakan await langsung dalam loop pesan utama untuk tugas 10 detik, koneksi akan dibekukan. 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 harus 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 sekarang, harap tunggu.'".

Dialog contoh 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:

  • 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 senyap sistem yang panjang saat panggilan fungsi asinkron sedang diproses. Hal ini dapat meminimalkan risiko panggilan fungsi duplikat yang dipicu oleh kueri pengguna yang berulang ini.
  • Memberikan perintah sistem tambahan dapat menurunkan kemungkinan membuat panggilan duplikat dalam interaksi berikutnya.

Menangani panggilan fungsi duplikat

Ada kemungkinan kecil model menghasilkan panggilan fungsi duplikat sebelum menerima respons untuk panggilan pertama. Jika kasus penggunaan Anda mengizinkannya, 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 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 menangani respons 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 menghapus 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 akan membuat respons terhadap respons fungsi hanya jika tidak ada interaksi pengguna yang aktif. Jika interaksi pengguna sedang berlangsung, model akan menunggu hingga 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 membuat 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 pindahkan alat yang lambat (seperti mengkueri API eksternal atau menjalankan pipeline RAG) ke tugas latar belakang di backend Anda. Biarkan model terus menangani streaming 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 sopan.
  • 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 diproses di latar belakang.
  • Peringatan "Senyap": Model mungkin masih sesekali mencoba menarasikan eksekusi alat secara verbal meskipun dijadwalkan sebagai SILENT. Untuk menerapkan kesenyapan yang sebenarnya, tambahkan batasan eksplisit ke Petunjuk Sistem Anda (misalnya, "Saat menggunakan [Nama Alat], lakukan EKSEKUSI SENYAP dan jangan katakan apa pun"), atau gunakan pola backend "kirim dan lupakan" tempat 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.