Une fois la connexion à GPT-Live établie, utilisez les événements de session pour ajouter du contexte, afficher les transcriptions et gérer la connexion. GPT-Live peut écouter et parler en même temps. Suivez séparément la transcription, l’audio effectivement lu et l’avancement des tâches côté serveur. Votre interface peut ainsi afficher ce que dit l’assistant et indiquer quelles tâches sont encore en cours.
Ce guide suppose que votre connexion a déjà émis session.started. Consultez Connexions pour établir la connexion et transmettre l’audio en continu, et Délégation et outils pour exécuter des tâches côté serveur.
Configurer une session
Choisissez le modèle, la voix et le mode de délégation à la création de la session. Donnez au modèle des instructions pour la conversation et joignez l’historique pertinent. GPT-Live gère automatiquement le contexte à mesure que la conversation avance.
Champs de configuration
| Paramètre | Configuration au démarrage | Modification en cours de session |
|---|---|---|
| Modèle | Renseignez le champ obligatoire model. |
Démarrez une nouvelle session pour changer de modèle. |
| Instructions | Renseignez instructions pour définir le comportement du modèle pendant la conversation, dans la limite de 16 384 tokens. |
Ajoutez des instructions avec session.instructions.append. |
| Historique | Renseignez input avec les messages texte antérieurs pertinents. Sa valeur par défaut est []. |
Ajoutez du contexte avec les événements d’ajout. |
| Voix | Renseignez audio.output.voice avec une voix prise en charge ou une voix personnalisée autorisée. La voix par défaut est marin. |
Démarrez une nouvelle session pour changer de voix. |
| Délégation | Réglez delegation.type sur client ou responses. Si vous omettez la délégation ou lui donnez la valeur null, la session utilise le mode client. |
Modifiez les paramètres de Responses dans le mode existant. |
| Stockage | Réglez store sur true pour pouvoir forker la session. Sa valeur par défaut est false. |
Faites ce choix au démarrage. |
Voix disponibles
Choisissez une voix à la création de la session. Renseignez audio.output.voice avec son nom dans l’API, par exemple "quartz". GPT-Live propose les voix supplémentaires suivantes :
| Voix | Nom dans l’API | Langue | Influence régionale | Timbre | Origine |
|---|---|---|---|---|---|
| Quartz | quartz |
Anglais | Australie | Féminin | Générée |
| Ripple | ripple |
Anglais | Australie | Masculin | Naturelle |
| Vesper | vesper |
Anglais | Royaume-Uni | Masculin | Naturelle |
| Willow | willow |
Anglais | Irlande | Féminin | Naturelle |
| Stone | stone |
Anglais | Irlande | Masculin | Naturelle |
| Gleam | gleam |
Anglais | Amérique du Nord | Féminin | Naturelle |
| Meridian | meridian |
Anglais | Amérique du Nord | Masculin | Naturelle |
| Bossa | bossa |
Portugais | Brésil | Féminin | Naturelle |
| Tempo | tempo |
Portugais | Brésil | Masculin | Naturelle |
| Beacon | beacon |
Anglais | Philippines | Masculin | Générée |
| Delta | delta |
Anglais | Sud des États-Unis | Féminin | Générée |
| Cinder | cinder |
Anglais | Sud des États-Unis | Masculin | Générée |
| Nuri | nuri |
Allemand | — | Féminin | Naturelle |
| Juni | juni |
Allemand | — | Féminin | Naturelle |
| Flitz | flitz |
Allemand | — | Masculin | Naturelle |
| Brise | brise |
Français | — | Féminin | Naturelle |
| Sillage | sillage |
Français | — | Masculin | Naturelle |
| Nira | nira |
Hindi | — | Féminin | Naturelle |
| Harema | harema |
Japonais | — | Féminin | Naturelle |
| Shida | shida |
Japonais | — | Masculin | Naturelle |
| Noeul | noeul |
Coréen | — | Féminin | Naturelle |
L’influence régionale décrit la manière de parler associée à une voix. Testez la voix dans les langues utilisées par votre application et vérifiez la prononciation attendue. Pour créer une voix à partir d’une description textuelle ou d’un enregistrement approuvé, consultez Voix personnalisées.
Avec WebSocket, choisissez audio.format au démarrage. Ce format s’applique à l’audio en entrée et en sortie pendant toute la session. Pour utiliser un autre format, démarrez une nouvelle session. WebRTC négocie le format audio lors de l’établissement de la connexion. Omettez donc audio.format dans les requêtes WebRTC. Consultez Formats audio WebSocket pour connaître les formats pris en charge et les modalités de transmission en continu.
Mettre à jour une session en cours
Utilisez session.update pour modifier session.delegation.responses dans une session qui utilise déjà la délégation à Responses. Envoyez uniquement les paramètres à modifier. Les paramètres omis conservent leur valeur. Consultez Configurer la délégation à Responses pour connaître les paramètres et la procédure de mise à jour.
Choisissez le mode de délégation et renseignez les champs model, instructions, input, audio et store au démarrage. Utilisez session.update uniquement pour les paramètres de Responses pris en charge décrits ci-dessus. La session rejette les autres champs de configuration. Pour changer de mode de délégation, créez une nouvelle session. Au démarrage, delegation: null sélectionne la délégation au client et ne rétablit pas les paramètres par défaut de Responses.
Si la mise à jour réussit, la session émet session.updated avec la configuration obtenue. Associez cet événement à l’event_id que vous avez envoyé grâce à client_event_id. Traitez les commandes rejetées dans la même boucle d’événements. Suivez les tâches côté serveur et la parole de l’assistant à l’aide de leurs événements respectifs.
Fournir un historique et du contexte
Utilisez l’historique au démarrage pour reprendre un sujet, puis ajoutez du contexte pertinent au fil de la conversation. Séparez les instructions de confiance de l’application des messages utilisateur et des résultats factuels.
Initialiser une session avec une conversation antérieure
Incluez les messages texte antérieurs dans session.input à la création de la session. Par exemple, ajoutez ce champ input à votre configuration de création de session :
export const session = {
model: "gpt-live-1",
input: [
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "I need help with my recent order.",
},
],
},
{
type: "message",
role: "assistant",
content: [
{
type: "output_text",
text: "What is the order number?",
},
],
},
],
};La liste accepte jusqu’à 128 messages, dans la limite de 8 192 tokens au total. Chaque message contient une seule partie textuelle et porte l’un des rôles suivants : developer, user ou assistant. Les messages du développeur et de l’utilisateur utilisent input_text. Ceux de l’assistant utilisent text ou output_text. Placez les instructions de confiance de l’application dans instructions ou dans un message du développeur.
Sélectionnez les messages texte nécessaires à la prochaine interaction et fournissez-les au démarrage. En cours de session, transmettez les mises à jour à l’aide des événements de contexte ci-dessous. Pour les éléments propres au backend, comme les résultats des outils, suivez le workflow de délégation.
Savoir quand le contexte parvient au modèle
Placez dans input tout le contexte dont le modèle a besoin dès le départ. Le contenu intégral du champ est disponible au démarrage de la session.
En cours de session, session.instructions.append, session.thinking.append et session.commentary.append ajoutent progressivement du contexte. L’accusé de réception arrive lorsque la session atteint la fin estimée du contexte ajouté. Ses champs start_ms et end_ms indiquent où se situe approximativement cette mise à jour dans la chronologie de la session.
Ces repères temporels concernent la transmission du contexte. Ils ne renseignent ni sur la prise de parole ni sur la lecture audio. Le modèle peut répondre avant d’avoir utilisé toute la mise à jour. Lorsqu’une action dépend d’une nouvelle instruction ou d’un nouveau fait, vérifiez dans votre application que le comportement obtenu correspond à vos attentes.
Si la session cesse d’avancer dans sa chronologie, l’accusé de réception peut rester en attente. Associez chaque accusé de réception à l’event_id envoyé grâce à client_event_id et continuez de traiter les erreurs pendant l’attente. Si vous fermez la session, les ajouts encore en attente renvoient des erreurs.
Ajouter du contexte pendant la conversation
Choisissez l’événement en fonction de l’usage que le modèle doit faire de la mise à jour :
session.instructions.append: ajoutez des instructions de confiance de l’application pour orienter le comportement et les propos du modèle.session.thinking.append: ajoutez des éléments factuels sans demander au modèle de les énoncer immédiatement.session.commentary.append: fournissez des informations que le modèle doit énoncer à voix haute et qu’il peut reformuler.
Chaque événement accepte un champ content contenant une simple chaîne de 500 tokens maximum et exige un champ delegation_id. Utilisez null pour le contexte qui s’applique à toute la session. Par exemple, envoyez l’événement suivant une fois que votre application a vérifié l’accord de l’utilisateur et lancé la recherche :
export function sendUpdate(connection) {
connection.send({
type: "session.thinking.append",
event_id: "context_1",
delegation_id: null,
content:
"The user has already accepted the terms. The account lookup is still running.",
});
}Pour suivre cette mise à jour, traitez session.thinking.appended portant client_event_id: "context_1", ou l’erreur correspondante. Pour savoir quand attendre l’accusé de réception, consultez Savoir quand le contexte parvient au modèle.
L’assistant peut répéter les informations transmises par chacun de ces événements. Envoyez uniquement des informations adaptées à la conversation et conservez les identifiants d’accès et les secrets côté serveur. Utilisez session.instructions.append pour définir le comportement attendu par votre application. Fournissez les résultats factuels des outils comme éléments de contexte. Faites respecter les autorisations et exigez les confirmations nécessaires dans le code de l’application.
Pour la navigation entre les pages, les sélections et les autres changements dans l’interface, consultez Partager le contexte de l’interface. Vous y trouverez comment transmettre des mises à jour concises qui aident GPT-Live à comprendre à quoi l’utilisateur fait référence.
Pour transmettre une mise à jour sur une tâche précise du backend, utilisez l’identifiant de la délégation au client correspondante. L’identifiant de délégation identifie la tâche Live. Les identifiants de réponse de Responses et les identifiants d’appel d’outil correspondent à d’autres objets. Pour connaître la procédure, consultez Envoyer le bon type de mise à jour.
Si votre application détecte un problème, envoyez une brève correction sur la connexion WebSocket principale de la session ou sur une connexion WebSocket auxiliaire. Consultez Appliquer des garde-fous à la conversation pour mettre en place des vérifications, contrôler les actions et gérer la lecture audio.
Gérer la parole et les transcriptions
Fragments de transcription
Écoutez session.input_transcript.delta pour les propos de l’utilisateur et session.output_transcript.delta pour ceux de l’assistant. Chaque événement contient un fragment de texte et l’intervalle qu’il occupe dans la chronologie de la session :
{
"type": "session.input_transcript.delta",
"event_id": "event_transcript_1",
"delta": "What is",
"start_ms": 1000,
"end_ms": 1200
}
Pour chaque interlocuteur, ajoutez les fragments delta exactement tels que vous les recevez, en conservant les espaces et les mots répétés. Conservez aussi leurs champs start_ms et end_ms. Ces valeurs sont exprimées en millisecondes depuis le début de la session. L’exemple ci-dessus couvre l’intervalle allant de 1 000 ms inclus à 1 200 ms exclus. Ces valeurs situent approximativement le fragment sans délimiter précisément chaque mot. Utilisez-les pour organiser la transcription plutôt que de vous fier à l’heure d’arrivée des paquets.
Les événements de transcription correspondent aux intervalles qui contiennent du texte et peuvent arriver à un rythme irrégulier. Un fragment peut ne contenir qu’une partie d’une phrase. Un délai entre deux fragments peut être dû au réseau. Les fragments de transcription n’ont pas d’identifiant d’élément et aucun événement ne signale la fin d’un tour de parole. C’est donc votre application qui décide comment les regrouper à l’écran.
Le traitement des fragments de transcription est facultatif. Vous pouvez vous en servir pour actualiser l’interface, effectuer des vérifications ou lancer une tâche sans attendre la fin de la conversation. Pour des vérifications légères, envisagez un petit modèle comme gpt-5.6-luna avec un faible effort de raisonnement. Consultez Réagir aux fragments de transcription pour obtenir des exemples et des indications sur la connexion.
Utilisez des garde-fous fondés sur la transcription pour surveiller la conversation et déclencher des interventions pendant que les interlocuteurs parlent. Si votre application doit vérifier les propos de l’assistant avant leur lecture, consultez Vérifier les propos avant la lecture audio pour gérer la mise en mémoire tampon, l’approbation, l’interruption et la reprise.
Distinguez les repères temporels de la transcription de la lecture audio. Avec WebSocket, les événements session.output_audio.delta ne contiennent aucun champ temporel et aucun événement ne signale la fin de l’audio de sortie. WebRTC transmet l’audio sur sa piste multimédia. Consultez Connexions pour la gestion de l’audio.
Afficher des sous-titres
GPT-Live fonctionne en duplex intégral : l’appelant et l’assistant peuvent parler en même temps. Actualisez leurs sous-titres indépendamment pour que le texte de chacun puisse continuer à s’afficher lorsqu’ils parlent simultanément.
Si votre application utilise des bulles de conversation, les fragments « Je voudrais » et « modifier ma réservation » peuvent apparaître dans une même bulle de l’appelant. Si l’assistant répond « Bien sûr » alors que l’appelant continue de parler, affichez cette réponse dans une bulle distincte et continuez à compléter celle de l’appelant. Conservez les fragments d’origine et leurs horodatages pour pouvoir ajouter le texte reçu plus tard à la bonne bulle.
Utilisez session.output_transcript.delta pour sous-titrer les propos de l’assistant et affichez séparément les mises à jour du backend. Gérez l’exécution des outils et l’annulation des tâches dans la logique de gestion des tâches de votre application, indépendamment du regroupement du texte à l’écran.
Contrôler l’entrée du microphone
Envoyez session.input_audio.mute pour couper l’entrée audio sans mettre fin à la session :
export function sendUpdate(connection) {
connection.send({
type: "session.input_audio.mute",
event_id: "mute_1",
});
}Attendez session.input_audio.muted avec client_event_id: "mute_1" avant de considérer la commande comme acceptée. Pour réactiver l’entrée audio, envoyez session.input_audio.unmute et attendez session.input_audio.unmuted. Traitez les erreurs pour chacune de ces commandes.
Lorsque vous coupez l’entrée audio, la session reste active : le modèle peut continuer de parler et les tâches déléguées peuvent se poursuivre. Si vous devez aussi arrêter l’enregistrement ou la lecture en local, utilisez les commandes de capture du microphone et du lecteur audio de votre application.
Saluer l’appelant avant qu’il ne parle
Pour que GPT-Live engage la conversation dans les meilleures conditions, incluez des instructions de salutation dans un message developer de session.input à la création de la session. Avec WebSocket, incluez ce message dans l’événement session.start. Les instructions de salutation sont ainsi disponibles dès le départ.
Précisez la langue et le contenu de la salutation. Indiquez à l’assistant qu’il doit commencer immédiatement, puis s’arrêter pour écouter. Utilisez la langue de salutation choisie par l’application jusqu’à ce que l’appelant prenne la parole. Par exemple, utilisez ce texte dans le message du développeur :
Saluez maintenant l’appelant en anglais. Présentez-vous comme l’assistant du service d’assistance et demandez-lui comment vous pouvez l’aider. Puis arrêtez-vous pour l’écouter.
- Ajoutez le message à
session.inputavecrole: "developer"et une seule partie de contenu de typeinput_text. Pour connaître le format du message, consultez Initialiser une session avec une conversation antérieure. - Attendez
session.started, puis envoyez une seule fois les mêmes instructions de salutation avecsession.commentary.append, en utilisant unevent_idunique etdelegation_id: null, comme ci-dessous. Maintenez le flux audio d’entrée, y compris pendant le silence qui précède la prise de parole de l’appelant. Avec WebSocket, continuez d’envoyersession.input_audio.append. Avec WebRTC, gardez la piste audio d’entrée active. - Vérifiez dans l’audio de sortie et la transcription que l’assistant a salué l’appelant. Les instructions de démarrage peuvent faciliter la salutation, sans garantir que le modèle prendra la parole.
{
"type": "session.commentary.append",
"event_id": "greeting_1",
"delegation_id": null,
"content": "Greet the caller now in English. Introduce yourself as the support assistant and ask how you can help. Then pause and listen."
}
L’événement session.commentary.appended accuse réception de la demande. Il ne confirme ni que l’assistant a prononcé la salutation ni que l’application l’a diffusée. GPT-Live peut reformuler la salutation, ajouter des mots ou garder le silence.
Si vous avez besoin d’une diffusion prévisible, d’une formulation exacte ou de savoir précisément quand la lecture se termine, diffusez un enregistrement vérifié ou un extrait audio prégénéré dans votre application et contrôlez la lecture de l’audio de GPT-Live pendant sa diffusion. Testez les salutations dans les langues prises en charge, y compris lorsque l’appelant commence à parler pendant la salutation. Pour concevoir vos prompts, consultez Rédiger des prompts pour les modèles vocaux.
Énoncer une mention d’information
Utilisez session.instructions.append pour demander à l’assistant de prononcer une mention d’information dans des termes précis. Avec session.commentary.append, il peut reformuler le texte. Après session.started, envoyez par exemple :
export function sendUpdate(connection) {
connection.send({
type: "session.instructions.append",
event_id: "disclosure_1",
delegation_id: null,
content:
"Immediately say the following disclosure exactly and in full before responding to the caller: This call may be recorded for quality and training purposes.",
});
}Maintenez le flux audio d’entrée comme indiqué dans Saluer l’appelant avant qu’il ne parle. Une instruction envoyée pendant la conversation peut interrompre la prise de parole en cours.
Vérifiez la mention générée et sa lecture avant de la marquer comme diffusée. L’accusé de réception indique que l’instruction a été acceptée. Vérifiez les termes employés dans l’audio lui-même. Pour garantir une formulation exacte et savoir précisément quand la lecture se termine, diffusez un enregistrement vérifié ou un extrait audio prégénéré dans votre application et contrôlez la sortie de GPT-Live pendant sa diffusion. Consultez Contrôler la lecture si nécessaire.
Gérer les conversations longues
GPT-Live gère automatiquement les conversations longues et conserve les instructions fournies au démarrage.
La fenêtre de contexte par défaut contient jusqu’à 128 000 tokens. Elle comprend vos instructions, le texte de la conversation et les tokens audio qui n’apparaissent pas dans la transcription.
GPT-Live résume les échanges anciens en arrière-plan. Lorsque l’utilisation de la fenêtre de contexte dépasse 90 %, il démarre un moteur vocal de remplacement dans la même session. Ce moteur reçoit vos instructions initiales et jusqu’à 8 192 tokens d’historique, qui comprennent les messages récents et, le cas échéant, un résumé des messages plus anciens. La préparation d’un résumé ne modifie pas immédiatement le contexte du moteur en cours d’exécution.
Certains détails des échanges anciens peuvent être résumés ou omis. Conservez dans votre application les faits importants, les actions confirmées et l’état actuel des tâches, puis fournissez le contexte pertinent au besoin.
Stocker et forker une session
Un fork démarre une nouvelle session à partir d’une conversation vocale enregistrée. Utilisez-le pour effectuer plusieurs essais d’évaluation à partir de la même conversation de référence ou pour permettre à un utilisateur de reprendre une conversation après la fin de sa session. Chaque fork dispose d’une nouvelle connexion et d’un nouvel identifiant de session. Il prend pour point de départ la conversation source et sa configuration enregistrée.
Évaluer un agent à partir d’une conversation de référence
Supposons que vous souhaitiez tester la réaction de votre agent lorsqu’un appelant veut modifier une commande. Enregistrez une seule fois le début de la conversation, jusqu’au moment où l’appelant a identifié la commande. Terminez et finalisez la session avant qu’il en demande la modification. Pour chaque évaluation, vous pouvez ensuite forker la même session de référence et transmettre le même extrait audio de l’appelant : « Actually, can you send it to my office instead? »
Pour chaque essai, rétablissez la même commande de test et le même état de l’application, fournissez l’intervention suivante de l’appelant, puis évaluez la nouvelle réponse et les actions effectuées à l’aide des outils. Vous pouvez répéter le scénario ou comparer les paramètres pris en charge par le backend Responses. Mesurez séparément le temps de démarrage du fork et le temps de réponse. Consultez le guide d’évaluation de GPT-Live pour choisir des scénarios et mesurer les résultats.
Les forks héritent du modèle GPT-Live, de la voix et des instructions initiales. Pour comparer un autre modèle vocal ou un autre prompt de démarrage, créez de nouvelles sessions avec la configuration voulue. L’API de fork utilise l’enregistrement finalisé de la session source. Terminez donc la session de référence au point où vous souhaitez commencer l’évaluation.
Reprendre la conversation après la fin d’une session
Un appelant peut, par exemple, raccrocher et rappeler plus tard ou se reconnecter après une coupure. Si l’enregistrement de la session précédente a été finalisé et stocké, votre application peut forker cette session sur une nouvelle connexion et reprendre la conversation enregistrée.
Enregistrez l’état des tâches de l’application avec l’identifiant de la session source. Avant de poursuivre, vérifiez l’état des tâches encore en cours côté serveur et communiquez les résultats disponibles à la nouvelle session. Par exemple, si une demande de modification de commande a déjà été envoyée, confirmez son résultat avant de tenter une autre modification. Utilisez le nouvel identifiant de session pour les commandes et les connexions auxiliaires, puis acheminez les résultats ultérieurs du backend vers la nouvelle session.
Préparer une session pour pouvoir la forker
- Activez le stockage à la création de la session source. Définissez
store: truedans sa configuration. Le stockage est réglé par défaut surfalse. Il doit être activé pour votre projet et votre politique de gestion des données doit permettre leur conservation. - Enregistrez l’identifiant de la session source. Récupérez-le dans
session.startedou dans la réponse à la requête de création WebRTC, puis associez-le à la conversation enregistrée dans votre application. - Terminez et fermez la session source. Achevez les tâches nécessaires côté serveur, puis suivez les étapes de la section Suivi de l’utilisation et fermeture propre. Maintenez la connexion ouverte jusqu’à
session.closedet traitez toute erreur de finalisation. Pour forker la session, il faut un enregistrement finalisé et stocké. Sa sauvegarde peut prolonger la finalisation. - Démarrez un fork sur une nouvelle connexion. Utilisez l’identifiant source avec la procédure de transport ci-dessous, enregistrez le nouvel identifiant de session et attendez la fin du démarrage avant de poursuivre la conversation. Définissez explicitement
storepour la session enfant : utiliseztruesi vous souhaitez pouvoir forker la suite de la conversation, oufalsesi vous n’avez pas besoin de stocker cet essai. Si vous omettez ce champ, la session enfant hérite du paramètre de la source.
Les enregistrements stockés sont disponibles pendant 30 jours. Avec la politique de non-conservation des données (ZDR), store est traité comme false et il est impossible de forker une session. Pour effectuer des évaluations à partir de forks, utilisez une organisation sans ZDR et activez le stockage pour le projet.
Si vous ne disposez d’aucun enregistrement finalisé et stocké, démarrez une nouvelle session avec les messages pertinents de l’historique sauvegardé. Consultez Contrôles des données de GPT-Live pour connaître les conditions de stockage.
Par exemple, définissez ce champ dans la configuration WebSocket session.start de la session source ou dans la requête de création WebRTC :
{
"store": true
}
Démarrez le fork avec le transport utilisé par votre application :
| Transport | Démarrage du fork |
|---|---|
| WebSocket | Connectez-vous à wss://api.openai.com/v1/live/sessions/{source_session_id}/fork. |
| WebRTC | Envoyez une nouvelle offre SDP à POST /v1/live/sessions/{source_session_id}/fork. Appliquez la réponse transport.sdp reçue à la nouvelle connexion entre pairs. |
Un fork hérite du modèle, des instructions initiales et des données d’entrée de la session source. Au démarrage, transmettez uniquement les paramètres que vous pouvez redéfinir :
- WebSocket :
store, les paramètres de délégation à Responses et le champaudio.formatde la nouvelle connexion. Envoyez un événementsession.startavec un objetsession. Utilisez{}pour conserver les paramètres hérités lorsque cette option est prise en charge. - WebRTC :
store, les paramètres de délégation à Responses et les autorisations du client frontend.
Pour un fork WebSocket, définissez audio.format pour la nouvelle connexion ou utilisez le format par défaut, PCM16 à 24 kHz. Le fork n’hérite ni du format audio source ni des autorisations du frontend sur le canal de données. WebRTC négocie le format audio lors de l’établissement de la connexion. Omettez audio.format. WebRTC conserve les autorisations du frontend, sauf si vous les redéfinissez.
Avec WebSocket, attendez session.started avant d’envoyer d’autres commandes. Avec WebRTC, la requête HTTP démarre la session. Poursuivez sur la connexion négociée sans envoyer de nouvel événement session.start.
Démarrer un fork WebSocket
Définissez OPENAI_API_KEY. Les exemples utilisent l’identifiant de la session source stockée que votre application a sauvegardé. Ils confirment le démarrage, puis ferment le fork. Pour poursuivre la conversation, envoyez et recevez l’audio après session.started en suivant la procédure de connexion WebSocket. Consultez la référence du fork WebSocket pour connaître les champs et les événements de démarrage.
import OpenAI from "openai";
import { ForksWS } from "openai/resources/live/forks/ws";
async function forkSession(sourceSessionId) {
const ws = new ForksWS(new OpenAI(), { session_id: sourceSessionId });
let finalized = false;
let closeRequested = false;
try {
for await (const event of ws) {
if (event.type === "open") {
ws.send({ type: "session.start", session: {} });
} else if (event.type === "error") {
throw event.error;
} else if (event.type === "message") {
if (event.message.type === "session.started") {
console.log("Fork ready:", event.message.session.id);
// This startup example closes the fork after confirming it is ready.
ws.send({ type: "session.close" });
closeRequested = true;
} else if (event.message.type === "session.closed") {
console.log("Final usage:", event.message.usage);
if (!closeRequested) {
throw new Error("Fork ended before startup completed");
}
finalized = true;
break;
}
}
}
if (!finalized) throw new Error("Connection closed before session.closed");
} finally {
ws.close();
}
}Démarrer un fork WebRTC
Créez une nouvelle offre SDP dans votre frontend et envoyez-la à votre backend. Les exemples de code backend suivants utilisent cette offre et l’identifiant de la session source stockée que votre application a sauvegardé :
import OpenAI from "openai";
async function forkSession(sourceSessionId, offerSdp) {
const client = new OpenAI();
const fork = await client.live.sessions.fork(sourceSessionId, {
transport: { type: "webrtc", sdp: offerSdp },
});
console.log(JSON.stringify(fork));
}Renvoyez la réponse à votre frontend, appliquez transport.sdp comme réponse à l’offre de la nouvelle connexion entre pairs et conservez le nouvel identifiant session.id. Gardez la clé API côté serveur.
Utilisez le nouvel identifiant de session pour les connexions auxiliaires et les commandes de session. Avant de relancer une action inachevée, vérifiez son résultat côté serveur et rétablissez l’état actuel des tâches de l’application. Si vous ne disposez d’aucun enregistrement finalisé et stocké, initialisez une nouvelle session avec l’historique sauvegardé.
Télécharger un enregistrement
Une fois l’enregistrement stocké et finalisé, téléchargez son contenu audio avec GET /v1/live/sessions/{session_id}/content. La réponse contient des données binaires au format WAV stéréo, avec l’audio d’entrée sur le canal gauche et l’audio de sortie sur le canal droit. Les exemples utilisent l’identifiant de session sauvegardé par votre application et écrivent la réponse au fil de sa réception dans recording.wav :
import OpenAI from "openai";
import { createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";
async function downloadRecording(sessionId) {
const client = new OpenAI();
const response = await client.live.sessions.downloadRecording(sessionId);
if (!response.body) throw new Error("Recording response has no body");
await pipeline(response.body, createWriteStream("recording.wav"));
}Fermer les sessions inactives et reprendre la conversation
Pour les applications où de longs intervalles séparent les interactions, fermez la session vocale pendant les périodes d’inactivité et démarrez une nouvelle session au retour de l’utilisateur. Conservez le contexte de la conversation et l’état des tâches de l’application afin que l’utilisateur puisse poursuivre sans avoir à se répéter. Par exemple, un assistant embarqué peut reprendre la conversation lorsque le conducteur réactive la commande vocale, tandis qu’un assistant de programmation peut laisser son processus de traitement s’exécuter côté serveur entre deux conversations vocales.
- Déterminez quand fermer la session. Faites gérer le délai d’inactivité par l’application en tenant compte de l’activité audio, de la lecture des réponses de l’assistant et des interactions avec l’application. Prévoyez les pauses normales, par exemple lorsque l’utilisateur lit ou réfléchit. Fermez la session uniquement lorsque la lecture est terminée et qu’aucune tâche en attente n’a besoin de la session vocale en cours. Un intervalle entre deux événements de transcription ne suffit pas à établir qu’il y a eu un silence.
- Sauvegardez l’état et fermez proprement la session. Enregistrez l’identifiant de la session source, le contexte de la conversation et l’état actuel des tâches. Terminez les tâches Responses nécessaires, puis suivez la procédure de suivi de l’utilisation et de fermeture propre : installez le gestionnaire de
session.closed, envoyezsession.closeet attendezsession.closedavant de libérer la connexion. Avec la délégation au client, les tâches du backend gérées par l’application peuvent se poursuivre indépendamment une fois la session vocale fermée. - Détectez quand redémarrer. Proposez un bouton Reprendre la conversation, une commande sur laquelle appuyer pour parler ou un mécanisme de réveil géré par l’application. Une session Live fermée ne peut pas écouter l’utilisateur. Si vous utilisez la détection locale de la parole pour redémarrer automatiquement, maintenez la capture du microphone et mettez les premières paroles en mémoire tampon pendant l’établissement de la connexion. Transmettez cet audio dès que la nouvelle session est prête pour préserver les premiers mots de l’utilisateur.
- Rétablissez le contexte dans une nouvelle session. Si la session source a été créée avec
store: true, que le stockage est activé et autorisé et que l’enregistrement a été finalisé avec succès, forkez la session stockée. Dans le cas contraire, démarrez une nouvelle session avec l’historique textuel sauvegardé. Enregistrez le nouvel identifiant de session, vérifiez l’état des opérations encore en cours côté serveur et acheminez les résultats ultérieurs vers la nouvelle session. Conservez l’état des opérations dans votre application pour éviter qu’un redémarrage ne répète des actions déjà effectuées.
Couper le microphone laisse la session active. Pour choisir le délai d’inactivité, comparez la durée de session vocale économisée au coût de création d’une session et au délai nécessaire pour que la voix soit de nouveau disponible. Consultez Coûts des sessions vocales et Frais d’initialisation de WebRTC.
Gérer les erreurs et mettre fin à la session
Continuez à lire les événements jusqu’à la finalisation de la session. Distinguez le rejet d’une commande, l’échec d’une connexion et la fin d’une session pour que votre application puisse réagir de manière appropriée.
Traiter les commandes rejetées
Lisez les événements error en parallèle des accusés de réception. Lorsqu’il est présent, error.client_event_id identifie la commande envoyée qui a échoué :
{
"type": "error",
"event_id": "event_error",
"error": {
"type": "invalid_request_error",
"code": "immutable_field_update",
"message": "The delegation type cannot change after session startup.",
"param": "session.delegation.type",
"client_event_id": "event_update"
}
}
Prévoyez un gestionnaire général pour les erreurs dont le code vaut null ou dont l’identifiant d’événement client est absent. Si l’erreur concerne un champ immuable, conservez la configuration actuelle ou créez une nouvelle session avec les paramètres voulus.
Gérer la modération
La modération peut avoir deux effets sur la session :
- Certains événements de modération mettent fin à la session.
- D’autres coupent l’audio de l’assistant pour le reste de sa prise de parole en cours et émettent un événement
errorsans mettre fin à la session.
Continuez à traiter les événements error pendant la lecture audio. Suivez séparément les interruptions audio et la fermeture de la session. Ne marquez un message vocal comme diffusé qu’après avoir vérifié sa lecture. Appliquez vos propres garde-fous à la conversation en complément de la modération intégrée.
Suivi de l’utilisation et fermeture propre
session.usage.updated indique la durée vocale cumulée en secondes :
{
"type": "session.usage.updated",
"event_id": "event_usage_1",
"usage": { "seconds": 12 },
"context_window": { "usage_ratio": 0.42 }
}
Utilisez la dernière valeur de usage.seconds comme durée vocale cumulée. Par exemple, si deux mises à jour successives indiquent 12 puis 15 secondes, la durée d’utilisation est de 15 secondes. Comptabilisez séparément les tokens utilisés côté serveur à partir des événements imbriqués qui signalent la fin des réponses de Responses. Consultez Optimisation des coûts pour le suivi de l’utilisation.
Pour fermer proprement la session :
- Terminez les tâches déléguées à Responses dont votre application a besoin, y compris la transmission des résultats de fonction en attente et la poursuite des réponses.
- Installez le gestionnaire de
session.closedavant d’envoyersession.close. - Envoyez
session.closeet cessez de soumettre de nouvelles tâches à la session. Maintenez actifs la connexion WebSocket ou WebRTC, le canal de données et tout récepteur auxiliaire associé pendant le traitement des derniers événements de session. - Récupérez la valeur finale de
usage.seconds, le champreasonet l’instantané de la session danssession.closed. Conservez les données d’utilisation des tâches déléguées déjà reçues viaresponse.event. - Après cet événement, libérez les ressources de transport et les périphériques audio. Si la finalisation échoue ou dépasse le délai fixé par votre application, signalez que la finalisation est incomplète et libérez les ressources.
L’envoi de session.close annule les réponses de Responses en file d’attente et entraîne le rejet de toute nouvelle commande. Une réponse en cours peut se terminer, mais une réponse qui attend le résultat d’une fonction ne peut plus se poursuivre une fois la fermeture engagée. Pour les tâches que votre application exécute par délégation au client, décidez séparément s’il faut les terminer ou les annuler.
Utilisez session.closed pour confirmer la finalisation et lire l’instantané de la configuration finale. Maintenez le transport ouvert jusqu’à la réception de cet événement. Si la socket se ferme avant, consignez la finalisation comme non confirmée. Si elle se ferme après un événement session.closed valide, conservez le résultat confirmé.
Le champ reason du dernier événement indique pourquoi la session s’est terminée :
| Motif | Signification |
|---|---|
close_requested |
Votre application a envoyé session.close ou appelé le point de terminaison de raccrochage. |
expired |
La session a atteint sa durée maximale. |
content |
Un filtre de sécurité a mis fin à la session. |
remote_hangup |
La connexion principale distante s’est fermée proprement. |
connection_lost |
La connexion principale ou la connexion en amont a été interrompue de manière inattendue. |
Un événement session.closed confirme la finalisation même si la session s’est terminée à la suite d’une perte de connexion ou d’une intervention de sécurité. Sans cet événement, l’utilisation finale reste non confirmée. La sauvegarde de l’enregistrement peut prolonger la finalisation d’une session stockée. Tenez-en compte lorsque vous fixez le délai d’attente de l’application.
Reprendre après un échec de connexion
Une erreur HTTP à la création de la session signifie que celle-ci n’a pas atteint session.started. Traitez les erreurs de démarrage séparément des erreurs survenant en cours de session. Si une connexion établie échoue avant session.closed, conservez les dernières données d’utilisation observées et indiquez que l’utilisation finale reste non confirmée.
Si vous disposez d’un enregistrement finalisé et stocké, forkez la session correspondante pour poursuivre la conversation dans une nouvelle session. Sinon, créez une session de remplacement avec les éléments pertinents de l’historique sauvegardé. Avant de poursuivre, vérifiez l’état des actions inachevées auprès de votre backend, rétablissez l’état actuel des tâches et actualisez l’acheminement des résultats pour que les résultats tardifs de la session précédente ne puissent pas écraser ceux de tâches plus récentes.