Cum funcționează un apel
Un tur dintr-o conversație vocală trece prin șapte etape. Fiecare are culoarea ei, iar culoarea e aceeași peste tot unde apare — în diagrama de aici, în bara de latență din workbench-ul asistentului, în timeline-ul apelului și în tab-ul de metrici — așa că după o zi de folosit CallAgent culoarea devine eticheta și nu mai citești cuvântul.
Apelantul simte un singur număr: pauza dintre momentul în care își termină propoziția și prima silabă a răspunsului. Tot ce urmează există ca să facă pauza aia mică și ca să îți spună ce etapă a consumat-o.
Etapele
transport — sosește audio-ul
Un media stream Twilio, un canal FreeSWITCH de pe trunk-ul tău SIP sau o sesiune WebRTC dintr-un browser. Sunt definite șase transporturi (twilio_media_stream, telnyx_media, freeswitch_esl, websocket, webrtc, sip) și toate se normalizează în același format intern înainte să ruleze orice altceva: PCM mono la 16 kHz. G.711 µ-law/A-law și Opus sunt transcodate la margine, în packages/audio, așa că un trunk de carrier la 8 kHz și un browser la 48 kHz întâlnesc un pipeline identic.
Se măsoară ca transport_connect_ms și call_setup_ms.
Doar două din șase duc azi un apel real
Un media stream Twilio funcționează. O sesiune WebRTC din browser funcționează pentru audio și barge-in. Calea FreeSWITCH — și deci orice trunk SIP — moare la predarea media, iar Telnyx nu are niciun constructor de media stream, deși declară capabilitatea. Vezi Ce nu este construit.
stt — vorbirea devine text
Transcriber-ul trimite ipoteze parțiale în timp ce apelantul vorbește. În contracte sunt definiți paisprezece furnizori (deepgram, assemblyai, speechmatics, gladia, soniox, azure, google, openai, openai_realtime, elevenlabs, cartesia, talkscriber, xai, custom). Treisprezece au adaptor în gateway; trei au un format de fir revizuit. Vezi Furnizori.
Un transcriber pentru care gateway-ul nu are adaptor invalidează toată configurația apelului, nu doar câmpul acela — de asta validate îl refuză la publicare.
stt_first_partial_ms e metrica relevantă aici, iar ținta platformei pentru ea e 300 ms.
endpoint — decizia că a terminat de vorbit
E etapa la care nu se așteaptă nimeni și pe care o simte toată lumea. Dacă răspunzi prea devreme vorbești peste apelant; dacă răspunzi prea târziu asistentul pare lent și prost. CallAgent o tratează ca pe o configurație, nu ca pe o constantă — vezi Preluarea turului și barge-in pentru planuri, valori implicite și de ce maxWaitMs e de 20 de secunde, nu de trei.
Există cinci strategii: provider, vad_timeout, punctuation, semantic și hybrid, care e implicită. Fiecare detecție emite un eveniment endpoint.detected care poartă strategia care s-a declanșat și tăcerea care a declanșat-o.
llm — modelul gândește
Conversația de până acum, system prompt-ul, variabilele rezolvate, definițiile de tools și knowledge-ul regăsit merg la model. Sunt definiți optsprezece furnizori de model, șaptesprezece au adaptor și treisprezece au un format de fir revizuit. custom_llm acceptă un endpoint compatibil OpenAI, al tău.
Se trimit doar ultimele context_window_messages mesaje — implicit 60.
Se rețin separat două numere, iar diferența contează: llm_ttft_ms (timpul până la primul token, țintă 600 ms) e ce simte apelantul, pentru că sinteza pornește pe prima propoziție, nu pe ultima. llm_total_ms e ce ți se facturează.
numFastTurns și fastModel nu fac nimic
Ar trebui să trimită primele tururi ale apelului către un model mai mic. Gateway-ul nu citește niciunul dintre ele. Fiecare tur folosește model.model. Vezi Ce nu este construit.
tool — modelul acționează
Dacă modelul emite un apel de tool, turul se oprește aici. Tool-ul poate fi un request HTTP către API-ul tău, o interogare de knowledge, un transfer, o secvență DTMF, un handoff către alt asistent, un apel într-un server MCP sau o funcție executată chiar în browserul vizitatorului. messages configurate pe tool sunt rostite cât rulează, așa că apelantul aude „stai să verific" în loc de tăcere.
Mărginit de maxToolIterations (implicit 5) și de timeoutSeconds al tool-ului (implicit 20). Se măsoară ca tool_latency_ms, mcp_latency_ms și knowledge_latency_ms.
tts — textul devine vorbire
Sinteza e tăiată în bucăți, și de asta un răspuns începe înainte ca modelul să termine de scris. Chunker-ul rupe fluxul de tokeni la granițe de propoziție și de frază: prima bucată poate să rupă după 12 caractere, cele de după după 60, iar un plafon dur de 240 de caractere forțează ruperea la ultimul spațiu, cu graniță sau fără. Un rând nou e mereu o graniță.
Furnizorii care acceptă text incremental țin un singur socket deschis pe tot turul; restul primesc un request per frază.
Chunker-ul nu e configurabil
voice_formatting de pe un asistent devine chunkPlan din contract, iar gateway-ul nu îl citește niciodată. Numerele de mai sus sunt valorile implicite din cod și nu există niciun câmp care să le schimbe.
tts_ttfa_ms — timpul până la primul audio — are ținta de 400 ms. Sunt definiți nouăsprezece furnizori de voce, șaisprezece au adaptor, iar doi — ElevenLabs și OpenAI — au un format de fir revizuit. Niciunul nu a fost rulat pe un vendor live în CI.
playback — apelantul aude
Audio-ul e trimis înapoi pe transport în timp real, și exact de aceea barge-in-ul e posibil: în buffer există mereu audio nerostit care poate fi aruncat în clipa în care apelantul începe să vorbească.
Numărul care contează
| Metrică | Etapă | Țintă |
|---|---|---|
transport_connect_ms | transport | — |
stt_first_partial_ms | stt | 300 ms |
llm_ttft_ms | llm | 600 ms |
tts_ttfa_ms | tts | 400 ms |
endpoint_to_audio_ms | cap-coadă | 1200 ms |
barge_in_stop_audio_ms | întrerupere | 120 ms |
endpoint_to_audio_ms e singura pe care apelantul o percepe direct: din clipa în care se declanșează endpointing-ul până când primul eșantion audio al răspunsului pleacă din gateway. Cele cinci ținte sunt definite o singură dată, în LATENCY_TARGETS_MS din @callagent/contracts, iar dashboard-ul colorează un tur față de ele.
În total se rețin douăzeci și patru de nume de metrici — lista completă e CallMetricName din pachetul de contracte, iar GET /calls/{call}/metrics le întoarce per tur.
Citește un apel real
Fiecare dintre etapele astea apare, cronometrată și colorată, în timeline-ul apelului: GET /calls/{call}/events pentru fluxul brut, GET /calls/{call}/metrics pentru numere, sau tab-ul Timeline al unui apel din dashboard.
Speech to speech
În principiu, unui model i se poate da audio-ul direct, sărind peste etapele stt și tts. Sunt definiți patru furnizori realtime (openai_realtime, google_realtime, elevenlabs_realtime, custom_realtime), iar asistentul are un câmp speech_to_speech_model pentru asta.
Asta nu rulează
Sesiunea live de apel nu citește niciodată speech_to_speech_model. În arbore există un pipeline de speech-to-speech complet, cu teste unitare, și nimeni nu construiește vreodată unul. Un asistent configurat pentru el rulează pipeline-ul obișnuit transcriere → model → sinteză și raportează metricile obișnuite.
Doar unul dintre cei patru furnizori are, în general, un adaptor. Vezi Ce nu este construit.
Ce se întâmplă în jurul turului
Înainte de primul tur, gateway-ul cere control plane-ului o configurație de apel: snapshot-ul înghețat al asistentului, credențialele rezolvate, lista de servere MCP, limitele (durată maximă, număr maxim de apeluri de tools, concurență rămasă, secunde de credit) și destinația de storage pentru înregistrări. Nimic din request-ul acela nu se repetă în timpul apelului.
După ultimul tur, apelul e finalizat: slotul de concurență se eliberează, transcrierea se asamblează, artefactele se stochează și se calculează costurile pe componente. Vezi Apeluri și artefacte.
Mai departe
- Preluarea turului și barge-in — planurile de endpointing în detaliu.
- Stările și evenimentele apelului — cele 17 stări și 60 de tipuri de eveniment.
- Furnizori și fallback-uri — cum alegi ce umple fiecare etapă.