VAD : détection automatique de la parole
Sur cette page
Leçon réécrite le 3 novembre 2026 d’après la page Speech to Speech et la référence de l’API Voice de xAI : la détection des tours de parole se règle par
turn_detection.type("server_vad"ounull) et, en option,turn_detection.idle_timeout_ms. Les réglagesthreshold,silence_duration_msetprefix_padding_msde l’ancienne version, avec leurs valeurs par défaut, viennent de l’API Realtime d’OpenAI : ils ne figurent nulle part dans la documentation de xAI — qui se dit compatible avec cette API, sans jamais les mentionner —, pas plus que les champsaudio_start_msetaudio_end_msdes événements. Sources : Speech to Speech · Voice API.
Comprendre la détection de tour de parole
Dans une conversation vocale, le système doit savoir quand l’utilisateur commence à parler et quand il s’arrête. C’est le rôle du VAD (Voice Activity Detection). L’API Voice Agent de xAI propose un VAD côté serveur, server_vad : le serveur analyse le flux audio, repère la fin de chaque intervention et déclenche lui-même la réponse.
Deux modes, un seul champ
Le mode se choisit dans l’objet turn_detection de session.update :
{
"type": "session.update",
"session": {
"turn_detection": { "type": "server_vad" }
}
}
turn_detection.type | Qui décide de la fin du tour | Ce que vous envoyez |
|---|---|---|
"server_vad" | Le serveur | input_audio_buffer.append, rien d’autre |
null | Vous | input_audio_buffer.append, puis input_audio_buffer.commit et response.create |
En mode server_vad, le serveur découpe les tours, valide l’audio et lance la réponse. Les interruptions sont elles aussi automatiques : xAI recommande ce mode pour une prise de parole naturelle, quand l’utilisateur coupe l’agent au milieu d’une phrase. La documentation ne propose en revanche aucun réglage de sensibilité ni de durée de silence : le découpage des tours est l’affaire du serveur.
Les événements du VAD
Avec server_vad, le serveur signale chaque transition :
input_audio_buffer.speech_started: le VAD a détecté le début de la parole ;input_audio_buffer.speech_stopped: il en a détecté la fin ;input_audio_buffer.committed: l’audio a été validé comme message de l’utilisateur.
ws.on("message", (data) => {
const event = JSON.parse(data);
switch (event.type) {
case "input_audio_buffer.speech_started":
arreterLecture(); // l'utilisateur parle : coupez l'audio de l'agent déjà reçu
break;
case "input_audio_buffer.speech_stopped":
afficherReflexion(); // fin de parole détectée : la réponse va suivre
break;
}
});
Côté serveur, l’interruption est automatique ; côté client, l’audio déjà reçu continuerait de jouer si vous ne l’arrêtiez pas. speech_started est le bon moment pour vider votre file de lecture.
Relancer l’utilisateur silencieux : idle_timeout_ms
Seul réglage documenté autour du VAD, idle_timeout_ms fait relancer la conversation par l’agent quand l’utilisateur se tait après une réponse :
{
"type": "session.update",
"session": {
"turn_detection": { "type": "server_vad", "idle_timeout_ms": 8000 }
}
}
Si aucune parole n’est détectée pendant ce délai après la fin d’une réponse, le serveur émet input_audio_buffer.timeout_triggered, valide un tour utilisateur silencieux et génère une relance. Le minuteur se réarme après chaque réponse : il se déclenche donc de nouveau, toutes les idle_timeout_ms, tant que l’utilisateur ne dit rien. Par défaut, il est désactivé (null). Sur un standard téléphonique, une relance au bout de quelques secondes évite les silences qui s’éternisent ; écrivez dans vos instructions la formule de relance que l’agent doit employer.
Mode manuel : turn_detection.type à null
Pour une interface « push-to-talk », ou dès que vous voulez décider vous-même de la fin du tour, passez le type à null :
{
"type": "session.update",
"session": {
"turn_detection": { "type": null }
}
}
Vous envoyez alors l’audio avec input_audio_buffer.append puis, quand l’utilisateur relâche le bouton, input_audio_buffer.commit pour valider le tour et response.create pour demander la réponse. input_audio_buffer.commit n’est disponible qu’en mode manuel. input_audio_buffer.clear jette l’audio envoyé mais pas encore validé, et response.cancel interrompt une réponse en cours, puisqu’en mode manuel l’interruption n’est plus automatique.
Choisir son mode
- Conversation libre (assistant, standard téléphonique, kiosque) :
server_vad, avec au besoinidle_timeout_mspour relancer - Talkie-walkie, dictée, environnement très bruyant : mode manuel, la fin du tour suit le bouton, et le bruit ambiant ne déclenche plus rien
Points clés à retenir
turn_detection.typevaut"server_vad"(le serveur découpe les tours et gère les interruptions) ounull(mode manuel)- La documentation de xAI ne propose ni seuil de sensibilité ni durée de silence à régler
speech_started,speech_stoppedetcommittedsignalent les transitions du VADidle_timeout_msfait relancer l’utilisateur silencieux, avec l’événementinput_audio_buffer.timeout_triggered- En mode manuel :
append, puiscommitetresponse.create