Aller au contenu principal
Leçon 2 sur 18 · API Temps Réel et Agents Vocaux

Sessions, événements et lifecycle

Leçon 2 sur 18 Mis à jour le 3 novembre 2026 Développeur
Sur cette page
  1. Sessions, événements et lifecycle
  2. Le cycle de vie d’une session
  3. Configurer une session
  4. Le système d’événements
  5. Gestion des erreurs
  6. Points clés à retenir

Mise à jour du 2 novembre 2026 — modèles audio. Plusieurs modèles de ce cours sont dépréciés : tts-1, tts-1-hd et gpt-4o-mini-tts s’arrêtent le 6 janvier 2027 (remplaçant indiqué : gpt-realtime-2.1-mini, que le guide TTS d’OpenAI déclare non pris en charge par /v1/audio/speech : la migration de la synthèse vocale passe par l’API Realtime) ; gpt-realtime, gpt-4o-realtime et les anciens modèles audio le 20 janvier 2027 (gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-audio-1.5) ; whisper-1, gpt-4o-transcribe et /v1/audio/translations le 26 février 2027 (gpt-transcribe, gpt-live-transcribe, v1/realtime/translations). Pour la voix full-duplex, GPT-Live 1 est disponible dans l’API depuis le 10 septembre 2026.

Corrigé le 3 novembre 2026. La transcription de l’entrée utilisait gpt-live-transcribe, qui ne fonctionne que dans une session de transcription et ne prend en charge ni server_vad ni semantic_vad. Dans une session de conversation comme celle-ci, où le VAD valide chaque tour, la documentation désigne gpt-transcribe, qui transcrit les tours validés et se sert des tours précédents comme contexte. Sources : Realtime transcription · GPT-Transcribe · GPT-Live-Transcribe.

Sessions, événements et lifecycle

Chaque connexion WebSocket à la Realtime API crée une session. Cette session est l’unité fondamentale de gestion : elle encapsule la configuration du modèle, l’historique de conversation, les outils disponibles et l’état courant de l’interaction. Comprendre son cycle de vie est essentiel pour construire des agents vocaux robustes.

Le cycle de vie d’une session

Dès que la connexion WebSocket est établie, le serveur émet un événement session.created. La session passe par plusieurs phases :

1

Connexion → session.created

Le serveur confirme la session avec un ID unique et la configuration par défaut.

2

Configuration → session.update

Vous envoyez session.update pour définir les instructions, la voix, les outils et les modalités.

3

Conversation active

Échange d'événements audio et texte entre client et serveur.

4

Fermeture → déconnexion WebSocket

La session est détruite à la fermeture de la connexion. Aucun état n'est conservé côté serveur.

Configurer une session

Après session.created, envoyez un événement session.update pour configurer le comportement du modèle. La transcription de ce que dit l’utilisateur (audio.input.transcription) est facultative : sans elle, vous recevez la voix mais pas son texte. languages indique les langues attendues et améliore la reconnaissance :

import asyncio
import websockets
import json

async def configure_session():
    headers = {
        "Authorization": f"Bearer {OPENAI_API_KEY}"
    }

    async with websockets.connect(URL, additional_headers=headers) as ws:
        # Attendre session.created
        event = json.loads(await ws.recv())
        session_id = event["session"]["id"]
        print(f"Session créée : {session_id}")

        # Configurer la session
        await ws.send(json.dumps({
            "type": "session.update",
            "session": {
                "type": "realtime",
                "output_modalities": ["audio"],
                "instructions": "Vous êtes un assistant vocal francophone. "
                                "Répondez de manière concise et naturelle.",
                "audio": {
                    "input": {
                        "format": {"type": "audio/pcm", "rate": 24000},
                        "transcription": {"model": "gpt-transcribe", "languages": ["fr"]},
                        "turn_detection": {
                            "type": "server_vad",
                            "threshold": 0.5,
                            "prefix_padding_ms": 300,
                            "silence_duration_ms": 500
                        }
                    },
                    "output": {
                        "format": {"type": "audio/pcm", "rate": 24000},
                        "voice": "marin"
                    }
                },
                "tools": []
            }
        }))

        # Attendre la confirmation (d'autres événements peuvent arriver avant)
        while True:
            event = json.loads(await ws.recv())
            if event["type"] == "session.updated":
                print("Session mise à jour")
                break
            if event["type"] == "error":
                raise RuntimeError(event["error"]["message"])

Paramètres clés de la session

Paramètre Description Valeur recommandée
output_modalities Modalités de sortie ["audio"] (ou ["text"])
audio.output.voice Voix de synthèse marin, cedar, alloy, echo, etc.
audio.input.turn_detection Détection de fin de parole server_vad avec seuil 0.5
audio.input.format Format audio entrant {"type": "audio/pcm", "rate": 24000}

Le système d’événements

La Realtime API est entièrement événementielle. Chaque message échangé est un objet JSON avec un champ type qui détermine sa nature. Les événements se répartissent en deux catégories :

Événements client (vous → serveur)

# Les principaux événements que vous envoyez
client_events = {
    "session.update":              "Modifier la configuration",
    "input_audio_buffer.append":   "Envoyer un chunk audio",
    "input_audio_buffer.commit":   "Valider le buffer audio",
    "input_audio_buffer.clear":    "Vider le buffer audio",
    "conversation.item.create":    "Ajouter un message manuellement",
    "conversation.item.truncate":  "Tronquer une réponse",
    "conversation.item.delete":    "Supprimer un message",
    "response.create":             "Déclencher une réponse",
    "response.cancel":             "Annuler la réponse en cours",
}

Événements serveur (serveur → vous)

# Les principaux événements que vous recevez
server_events = {
    "session.created":             "Session initialisée",
    "session.updated":             "Configuration appliquée",
    "input_audio_buffer.speech_started":  "Parole détectée",
    "input_audio_buffer.speech_stopped":  "Silence détecté",
    "conversation.item.created":   "Nouveau message dans l'historique",
    "response.created":            "Début de génération",
    "response.output_audio.delta":        "Chunk audio de réponse",
    "response.output_audio_transcript.delta": "Chunk de transcription",
    "response.done":               "Réponse terminée",
    "error":                       "Erreur",
}

Gestion des erreurs

Les erreurs sont émises via un événement de type error. Vous devez toujours les intercepter :

async def handle_events(ws):
    async for raw_message in ws:
        event = json.loads(raw_message)
        event_type = event["type"]

        if event_type == "error":
            error = event["error"]
            print(f"Erreur [{error['type']}]: {error['message']}")

            if error["type"] == "invalid_request_error":
                # Erreur de configuration, corriger et réessayer
                pass
            elif error["type"] == "server_error":
                # Problème côté OpenAI, reconnecter
                pass

        elif event_type == "session.updated":
            print("Configuration appliquée avec succès")

        elif event_type == "response.done":
            usage = event["response"].get("usage", {})
            print(f"Tokens utilisés : {usage}")

Points clés à retenir

  • Une session est créée automatiquement à la connexion WebSocket et détruite à la déconnexion
  • session.update configure la session après session.created ; attendez session.updated avant de compter sur la nouvelle configuration
  • Pour transcrire l’entrée dans une session de conversation, utilisez gpt-transcribe ; gpt-live-transcribe est réservé aux sessions de transcription
  • Le protocole est purement événementiel : chaque message a un type qui détermine son traitement
  • Les événements client pilotent l’interaction, les événements serveur rapportent les résultats
  • La gestion d’erreurs est critique : toujours écouter les événements error