Édition de documents pilotée par la voix avec Gemini Live : architecture et compromis
La plupart des démos d'« éditeur piloté par la voix » que vous avez vues font quelque chose de discrètement coûteux : l'audio passe par un modèle de transcription, la transcription passe par un modèle d'instructions, et le modèle d'instructions émet des appels d'outils vers l'éditeur. Trois allers-retours, deux LLM, et la surface que voit le modèle vocal n'est pas la surface qu'expose l'éditeur.
AgentDoc emprunte une voie différente. Nous connectons Gemini 3.1 Flash Live – la variante audio native – directement au même serveur MCP qu'utilise l'agent textuel. Il n'y a pas de proxy de transcription, pas de second LLM, et pas de surface d'outils distincte pour la voix. Cet article explique pourquoi nous avons choisi cette conception, ce qu'elle coûte, et où se trouvent encore les aspérités.
La conception naïve (et pourquoi elle perd)
Le modèle à proxy de transcription ressemble à ceci :
mic → STT → transcript → text-LLM → tool-call → MCP → editor
↑
(instructions, tool list, history)
Il pose trois véritables problèmes. Premièrement, la latence est la somme de trois appels de modèle séquentiels ; vous ressentez la pause chaque fois que vous finissez de parler. Deuxièmement, l'étape STT rejette la prosodie – qui est précisément le signal qui distingue « 'vraiment' en italique » de « vraiment, en italique ». Troisièmement, vous maintenez deux surfaces de prompt divergentes : la documentation des outils de l'agent textuel et celle de l'agent vocal, qui s'écartent l'une de l'autre avec le temps.
La conception audio native
Le chemin audio natif de Gemini Live prend l'audio brut, exécute des appels d'outils contre un schéma typé, et renvoie de l'audio en flux. Le diagramme se réduit à :
mic → Gemini Live → tool-call → MCP → editor
↑
(same tool list as text agent)
Deux conséquences en découlent :
- Une source unique de vérité pour la surface d'outils. L'agent vocal appelle
insert_textavec le même schéma qu'utilise l'agent textuel. Nous ne maintenons pas une « liste d'outils vocaux » parallèle. - La prosodie survit. Le modèle reçoit l'audio directement, donc l'emphase et les pauses orientent la sélection de l'appel d'outils sans que nous ayons à écrire de règles.
Ce que nous avons dû construire
Trois points d'intégration ont nécessité du travail :
- Pontage WebSocket. Gemini Live parle un protocole WS ; l'éditeur en utilise un autre pour la synchronisation de documents en temps réel. Le service d'agent exécute les deux et traduit les résultats des appels d'outils en événements de rendu de l'éditeur. Voir [agent/](agent/).
- Observabilité des appels d'outils. Le modèle vocal a besoin d'un retour structuré pour éviter la dérive des indices après les mutations. Nous lui renvoyons les mêmes descripteurs de plage modifiée que reçoit l'agent textuel (abordés dans l' article sur la granularité des outils).
- Verrouillage FSM, variante vocale. La machine à états ReAct sous contraintes d'état (FSM) ne se soucie pas de la modalité – le verrou sur les outils d'écriture après une mutation fonctionne de manière identique pour la voix. Nous devions simplement nous assurer que le canal de sortie audio ne se bloque pas lorsque la FSM force une relecture.
Latence : le gain attendu et le gain inattendu
La latence de bout en bout « j'ai cessé de parler → le document mute » chute d'environ 2,4 s dans la conception à proxy à ~700 ms avec l'audio natif. Le gain attendu.
Le gain inattendu, c'est ce qui se passe pendant les échanges à plusieurs tours. Parce que nous ne payons pas l'aller-retour STT à chaque tour, le modèle peut conserver à moindre coût un contexte plus long de conversation parlée. Des instructions composées (« mets le titre en gras, puis mets le paragraphe suivant en italique, puis exporte ») qui nous obligeaient auparavant à découper la transcription en appels LLM distincts s'exécutent désormais comme une seule séquence d'appels d'outils dans une même session Live.
À quoi ressemblent les aspérités
Trois choses mordent encore :
- Quota de l'API Live. Les sessions audio natives sont décomptées sur un quota
différent de celui des complétions de texte, et une longue session vocale peut le consommer plus
vite qu'un dactylographe ne s'y attendrait. Notre pastille d'état de quota (le nouveau module
quota_status.js) est la réponse visible par l'utilisateur. - Désambiguïsation entre homophones. « Insert here » et « insert hear » ne sonnent pas différemment pour un microphone dans une pièce bruyante. Nous avons ajouté un petit ensemble d'invites de confirmation sur les opérations irréversibles – énoncées à voix haute « suppression du paragraphe 3, confirmer ? » – qui conditionnent la mutation réelle.
- Reconnexions. Le WebSocket Live peut tomber sur des réseaux instables, et l'état du tampon audio au moment de la coupure n'est pas toujours récupérable. Nous rejouons actuellement les ~3 dernières secondes de texte confirmé dans une nouvelle session, ce qui est suffisant pour la plupart des utilisateurs mais constitue le prochain élément sur la liste des finitions.
Pourquoi cela compte pour l'accessibilité
La motivation initiale de la conception axée sur la voix figure sur la page accessibilité : AgentDoc est conçu pour être utilisable par les personnes qui ne peuvent pas, ou ne veulent pas, utiliser une souris et un clavier. La conception à proxy de transcription a toujours semblé inadaptée à ce public, car elle imposait une pénalité de 2 secondes à chaque énoncé, ce qui s'aggrave fortement au cours d'une longue session d'écriture.
L'audio natif n'est pas qu'une préférence d'ingénierie. C'est la différence entre la voix comme entrée gadget et la voix comme entrée principale.
La suite
Travaux en cours : une meilleure gestion des reconnexions, un repli vers le mode texte tenant compte du quota lorsque le budget Live est faible, et une étude comparant les temps de réalisation en mode voix uniquement et en mode texte uniquement à travers les 13 scénarios de référence. Ce dernier point aura droit à son propre compte rendu ici lorsque les données arriveront.