Démarrer et gérer des sessions en direct

L'API Gemini Live permet des interactions vocales et textuelles à faible latence en traitant des flux continus d'audio ou de texte appelés sessions pour fournir des réponses vocales immédiates et semblables à celles d'un humain. La gestion du cycle de vie de la session, de l'établissement de liaison initial à l'arrêt progressif, est contrôlée par le développeur.

Cette page vous explique comment démarrer une session de conversation avec des modèles Gemini à l'aide de l'API Gemini Live. Vous pouvez démarrer une session à l'aide de Vertex AI Studio, du SDK Google Gen AI ou de WebSockets.

Cette page vous explique également comment :

  • Prolonger une session au-delà de la durée maximale par défaut
  • Reprendre une session précédente
  • Mettre à jour les instructions système pendant une session
  • Mettre à jour les instructions et les outils système pendant une session avec Gemini 3.8 Live
  • Configurer la fenêtre de contexte d'une session
  • Activer la transcription pour une session
  • Chiffrer les données de session avec une clé de chiffrement gérée par le client (CMEK)

Durée de vie de la session

Sans compression de la fenêtre de contexte, les sessions audio uniquement sont limitées à 15 minutes et les sessions audio-vidéo à 2 minutes en raison des limites de jetons. Le dépassement de ces limites met fin à la session, mais vous pouvez utiliser la compression de la fenêtre de contexte pour prolonger les sessions pour une durée illimitée.

La durée de vie d'une connexion est limitée à environ 10 minutes en raison des contraintes de connexion WebSocket. Lorsque la connexion se termine, la session se termine également. Dans ce cas, vous pouvez configurer une seule session pour qu'elle reste active sur plusieurs connexions à l'aide de la reprise de session. Vous recevrez également un message GoAway avant la fin de la connexion, ce qui vous permettra de prendre d'autres mesures.

Nombre maximal de sessions simultanées

Vous pouvez avoir jusqu'à 1 000 sessions simultanées par projet avec un forfait de paiement à l'usage (PayGo). Cette limite ne s'applique pas aux clients utilisant le débit provisionné.

Démarrer une session

Les onglets suivants montrent comment démarrer une session de conversation en direct à l'aide de Vertex AI Studio, du SDK Google Gen AI ou de WebSockets :

Console

  1. Ouvrez Vertex AI Studio > Diffuser en temps réel.
  2. Cliquez sur Démarrer la session pour lancer la conversation.

Pour mettre fin à la session, cliquez sur Arrêter la session.

Python

Avant de commencer, vous devez vous authentifier auprès de Gemini Enterprise Agent Platform à l'aide d'une clé API ou des identifiants par défaut de l'application (ADC) :

gcloud auth application-default login
      

Pour en savoir plus sur la configuration de l'authentification, consultez notre guide de démarrage rapide.

import asyncio
from google import genai

# Replace the PROJECT_ID and LOCATION with your Project ID and location.
client = genai.Client(vertexai=True, project="PROJECT_ID", location="LOCATION")

# Configuration
MODEL = "gemini-3.8-live"
config = {
   "response_modalities": ["audio"],
}

async def main():
   # Establish WebSocket session
   async with client.aio.live.connect(model=MODEL, config=config) as session:
       print("Session established. Sending audio...")

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

Python

Lorsque vous utilisez WebSockets, la connexion est établie avec un handshake WebSocket standard. Le point de terminaison est régional et utilise des jetons de support OAuth 2.0 pour l'authentification. Dans ce scénario, le jeton d'authentification est généralement transmis dans les en-têtes WebSocket (comme Authorization: Bearer [TOKEN]).

import asyncio
import websockets

# Replace the PROJECT_ID and LOCATION with your Project ID and location.
PROJECT_ID = "PROJECT_ID"
LOCATION = "LOCATION"

# Authentication
token_list = !gcloud auth application-default print-access-token
ACCESS_TOKEN = token_list[0]

# Configuration
MODEL_ID = "gemini-3.8-live"
MODEL = f"projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/{MODEL_ID}"
config = {
   "response_modalities": ["audio"],
}

# Construct the WSS URL
HOST = f"{LOCATION}-aiplatform.googleapis.com"
URI = f"wss://{HOST}/ws/google.cloud.aiplatform.v1.LlmBidiService/BidiGenerateContent"

async def main():
   headers = {"Authorization": f"Bearer {ACCESS_TOKEN}"}

   async with websockets.connect(URI, additional_headers=headers) as ws:
       print("Session established.")

       # Send Setup (Handshake)
       await ws.send(json.dumps({
           "setup": {
               "model": MODEL,
               "generation_config": config
           }
       }))
    # Send audio/video ...

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

Prolonger une session

