Terug naar Insights
Technologie

Waarom gesprekken van voice-agents mislukken: de SIP-logs lezen

Een dashboard dat 'fout' zegt vertelt je niets. De vier lagen waarop een telefoongesprek faalt, de SIP-responscodes en Q.850-oorzaken die de oorzaak benoemen, en een triagevolgorde die convergeert in plaats van gokt.

J

Jesper Rietbergen

CEO/CTO, VoiceDock

Gepubliceerd July 30, 2026
13 min leestijd

Een beller zegt dat hij gebeld heeft en dat het niet werkte. Je dashboard zegt dat het gesprek eindigde met een fout. In die twee zinnen zit het hele probleem: ergens tussen de telefoon van de beller en jouw agent kunnen zeven dingen misgaan, en één woord in een dashboard kan niet vertellen welke. Het antwoord staat bijna altijd in de SIP-dialoog, één laag onder het niveau waar de meeste voice-AI-platformen je laten kijken.

Vier lagen, en slechts één ervan is de AI

Wie een voice-agent debugt grijpt eerst naar de prompt, want dat is het deel dat hij zelf geschreven heeft. Maar een telefoongesprek is een stapel, en het model zit daar bovenin. Onder de agent zit een orchestratielaag die bepaalt welke assistent opneemt en die de sessie vasthoudt. Daaronder zit SIP, het signaleringsprotocol dat het gesprek opzet, uitonderhandelt welke audio beide kanten spreken, en het weer afbreekt. En daaronder, over een compleet eigen route, gaat de media: de RTP-pakketten die de stem dragen.

Die laatste scheiding is het nuttigste dat je je eigen kunt maken. Signalering en media reizen apart. Een gesprek kan op SIP-niveau perfect verbonden zijn terwijl er geen enkele audio loopt, en dat is precies waarom "het gesprek kwam op maar de agent zei nooit iets" een mediaprobleem is en geen promptprobleem. Negentig procent van de verwarring bij het debuggen van voice AI komt doordat de ene stapel wordt behandeld als de andere.

De regel

Repareer de laag waar het symptoom woont

Beller hoort helemaal niets: media. Gesprek wordt direct geweigerd: signalering. Agent neemt op maar zegt het verkeerde: model. Agent neemt op en valt halverwege stil: meestal geen van beide, dan is het de sessie. Door de lagen heen gokken is hoe een reparatie van een kwartier er een van twee dagen wordt.

Hoe een gezond gesprek er in SIP uitziet

Voordat je een kapotte dialoog kunt herkennen moet je weten hoe een intacte leest. Een inkomend gesprek is een kort en uitermate voorspelbaar gesprek tussen de carrier en jouw platform. De carrier biedt het gesprek aan met een INVITE, met daarin een SDP-blok dat opsomt welke codecs hij kan spreken. Jouw kant bevestigt, laat rinkelen, neemt op met 200 OK en zijn eigen SDP, en beide kanten beginnen RTP te sturen. Hangt iemand op, dan sluit een BYE het af met een reden.

inkomend-gesprek.sip.log
>> INVITE sip:+31570238200@trunk SIP/2.0
   From: <sip:+31612345678@carrier>;tag=8f2b
   Call-ID: 4c1d9e77-3a2f-4b10-9c8e-11e2a6d0f5aa
   SDP: audio 41002 RTP/AVP 8 0 101   (PCMA, PCMU, telephone-event)

<< SIP/2.0 100 Trying
<< SIP/2.0 180 Ringing
<< SIP/2.0 200 OK
   SDP: audio 24518 RTP/AVP 8 101     (PCMA agreed)

   [rtp] inbound  stream established   ssrc=0x6b21f0
   [rtp] outbound stream established   ssrc=0x11c4ae

>> BYE sip:+31570238200@trunk SIP/2.0
   Reason: Q.850;cause=16;text="normal clearing"

   call ended · 47.2s · two-way audio · caller hung up

