[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-\u002Fen\u002Fblog\u002Fvoix-temps-reel-vs-batch":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"author":10,"date":11,"tags":12,"body":16,"_type":521,"_id":522,"_source":523,"_file":524,"_stem":525,"_extension":526},"\u002Fen\u002Fblog\u002Fvoix-temps-reel-vs-batch","blog",false,"","Phone AI agents: real-time voice vs. batch","Why a voice assistant demands a radically different architecture from a text chatbot, and what that means for latency, barge-in and model selection.","Équipe betool","2026-04-28",[13,14,15],"voice","architecture","latency",{"type":17,"children":18,"toc":512},"root",[19,40,45,52,71,84,89,95,105,124,129,200,205,210,244,250,262,274,285,308,313,319,324,329,382,388,393,441,446,452,457,500],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,33,35],{"type":25,"value":26},"text","When a vendor pitches you a ",{"type":20,"tag":28,"props":29,"children":30},"em",{},[31],{"type":25,"value":32},"\"phone AI agent\"",{"type":25,"value":34},", ask them one question: ",{"type":20,"tag":28,"props":36,"children":37},{},[38],{"type":25,"value":39},"\"What is your end-to-end latency between the end of the user's speech and the start of the response?\"",{"type":20,"tag":21,"props":41,"children":42},{},[43],{"type":25,"value":44},"If the answer exceeds 1.5 seconds, it is not a phone agent. It is a chatbot with an ASR \u002F TTS module glued to the front.",{"type":20,"tag":46,"props":47,"children":49},"h2",{"id":48},"the-800-ms-rule",[50],{"type":25,"value":51},"The 800 ms rule",{"type":20,"tag":21,"props":53,"children":54},{},[55,57,62,64,69],{"type":25,"value":56},"A human on the phone tolerates silence after their question. But that silence has a threshold: beyond 800 ms, the other end feels ",{"type":20,"tag":28,"props":58,"children":59},{},[60],{"type":25,"value":61},"\"frozen\"",{"type":25,"value":63},". At 1,500 ms, the caller says ",{"type":20,"tag":28,"props":65,"children":66},{},[67],{"type":25,"value":68},"\"hello?\"",{"type":25,"value":70},". At 3,000 ms, they hang up assuming a line problem.",{"type":20,"tag":21,"props":72,"children":73},{},[74,76,82],{"type":25,"value":75},"The target for a serious voice agent is therefore: ",{"type":20,"tag":77,"props":78,"children":79},"strong",{},[80],{"type":25,"value":81},"under 800 ms",{"type":25,"value":83}," between the end of speech and the first audible byte of the response.",{"type":20,"tag":21,"props":85,"children":86},{},[87],{"type":25,"value":88},"Let's break it down.",{"type":20,"tag":46,"props":90,"children":92},{"id":91},"the-time-budget-in-detail",[93],{"type":25,"value":94},"The time budget in detail",{"type":20,"tag":96,"props":97,"children":99},"pre",{"code":98},"[user speech]──▶[ASR streaming]──▶[LLM]──▶[TTS streaming]──▶[audio out]\n      ~150ms          ~80ms        ~?       ~250ms             ~50ms\n",[100],{"type":20,"tag":101,"props":102,"children":103},"code",{"__ignoreMap":7},[104],{"type":25,"value":98},{"type":20,"tag":21,"props":106,"children":107},{},[108,110,115,117,122],{"type":25,"value":109},"Of the ~800 ms available, ",{"type":20,"tag":77,"props":111,"children":112},{},[113],{"type":25,"value":114},"roughly 270 ms are consumed by ASR + TTS + transport",{"type":25,"value":116},". That leaves ",{"type":20,"tag":77,"props":118,"children":119},{},[120],{"type":25,"value":121},"530 ms for the LLM",{"type":25,"value":123}," — including prefill time, reasoning, and first-token generation.",{"type":20,"tag":21,"props":125,"children":126},{},[127],{"type":25,"value":128},"Implications:",{"type":20,"tag":130,"props":131,"children":132},"ul",{},[133,151,167,183],{"type":20,"tag":134,"props":135,"children":136},"li",{},[137,142,144,149],{"type":20,"tag":77,"props":138,"children":139},{},[140],{"type":25,"value":141},"A large reasoning model, non-streaming",{"type":25,"value":143},": several seconds before the first audible word. ",{"type":20,"tag":77,"props":145,"children":146},{},[147],{"type":25,"value":148},"Out of the question",{"type":25,"value":150},".",{"type":20,"tag":134,"props":152,"children":153},{},[154,159,161,166],{"type":20,"tag":77,"props":155,"children":156},{},[157],{"type":25,"value":158},"A high-end model, streaming",{"type":25,"value":160},": fast first token on good days, much less so on bad ones. ",{"type":20,"tag":77,"props":162,"children":163},{},[164],{"type":25,"value":165},"Acceptable but tight",{"type":25,"value":150},{"type":20,"tag":134,"props":168,"children":169},{},[170,175,177,182],{"type":20,"tag":77,"props":171,"children":172},{},[173],{"type":25,"value":174},"A fast model, streaming",{"type":25,"value":176}," (\"lightweight\" tiers of Claude, GPT and Gemini): ",{"type":20,"tag":77,"props":178,"children":179},{},[180],{"type":25,"value":181},"Comfortable",{"type":25,"value":150},{"type":20,"tag":134,"props":184,"children":185},{},[186,191,193,198],{"type":20,"tag":77,"props":187,"children":188},{},[189],{"type":25,"value":190},"A small open-weight model served on your GPU (vLLM)",{"type":25,"value":192},": ",{"type":20,"tag":77,"props":194,"children":195},{},[196],{"type":25,"value":197},"Excellent",{"type":25,"value":199}," (and private).",{"type":20,"tag":21,"props":201,"children":202},{},[203],{"type":25,"value":204},"Measure TTFT on your own traffic: it varies by provider, region and time of day.",{"type":20,"tag":21,"props":206,"children":207},{},[208],{"type":25,"value":209},"A serious voice architecture therefore requires:",{"type":20,"tag":211,"props":212,"children":213},"ol",{},[214,224,234],{"type":20,"tag":134,"props":215,"children":216},{},[217,222],{"type":20,"tag":77,"props":218,"children":219},{},[220],{"type":25,"value":221},"Everything is streaming",{"type":25,"value":223}," — ASR, LLM, TTS. Not a single link in batch mode.",{"type":20,"tag":134,"props":225,"children":226},{},[227,232],{"type":20,"tag":77,"props":228,"children":229},{},[230],{"type":25,"value":231},"The LLM model is selected for TTFT",{"type":25,"value":233}," (time to first token), not for MMLU score.",{"type":20,"tag":134,"props":235,"children":236},{},[237,242],{"type":20,"tag":77,"props":238,"children":239},{},[240],{"type":25,"value":241},"TTS starts speaking on the first received token",{"type":25,"value":243},", not after the full response is complete.",{"type":20,"tag":46,"props":245,"children":247},{"id":246},"barge-in",[248],{"type":25,"value":249},"Barge-in",{"type":20,"tag":21,"props":251,"children":252},{},[253,255,260],{"type":25,"value":254},"On a text channel, the user waits for the bot to finish. On the phone, ",{"type":20,"tag":77,"props":256,"children":257},{},[258],{"type":25,"value":259},"they interrupt",{"type":25,"value":261},". Three times out of five, in natural conversations.",{"type":20,"tag":21,"props":263,"children":264},{},[265,267,272],{"type":25,"value":266},"A voice agent that cannot handle being cut off feels ",{"type":20,"tag":28,"props":268,"children":269},{},[270],{"type":25,"value":271},"\"robotic\"",{"type":25,"value":273}," — it keeps talking while the user is trying to interrupt. It is intolerable, and it immediately signals a poorly built bot.",{"type":20,"tag":21,"props":275,"children":276},{},[277,279,283],{"type":25,"value":278},"Technical ",{"type":20,"tag":77,"props":280,"children":281},{},[282],{"type":25,"value":246},{"type":25,"value":284}," requires:",{"type":20,"tag":130,"props":286,"children":287},{},[288,293,298,303],{"type":20,"tag":134,"props":289,"children":290},{},[291],{"type":25,"value":292},"TTS stops immediately when the ASR detects outgoing vocal signal from the user.",{"type":20,"tag":134,"props":294,"children":295},{},[296],{"type":25,"value":297},"The LLM discards the in-progress completion (without complaint).",{"type":20,"tag":134,"props":299,"children":300},{},[301],{"type":25,"value":302},"The outgoing audio buffer is flushed instantly (otherwise a residual half-syllable is audible).",{"type":20,"tag":134,"props":304,"children":305},{},[306],{"type":25,"value":307},"The conversation history notes that the response was not heard in full — to avoid inadvertently repeating it.",{"type":20,"tag":21,"props":309,"children":310},{},[311],{"type":25,"value":312},"It is a technical detail that changes everything in how the interaction feels.",{"type":20,"tag":46,"props":314,"children":316},{"id":315},"handling-uncertainty",[317],{"type":25,"value":318},"Handling uncertainty",{"type":20,"tag":21,"props":320,"children":321},{},[322],{"type":25,"value":323},"On the phone, the ASR makes mistakes regularly. Where a text chatbot always receives the exact text typed by the user, the voice agent receives a frequently imperfect transcription.",{"type":20,"tag":21,"props":325,"children":326},{},[327],{"type":25,"value":328},"Strategies that work:",{"type":20,"tag":130,"props":330,"children":331},{},[332,342,366],{"type":20,"tag":134,"props":333,"children":334},{},[335,340],{"type":20,"tag":77,"props":336,"children":337},{},[338],{"type":25,"value":339},"Request confirmation",{"type":25,"value":341}," on high-consequence items (case number, amount, unusual surname). Not systematically — that becomes unbearable.",{"type":20,"tag":134,"props":343,"children":344},{},[345,350,352,357,359,364],{"type":20,"tag":77,"props":346,"children":347},{},[348],{"type":25,"value":349},"Do not blindly trust the LLM",{"type":25,"value":351}," when the ASR is ambiguous. If the received phrase is ",{"type":20,"tag":28,"props":353,"children":354},{},[355],{"type":25,"value":356},"\"I want to cancel my contract\"",{"type":25,"value":358}," with a low confidence score, it is better to ask ",{"type":20,"tag":28,"props":360,"children":361},{},[362],{"type":25,"value":363},"\"Did you mean cancel your contract?\"",{"type":25,"value":365}," than to trigger the cancellation procedure.",{"type":20,"tag":134,"props":367,"children":368},{},[369,374,376,381],{"type":20,"tag":77,"props":370,"children":371},{},[372],{"type":25,"value":373},"Cut off derailments",{"type":25,"value":375}," — an agent that drifts from the script should be brought back by a condition \u002F operator node, not by a prompt that ",{"type":20,"tag":28,"props":377,"children":378},{},[379],{"type":25,"value":380},"\"should be enough\"",{"type":25,"value":150},{"type":20,"tag":46,"props":383,"children":385},{"id":384},"the-phone-is-also-a-stack",[386],{"type":25,"value":387},"The phone is also a stack",{"type":20,"tag":21,"props":389,"children":390},{},[391],{"type":25,"value":392},"Beyond the AI, a phone agent requires:",{"type":20,"tag":130,"props":394,"children":395},{},[396,408,419,430],{"type":20,"tag":134,"props":397,"children":398},{},[399,401,406],{"type":25,"value":400},"A ",{"type":20,"tag":77,"props":402,"children":403},{},[404],{"type":25,"value":405},"SIP trunk",{"type":25,"value":407}," from a carrier (Twilio, Voxbone, OVH, Sewan…).",{"type":20,"tag":134,"props":409,"children":410},{},[411,412,417],{"type":25,"value":400},{"type":20,"tag":77,"props":413,"children":414},{},[415],{"type":25,"value":416},"media gateway",{"type":25,"value":418}," (LiveKit-SIP, FreeSWITCH, Asterisk) that speaks SIP on the carrier side and WebRTC on the platform side.",{"type":20,"tag":134,"props":420,"children":421},{},[422,423,428],{"type":25,"value":400},{"type":20,"tag":77,"props":424,"children":425},{},[426],{"type":25,"value":427},"transcriber",{"type":25,"value":429}," robust to noise, accents and overlapping voices.",{"type":20,"tag":134,"props":431,"children":432},{},[433,434,439],{"type":25,"value":400},{"type":20,"tag":77,"props":435,"children":436},{},[437],{"type":25,"value":438},"synthesiser",{"type":25,"value":440}," that correctly pronounces proper nouns, numbers and dates.",{"type":20,"tag":21,"props":442,"children":443},{},[444],{"type":25,"value":445},"None of these elements is trivial. All of them interact.",{"type":20,"tag":46,"props":447,"children":449},{"id":448},"what-betool-handles",[450],{"type":25,"value":451},"What betool handles",{"type":20,"tag":21,"props":453,"children":454},{},[455],{"type":25,"value":456},"betool's voice architecture — LiveKit + LiveKit-SIP + dedicated worker + LLM streaming into speech synthesis — covers the above requirements out of the box. You remain in control of:",{"type":20,"tag":130,"props":458,"children":459},{},[460,471,489],{"type":20,"tag":134,"props":461,"children":462},{},[463,465,469],{"type":25,"value":464},"The ",{"type":20,"tag":77,"props":466,"children":467},{},[468],{"type":25,"value":405},{"type":25,"value":470}," (your carrier, your numbers).",{"type":20,"tag":134,"props":472,"children":473},{},[474,475,480,482,487],{"type":25,"value":464},{"type":20,"tag":77,"props":476,"children":477},{},[478],{"type":25,"value":479},"models",{"type":25,"value":481}," (managed models, BYOK or private models) and the ",{"type":20,"tag":77,"props":483,"children":484},{},[485],{"type":25,"value":486},"voices",{"type":25,"value":488}," (Deepgram or faster-whisper transcription; ElevenLabs, Cartesia, OpenAI or Deepgram Aura synthesis).",{"type":20,"tag":134,"props":490,"children":491},{},[492,493,498],{"type":25,"value":464},{"type":20,"tag":77,"props":494,"children":495},{},[496],{"type":25,"value":497},"parameters",{"type":25,"value":499}," (barge-in sensitivity, end-of-turn detection, filler phrases, transfer to a human).",{"type":20,"tag":21,"props":501,"children":502},{},[503,505,510],{"type":25,"value":504},"You do not configure the real-time plumbing — that is the platform's job. You design the ",{"type":20,"tag":77,"props":506,"children":507},{},[508],{"type":25,"value":509},"conversation",{"type":25,"value":511},", which is the actual business challenge.",{"title":7,"searchDepth":513,"depth":513,"links":514},2,[515,516,517,518,519,520],{"id":48,"depth":513,"text":51},{"id":91,"depth":513,"text":94},{"id":246,"depth":513,"text":249},{"id":315,"depth":513,"text":318},{"id":384,"depth":513,"text":387},{"id":448,"depth":513,"text":451},"markdown","content:en:blog:2.voix-temps-reel-vs-batch.md","content","en\u002Fblog\u002F2.voix-temps-reel-vs-batch.md","en\u002Fblog\u002F2.voix-temps-reel-vs-batch","md"]