Sessions, événements et lifecycle
Sur cette page
Mise à jour du 2 novembre 2026 — modèles audio. Plusieurs modèles de ce cours sont dépréciés :
tts-1,tts-1-hdetgpt-4o-mini-ttss’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-realtimeet 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-transcribeet/v1/audio/translationsle 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 niserver_vadnisemantic_vad. Dans une session de conversation comme celle-ci, où le VAD valide chaque tour, la documentation désignegpt-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 :
Connexion → session.created
Le serveur confirme la session avec un ID unique et la configuration par défaut.
Configuration → session.update
Vous envoyez session.update pour définir les instructions, la voix, les outils et les modalités.
Conversation active
Échange d'événements audio et texte entre client et serveur.
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.updateconfigure la session aprèssession.created; attendezsession.updatedavant de compter sur la nouvelle configuration- Pour transcrire l’entrée dans une session de conversation, utilisez
gpt-transcribe;gpt-live-transcribeest réservé aux sessions de transcription - Le protocole est purement événementiel : chaque message a un
typequi 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