ב-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.