La durée maximale par défaut d'une session de conversation est de 10 minutes. Vous pouvez la prolonger à l'aide des notifications goAway. Une notification goAway (BidiGenerateContentServerMessage.goAway) est envoyée au client 60 secondes avant la fin de la session.

Pour prolonger une session au-delà de la limite de connexion de 10 minutes, vous devez vous reconnecter en utilisant la reprise de session. Lorsque vous recevez une notification goAway ou que la connexion est interrompue pour d'autres raisons, vous pouvez démarrer une nouvelle connexion à l'aide d'un handle de session obtenu pendant la session. Votre session reprend alors avec son contexte intact sur la nouvelle connexion. Vous pouvez effectuer cette opération autant de fois que vous le souhaitez. Pour obtenir un exemple de reprise de session, consultez Reprendre une session précédente.

L'exemple suivant montre comment détecter l'arrêt imminent d'une session en écoutant une notification goAway :

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)
      

Reprendre une session précédente

L'API Gemini Live prend en charge la reprise de session pour éviter que l'utilisateur ne perde le contexte de la conversation lors d'une brève déconnexion (par exemple, en passant du Wi-Fi à la 5G). Vous pouvez reprendre une session précédente dans un délai de 24 heures. La reprise de session est possible grâce au stockage des données mises en cache, y compris les prompts textuels, vidéo et audio, ainsi que les sorties du modèle. La confidentialité au niveau du projet est appliquée à ces données mises en cache.

La reprise de session est désactivée par défaut. Pour activer la reprise de session, définissez le champ sessionResumption du message BidiGenerateContentSetup. Si cette option est activée, le serveur envoie régulièrement des messages SessionResumptionUpdate contenant un session_id et un jeton de reprise. Si la connexion WebSocket est interrompue, le client peut se reconnecter et inclure ces identifiants dans le nouveau message de configuration. Le serveur restaure ensuite le contexte précédent, ce qui permet à la conversation de se poursuivre de manière fluide.

La fenêtre de reprise est limitée (généralement environ 10 minutes). Si le client ne se reconnecte pas dans ce délai, l'état de la session est supprimé pour libérer des ressources du serveur.

L'exemple suivant se connecte au service, obtient un handle de reprise de session, simule une déconnexion, puis se reconnecte à l'aide du handle pour reprendre la session :

Python

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

# Replace the PROJECT_ID and LOCATION with your Project ID and location.
client = genai.Client(vertexai=True, project="PROJECT_ID", location="LOCATION")

# Configuration
MODEL = "gemini-3.8-live"

async def resumable_session_example():
    """Demonstrates session resumption by connecting, disconnecting, and reconnecting."""
    session_handle = None

    print("Starting a new session...")
    try:
        async with client.aio.live.connect(
            model=MODEL,
            config=types.LiveConnectConfig(
                response_modalities=["audio"],
                session_resumption=types.SessionResumptionConfig(handle=None),
            ),
        ) as session:
            await session.send_content(
                content=types.Content(role="user", parts=[types.Part(text="Hello!")])
            )
            async for message in session.receive():
                if message.session_resumption_update:
                    update = message.session_resumption_update
                    if update.resumable and update.new_handle:
                        session_handle = update.new_handle
                        print(f"Received session handle: {session_handle}")
                        # For demonstration, we break to simulate a disconnect
                        # after receiving a handle.
                        break
                if message.server_content and message.server_content.turn_complete:
                    break
    except websockets.exceptions.WebSocketException as e:
        print(f"Initial connection failed: {e}")
        return

    if not session_handle:
        print("Did not receive a session handle. Cannot demonstrate resumption.")
        return

    print(f"\nSimulating disconnect and reconnecting with handle {session_handle}...")

    try:
        async with client.aio.live.connect(
            model=MODEL,
            config=types.LiveConnectConfig(
                response_modalities=["audio"],
                session_resumption=types.SessionResumptionConfig(handle=session_handle),
            ),
        ) as session:
            print("Successfully resumed session.")
            await session.send_content(
                content=types.Content(role="user", parts=[types.Part(text="I am back!")])
            )
            async for message in session.receive():
                if message.session_resumption_update:
                    update = message.session_resumption_update
                    if update.resumable and update.new_handle:
                        session_handle = update.new_handle
                        print(f"Received updated session handle: {session_handle}")
                if message.server_content:
                    print(f"Received server content: {message.server_content}")
                    if message.server_content.turn_complete:
                        break
            print("Resumed session finished.")
    except websockets.exceptions.WebSocketException as e:
        print(f"Failed to resume session: {e}")

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

Activer la reprise de session fluide avec le mode transparent

Lorsque vous activez la reprise de session, vous pouvez également activer le mode transparent pour faciliter le processus de reprise pour l'utilisateur. Lorsque le mode transparent est activé, l'index du message client correspondant à l'instantané de contexte est renvoyé explicitement. Cela permet d'identifier le message client que vous devez renvoyer lorsque vous reprenez la session à partir du handle de reprise.

