Realtime evals voor voice: zo maak je van een demo iets waar je op kunt bouwen

Home
/
bloggen

Een voice demo kan in vijf minuten indruk maken. Maar zodra echte klanten gaan bellen, wordt het pas spannend. Dan blijkt vaak dat “lijkt prima” niet hetzelfde is als “werkt elke dag”. Evals zijn het verschil.

In deze gids leg ik uit hoe je voice systemen stap voor stap test, zonder jezelf gek te maken. Je begint klein met Crawl, je voegt realisme toe met Walk, en pas daarna ga je naar Run met meerdere beurten. Onderweg bouw je drie onderdelen die je nodig hebt om steeds beter te meten: een dataset, graders en een eval harness. En je zorgt dat fouten uit productie niet verdwijnen in een Jira ticket, maar terugkomen als nieuwe tests.

Waarom realtime evaluaties lastig zijn

Als je alleen tekst beoordeelt, kijk je vooral of het antwoord klopt. Bij voice beoordeel je een streaming gesprek. Daarin zijn er twee uitkomsten tegelijk: wat de assistent doet en hoe het klinkt. Het vervelende is dat die twee los van elkaar kunnen falen.

Ik heb systemen gezien die inhoudelijk precies deden wat je wilde, maar die toch onbruikbaar voelden omdat de audio hapert, omdat de timing vreemd is, of omdat de assistent de gebruiker steeds onderbreekt. Andersom kan het ook. Een mooie stem met een vriendelijk tempo die ondertussen de verkeerde tool aanroept of net een verkeerd nummer invult. Als je alles in één eindscore stopt, verstop je vaak het echte probleem.

De twee assen van kwaliteit: inhoud en audio

Bij realtime kwaliteit kun je meestal terug naar twee assen.

De eerste as is inhoud. Begrijpt het systeem de vraag en doet het daarna het juiste. Denk aan juistheid, behulpzaamheid, de keuze voor een tool, de argumenten die meegaan, en hoe goed instructies en regels worden gevolgd.

De tweede as is audio. Klinkt het acceptabel voor een mens die belt of een spraakbericht inspreekt. Dan gaat het om natuurlijkheid, intonatie, uitspraak, stabiliteit en gedrag onder minder fijne omstandigheden zoals ruis, galm of een goedkope microfoon.

Als je dit uit elkaar trekt in je metingen, wordt het ineens veel makkelijker om te verbeteren. Je hoeft dan niet meer te raden of een daling komt door ‘de AI’, terwijl het in werkelijkheid je audioketen is.

Waarom debuggen zonder logging je blind maakt

Bij een gewone tekstrequest is het modelbeeld simpel: request erin, response eruit. Bij realtime is één beurt een keten van events. Je krijgt bijvoorbeeld een start en stop van spraak, daarna commit je audio, je triggert response.create, je ontvangt audiodeltas, en uiteindelijk een done.

Als je dat als zwarte doos behandelt, ga je snel achter de verkeerde oorzaak aan. Audio die wordt afgekapt bij onderbreken voelt als een modelprobleem, maar is vaak een verkeerd ingestelde grens voor interruptie. Een antwoord dat goed is maar traag aanvoelt, komt geregeld door netwerk, turn detectie of buffering, niet door langzaam denken.

Mijn advies is altijd hetzelfde: log de stappen. Niet omdat het leuk is, maar omdat je anders aan het zoeken bent in het donker. Als je wilt snappen welke events je allemaal kunt verwachten, kijk dan ook in de documentatie van de Realtime server events: https://platform.openai.com/docs/api-reference/realtime-server-events.

Een transcript is handig, maar niet de waarheid

In realtime is de waarheid wat de microfoon heeft vastgelegd en wat het model daadwerkelijk hoorde. Een transcript is een interpretatie, meestal ook nog eens gemaakt door een model. Dat betekent dat het transcript soms afwijkt van de werkelijkheid.

Dat levert twee klassieke valkuilen op. De eerste is een valse fail. De transcriptie mist een cijfer, maar het systeem hoorde het wel en roept de juiste tool aan. Je grader markeert dan onterecht fout. De tweede is een valse pass. Het transcript ziet er netjes uit, maar de audio was geknipt of vervormd en het systeem gokte. Dan mis je het echte probleem.

