Session management with Live API

Nell'API Live, una sessione si riferisce a una connessione persistente in cui input e output vengono trasmessi in streaming continuamente sulla stessa connessione (scopri di più su come funziona). Questo design unico della sessione consente una bassa latenza e supporta funzionalità uniche, ma può anche introdurre sfide, come limiti di tempo della sessione e interruzione anticipata. Questa guida illustra le strategie per superare le sfide di gestione delle sessioni che possono sorgere quando si utilizza l'API Live.

Durata della sessione

Senza compressione, le sessioni solo audio sono limitate a 15 minuti e le sessioni audio-video sono limitate a 2 minuti. Il superamento di questi limiti terminerà la sessione (e quindi la connessione), ma puoi utilizzare la compressione della finestra contestuale per estendere le sessioni a un periodo di tempo illimitato.

Anche la durata di una connessione è limitata a circa 10 minuti. Quando la connessione termina, anche la sessione termina. In questo caso, puoi configurare una singola sessione in modo che rimanga attiva su più connessioni utilizzando il ripristino della sessione. Riceverai anche un messaggio di disconnessione prima che la connessione termini, per consentirti di intraprendere ulteriori azioni.

Compressione della finestra contestuale

Per abilitare sessioni più lunghe ed evitare l'interruzione improvvisa della connessione, puoi attivare la compressione della finestra contestuale impostando il campo contextWindowCompression nell'ambito della configurazione della sessione.

In ContextWindowCompressionConfig, puoi configurare un meccanismo a finestra scorrevole e il numero di token che attiva la compressione.

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

Ripresa della sessione

Per evitare la chiusura della sessione quando il server reimposta periodicamente la connessione WebSocket, configura il campo sessionResumption all'interno della configurazione di setup.

Il passaggio di questa configurazione fa sì che il server invii messaggi SessionResumptionUpdate, che possono essere utilizzati per riprendere la sessione passando l'ultimo token di ripresa come SessionResumptionConfig.handle della connessione successiva.

I token di ripresa sono validi per 2 ore dopo la chiusura dell'ultima sessione.

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

Ricevere un messaggio prima che la sessione si disconnetta

Il server invia un messaggio GoAway che segnala che la connessione corrente verrà terminata a breve. Questo messaggio include timeLeft, che indica il tempo rimanente e ti consente di intraprendere ulteriori azioni prima che la connessione venga terminata come INTERROTTA.

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

Ricevere un messaggio al termine della generazione

Il server invia un messaggio generationComplete che indica che il modello ha terminato di generare la risposta.

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

Passaggi successivi

Scopri altri modi per utilizzare l'API Live nella guida completa alle funzionalità, nella pagina Utilizzo degli strumenti o nel cookbook dell'API Live.