בקשות אסינכרוניות להפעלת פונקציות באמצעות Gemini Live API

כשמפתחים סוכני קול בזמן אמת, חלק מהבקשות להפעלת פונקציות יכולות לחסום את הפעולה של המודל, וכתוצאה מכך שידור האודיו מושתק והמשתמש נשאר להמתין בשקט. ב-Gemini Live API, כל בקשות הפעלת הפונקציות לא חוסמות כברירת מחדל, וכך אפשר להפעיל פונקציות במקביל לזרימת השיחה הראשית. התהליך הזה נקרא קריאה אסינכרונית להפעלת פונקציות. הקצה העורפי יכול לעבד משימות כבדות כמו חיפוש מחירי טיסות בזמן אמת או שליחת שאילתות לממשקי API חיצוניים מורכבים ברקע, בזמן שהמודל ממשיך להאזין, לדבר ולנהל שיחה טבעית עם המשתמש. ‫Gemini Live API מאפשר לעבד קריאות להפעלת פונקציות ברקע בלי להפריע לאינטראקציה של המשתמש עם המודל, וכך מאפשר אינטראקציות חלקות יותר בזמן אמת.

קריאה אסינכרונית להפעלת פונקציות מאפשרת לכם לבצע משימות כמו קביעת פגישות, הגדרת תזכורות או אחזור נתונים בלי להשהות את השיחה. לדוגמה, משתמש יכול לבקש להזמין טיסה ומיד לבקש מידע על מזג האוויר בזמן שההזמנה מעובדת ברקע.

דוגמה לקריאה אסינכרונית להפעלת פונקציות

בדוגמה הזו, המשתמש מזמין טיסה ושואל מה השעה בניו יורק, בזמן שהפונקציה book_ticket פועלת באופן אסינכרוני ברקע:

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.

הטמעה של קריאה אסינכרונית להפעלת פונקציות

בקטע הזה יש כמה דוגמאות לשימוש בגרסת Python של Agent Platform SDK כדי ליצור ארכיטקטורה בו-זמנית ורספונסיבית מאוד, שמשתמשת ביכולת קריאה להפעלת פונקציות אסינכרונית של Gemini Live API. הדוגמאות מחולקות למשימות הבאות:

הגדרת הכלים

אתם יכולים לקבוע איך כל כלי יפעל באמצעות הגדרת השדה behavior של ה-FunctionDeclaration שלו:

  • NON_BLOCKING (ברירת המחדל כשלא מגדירים את behavior): המודל ממשיך בשיחה בזמן שהכלי פועל. ההגדרה הזו מתאימה לחיפושים לקריאה בלבד או למשימות ברקע שאפשר להעביר את התוצאות שלהן מאוחר יותר.
  • ‫BLOCKING: המודל עוצר וממתין לFunctionResponse לפני שהוא ממשיך ליצור פלט. השתמשו בהגדרה הזו לפעולות שמשנות מצב או לפעולות בלתי הפיכות (כמו תשלומים, הזמנות או עדכוני חשבון) שבהן המודל לא יכול לאשר תוצאה לפני שהוא יודע מה היא. אם מתקבל קלט חדש מהמשתמש בזמן שקריאה חוסמת פועלת, השרת מבטל את הקריאה, וזה דורש אידמפוטנטיות בקצה העורפי.

אם אתם משתמשים ב-framework בנוסף ל-Gemini Live API, ודאו שה-framework מעביר את behavior בהודעת הגדרת הסשן. אם משמיטים את זה, הכלים פועלים כ-NON_BLOCKING כברירת מחדל.

בדוגמה הבאה ב-Python אפשר לראות איך להצהיר על כלים חוסמים וכלים לא חוסמים:

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

טיפול בבקשות להפעלת פונקציות מזרם ההודעות

כשהמודל צריך לקרוא לפונקציה אחת או יותר, Gemini Live API שולח אירוע tool_call דרך זרם ההודעות בזמן אמת.

ה-backend לא יכול לחסום את הסטרימינג כי המודל אמור להמשיך לפעול. כשאתם מקבלים קריאה לפונקציה איטית (כמו search_live_flights), אתם צריכים להעביר אותה ל-worker ברקע. אם משתמשים ב-await ישירות בלולאת ההודעות הראשית למשימה של 10 שניות, החיבור יוקפא. אפשר להמתין בבטחה למשימות מהירות (כמו get_current_weather).

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)

