Session management with Live API

W przypadku interfejsu Live API sesja to trwałe połączenie, w którym dane wejściowe i wyjściowe są przesyłane w ciągu przez to samo połączenie (więcej informacji o sposobie działania). Ta wyjątkowa konstrukcja sesji umożliwia niską latencję i obsługę unikalnych funkcji, ale może też powodować problemy, takie jak limity czasu sesji i przedwczesne jej zakończenie. Ten przewodnik zawiera strategie radzenia sobie z problemami związanymi z zarządzaniem sesjami, które mogą wystąpić podczas korzystania z Live API.

Czas trwania sesji

Bez kompresji sesje z tylko dźwiękiem są ograniczone do 15 minut, a sesje z dźwiękiem i obrazem do 2 minut. Przekroczenie tych limitów spowoduje zakończenie sesji (a co za tym idzie, połączenia), ale możesz użyć kompresji okna kontekstowego, aby wydłużyć sesję do nieograniczonego czasu.

Czas trwania połączenia jest również ograniczony do około 10 minut. Gdy połączenie zostanie zakończone, sesja również się zakończy. W takim przypadku możesz skonfigurować jedną sesję tak, aby była aktywna w ciągu wielu połączeń, korzystając z wznawiania sesji. Zanim połączenie zostanie zakończone, otrzymasz też wiadomość GoAway, która pozwoli Ci podjąć dalsze działania.

Kompresja okna kontekstu

Aby umożliwić dłuższe sesje i uniknąć nagłego zakończenia połączenia, możesz włączyć kompresję okna kontekstowego, ustawiając pole contextWindowCompression w ramach konfiguracji sesji.

W ustawieniu ContextWindowCompressionConfig możesz skonfigurować mechanizm okna przesuwającego oraz liczbę tokenów, które uruchamiają kompresję.

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

Wznowienie sesji

Aby zapobiec zakończeniu sesji, gdy serwer okresowo resetuje połączenie WebSocket, skonfiguruj pole sessionResumption w konfiguracji konfiguracji.

Przekazanie tej konfiguracji powoduje, że serwer wysyła wiadomości SessionResumptionUpdate, których można użyć do wznowienia sesji, przekazując ostatni token wznowienia jako SessionResumptionConfig.handle kolejnego połączenia.

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

Otrzymywanie wiadomości przed zakończeniem sesji

Serwer wysyła wiadomość GoAway, która sygnalizuje, że bieżące połączenie zostanie wkrótce zakończone. Wiadomość zawiera timeLeft, czyli pozostały czas, oraz umożliwia podjęcie dalszych działań, zanim połączenie zostanie zakończone jako 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);
  }
}

otrzymywanie wiadomości po zakończeniu generowania.

Serwer wysyła wiadomość generationComplete, która sygnalizuje, że model zakończył generowanie odpowiedzi.

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

Co dalej?

Więcej informacji o tym, jak korzystać z Live API, znajdziesz w pełnej wersji przewodnika Możliwości, na stronie Używanie narzędzia oraz w poradniku Live API.