Merci — je réponds point par point à vos 4 questions en me concentrant sur le flux SIP/RTP, la gestion d’état, l’architecture logicielle et les optimisations de latence.
1) Architecture globale et configuration LiveKit SIP Inbound (comment relier Asterisk/Vicidial)
• Schéma simple :
◦ Asterisk/Vicidial (Dialer) envoie un SIP INVITE vers le SIP Inbound Trunk LiveKit → LiveKit crée un Participant SIP et, selon la règle de dispatch, crée/associe une Room → un Agent IA (WebRTC participant) rejoint la Room → audio RTP ↔️ WebRTC transitera via le SIP Gateway LiveKit.
• Configuration côté LiveKit (concept) :
◦ Créez un SIP Inbound Trunk avec :
▪︎ numéros routés (DID),
▪︎ allowed_addresses (IP de vos serveurs Asterisk/Vicidial),
▪︎ auth_username / auth_password (ou whitelist IP),
▪︎ options de qualité (ex. krisp_enabled pour réduction de bruit).
◦ Définissez une SIP Dispatch Rule de type “individual” (génère une Room unique par INVITE, ex. prefix call-{uuid}) pour isoler chaque appel.
• Exemple Asterisk (peer) minimal :
◦ dans sip.conf/pjsip.conf pointez vers l’endpoint LiveKit (host = votre trunk ou ip gateway) avec username/secret.
◦ Dialplan : avant de Dial(), effectuez un health-check (voir §2) ; si OK envoyez Dial(SIP/livekit-trunk/…).
• Flux SIP/RTP clé à connaître :
a. Dialer -> INVITE (SDP offer) vers LiveKit.
b. LiveKit -> 200 OK (SDP answer) ; échange de RTP entre Asterisk et LiveKit SIP gateway.
c. ACK finalise l’établissement.
d. Audio RTP (RTP/RTCP) circule entre Asterisk
- LiveKit, LiveKit gère transcodage/forwarding vers WebRTC agent.
2) Gestion de la disponibilité (State Management) — empêcher que le dialer envoie 20 appels si seuls 5 agents libres
• Conclusion rapide : ne vous fiez pas uniquement au comportement interne LiveKit ; mettez en place un mécanisme de coordination externe pour garantir le pacing (recommandé).
• Deux approches possibles :
A) Simple / Pull-based (moins robuste)
• Exposez un endpoint health/availability côté backend des agents (ex. HTTP GET retourne 200 si au moins 1 agent libre, 503 sinon).
• Le dialer vérifie cet endpoint avant d’initier chaque INVITE. Si 503 → retarder/retry selon votre pacing.
• Avantage : simple à implémenter dans Asterisk (CURL depuis le dialplan). Inconvénient : latence de polling et risques de race conditions entre check et INVITE.
B) Recommandé — Queue/Coordinator externe (Redis + Service de dispatch)
• Architecture :
◦ Tous les agents (instances LiveKit Agent processes) mettent à jour leur état (available/occupied) dans Redis ou DB via un Agent Manager.
◦ Le Dialer interroge le Coordinator (API) avant de lancer un INVITE. Le Coordinator réserve un slot atomiquement (SETNX / transaction) et renvoie OK/NOT_OK.
◦ Si OK -> Dialer lance INVITE vers LiveKit (Room dynamique). Si NOT_OK -> dialer retarde le call ou place le numéro en waiting queue.
• Bénéfices : pas de dropped calls, pas de course entre check et INVITE, possibilité de priorisation/pacing global.
• Détails d’implémentation : utilisez des locks TTL pour éviter stuck states (ex. agent réserve 30s) ; mettre à jour l’état à connexion Room & à fin de job.
• Signalisation côté LiveKit :
◦ Lorsque LiveKit crée la Room et dispatch l’agent, votre Agent Manager doit marquer l’agent comme occupé.
◦ À la fin de la Room (départ/cleanup) il remet l’agent en available.
3) Gestion des Rooms : dynamique par appel vs 5 Rooms permanentes
• Recommandation : créer une Room dynamique par appel (call-{uuid}).
◦ Raisons :
▪︎ Isolation audio complète (évite cross-talk).
▪︎ Pas de contention sur la Room quand plusieurs appels arrivent.
▪︎ Cycle de vie simple : créer à l’INVITE, détruire à la fin.
▪︎ Facilite enregistrement/egress par-call.
• Pourquoi pas 5 Rooms permanentes :
◦ Si vous avez 5 agents physiques, il est tentant d’avoir 5 Rooms “slots” ; mais cela complique la gestion (quel SIP entrant mappe sur quel slot?) et peut causer conflits RTP si plusieurs appels arrivent simultanément dans une même Room.
◦ Exception : si vous avez une contrainte très forte de reconnection d’état ou d’architecture legacy, vous pouvez maintenir rooms “slots” + broker pour rediriger, mais ce n’est pas recommandé.
• Implémentation pratique :
◦ Configurez la SIPDispatchRule pour créer un room unique par INVITE (room_prefix).
◦ Lors de la création de la Room, créez/attribuez un Job/Task côté Agent Manager, notifiez l’agent sélectionné de se connecter à cette Room (ws/wss avec les credentials).
4) Réduction de la latence (optimiser temps entre “Allô” et réponse IA)
• Domaines d’optimisation :
1) Géographie & réseau :
• Déployez Agents LiveKit et vos services STT/LLM/TTS dans la même région que votre trunk/dialer.
• Minimisez les sauts réseau (Asterisk -> LiveKit région proche -> services IA co-localisés).
2) Pipeline audio & VAD/Turn detection :
• Paramétrez VAD permissif (min_silence_duration faible, min_speech_duration faible) pour détecter plus vite la fin de la parole et lancer le STT.
• Utilisez streaming STT et streaming TTS (pour commencer la synthèse dès les premiers tokens) et un LLM avec streaming de tokens.
3) Warm agents et modèles :
• Gardez agents “chauds” (warm) ; évitez cold-start des containers/model clients.
• Préférez modèles low-latency pour le path critique (ex. mini/streaming variants).
4) RTP/codec & transcoding :
• Standardisez codecs entre Asterisk et LiveKit (ex. PCMU/PCMA) pour éviter transcodage serveur-side qui ajoute latence.
• Si TTS doit être envoyé, préférez l’envoi direct en RTP (chunking court) ou envoyez audio chunk TTS en streaming vers la Room.
5) Prioriser Time-to-first-token (TTFT) et détection de tour :
• Objectif TTFT < 300ms si possible ; mesurer et alerter.
6) Paramètres Asterisk et RTP :
• Ouvrez et privilégiez ports RTP/RTCP faibles jitter, utilisez QoS/prioritization sur réseau.
Flux SIP/RTP optimisé (pratique) :
• INVITE -> 200 OK (SSRC & codecs alignés) -> ACK.
• LiveKit commence immédiatement à forwarder RTP vers Room.
• Agent IA (déjà connecté) reçoit audio en quasi temps réel, VAD détecte fin de tour (ou streaming STT commence dès premiers paquets), LLM génère streaming réponse, TTS stream en RTP vers Room.
Recommandations opérationnelles rapides
• Utilisez Room dynamiques + Coordinator (Redis) pour gérer disponibilité.
• Configurez trunk LiveKit avec whitelist IP + auth.
• Favorisez codecs compatibles (PCMU/OPUS) pour réduire transcodage.
• Activez réduction de bruit côté trunk (krisp) pour améliorer STT.
• Gardez agents pré-warm et STT/LLM/TTS en streaming pour réduire TTFT.
• Sur Asterisk, effectuez un health-check avant l’INVITE (ou gate via Coordinator) pour bloquer INVITES quand pas d’agents libres.
Points d’implémentation SIP précis à respecter
• Authentification INVITE : IP whitelist ou auth header (credentials).
• SDP : négociez codecs communs (OPUS si WebRTC agent ; PCMU/PCMA si Asterisk).
• Clés RTP : surveillez SSRC collisions, configurez RTCP interval court pour monitoring.
• Gestion erreurs SIP : si LiveKit renvoie 503/486/488, traitez en backoff/retry côté dialer plutôt que retrials immédiats.
Si vous voulez, je peux :
• Fournir un exemple concret de dialplan Asterisk (extensions.conf/pjsip.conf) qui fait le check de disponibilité via un endpoint HTTP/Redis puis effectue l’INVITE.
• Rédiger le pseudo-code du Coordinator (Redis patterns, réservation atomique) et les webhooks à placer côté LiveKit Agent.
• Donner un exemple d’SDP / pcap simplifié montrant INVITE → 200 OK → ACK → RTP pour votre intégration.
Laquelle de ces 3 prochaines étapes souhaitez-vous que je vous fournisse en premier : 1) dialplan Asterisk concret, 2) pseudo-code Coordinator + Redis, 3) exemple SDP/PCAP et configuration codec ?
Sources:
Python SDKs | livekit/livekit_composite | DeepWiki |
examples/voice_agents | livekit/livekit_composite | DeepWiki |
sip | livekit/livekit_composite | DeepWiki |
Sequential Pipeline Architecture for Voice Agents | LiveKit |
Agents (Python) | livekit/livekit_composite | DeepWiki, with interactive elements