Vier dingen in dat spoor zijn het aanwijzen waard. De Call-ID is de greep die elk pakket, elke logregel en elke opname van dít ene gesprek aan elkaar knoopt, en het is het eerste dat je opvraagt als een klant een probleem meldt. De SDP-regels laten een geslaagde codec-onderhandeling zien: de carrier bood PCMA, PCMU en telephone-event aan, en jouw kant koos PCMA. De twee RTP-regels bevestigen audio in beide richtingen, elk met zijn eigen synchronisatiebron. En de BYE draagt een Q.850-oorzaak, waarmee het telefonienetwerk je in een standaardnummer vertelt waarom het gesprek eindigde.

De responscodes die een storing verklaren

Overleeft een gesprek de opzet niet, dan is de SIP-responscode de diagnose. De meeste voice-platformen persen die allemaal samen tot "mislukt", en gooien daarmee precies de informatie weg waaruit je had kunnen opmaken van wie het probleem is. Dit zijn de codes die je op echte trunks daadwerkelijk tegenkomt.

CodeBetekentVan wie is het
403 ForbiddenDe trunk weigert het verzoek meteen, meestal een IP dat niet op de toegangslijst staat, of inloggegevens die niet kloppen.Configuratie
404 Not FoundHet nummer bestaat niet op die trunk. Vaak een routeringsregel die nooit is aangemaakt, of een nummer dat is weggeporteerd.Carrier / routering
407 Proxy Authentication RequiredRegistratie of digest-authenticatie komt niet rond. Normaal als eerste uitdaging; een probleem als het zich herhaalt.Configuratie
408 Request TimeoutNiemand reageerde op de signalering. Vaak een firewall die SIP stil laat vallen, niet een bezette lijn.Netwerk
480 Temporarily UnavailableDe juiste plek bereikt, maar geen eindpunt beschikbaar. Op een AI-trunk betekent dit vaak dat geen worker de sessie oppakte.Platform
486 Busy HereEen echte in-gesprektoon, of een plafond op gelijktijdige gesprekken. Check je eigen limieten voor je de carrier de schuld geeft.Platform / capaciteit
487 Request TerminatedHet gesprek werd geannuleerd voordat het werd opgenomen: de beller hing op tijdens het rinkelen. Geen storing.Niemand
488 Not Acceptable HereCodec- of SDP-mismatch. Beide kanten wilden praten en werden het niet eens over hoe. Stil, direct, en nooit de schuld van het model.Configuratie
503 Service UnavailableDe andere kant leeft maar weigert werk: congestie, een storing bij de carrier, of een component verderop die nee zegt.Carrier / platform
Codes zoals vastgelegd in RFC 3261 en de uitbreidingen daarop. De kolom 'van wie is het' is onze eigen triage-steno, geen onderdeel van de standaard.

De 488 verdient een eigen alinea, want het is de storing die het meest op magie lijkt. Hier hetzelfde gesprek, aangeboden met een codec die de trunk niet mocht accepteren:

codec-mismatch.sip.log
>> INVITE sip:+31570238200@trunk SIP/2.0
   SDP: audio 41002 RTP/AVP 9 101     (G.722, telephone-event)

<< SIP/2.0 100 Trying
<< SIP/2.0 488 Not Acceptable Here
   Warning: 304 "Media type not available"

   call never connected · 0.4s · no RTP · no transcript

Vierhonderd milliseconden, geen audio, geen transcript, niets wat het model verkeerd gedaan kan hebben. Vanuit een dashboard dat alleen eindredenen rapporteert is dit niet te onderscheiden van een dozijn andere storingen. Vanuit de SIP-dialoog is het een reparatie van vijf minuten in de codeclijst van de trunk.

Eén code verdient vermelding juist omdát hij nooit bij een storing opduikt: OPTIONS. Het is helemaal geen fout, het is een keepalive: een klein periodiek verzoek dat als enige taak heeft de andere kant te vragen of hij er nog is. Zet je OPTIONS-pings aan op een trunk, met een interval in de orde van dertig seconden, dan verandert "leeft de trunk nog" van een vraag die je tijdens een storing beantwoordt in een grafiek waar je vóór een storing naar kunt kijken. Het houdt bovendien NAT-bindingen warm, wat stil een categorie eenrichtingsaudio-storingen voorkomt die hieronder wordt beschreven. Het is de goedkoopste monitoring in de telefonie en hij staat bijna overal standaard uit.

Q.850-oorzaakcodes die je uit je hoofd wilt kennen