Pour activer le mode transparent :

Python

config = {
   "response_modalities": ["audio"],
   "session_resumption_config": {
    "transparent": True,
   }
}
      

Chiffrer les données de session avec des clés CMEK

La reprise de session stocke les données de session mises en cache au repos pendant 24 heures au maximum. Pour protéger ces données avec votre propre clé au lieu d'uneGoogle Cloud-powered encryption key, utilisez un profil de diffusion. Un profil de diffusion associe une clé Cloud KMS à un projet, un emplacement et un champ d'application d'API. Lorsqu'un profil de diffusion existe, Agent Platform chiffre automatiquement les données. La configuration de votre session et le format de la requête ne changent pas.

Le profil de diffusion CMEK pour l'API Gemini Live est compatible avec les emplacements multirégionaux us et eu. La région globale n'est pas acceptée.

Pour configurer une CMEK pour l'API Gemini Live, procédez comme suit :

  1. Activez l'API Cloud KMS et l'API Agent Platform sur votre projet. Consultez la section Avant de commencer.
  2. Créez une clé Cloud KMS dans l'emplacement multirégional us ou eu. Consultez Créer un trousseau de clés et une clé.
  3. Attribuez à l'agent de service Gemini Enterprise Agent Platform le rôle roles/cloudkms.cryptoKeyEncrypterDecrypter sur la clé. Consultez Accorder des autorisations Agent Platform.
  4. Créez un profil de diffusion qui définit scope sur GEMINI_LIVE et cmekConfig.encryptionSpec.kmsKeyName sur votre clé. Consultez Créer un profil de diffusion.

Mettre à jour les instructions système pendant une session

L'API Gemini Live vous permet de mettre à jour les instructions système pendant une session active. Utilisez cette option pour adapter les réponses du modèle, par exemple en changeant la langue de réponse ou en modifiant le ton.

La méthode suivante s'applique à l'audio natif de l'API Gemini 2.5 Flash Live. Pour Gemini 3.8 Live, consultez Mettre à jour les instructions système et les outils avec Gemini 3.8 Live.

Pour mettre à jour les instructions système en cours de session, vous pouvez envoyer du contenu textuel avec le rôle system. L'instruction système mise à jour restera en vigueur pendant le reste de la session.

Python

session.send_client_content(
      content=types.Content(
          role="system", parts=[types.Part(text="new system instruction")]
      ),
      turn_complete=False
  )
      

Mettre à jour les instructions système et les outils avec Gemini 3.8 Live

Avec Gemini 3.8 Live, vous pouvez mettre à jour les instructions système et les outils d'une session active en envoyant un message BidiGenerateContentContextUpdate. Par exemple, vous pouvez modifier la langue ou le ton de la réponse, ou fournir au modèle un ensemble de fonctions différent lorsque la conversation passe à une nouvelle tâche. Avec le SDK Google Gen AI, appelez send_context_update. Avec WebSockets, définissez le champ context_update du message client. N'envoyez pas de contenu client avec le rôle system à Gemini 3.8 Live.

Définissez les champs que vous souhaitez modifier :

  • system_instruction : remplace l'instruction système du message de configuration pour le reste de la session.
  • tools : remplace la liste complète des outils de la session. Incluez tous les outils que le modèle doit encore pouvoir utiliser. Pour supprimer tous les outils, envoyez une liste vide.

Les champs que vous ne définissez pas conservent leurs valeurs actuelles. Les mises à jour sont traitées dans l'ordre avec le reste des entrées de la session.

Python

from google.genai import types

# Replace the system instruction.
await session.send_context_update(
    system_instruction="Respond only in Spanish."
)

# Replace the tool list.
get_current_weather = types.FunctionDeclaration(
    name="get_current_weather",
    description="Get the current weather in a given location",
    parameters=types.Schema(
        type=types.Type.OBJECT,
        properties={"location": types.Schema(type=types.Type.STRING)},
    ),
)
await session.send_context_update(
    tools=[types.Tool(function_declarations=[get_current_weather])]
)

# Remove all tools.
await session.send_context_update(tools=[])
      

Les outils côté serveur sont configurés au début de la session. Par conséquent, les limites suivantes s'appliquent lorsqu'une mise à jour d'outils les inclut. Les déclarations de fonction ne sont pas affectées et peuvent être ajoutées dans n'importe quelle mise à jour des outils.

  • Pour utiliser l'ancrage avec la recherche Google après une mise à jour des outils, déclarez également google_search dans le message de configuration.
  • Les outils d'ancrage sur le Web pour Enterprise, Agent Search et le moteur RAG ne peuvent être déclarés que dans le message de configuration. Un context_update qui les inclut renvoie une erreur INVALID_ARGUMENT.

