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

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

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

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

בדוגמה הזו, משתמש מזמין טיסה ומבקש לדעת מה השעה בניו יורק בזמן שהפונקציה 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 לקריאה אסינכרונית לפונקציות. הדוגמאות מחולקות למשימות הבאות:

הגדרת הכלים

הפעלת קריאה אסינכרונית לפונקציה מתבצעת ברמת המודל, כך שאפשר לציין אילו כלים רוצים להשתמש בהם בהגדרת הבקשה, כמו בכל קריאה רגילה ל-Gemini API ב-Gemini Enterprise Agent Platform. כך המודל יכול להמשיך בשיחה בזמן שהכלי פועל:

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

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

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

הקצה העורפי לא יכול לחסום את הזרם כי המודל מצפה להמשיך לפעול. כשמקבלים קריאה לפונקציה איטית (כמו search_live_flights), צריך להעביר אותה לעובד ברקע. אם משתמשים ב-await ישירות בלולאת ההודעות הראשית למשימה של 10 שניות, החיבור יקפא. אפשר להשתמש ב-await בבטחה במשימות מהירות (כמו 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. בזמן שהקצה העורפי מעבד קריאה לפונקציה, כמו חיפוש טיסות, המשתמש יכול לשאול את המודל שאלה שונה לחלוטין, למשל: What's the weather like in London? (מה מזג האוויר בלונדון?). המודל יגיב לבקשה בזמן אמת, במקביל להרצת הקריאה לפונקציה. יכול להיות שהמשתמש ימשיך באינטראקציה עם המודל אחרי שהפונקציה תסיים את הביצוע שלה, ולכן אפשר לציין מדיניות שמגדירה איך המודל צריך לטפל בתגובה הנכנסת הזו. אפשר לציין אחת מהמדיניות הבאות:

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

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

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

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

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

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

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

במדיניות 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, המודל יוצר תגובה לפונקציה response רק כשאין אינטראקציה פעילה של משתמש. אם מתבצעת אינטראקציה עם המשתמש, המודל ימתין לסיום האינטראקציה לפני שיפיק תשובה, כדי למנוע הפרעה.

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, המודל יוצר תגובה לפונקציה response באופן מיידי, ומפריע לכל אינטראקציה מתמשכת עם המשתמש.

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.

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

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

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

סקירה כללית

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

מקור מידע

מדריך הפניה ל-Live API.

מדריך

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

מדריך

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