Session management with Live API

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

משך החיים של הסשן

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

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

דחיסה של חלון ההקשר

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

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

Python

from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    context_window_compression=(
        # Configures compression with default parameters.
        types.ContextWindowCompressionConfig(
            sliding_window=types.SlidingWindow(),
        )
    ),
)

JavaScript

const config = {
  responseModalities: [Modality.AUDIO],
  contextWindowCompression: { slidingWindow: {} }
};

המשך הפעילות

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

העברת ההגדרה הזו גורמת לשרת לשלוח הודעות SessionResumptionUpdate, שאפשר להשתמש בהן כדי להמשיך את הסשן על ידי העברת טוקן ההמשך האחרון כ-SessionResumptionConfig.handle של החיבור הבא.

התוקף של אסימוני חידוש הוא שעתיים אחרי סיום הסשן האחרון.

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

async def main():
    print(f"Connecting to the service with handle {previous_session_handle}...")
    async with client.aio.live.connect(
        model=model,
        config=types.LiveConnectConfig(
            response_modalities=["AUDIO"],
            session_resumption=types.SessionResumptionConfig(
                # The handle of the session to resume is passed here,
                # or else None to start a new session.
                handle=previous_session_handle
            ),
        ),
    ) as session:
        while True:
            await session.send_client_content(
                turns=types.Content(
                    role="user", parts=[types.Part(text="Hello world!")]
                )
            )
            async for message in session.receive():
                # Periodically, the server will send update messages that may
                # contain a handle for the current state of the session.
                if message.session_resumption_update:
                    update = message.session_resumption_update
                    if update.resumable and update.new_handle:
                        # The handle should be retained and linked to the session.
                        return update.new_handle

                # For the purposes of this example, placeholder input is continually fed
                # to the model. In non-sample code, the model inputs would come from
                # the user.
                if message.server_content and message.server_content.turn_complete:
                    break

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

console.debug('Connecting to the service with handle %s...', previousSessionHandle)
const session = await ai.live.connect({
  model: model,
  callbacks: {
    onopen: function () {
      console.debug('Opened');
    },
    onmessage: function (message) {
      responseQueue.push(message);
    },
    onerror: function (e) {
      console.debug('Error:', e.message);
    },
    onclose: function (e) {
      console.debug('Close:', e.reason);
    },
  },
  config: {
    responseModalities: [Modality.TEXT],
    sessionResumption: { handle: previousSessionHandle }
    // The handle of the session to resume is passed here, or else null to start a new session.
  }
});

const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });

const turns = await handleTurn();
for (const turn of turns) {
  if (turn.sessionResumptionUpdate) {
    if (turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle) {
      let newHandle = turn.sessionResumptionUpdate.newHandle
      // ...Store newHandle and start new session with this handle here
    }
  }
}

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

קבלת הודעה לפני ניתוק הסשן

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

Python

async for response in session.receive():
    if response.go_away is not None:
        # The connection will soon be terminated
        print(response.go_away.time_left)

JavaScript

const turns = await handleTurn();

for (const turn of turns) {
  if (turn.goAway) {
    console.debug('Time left: %s\n', turn.goAway.timeLeft);
  }
}

קבלת הודעה כשהיצירה מסתיימת

השרת שולח הודעה מסוג generationComplete שמציינת שהמודל סיים ליצור את התגובה.

Python

async for response in session.receive():
    if response.server_content.generation_complete is True:
        # The generation is complete

JavaScript

const turns = await handleTurn();

for (const turn of turns) {
  if (turn.serverContent && turn.serverContent.generationComplete) {
    // The generation is complete
  }
}

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

אפשר לעיין בדרכים נוספות לעבודה עם Live API במדריך המלא יכולות, בדף שימוש בכלי או בספר המתכונים של Live API.