Configurer la fenêtre de contexte de la session

La fenêtre de contexte de l'API Gemini Live permet de stocker les données diffusées en temps réel (25 jetons par seconde (TPS) pour l'audio et 258 TPS pour la vidéo) et d'autres contenus, y compris les entrées textuelles et les sorties du modèle. Tous les modèles de l'API Gemini Live ont une limite de fenêtre de contexte de 128 000 jetons.

Dans les sessions de longue durée, à mesure que la conversation progresse, l'historique des jetons audio et textuels s'accumule. Si cet historique dépasse la limite du modèle, celui-ci peut halluciner, ralentir ou la session peut être interrompue de force. Pour autoriser des sessions plus longues, vous pouvez activer la compression de la fenêtre de contexte en définissant le champ contextWindowCompression dans la configuration de la session.

La compression de la fenêtre de contexte utilise une fenêtre glissante côté serveur pour tronquer les tours les plus anciens lorsqu'elle est activée. Lorsque les jetons accumulés dépassent une longueur maximale définie (définie à l'aide du curseur Taille maximale du contenu dans Vertex AI Studio ou de trigger_tokens dans l'API), le serveur supprime automatiquement les tours les plus anciens ou les résume pour maintenir le contexte dans la limite. Dans ContextWindowCompressionConfig, vous pouvez configurer un mécanisme de fenêtre glissante et le nombre de jetons définis dans le paramètre target_tokens qui déclenche la compression.

Cela permet d'obtenir des durées de session théoriquement infinies du point de vue de l'utilisateur, car la "mémoire" est gérée en permanence. Sans compression, les sessions audio uniquement peuvent être limitées à environ 15 minutes avant d'atteindre les limites strictes.

Les longueurs minimale et maximale de la longueur de contexte et de la taille cible sont les suivantes :

Paramètre (option d'API) Valeur minimale Valeur maximale
Longueur maximale du contexte (trigger_tokens) 5 000 128 000
Taille du contexte cible (target_tokens) 0 128 000

Pour définir la fenêtre de contexte :

Console

  1. Ouvrez Vertex AI Studio > Diffuser en temps réel.
  2. Cliquez pour ouvrir le menu Avancé.
  3. Dans la section Contexte de la session, utilisez le curseur Taille maximale du contexte pour définir la taille du contexte sur une valeur comprise entre 5 000 et 128 000.
  4. (Facultatif) Dans la même section, utilisez le curseur Taille du contexte cible pour définir la taille cible sur une valeur comprise entre 0 et 128 000.

Python

Définissez les champs context_window_compression.trigger_tokens et context_window_compression.sliding_window.target_tokens dans le message de configuration :

config = {
   "response_modalities": ["audio"],
   # Configures compression
   "context_window_compression" : {
    "trigger_tokens": 10000,
    "sliding_window": {"target_tokens" : 512}
   }
}
      

Activer la transcription audio pour la session

Vous pouvez activer les transcriptions pour l'audio d'entrée et de sortie.

Pour recevoir des transcriptions, vous devez mettre à jour la configuration de votre session. Vous devez ajouter les objets input_audio_transcription et output_audio_transcription, et vous assurer que text est inclus dans response_modalities.

Pour améliorer la qualité de la transcription pour la reconnaissance vocale automatique (ASR) multilingue, vous pouvez fournir des indices de langue à l'aide du champ language_codes dans input_audio_transcription ou output_audio_transcription. Il est recommandé de fournir des indices pour améliorer la qualité de la transcription, car cela réduit le risque de détection incorrecte de la langue, en particulier pour les requêtes courtes. Le champ language_codes accepte une liste de codes de langue BCP-47 (par exemple, "en-US", "es-US").

config = {
    "response_modalities": ["audio", "text"],
    "input_audio_transcription": {
        "language_codes": ["en-US"]
    },
    "output_audio_transcription": {},
}

Traitement de la réponse…

L'exemple de code suivant montre comment se connecter à l'aide de la session configurée et extraire les parties de texte (transcriptions) ainsi que les données audio.

# Receive Output Loop
async for message in session.receive():
    server_content = message.server_content
    if server_content:
        # Handle Model Turns (Audio + Text)
        model_turn = server_content.model_turn
        if model_turn and model_turn.parts:
            for part in model_turn.parts:
                # Handle Text (Transcriptions)
                if part.text:
                    print(f"Transcription: {part.text}")
                # Handle Audio
                if part.inline_data:
                    audio_data = part.inline_data.data
                    # Process audio bytes...
                    pass

        # Check for turn completion
        if server_content.turn_complete:
            print("Turn complete.")

Étapes suivantes