Elk voice-platform noemt een latency-getal, en elk van die getallen is op een gunstige plek gemeten. Het probleem is dat een beller geen getal ervaart. Hij ervaart een stilte: het gat tussen het moment dat hij stopt met praten en het moment dat de agent begint. Dat gat is een keten van acht stappen, waarvan er maar twee bij het model horen, en de grootste post is meestal de post die niemand meetelt.
Twee soorten latency, voortdurend verward
Vraag drie mensen hoe snel een voice-agent is en je krijgt antwoord op drie verschillende vragen. De eerste is opneemlatency: hoe lang het duurt tussen het opnemen van de telefoon en de openingszin van de agent. De tweede is beurtlatency: hoe lang het duurt tussen het einde van de zin van de beller en het begin van het antwoord. De derde is wat de meeste benchmarks werkelijk meten, namelijk de tijd tot het eerste token van een taalmodel op een GPU, met de audio al uitgeschreven.
Alleen de tweede is wat mensen bedoelen als ze zeggen dat een voice-agent traag aanvoelt. Opneemlatency gebeurt één keer aan het begin en bellers vergeven het, want een telefoon die overgaat en dan even stil is, doet dat al sinds jaar en dag. De tijd tot het eerste token is een echt getal, maar op een telefoonlijn is het één post van de acht, en wie die post los optimaliseert, knabbelt vijftig milliseconden af van een gat van meer dan een seconde.
Beurtlatency is het product, tokenlatency is een onderdeel
De keten, stap voor stap
Dit is wat er werkelijk gebeurt tussen het stilvallen van de beller en het opnieuw horen van een stem, bij een gewoon inkomend gesprek over een SIP-trunk met een klassieke keten van herkenning, model en synthese. Lees het als een budget en niet als een benchmark: de verhoudingen zijn de les, en elk van deze stappen is een plek waar een milliseconde zich kan verstoppen.
- Netwerk inkomend, plus jitterbuffer
- ~40 ms
- Beurtdetectie, voordat er iets gevraagd is
- vloer van 400 ms
- Spraakherkenning rondt af
- ~150 ms
- Model, tijd tot eerste token
- ~300 ms
- Spraaksynthese, eerste audiobyte
- ~150 ms
- Pakketisering en netwerk uitgaand
- ~40 ms
De getallen voor herkenning, model en synthese zijn de orde van grootte die aanbieders voor hun eigen onderdelen publiceren, en ze bewegen mee met de aanbieder die je kiest. De eerste en de laatste stap zijn netwerk. De tweede is de interessante, en die is de reden dat dit artikel bestaat: voordat er één byte bij je spraakherkenning aankomt, heeft je systeem al langer besteed aan de vaststelling dát de beller klaar was dan het model straks aan het antwoord besteedt.
caller stops speaking t+0
[rtp] last voiced packet arrives t+38ms (jitter buffer)
[vad] silence run starts t+38ms
[vad] silence threshold reached t+438ms <-- nothing has been asked yet
[turn] endpointing confirms turn end t+438ms (floor reached, dynamic)
[stt] final transcript emitted t+571ms
[llm] first token t+864ms
[tts] first audio byte t+1002ms
[rtp] first packet leaves t+1041ms
caller-perceived gap 1.04sDe 400 milliseconden vóór je model
Een voice-agent kan pas antwoorden als hij gelooft dat de beller is opgehouden met praten, en stilte is geen signaal dat binnenkomt. Het is de afwezigheid ervan, en de enige manier om die vast te stellen is wachten en kijken of ze aanhoudt. Elke milliseconde van dat wachten is dode lucht op de lijn, en ze wordt besteed voordat aan de keten ook maar iets gevraagd is.
Dit is een echte afweging en geen bug die je oplost. Kort je het wachten in, dan valt de agent mensen midden in hun gedachte in de rede en behandelt hij de pauze vóór een telefoonnummer als het einde van een zin. Rek je het op, dan krijgt het gesprek een vertraging waardoor elke wisseling aanvoelt als een satellietverbinding. Er is geen instelling die beide problemen laat verdwijnen, alleen een stand op een knop die past bij de gesprekken die je werkelijk voert.
Op onze eigen keten is het wachten begrensd in plaats van vast. Beurtdetectie draait in dynamische modus met een vloer van 400 milliseconden en een plafond van 2 seconden, zodat een duidelijk beurteinde snel wordt vastgelegd en een twijfelgeval de ruimte krijgt om af te ronden. Daaronder heeft de spraakdetectie 400 milliseconden aaneengesloten stilte nodig voordat ze een spraakreeks als afgelopen beschouwt, met een activatiedrempel van 0,4 en een minimale spraakduur van 50 milliseconden, zodat een kuch geen beurt opent.
Je stelt het gevoel van het product af, niet een configuratiebestand
Hoe die knop werkt, en hoe je voorkomt dat hij mensen afkapt, is een onderwerp op zichzelf. Dat hebben we apart uitgeschreven in barge-in die wel werkt, over waarom instellingen die op schone studio-audio zijn afgesteld het op een 8 kHz-telefoonlijn begeven.
Wat je niet kunt optimaliseren
Een deel van het budget is niet van jou. Klassieke telefonie levert audio als 8 kHz smalband, verpakt in frames van 20 milliseconden, en elke schakel die het aanraakt doet er iets bovenop. De jitterbuffer is de eerlijkste post: die houdt pakketten bewust vast zodat ongelijke aankomsttijden tot vloeiende audio kunnen worden gladgestreken. Maak hem kleiner en je ruilt vertraging in voor gaten en klikken. Het is vertraging die je bewust koopt, en dat kopen is de juiste keuze.
| Stap | Gebruikelijke orde | Zelf te veranderen? |
|---|---|---|
| Carrier en netwerktransport | 10 tot 40 ms per richting | Nee. Kies een carrier met verstandige routering en laat het daarbij. |
| Jitterbuffer | 20 tot 60 ms | Technisch wel, praktisch niet. Verkleinen levert je storingen in de audio op. |
| Codecafhandeling | Klein, maar omzetten kost een schakel | Ja, door aan beide kanten dezelfde codec af te spreken in plaats van om te zetten. |
| Beurtdetectie | 400 ms tot 2 s | Ja, en hier zit het geld. |
| Herkenning, model en synthese | Afhankelijk van de aanbieder | Ja, via je keuze van aanbieder en door te streamen in plaats van op te sparen. |
Zet je audio om tussen codecs omdat beide kanten het nooit eens zijn geworden, dan betaal je voor elk pakket van elk gesprek een extra schakel. Dat is het waard om op te lossen voordat je ook maar één model verandert.
De enige echte truc: stop met in serie wachten
Lees het budget nog eens en het structurele probleem springt eruit. Elke stap wacht netjes tot de vorige klaar is. Eerst rondt de spraakdetectie af, dan de herkenning, dan begint het model te lezen en pas daarna de synthese te spreken. Achter elkaar opgeteld levert een keten van op zichzelf redelijke getallen een onredelijk gat op.
De oplossing is niet om de stappen sneller te maken. De oplossing is om ze niet meer na elkaar te draaien. Herkenning kan deeltranscripties doorsturen terwijl de beller nog praat. Synthese kan de eerste deelzin al uitspreken terwijl het model de laatste nog schrijft. En je kunt het model laten beginnen aan een antwoord voordat het beurteinde formeel is vastgesteld, op de gok dat de beller echt klaar is, en dat is wat preëmptieve generatie op onze keten doet. Klopt de gok, dan ligt het antwoord al klaar. Klopt hij niet, dan wordt het concept weggegooid en heeft niemand iets gehoord.
- 01
Stuur deeltranscripties door in plaats van te wachten op een definitieve transcriptie
Een herkenner die tussentijds doorgeeft laat alles verderop in de keten eerder beginnen. Wachten op een definitieve transcriptie is veruit de meest voorkomende manier waarop teams hun keten per ongeluk in serie zetten. - 02
Begin de synthese bij de eerste deelzin, niet bij de laatste punt
De beller hoeft alleen het begin van de zin op tijd te horen. Een compleet antwoord opsparen voordat je er iets van uitspreekt zet modelvertraging rechtstreeks om in stilte. - 03
Genereer preëmptief tijdens het wachten op het beurteinde
Dat wachten is per definitie dode tijd. Die besteden aan een concept dat misschien wordt weggegooid kost tokens en koopt de duurste post uit het budget terug. - 04
Zeg iets terwijl een tool-aanroep loopt
Vraagt een antwoord om een opzoekactie, dan is de eerlijke oplossing niet een snellere opzoekactie maar een overbruggingszin, zodat de stilte wordt gevuld door de agent en niet door een beller die zich afvraagt of de lijn wegviel.
Speech-to-speech verandert de vorm, niet alleen de omvang
Een native-audiomodel hoort audio en antwoordt in audio zonder tekststap ertussen, waarmee herkenning, redenering en synthese tot één schakel worden samengetrokken. Dat haalt echte stappen uit het budget in plaats van ze in te korten, en daarom voelen realtime-modellen anders aan in plaats van alleen sneller.
Wat je erbij krijgt is een andere set beperkingen, geen gratis winst. Beurtdetectie verhuist naar de aanbieder, dus de knop die je aan het afstellen was is nu de zijne en bereikbaar via de instellingen die hij besluit je te geven. Een aantal dingen die je in een keten midden in het gesprek kon doen, kunnen niet meer. En de instructie waarmee je opent is bij sommige modellen de enige instructie die je het hele gesprek hebt. Die afweging beschreven we in de prompting-gids voor native-audio voice-modellen.
Minder stappen, minder controle
Je eigen budget doormeten
Niets van het bovenstaande is veel waard als gemiddelde. Latency is een verdeling, en bellers onthouden de staart: die ene wisseling op de twintig waarbij de agent drie seconden nodig had, is de wisseling die als kapot wordt omschreven. Een mediaan die er gezond uitziet kan een p95 verhullen die je gesprekken kost.
Het praktische beginpunt is correlatie en niet instrumentatie. Elk gesprek heeft een Call-ID die de signalering, de audio, de transcriptie en de logs aan elkaar knoopt. Pak een handvol gesprekken waarover een klant klaagde, leg de tijdstempels van elke stap langs die identifier, en de vorm van het probleem wordt meestal binnen een middag duidelijk: óf het gat zit vóór het model, en dan is het beurtdetectie, óf het zit erachter, en dan is het serialisatie.
Optimaliseer de stap waar de vertraging werkelijk zit. Vrijwel elk voice-team dat we spreken is het model aan het afstellen terwijl de beller op een stilteteller stond te wachten.
Over de getallen Het budgetbeeld is illustratief en samengesteld uit de orde van grootte die aanbieders voor hun eigen onderdelen publiceren, en is geen meting van VoiceDock; behandel de verhoudingen als het argument en meet je eigen totalen. De vloer van 400 milliseconden voor beurtdetectie, het plafond van 2 seconden, de vereiste van 400 milliseconden stilte, de activatiedrempel van 0,4 en het preëmptieve genereren zijn de waarden waarmee onze eigen keten draait. De mediane stilte van ongeveer 200 milliseconden in menselijke gesprekken is een breed gerepliceerde bevinding uit gespreksonderzoek in meerdere talen. Het gedrag van codecs, pakketisering en jitterbuffers volgt de gangbare telefoniepraktijk en is niet specifiek voor ons platform.