Je kunt dit praktisch aanpakken. Werk aan betere transcriptie door te spelen met prompts en modellen, en kijk ook eens naar out of band transcriptie als je schaal zoekt. Gebruik transcripts vooral voor bulk scoring, maar kalibreer je graders op rommelige, productieachtige transcripts. En houd een audio audit loop aan. Als je één tot vijf procent van de sessies echt terugluistert met traces erbij, voorkom je dat je jezelf voor de gek houdt.

Crawl, Walk, Run: bouw complexiteit op zonder chaos

Veel teams beginnen te zwaar. Ze willen meteen echte audio, echte tools en een gesprek van tien beurten testen. Dan krijg je wel veel signalen, maar weinig houvast. Alles faalt tegelijk en niemand weet waarom.

Crawl, Walk, Run dwingt je om het klein te maken. Je start met tests die goedkoop zijn, herhaalbaar en goed te verklaren. Daarna voeg je realisme toe, en pas als de basis klopt ga je naar meerbeurts scenario’s. Dat klinkt trager, maar in de praktijk ga je sneller vooruit omdat je gericht kunt fixen en daarna ook echt kunt aantonen dat het beter is.

Eerste as van moeilijkheid: clean audio versus productieaudio

De eerste as gaat over wat het model hoort.

Bij Crawl wil je vaak synthetische audio, bijvoorbeeld via TTS. Dat geeft je herhaalbaarheid. Je test dan vooral intelligentie: intent routing, tool calling, argumenten, instructies.

Zodra dat stabiel is, schuif je richting productieaudio. Dan ga je bewust ruis, compressie, echo, far field opname, aarzelingen en zelfcorrecties meenemen. Dit is waar echte gebruikers zitten, zeker in klantenservice of telefonie. Hier meet je of iemand nog steeds correct wordt begrepen als het rommelig is. Een ordernummer, naam of tijdstip breekt sneller dan je denkt.

Tweede as van moeilijkheid: één beurt versus meerdere beurten

De tweede as gaat over wat je precies beoordeelt.

Met één beurt test je kerncompetentie. Je voert één gebruikersvraag in en je kijkt naar de volgende assistentreactie. Dat is de beste plek om toolkeuze, schema geldigheid en een goede verhelderende vraag te checken. Als dit al wankelt, heeft een lang gesprek geen zin.

Daarna pas ga je naar meerdere beurten. Dan test je of het systeem doelen en beperkingen vasthoudt, tools in de juiste volgorde aanroept, om kan gaan met toolfouten en netjes herstelt als de gebruiker zichzelf corrigeert. De lat verschuift dan van beurtcorrectheid naar uitkomst. Is het doel behaald, hoe veel beurten kostte het, en bleef het gesprek prettig.

Eén beurt vertelt je of je de strijd kunt winnen. Meerdere beurten vertellen je of je de oorlog kunt winnen.

De eval kwadranten: een eenvoudige kaart die rust geeft

Als je deze twee assen combineert, krijg je een twee bij twee kaart. Rechts wordt audio realistischer, omhoog wordt interactie realistischer. Begin linksonder en maak het pas moeilijker op één as tegelijk.

Crawl zit linksonder: synthetische audio en één beurt. Walk schuift naar rechts: realistische, vaak ruisachtige audio maar nog steeds één beurt. Run gaat omhoog: meerdere beurten, meestal met gesimuleerde user turns en deterministische toolmocks.

Rechtsboven, dus echte audio en een volledig gesprek zoals in productie, is meestal handmatige evaluatie. Dat blijft je nodig hebben, ook als je automatisering goed staat. Het is de plek waar je de dingen hoort en voelt die cijfers nog niet vangen.

Voorbeeld: “Zet mijn reservering naar 19.00 uur”

Een concreet voorbeeld maakt dit sneller tastbaar.

In Crawl voer je deterministische TTS audio in met die zin. Je grade alleen de volgende beurt. Roept het systeem de juiste reservering wijzig tool aan en geeft het tijd gelijk aan 19.00. Of stelt het één strakke vraag als er informatie ontbreekt, zoals de naam of datum.