Waar SIP het verzoek beschrijft, beschrijft Q.850 wat het telefonienetwerk ervan vond. Oorzaakcodes komen binnen in de Reason-header op een BYE of een CANCEL, en ze overleven het oversteken van gateways. Daardoor dragen ze vaak de waarheid, ook als de SIP-code ergens onderweg is herschreven.

OorzaakStandaardbetekenisWat het in de praktijk meestal is
1Niet-toegekend nummerHet gedraaide nummer bestaat niet. Bij uitbelcampagnes is dit een datakwaliteitsprobleem, geen platformprobleem.
16Normaal beëindigdEen normale beëindiging van het gesprek. Zie je dit bij een gesprek waarvan de klant zegt dat het mislukte, dan zat de storing in de audio, niet in het gesprek.
17Gebruiker in gesprekEcht bezet, of een toestel dat een tweede gesprek weigert.
19Geen antwoord van gebruikerHet is overgegaan. Controleer je beltijd voordat je aanneemt dat het nummer dood is.
21Gesprek geweigerdIets zei actief nee: een blokkeerlijst, een spamfilter, of beleid van de carrier op de bestemming.
34Geen circuit beschikbaarCapaciteit, verderop in de keten. Hier is opnieuw proberen zinvol; hard falen niet.
38Netwerk buiten dienstEen echte storing verderop. Dit is de code waarbij je eerst de statuspagina van de carrier opent.
41Tijdelijke storingDe vaagste nuttige code. Bijna altijd één keer opnieuw proberen waard.
102Herstel na verlopen timerIets antwoordde niet op tijd en een timer gaf op. Wijst op latency of een vastgelopen tak, niet op een weigering.
127Interworking, niet gespecificeerdEen gateway heeft iets vertaald en de oorspronkelijke reden verloren. Behandel als 'geen informatie beschikbaar'.
Oorzaakwaarden uit ITU-T Q.850. De rechterkolom is onze praktijklezing, niet de standaard.

Eenrichtingsaudio: de klassieker die nooit het model is

De meest voorkomende serieuze klacht bij elke nieuwe voice-uitrol is dat de ene kant de andere niet hoort. De beller hoort de agent prima en de agent doet alsof de beller niets zei, of precies omgekeerd. Het presenteert zich als een AI-storing en het is bijna nooit een AI-storing.

Omdat media over een eigen route gaat, werkt audio alleen als RTP beide eindpunten in beide richtingen kan bereiken. Signalering kan over de ene route wél aankomen terwijl de mediaroute geblokkeerd is, en niets in de SIP-dialoog zal klagen. De gebruikelijke daders zijn voorspelbaar: een firewall die de SIP-poort toestaat maar het RTP-bereik niet, netwerkadrestranslatie die een adres binnen de SDP herschrijft zodat de andere kant pakketten het niets in stuurt, of verwachtingen rond symmetrische RTP waar één kant zich niet aan houdt.

De diagnose is mechanisch, niet slim. Kijk naar de pakkettellers per richting afzonderlijk. Komt inkomende RTP wel binnen en is uitgaand nul, dan heb je een routerings- of filterprobleem op de weg naar buiten, geen transcriptieprobleem. Zijn beide tellers gezond en doet de agent nog steeds alsof hij stilte hoorde, dan pas wordt het een spraakherkenningsvraag.

Waarom dit commercieel uitmaakt

Dit is de laag waar een doorverkoper niet komt

Is je voice-leverancier een omhulsel om het platform van iemand anders, dan valt deze hele paragraaf buiten zijn bereik. Hij kan een statusveld lezen en een supportticket openen. Hij kan geen RTP-tellers op de trunk bekijken, want de trunk is niet van hem. Op een telefoonlijn waar een bedrijf van afhankelijk is, bepaalt dat verschil of een storing twintig minuten duurt of drie dagen.

Als de toetsdruk niet aankomt

Een beller wordt gevraagd 1 te toetsen, toetst 1, en er gebeurt niets. DTMF, de tonen die een toetsenblok maakt, kan op drie verschillende manieren reizen, en een mismatch daartussen is geruisloos. De toon kan als eigen RTP-payloadtype meereizen zoals beschreven in RFC 4733 en zijn voorganger RFC 2833, en dat is wat de telephone-event in de SDP hierboven aankondigt. Hij kan als gewone audio worden meegestuurd, gemengd in de spraakstroom, wat minder tussenstappen overleeft dan mensen verwachten. Of hij kan buiten de mediastroom om worden gestuurd als een SIP INFO-bericht.