ניהול הציפיות של המשתמשים

כדי לנהל את הציפיות של המשתמשים במהלך קריאות אסינכרוניות לפונקציות שנמשכות זמן רב, שלחו הודעת טקסט מהלקוח שמבקשת מהמערכת להודיע למשתמש שהבקשה בטיפול ולבקש ממנו להתאזר בסבלנות. לדוגמה, אחרי שהלקוח מקבל בקשה להפעלת פונקציה, הוא יכול לשלוח למודל הודעת טקסט כמו: "חזור על המשפט הזה: 'אני מזמין את הכרטיס שלך עכשיו, המתן בבקשה'".

הדוגמה הבאה מראה את השיחה הזו:

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.

היתרונות של אסטרטגיית ההודעות הפרואקטיבית הזו:

  • המשתמש מקבל מידע על פעולות המערכת הנוכחיות, וכך הוא יודע למה לצפות במהלך קריאות ארוכות להפעלת פונקציות.
  • מפחית את התדירות של הנחיות מיותרות וקצרות של משתמשים, כמו "הלו?" או "אתה שם?". השגיאות האלה קורות בדרך כלל כשהמערכת לא מגיבה במשך זמן רב, בזמן שהיא מעבדת קריאות אסינכרוניות להפעלת פונקציות. כך אפשר לצמצם את הסיכון לקריאות כפולות להפעלת פונקציות שמופעלות על ידי השאילתות החוזרות האלה של המשתמשים.
  • הוספת הנחיית מערכת נוספת יכולה להפחית את הסבירות ליצירת קריאות כפולות באינטראקציות הבאות.

טיפול בקריאות כפולות להפעלת פונקציות

יש סיכוי קטן שהמודל ייצור קריאות כפולות להפעלת פונקציות לפני שתתקבל תשובה לקריאה הראשונה. אם תרחיש השימוש שלכם מאפשר זאת, האפליקציה יכולה להתעלם מקריאות כפולות להפעלת פונקציות אם התגובה לאותה קריאה עדיין בהמתנה.

בדוגמה הבאה אפשר לראות איך הלקוח יכול להתעלם מקריאה כפולה להפעלת פונקציה:

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.

טיפול בתשובות של פונקציות אסינכרוניות

כשהבקשה האסינכרונית להפעלת פונקציה מסתיימת, האפליקציה שולחת את התוצאה למודל ב-function_response. בזמן שה-backend מעבד בקשה להפעלת פונקציה, כמו חיפוש טיסות, המשתמש יכול לשאול את המודל שאלה אחרת לגמרי, כמו "What's the weather like in London?‎". המודל מגיב לבקשה בזמן אמת, במקביל להפעלת הפונקציה. יכול להיות שהמשתמש יהיה באינטראקציה מתמשכת עם המודל כשהפונקציה תסיים לפעול, לכן אפשר לציין מדיניות שמגדירה איך המודל צריך לטפל בתגובה הנכנסת הזו. אפשר לציין אחת מהמדיניות הבאות:

כדי לציין מדיניות, צריך לכלול את השדה scheduling ב-payload של function_response:

{
  "name": "book_ticket",
  "scheduling": "WHEN_IDLE",
  "response": {
    "booking_status": "booked"
  }
}

התמיכה של המודלים ב-FunctionResponse.scheduling משתנה בהתאם למודל:

  • ‫Gemini 3.8 Live: תומך ב-scheduling (SILENT,‏ WHEN_IDLE ו-INTERRUPT).
  • ‫gemini-3.8-live-extended-thinking-preview: לא תומך בהגדרות תזמון מפורשות. שליחת scheduling גורמת לסגירת הסשן עם שגיאת WebSocket‏ 1007. במודל הזה, משמיטים את השדה scheduling.

כשמשמיטים את scheduling במודלים נתמכים, Gemini Live API משתמש בערך ברירת המחדל WHEN_IDLE. כל תגובה לפונקציה נכנסת מפעילה תור חדש של המודל אחרי שהמשתמש מסיים לדבר.