In Walk neem je een echte opname op, bijvoorbeeld met een telefoon. Daarna speel je hem terug met telefooncompressie en lichte achtergrondruis. Je verwacht dat 19.00 nog steeds 19.00 blijft en niet verandert in 19, 19.15 of alleen 19.

In Run laat je een gesimuleerde gebruiker vervolgbeurten geven, zoals “Onder de naam Minhajul voor vanavond, nee wacht maak er 19.30 van, toch morgen”. Je injecteert ook een toolfout. Daarna kijk je of de assistent netjes verduidelijkt wat ontbreekt, state consistent houdt, herstelt na een fout en eindigt met één correcte wijziging die klopt met de laatste bedoeling van de gebruiker.

Data: bouw een benchmark waar je echt mee kunt werken

Evals staan of vallen met je dataset. Niet met omvang, maar met dekking.

Begin met een kleine gouden set, ergens tussen tien en vijftig voorbeelden. Kies daarin de flows die je je niet kunt permitteren om te missen. Denk aan je kernintents, must work tool calls, escalatie, en weigeren waar beleid dat vraagt. Genereer snel, laat mensen ernaar kijken, en accepteer dat de eerste versie niet perfect is.

Daarna bouw je voor iteratie. Het doel is een vaste loop: draaien, failures lokaliseren naar één gedrag, één wijziging doen, opnieuw draaien en controleren dat het beter is zonder bijwerkingen. Dat lukt alleen als je niet alleen positieve voorbeelden hebt. Voor elk gedrag wil je ook negatieve voorbeelden. Anders leert het systeem shortcuts.

Ik heb bijvoorbeeld teams gezien die keihard op escaleren trainden, met vooral cases waar escalatie gewenst was. Offline scoorden ze geweldig, maar in het echt escaleerden ze bijna alles zodra het even onzeker werd. Dat is geen modelmysterie, dat is datasetbalans.

Tot slot helpt tagging je om te snijden. Als je vastlegt wat de intent is, wat de verwachte uitkomst is, onder welke audioconditie, in welke taal, en welke toolcall je verwacht, kun je veel sneller zeggen waar het misgaat.

Laat productie je dataset groter maken

Offline evaluaties zijn snel en goedkoop, maar ze hebben één risico. Je kunt er te goed in worden. Dan stijgt je score, maar blijven echte gesprekken achter omdat je users dingen doen die niet in je set zitten.

De remedie is een eenvoudige flywheel. Productie breidt je benchmark uit. Elke nieuwe failure of bijna failure reproduceer je, je labelt hem, en je voegt hem toe.

In de praktijk werk ik graag met drie sets. Je regressiesuite bevat harde gevallen die ooit misgingen en nu niet meer mogen breken, die draai je bij elke prompt, model of toolwijziging. Je rolling discovery set bevat verse productiegevallen waar je nog van leert. En je holdout set blijft met rust, die draai je af en toe om te checken of je niet alleen beter wordt in je eigen toets.

Graders: je meetinstrumenten moeten je kunnen vertrouwen

Graders zijn niets meer en niets minder dan meetinstrumenten. Als ze structureel te streng of te soepel zijn, stuur je op de verkeerde dingen.

Handmatige review blijft het hoogste rendement leveren, zeker in het begin. Luister echte audio, lees de trace en kijk naar het hele verloop. Dit is waar je turn taking problemen hoort, awkward stiltes ziet, te snelle of te trage spraak opmerkt, en ontdekt dat transcriptie je op het verkeerde been zette. Het is ook de plek waar je merkt dat je evaluatieset gaten heeft.

Daarna wil je automatisering, want mensen schalen niet. Het helpt om in lagen te denken. Start met deterministische checks voor alles wat objectief is, zoals toolkeuze, JSON geldigheid en patroonchecks. Gebruik daarna een LLM grader met een rubric voor zaken als juistheid, instructies volgen en of een verhelderende vraag terecht was. En voeg audio checks toe, desnoods simpel in het begin, zoals lange stiltes, overlap en interruptiegedrag. De gebruiker ervaart de stem, niet je transcript.

