Session management with Live API

Di Live API, sesi mengacu pada koneksi persisten tempat input dan output di-streaming secara terus-menerus melalui koneksi yang sama (baca selengkapnya tentang cara kerjanya). Desain sesi unik ini memungkinkan latensi rendah dan mendukung fitur unik, tetapi juga dapat menimbulkan tantangan, seperti batas waktu sesi, dan penghentian awal. Panduan ini membahas strategi untuk mengatasi tantangan pengelolaan sesi yang dapat muncul saat menggunakan Live API.

Masa aktif sesi

Tanpa kompresi, sesi audio saja dibatasi hingga 15 menit, dan sesi audio-video dibatasi hingga 2 menit. Melampaui batas ini akan menghentikan sesi (dan dengan demikian, koneksi), tetapi Anda dapat menggunakan kompresi jendela konteks untuk memperpanjang sesi hingga waktu yang tidak terbatas.

Masa aktif koneksi juga dibatasi, hingga sekitar 10 menit. Saat koneksi berakhir, sesi juga akan berakhir. Dalam hal ini, Anda dapat mengonfigurasi satu sesi agar tetap aktif melalui beberapa koneksi menggunakan lanjutan sesi. Anda juga akan menerima pesan GoAway sebelum koneksi berakhir, sehingga Anda dapat mengambil tindakan lebih lanjut.

Kompresi jendela konteks

Untuk mengaktifkan sesi yang lebih lama, dan menghindari penghentian koneksi secara tiba-tiba, Anda dapat mengaktifkan kompresi jendela konteks dengan menetapkan kolom contextWindowCompression sebagai bagian dari konfigurasi sesi.

Di ContextWindowCompressionConfig, Anda dapat mengonfigurasi mekanisme jendela geser dan jumlah token yang memicu kompresi.

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: {} }
};

Melanjutkan sesi

Untuk mencegah penghentian sesi saat server mereset koneksi WebSocket secara berkala, konfigurasikan kolom sessionResumption dalam konfigurasi penyiapan.

Meneruskan konfigurasi ini akan menyebabkan server mengirim pesan SessionResumptionUpdate, yang dapat digunakan untuk melanjutkan sesi dengan meneruskan token lanjutan terakhir sebagai SessionResumptionConfig.handle koneksi berikutnya.

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();

Menerima pesan sebelum sesi terputus

Server mengirim pesan GoAway yang menandakan bahwa koneksi saat ini akan segera dihentikan. Pesan ini menyertakan timeLeft, yang menunjukkan waktu yang tersisa dan memungkinkan Anda mengambil tindakan lebih lanjut sebelum koneksi dihentikan sebagai 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);
  }
}

Menerima pesan saat pembuatan selesai

Server mengirimkan pesan generationComplete yang menandakan bahwa model telah selesai membuat respons.

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

Langkah berikutnya

Jelajahi lebih banyak cara menggunakan Live API dalam panduan Kemampuan lengkap, halaman Penggunaan alat, atau cookbook Live API.