Le problème que personne ne met dans la démo
Chaque démo de voice AI commence pareil : un appel client sans friction, un son propre, un transcript bien rangé. Puis vous signez le contrat, vous essayez de mettre ce même agent en frontline d'un flow assurance régulé, et tout part en vrille. Les PII fuitent dans les transcripts. Le consentement n'est pas capturé. Les logs d'audit sont des blobs JSON que personne ne peut requêter. Le responsable conformité pose une seule question — « prouvez-moi que cet appel était licite » — et toute la stack devient silencieuse.
C'est la partie du voice AI sur laquelle personne ne publie de tutoriel. Donc voilà le nôtre.
L'architecture de référence qu'on déploie
Chaque déploiement voice régulé est construit sur trois couches, dans cet ordre :
- Téléphonie + médias — typiquement Twilio ou un trunk SIP régional. Le job ici est juste de faire atterrir l'audio en sécurité dans notre périmètre et de tagger chaque appel avec un
call_idqui vit pour toujours. - Inférence + orchestration — Ultravox pour le speech-to-speech, avec un orchestrateur léger (service TypeScript, pas de framework) qui tient la state machine. Pourquoi notre propre state machine et pas LangGraph ? Parce que les flows régulés ont des règles dures — vous ne pouvez pas citer une prime avant que le consentement soit capturé — et on veut ces règles en code lisible qu'un auditeur peut lire.
- Stockage + audit — Postgres pour la donnée opérationnelle, S3 (avec object lock + KMS) pour l'audio brut, et une table
audit_eventsappend-only séparée sur laquelle aucun service ne peut faireUPDATEouDELETE.
Ce qui fait que ça marche, ce n'est pas un composant en particulier. C'est que consentement, rétention et audit sont des préoccupations first-class dès le schéma — pas un middleware de logging bricolé à la fin.
Le consentement, version régulateur
Le consentement en voice AI a trois moments, et il faut les capturer tous les trois :
- Consentement à l'enregistrement — capturé avant que l'agent dise quoi que ce soit de substantiel. Le prompt d'ouverture est un script que votre équipe juridique a validé, et la réponse du client est timestampée contre
call_idet contre la version du prompt (parce que les prompts changent chaque semaine et un auditeur va demander « qu'est-ce qu'on lui a exactement lu en mars ? »). - Consentement au traitement des données — séparé de l'enregistrement. Le client consent à ce que votre IA traite ses données, pas juste à être enregistré.
- Consentement à l'issue — le client accepte ce que l'appel a produit (un devis, un changement de contrat, un rappel). C'est celui qu'on saute le plus souvent et le plus douloureux quand il manque.
Chacun atterrit dans audit_events comme une ligne avec event_type, consent_version, prompt_version, agent_version, transcript_offset_ms. Quand le régulateur demande, vous pouvez reconstruire exactement ce qui a été dit, quand, par qui, et ce que le client a accepté.
Un logging d'audit qui survit à un vrai audit
Le piège du logging d'audit, c'est d'écrire trop et de requêter trop peu. On logge cinq choses, religieusement :
- Transitions d'état dans la state machine de la conversation (avec le trigger et l'état suivant)
- Tool calls que l'agent a fait (avec arguments et hash du résultat — pas le résultat brut, parce qu'il peut contenir des PII qu'on ne veut pas en audit pour toujours)
- Événements de consentement (voir plus haut)
- Escalades vers un agent humain (et le code raison)
- Hits de policy guardrail — quand un guardrail a bloqué l'agent
Voilà. Pas de dump request/response. Pas de logs « info ». L'audit, c'est pour prouver la conformité, pas pour debugger. Les logs de debug vivent ailleurs avec une rétention de 30 jours.
Ce qu'on ferait différemment
Après Hayah on a changé deux choses dans le template. D'abord, on versionne maintenant le script de consentement lui-même comme une entrée content-collection, donc le script et le prompt qui le lit sont liés au moment du deploy. Ensuite, on a construit un outil de replay qui prend un call_id et fait défiler l'appel à l'auditeur comme une timeline — transcripts, événements de consentement, tool calls, tout dans une vue. L'auditeur a arrêté de demander des screenshots. Ça à soi seul valait une semaine d'engineering.
À retenir
Le voice AI en périmètre régulé n'est pas un problème de modèle. C'est un problème de discipline data. Versionner le consentement, immutabiliser l'audit, outiller le replay — bien dès le jour un, et le reste du build n'est plus que du produit. Loupez-les et vous reconstruirez depuis le schéma six mois plus tard.