Luistert jouw kant naar RTP-events terwijl de carrier tonen in de audio meestuurt, dan zit de toetsdruk fysiek in het geluid en is hij volledig onzichtbaar voor je applicatie. Stel eerst vast welke van de drie daadwerkelijk in gebruik is voordat je iets in de agent aanraakt, en onderhandel bij voorkeur telephone-event in de SDP, zodat de toon aankomt als een losse gebeurtenis en niet als een geluid dat je moet detecteren.

Waarom je eindreden geen diagnose is

Goede platformen geven je per gesprek een deterministische eindreden. Op VoiceDock sluit elk gesprek af met één uit een vaste verzameling: de beller hing op, de assistent hing op, het gesprek is doorverbonden, de maximale duur is bereikt, er is voicemail gedetecteerd, niemand nam op, het krediet was op, of er trad een fout op. Die verzameling is oprecht nuttig voor rapportage, want je kunt uitkomsten tellen zonder vrije tekst te ontleden.

Wat een eindreden niet kan, is een storing verklaren. "Fout" is een categorie, geen oorzaak. De waarde van het bezitten van de laag eronder is dat er, als de categorie niet genoeg is, een volgende vraag te stellen valt: welke SIP-code, welke Q.850-oorzaak, in welke richting ontbrak de RTP, welke Call-ID. Een platform dat stopt bij de eindreden heeft die volgende vraag per ontwerp onbeantwoordbaar gemaakt.

De eindreden vertelt je wat er met het gesprek gebeurde. De SIP-dialoog vertelt je waarom. Je hebt een leverancier nodig die je beide kan overhandigen.

Een triagevolgorde die wél convergeert

Telefonie slecht debuggen betekent vijf dingen tegelijk openzetten. Het goed doen betekent vragen stellen in een volgorde die de zoekruimte elke keer halveert. Dit is de volgorde die wij gebruiken.

  1. 01

    Haal de Call-ID op voor je iets anders doet

    Al het andere is gokwerk zonder. Een tijdstip en een bellernummer volstaan als de klant niets anders heeft, maar de Call-ID maakt van een verhaal een registratie.
  2. 02

    Stel vast of het gesprek überhaupt tot stand kwam

    Een 200 OK splitst het probleem netjes. Geen 200 OK betekent dat de storing in de opzet zit en de responscode hem benoemt. Wel een 200 OK betekent dat de opzet werkte en je doorschuift naar media.
  3. 03

    Controleer RTP per richting afzonderlijk

    Twee tellers, niet één. Stilte in slechts één richting is een netwerk- of NAT-probleem, en het is de meest waarschijnlijke oorzaak van "de agent negeerde mij".
  4. 04

    Lees de afsluitende oorzaak, niet alleen de status

    Een Q.850-oorzaak 16 bij een gesprek waarvan de klant zegt dat het mislukte is een sterk signaal: het gesprek was in orde en de ervaring niet. Dat wijst naar audiokwaliteit, latency of de agent, en weg van telefonie.
  5. 05

    Open nu pas het transcript en de prompt

    Kwam de opzet rond, liep de audio beide kanten op en sloot het gesprek normaal af, dan en alleen dan is het een model- of instructieprobleem, en heb je vier lagen ruis uitgesloten voordat je daar tijd in stopt.

Niets hiervan is exotische kennis. Het is gewone telefonie-engineering, en het is precies wat verdwijnt als een voice-platform het telefoonnetwerk behandelt als een implementatiedetail dat je niet mag zien. Wij publiceren het omdat de vraag niet is of gesprekken op een echt netwerk soms mislukken. Dat doen ze. De vraag is of de mensen met wie je bouwt je kunnen vertellen waarom.

Bronnen Responscodes en dialooggedrag zoals vastgelegd in RFC 3261 (SIP), DTMF-transport in RFC 4733, en oorzaakwaarden uit ITU-T Q.850. De triagevolgorde en de praktijklezingen komen uit onze eigen ervaring met voice-verkeer op productie-trunks.