De eval harness: maak runs vergelijkbaar, anders meet je ruis

Een goede harness heeft één taak: zorgen dat je runs vergelijkbaar zijn. Als hetzelfde inputmateriaal niet opnieuw kan worden afgespeeld onder dezelfde instellingen met ongeveer hetzelfde gedrag, dan kun je niet serieus meten.

Bij Crawl begin je met één beurt replay. Je bewaart precies dezelfde audiobytes, dezelfde preprocessing, dezelfde codec en dezelfde chunking. Vaak is het verstandig om VAD uit te zetten zodat jij de turn boundary bepaalt. Dan commit je direct na de laatste audiobrok en trigger je response.create.

Het proces is in de kern steeds hetzelfde. Je genereert of laadt audio, je streamt in vaste chunks, je commit, je triggert de respons, je verzamelt output zoals audiodeltas, transcript en toolcalls, en je grade en bewaart de resultaten.

Bij Walk verandert er één ding: je streamt opgeslagen, realistische audio in plaats van TTS. Daar moet je extra scherp zijn op preprocessing. Resampling, normalisatie, kanaalafhandeling en eventuele ruisonderdrukking moeten overeenkomen met productie, anders test je een andere wereld. En je streamingbeleid moet expliciet zijn. Als je latentie wil meten, stuur je chunks op vaste cadans, bijvoorbeeld elke twintig milliseconden. Als je vooral snel wil itereren, kun je sneller streamen, maar houd chunkgrootte gelijk.

Bij Run ga je naar multiturn simulatie. Dan werk je met een usersimulator die de volgende beurt schrijft, vaak op basis van wat de assistent net deed. Om dit vergelijkbaar te houden pin je de simulatorprompt en versieer je hem alsof het code is. Je beperkt randomness met vaste samplinginstellingen. En je mockt tools deterministisch met vooraf vastgelegde outputs. Bewaar de hele trajectory, elke user beurt, alle audiobytes die je streamde, toolcalls, toolreturns en timestamps. Als simulatie een echt failure patroon vindt, vertaal je dat terug naar een deterministische test voor Crawl of Walk.

Case: een klantenservice voice bot die je wel durft te laten bellen

Stel je bouwt een voice bot voor klantenservice. Het doel is simpel te zeggen maar lastig goed te doen. Veel vragen oplossen via tools, snel en veilig. De bot moet de juiste gegevens verzamelen, de juiste backendactie aanroepen, beleid volgen en netjes escaleren als het niet kan. En hij moet ook nog omgaan met frustratie zonder te gaan praten als een folder.

Met Crawl start je synthetisch en één beurt. Je test routing en beleid. Een korte vraag moet leiden tot de juiste intent, een gerichte vraag om ontbrekende info, of een weigering als het niet mag.

Met Walk ga je naar echte audio, liefst met telefoonkwaliteit en ruis. Dit is waar ordernummers, namen en adressen stuklopen. Je kijkt vooral of hij verheldert in plaats van gokken.

Met Run simuleer je complete workflows met toolmocks. Denk aan authenticatie, accountopzoek, orderstatus, retourgeschiktheid, refund, ticket aanmaken en escalatie. Je maakt de gebruiker realistisch lastig. Doelwijzigingen, half antwoord geven, door elkaar praten, of op een andere vraag reageren dan gesteld.

En je blijft handmatig luisteren in je lifecycle. Dat is waar je merkt dat disclaimers te lang zijn, dat hij herhaalt, of dat turn taking tijdens authenticatie stroef is.

Als je dit goed doet, heb je niet alleen een score. Je hebt een stuur. Dan kun je met een gerust hart wijzigingen doorvoeren, omdat je ziet wat er faalt, waarom het faalt, en of de fix ook echt helpt.

Neem contact op

Eerlijkheid staat voorop in mijn werk. Daarom zeg ik direct: ik ben niet de juiste partner voor jou als. Ik help je om jouw merk te transformeren van een fluistering naar een brul die niemand kan negeren.

Ik ben niet gebouwd om mee te doen, ik ben ontworpen om te domineren.

Contact Us