בדוגמה הבאה ב-Python אפשר לראות איך להגדיר את הפורמט של function_response ולשלוח אותו עם scheduling="WHEN_IDLE" כדי להמתין להפסקה טבעית בשיחה לפני שמכריזים על התוצאות:

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

אפשר לציין את כללי המדיניות הבאים בשדה scheduling כדי לנהל את התגובות של הפונקציות:

מדיניות תגובה שקטה (SILENT)

במדיניות SILENT, התגובה של הפונקציה מתווספת להקשר של המודל, אבל המודל לא יוצר תגובה בשבילה, וכל אינטראקציה מתמשכת של המשתמש לא מופסקת.

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.

מדיניות התגובה WHEN_IDLE

במדיניות WHEN_IDLE, המודל יוצר תשובה לפונקציה רק כשאין אינטראקציה פעילה עם המשתמש. אם המשתמש מבצע פעולה, המודל מחכה שהיא תסתיים לפני שהוא יוצר תשובה כדי לא להפריע.

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

במדיניות INTERRUPT, המודל יוצר תשובה לפונקציה באופן מיידי, וקוטע כל אינטראקציה מתמשכת עם המשתמש.

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.

צבירת כמה תשובות שלא חוסמות

כשהמודל קורא לכמה כלים לא חוסמים בו-זמנית (כמו חיפושי נתונים מקבילים), שליחת כל תוצאה בנפרד באמצעות WHEN_IDLE גורמת למודל ליצור כמה תורות דיבור נפרדים. כדי להחזיר תשובה אחת מאוחדת, צריך להשתמש באחת מהתבניות הבאות:

  • שימוש ב-SILENT לתוצאות ביניים: שליחת כל התגובות של כלי הביניים באמצעות scheduling="SILENT". שולחים את התשובה הסופית עם scheduling="WHEN_IDLE" כדי שהמודל יסכם את כל הנתונים שנאספו בסבב אחד.
  • תגובות באצווה: המתינו עד שכל המשימות של הכלים שפועלים בו-זמנית יסתיימו, ושלחו אותן יחד בקריאה אחת של send_tool_response עם function_responses=[...].

שיטות מומלצות

  • הצהירו על התנהגות הכלי באופן מפורש: הגדירו כלים שמשנים מצב או כלים בלתי הפיכים ל-BLOCKING, והגדירו חיפושים לקריאה בלבד או חיפושים ברקע ל-NON_BLOCKING.
  • תכנון לפעולות בו-זמניות: תמיד כדאי להעביר כלים איטיים (כמו שליחת שאילתות לממשקי API חיצוניים או הפעלת צינורות עיבוד נתונים של RAG) למשימות ברקע בקצה העורפי. נותנים למודל להמשיך לטפל בשידור האודיו הפעיל.
  • תזמנו תשובות שלא חוסמות את השיחה: השתמשו ב-SILENT לתשובות ביניים, ב-WHEN_IDLE לתוצאה הסופית שאמורה להפעיל פלט קולי, וב-INTERRUPT רק להתראות קריטיות. אם לא מגדירים את scheduling, ברירת המחדל היא WHEN_IDLE ומתחיל תור של המודל לכל תשובה.
  • סבבי שיחה עצמאיים: ב-Gemini Live API, הפעלת הכלים לא תלויה בסבבי השיחה. השיחה יכולה להסתעף, להמשיך ולהתנהל באופן טבעי בזמן שהכלי שלכם מעבד את הנתונים ברקע.
  • האזהרה "שקט": יכול להיות שהמודל עדיין ינסה מדי פעם לתאר באופן מילולי את הפעלת הכלי, גם אם הוא מתוזמן כ-SILENT. כדי לאכוף שתיקה מוחלטת, הוסיפו הנחיות מפורשות להוראות המערכת (לדוגמה, "כשמשתמשים ב-[שם הכלי], צריך לבצע SILENT EXECUTION ולא להגיד כלום"), או השתמשו בתבנית קצה עורפי מסוג "fire-and-forget" שבה לא שולחים FunctionResponse בחזרה למודל בכלל.

המאמרים הבאים

סקירה כללית

סקירה כללית על Live API.

מקור מידע

מדריך עזר ל-Live API.

מדריך

איך מתחילים ומנהלים סשנים בשידור חי באמצעות Live API.

מדריך

איך מגדירים את היכולות של Gemini ב-Live API.