Voice agents
Voice agents voor vakmensen: case van een Tilburgse dakdekker
De officemanager van een Tilburgse dakdekker tikte vrijdagmiddagen lang werkbonnen over in Exact Online. Nu praten de ploegen, en staan de regels er 's ochtends.

Het is 17:42 op een donderdag in maart. Karin, officemanager bij een dakdekkersbedrijf met 34 man aan het Wilhelminakanaal in Tilburg, heeft een stapel van eenenveertig papieren werkbonnen voor zich liggen. Elke bon is een vochtig A5'tje met een gekrabbeld adres, een regel met EPDM 1,5 mm, 38 m², een paar gokken over uren, en een handtekening van een bewoner die de ploeg van het dak af wilde hebben voordat de regen terugkwam. Ze heeft tot maandagochtend om die stapel om te zetten in factuurregels in Exact Online, anders schuift de mei-facturatie op en begint de boekhouder pinnige mailtjes te sturen.
Dit is het bedrijf dat ons in februari inhuurde. Ze doen platdakrenovaties, vooral via verzekeringen, vooral binnen een straal van veertig kilometer. Omzet rond de 6,2 miljoen euro. Veertien bussen, zes ploegen van twee man, vier calculators, een voorman, Karin, en een directeur die al drie jaar dreigt een field-service SaaS te kopen en de knoop nooit doorhakte omdat elke offerte begon bij 18k aan setup en de ploegen vastzette in een tabletworkflow die ze toch nooit zouden gebruiken.
Wat we in plaats daarvan bouwden, is een voice agent. De ploegen praten negentig seconden in hun telefoon aan het eind van elke klus. Tegen de tijd dat Karin de volgende ochtend haar laptop opent, staan de regels in Exact Online, in conceptstatus, klaar om even na te lopen en vrij te geven. Hieronder lees je hoe het werkt, wat er stuk ging, en wat we anders zouden doen.
Waarom de papieren werkbonnen zo lang overleefden
Voor we bij de agent komen, is het goed om eerlijk te zijn over waarom het papieren systeem zo hardnekkig was. De ploegen haatten tablets. De vorige poging, een Nederlands field-service product waarvan we de naam niet door het slijk halen, had zes schermen per klus: kies klant, kies project, kies materiaal uit een dropdown van 1.400 SKU's, vul aantallen in, vul uren per man in, teken, sync. Op een winderig dak, met handschoenen aan, in februari, kom je daar niet doorheen. De exacte woorden van de voorman waren "ik ben dakdekker, geen datatypist". De tablets belandden in het dashboardkastje.
Papier werkte omdat er één interactiemodel was: schrijf iets op, wat dan ook, en geef het aan Karin. De prijs was dat Karin de integratielaag werd. Zij las het handschrift, zocht SKU's op, herstelde rekenfouten van de ploeg, en stemde af met de oorspronkelijke offerte. Drie tot vier uur per vrijdag, plus de paniek op maandagochtend als er een bon kwijt was.
Hoe de voice agent eruitziet
We hebben geen chatbot gebouwd. We bouwden iets dat dichter bij een dictafoon met één knop en een brein eraan zit. De ploeg opent een PWA die we op hun telefoons hebben gezet, tikt op een grote oranje cirkel, en praat. Geen formulier. Geen dropdown. De prompt die de ploeg in het oortje hoort is elke keer hetzelfde:
"Welke klus, welk adres, wat heb je gedaan, hoeveel materiaal, hoeveel uur per man. Praat gewoon."
Onboardingscript dat we met de voorman opnamen, 2026
Een typische opname duurt tussen de zestig en honderdtwintig seconden. Dit is hoe het klinkt, licht geanonimiseerd:
"Ja, dit is Mo, klus Van Goghlaan 14 in Goirle,
we hebben de hele achterdakkapel gedaan,
ongeveer tweeënveertig vierkante meter EPDM anderhalve mil,
drie rollen, twee tubes Bostik, één afvoer vervangen,
ik en Driss vier uur, schuif maar onder de offerte van
vorige week, die met die loodslab."
Die opname gaat door vier fases: transcriptie, extractie, matching, en posten. Elke fase is een aparte modelaanroep, want alles in één prompt proberen leverde zelfverzekerde hallucinaties op over SKU's die niet bestonden.
Fase 1: transcriptie
We gebruiken een Nederlands getunede Whisper-variant op een Hetzner GPU-box. Cloud-STT was aantrekkelijk, maar de ploegen mompelen, de wind raakt de microfoon, en het Brabantse accent eet de einden van woorden op. Een model dat we konden fine-tunen op onze eigen corpus van negentig opnames presteerde beter dan elke kant-en-klare API die we testten. Het Whisper-paper en de bijbehorende code is het logische startpunt als je dit zelf wil doen.
Fase 2: extractie
Het transcript gaat naar een LLM met een strikt JSON-schema. We laten het model geen velden verzinnen. Het schema is het hele contract:
{
"job_reference": "string | null",
"address_hint": "string | null",
"work_summary": "string",
"materials": [
{ "description": "string", "quantity": "number", "unit": "string" }
],
"labour": [
{ "worker_hint": "string", "hours": "number" }
],
"quote_link_hint": "string | null",
"confidence": "low | medium | high"
}
Het veld confidence is het belangrijkste. Alles onder high krijgt een vlag, zodat Karin er even naar kijkt voor vrijgave. We hebben de prompt twee weken bijgesteld tot het model eerlijk low ging zeggen als een ploeglid over een kettingzaag heen praatte, in plaats van te gokken.
Fase 3: matching
Dit is de fase die iedereen onderschat. "Drie rollen EPDM 1,5 mm" is geen factuurregel in Exact Online. Het moet SKU EPDM-150-RL20 worden, aantal 3, eenheid rol, prijs uit het lopende contract van de klant. We bouwden een kleine matching-service die de SKU-catalogus in Postgres houdt met een pg_trgm-index op de omschrijving, plus een vector embedding van de marketingnaam. De woorden van de ploeg worden ge-embed, top-k kandidaten komen terug, en een tweede LLM-aanroep kiest de juiste met de prijslijst in context.
Adres-hints worden gematcht tegen de lijst met lopende klussen. "Van Goghlaan 14 in Goirle" past bij een project waar al een offerte aan hangt, dus de nieuwe regels schuiven onder dat project. Komt er niks boven de 0,82 cosine similarity uit, dan gaat de klus naar een needs human queue. Die queue telt gemiddeld twee klussen per dag.
Fase 4: posten naar Exact Online
De REST API van Exact Online is prima zodra je accepteert dat de OAuth-token elke tien minuten verloopt en de rate limit je bijt zodra je iets probeert te backfillen. We posten conceptverkoopfactuurregels via de Exact Online REST resources, nooit met automatische finalisatie. Karin ziet elke ochtend een lijst concepten, gesorteerd op confidence, met de originele audioclip ingebed als afspeelknop. Eén klik om vrij te geven, één klik om terug te sturen voor verduidelijking.
Laat factuurconcepten niet automatisch finaliseren. Zelfs bij 98% extractienauwkeurigheid zijn de 2% die misgaan precies de regels die een klant twee jaar lang onthoudt. Houd een mens op de vrijgaveknop tot je zes maanden schone data hebt.
Wat er stuk ging in week één
De eerste productieweek was leerzaam. Drie dingen gingen stuk die we niet hadden voorzien.
Ten eerste namen de ploegen klussen in de bus op, op weg naar het volgende adres, met de radio aan. Sky Radio op 80 km/u is een verrassend vijandige akoestische omgeving. We voegden een check toe van dertig seconden voorgeluid en een vriendelijke duw in de PWA: "Te veel achtergrondgeluid. Even pauzeren?". De opnamekwaliteit ging gelijk omhoog.
Ten tweede was er één ploeglid, een oudere dakdekker met dertig jaar op het vak, die simpelweg weigerde. Hij wilde niet opnemen. De oplossing van de voorman was elegant: hij koppelde hem aan een jongere collega die in zijn plaats opnam en vertelde wat de oudere dakdekker had gedaan. De les is dat adoptie een sociaal probleem is, geen technisch, en dat we meer tijd hadden moeten steken in het kickoff-gesprek.
Ten derde begon het model materialen te verzinnen. Een ploeglid zei "en wat tape" en het model produceerde zelfverzekerd "Bostik flexibele afdichtingsband, 1 rol, 25m". We hadden geen terugvaloptie gegeven voor vage termen. De fix was een regel: als de hoeveelheid of eenheid ontbreekt in de audio, gaat de regel naar needs human, ongeacht de confidence score. De hallucinatiegraad op materialen zakte naar ongeveer één regel per tweehonderd.
De cijfers na tien weken
We hebben tien weken aan productiedata. De vrijdagmiddag van Karin ging van drie tot vier uur data invoeren naar zo'n vijfendertig minuten nakijken en vrijgeven. De mei-facturatie sloot op de woensdag van de week erna in plaats van op vrijdag. De cashinning schoof gemiddeld ongeveer negen dagen naar voren, wat op een boek van 6,2 miljoen euro echt geld is, zelfs bij een voorzichtige kapitaalkost.
De ploegen nemen ongeveer tweeënnegentig procent van de klussen op. De resterende acht procent zijn meestal hele korte bezoeken waar de ploeg de opname overslaat en Karin de regels uit de oorspronkelijke offerte trekt. Daar zijn we tevreden mee. Het doel was nooit honderd procent dekking, het was de vrijdagstapel om zeep helpen.
De winst zat niet in de AI. De winst zat in het schrappen van het formulier. De voice agent werkte omdat de ploegen al konden praten, en wij stopten met ze om iets anders te vragen.
Waar dit niet werkt
Een paar kanttekeningen voor wie dit klakkeloos wil overnemen. Deze opzet werkt omdat het bedrijf een strakke SKU-catalogus heeft, één ERP, en een officemanager die het bedrijf al door en door kende. Heb je drie werkmaatschappijen, een uitdijende productlijst, en niemand die een verkeerde regel in één oogopslag pakt, dan krijg je hetzelfde resultaat niet. De voice agent is een compressielaag tussen de werkvloer en de backoffice, en de backoffice moet nog steeds weten hoe "juist" eruitziet.
We willen ook eerlijk zijn dat dit geen toveren is. Er zijn reële doorlopende kosten. Whisper-inference, LLM-aanroepen, embeddings, de PWA, en de Exact Online sync landen bij elkaar rond de 380 euro per maand bij het huidige volume. Dat zit comfortabel onder de loonkosten die het verving, maar gratis is het niet, en het groeit met gebruik.
Wat we anders zouden doen
Als we opnieuw zouden beginnen, zouden we de needs human queue als eerste bouwen, vóór het gelukkige pad. In die queue wordt vertrouwen verdiend of verloren. We hebben de eerste sprint besteed aan de extractie zo goed mogelijk maken, en de tweede sprint aan een acceptabel beoordelingsscherm. Andersom was beter geweest.
We zouden de PWA ook overslaan en starten met WhatsApp-spraaknotities. De ploegen gebruiken WhatsApp toch al. De PWA gaf ons een schonere audiopipeline, maar kostte twee weken onboarding-wrijving. Voor de volgende aannemer met wie we praten, is WhatsApp-in, Exact-out de v1.
Toen we deze voice agent bouwden voor de Tilburgse dakdekker, was het ding waar we steeds tegenaan liepen dat elk kant-en-klaar field-service product wilde veranderen hoe de ploegen werkten. We hebben het opgelost door niets aan de ploegen te veranderen, en de hele structuurlast op het model en de queue erachter te leggen.
Wil je de kleinste versie hiervan vandaag proberen: kies één type klus, vraag één ploeglid om je een week lang aan het eind van de dag een spraaknotitie te sturen, en transcribeer ze met de hand. Lees de transcripten op vrijdag. Binnen een uur weet je of de structuur eruit te halen is, zonder dat je een regel code hebt geschreven.
Kern
De winst zat niet in de AI, maar in het schrappen van het formulier. De voice agent werkte omdat de ploegen al konden praten, en wij stopten met ze om iets anders te vragen.
FAQ
Waarom niet vanaf dag één gewoon WhatsApp-spraaknotities gebruiken?
Kan prima. Wij gebruikten een PWA voor schonere audio en een UX met één knop, maar voor een v1 levert een WhatsApp-nummer dat doorprikt naar Whisper en Exact Online je in een week 80% van de waarde.
Hoe nauwkeurig is de extractie in de praktijk?
Na tuning stroomt ongeveer 92% van de klussen direct door naar conceptfactuurregels. De andere 8% komt in een beoordelingsqueue. Materiaalhallucinaties zitten op zo'n 1 op 200 regels.
Wat kost dit per maand om te draaien?
Rond de 380 euro bij het huidige volume van de aannemer: Whisper-inference op een Hetzner GPU, LLM-aanroepen voor extractie en matching, embeddings, de PWA, en de Exact Online sync.
Stuurt het automatisch facturen naar klanten?
Nee. Alles landt als concept in Exact Online. De officemanager kijkt het na en geeft vrij. We raden sterk af om de eerste zes maanden automatisch te finaliseren.
Werkt het in het Nederlands met regionale accenten?
Ja, maar pas na fine-tuning. Kant-en-klare cloud-STT had moeite met het Brabantse accent en windgeruis. Een Nederlands getunede Whisper-variant op onze eigen corpus presteerde beter dan elke API die we testten.