← Blog

Chat agents

Verzuim-intake chat agent: een Leuvense case study

Maandagochtend 7:45 in Leuven. Tachtig telefoontjes in de wachtrij. Negen maanden later draait één chat agent 1.260 verzuim-meldingen per week in NL en FR.

Jacob Molkenboer· Oprichter · A Brand New Company· 13 jun 2026· 8 min
Antieke koperen bureaubel, gevouwen papierstrook met groen lint, ivoren kaart met rood zegel op linnen vloei.

Het is 7:45 op een maandag in Leuven. De intake-balie van een arbodienst heeft tachtig telefoontjes in de wachtrij en drie mensen aan de lijn. Om 09:30 piekt de rij op 220. Elk gesprek heeft dezelfde vorm: naam, werkgever, soort klacht, hoe lang, wanneer kunnen we een terugkeer verwachten. Elk gesprek eindigt met een samenvatting die in Humannet moet landen, het verouderde verzuim-managementsysteem dat de dienst sinds 2013 gebruikt, en dat moet gebeuren vóór de eerste koffie van de werkgever.

Negen maanden draaien we nu een intake chat agent die de eerste golf van die wachtrij opvangt. Hij doet 1.260 gesprekken per week in Nederlands en Frans. Gemiddelde tijd van ik wil mij ziekmelden tot een schone, Arbowet-conforme samenvatting in Humannet: 47 seconden, p95 op 71 seconden. Het intake-team ging van 11 naar 4. Niemand werd ontslagen. Zeven mensen schoven door naar casemanagement voor de langlopende dossiers, waar ze sowieso al wilden zitten.

Zo werkt die agent, dit zijn de stukken waar we over hebben moeten ruziën, en de onderdelen die het project bijna omver hebben getrokken.

De vorm van de wachtrij vóór de agent

De dienst heeft 36 medewerkers en zo'n 700 klant-werkgevers, verspreid over Vlaanderen en de zuidelijke Randstad. Hun werknemers melden zich ziek via drie kanalen: een telefoonnummer, een webformulier en een e-mailadres dat niemand naar eigen zeggen leest. Het telefoonnummer was goed voor 71% van het volume. Het webformulier 22%. Mail 7%, en bijna gegarandeerd te laat.

De structuur van een verzuim-melding verandert niet. Je hebt de naam en het BSN of rijksregisternummer van de melder nodig, de werkgever, het type melding (eerste dag, vervolg, betermelding), de klacht in eigen woorden, een geschatte duur, en een flag als er aanwijzingen zijn voor een psychosociale oorzaak. De Arbowet voor Nederlandse werkgevers en de Codex over het welzijn op het werk voor Belgische willen diezelfde velden, met iets andere namen, op dezelfde dag.

Vóór de agent stelden intake-medewerkers deze vragen in een vaste volgorde, tikten de antwoorden in een zelfgebouwde web-app, en typten daarna ongeveer 60% ervan over in Humannet, omdat de export-connector in 2019 stuk was gegaan en niemand de eerste wilde zijn om dat te repareren.

Waarom de taallaag eerst moest

Leuven ligt dicht genoeg bij de taalgrens dat ongeveer 18% van de bellers Frans als eerste taal heeft. Tot de agent kwam, werd dat opgelost door elke Franstalige beller door te zetten naar één van twee Waalse medewerkers. Beide stonden op het punt om op te stappen, want ze deden 40% van het Franse volume met 18% van de bezetting.

Het eerste wat we bouwden was niet de agent. Het was een kleine classifier die luistert naar de eerste drie berichten van de gebruiker, de taal kiest en het gesprek vastzet. Nederlands en Frans liggen ver genoeg uit elkaar dat dit op tokenniveau bijna geen probleem is. Het echte werk zat bij Brusselse bellers die midden in een zin wisselen. We hebben taal behandeld als een sessievariabele, niet als een turn-variabele: eenmaal vastgezet, blijft de agent. Vraagt de melder expliciet kan ik in het Frans verder, dan zetten we opnieuw vast.

We hebben het LLM de taal niet op gevoel laten kiezen. De classifier is een deterministisch fastText-model met een vertrouwensondergrens. Onder die grens vraagt de agent, in beide talen: Liever Nederlands of Frans? / Néerlandais ou français? Die ene vraag, gesteld in misschien 3% van de gesprekken, haalde een hele categorie klachten weg. Een chat agent die de verkeerde taal raadt is erger dan een die het vraagt. Taal hoort thuis in een deterministische stap, niet in een LLM-oordeel.

De Humannet-integratie was het project

LLMs zijn makkelijk. Het zware werk in deze bouw zat altijd in het netjes wegschrijven van een samenvatting in een dertien jaar oud verzuimsysteem waarvan de API een SOAP-endpoint is dat staat beschreven in een PDF die voor het laatst in 2017 is aangeraakt.

We hadden twee opties. Optie A: de connector goed herbouwen, met retries, idempotency en een dead-letter queue. Optie B: Humannet headless besturen via Playwright, alsof er een mens zit te typen. Optie A was het juiste antwoord geweest als de SOAP-service niet HTTP 200 had teruggegeven met een XML-envelope waarvan de body letterlijk de string InternalServerError bevatte. We hebben het geprobeerd. In de eerste week op staging logden we 600 false-success writes voordat we het door hadden. We zijn overgestapt op optie B.

De agent schrijft samenvattingen nu weg via een headless browser die inlogt op Humannet, naar de verzuimmodule navigeert, het nieuwe-meldingformulier opent, de velden invult en opslaat. De hele sessie duurt zo'n 4,5 seconden als het netwerk meewerkt. De formulierlayout is in negen maanden twee keer gewijzigd. Allebei de keren braken de selectors luid. Luid is de enige soort kapot die je wil.

We hebben een kleine shim geschreven die de gestructureerde samenvatting van de agent mapt op de form-field-ID's van Humannet, elke nacht een dry-run draait tegen een staging-tenant, en de operations lead van de dienst mailt als een selector verlopen is. In negen maanden is dat drie keer afgegaan. Alle drie de keren opgevangen vóór de ochtendrij.

# structured summary → humannet form mapping
SUMMARY = {
    "melder_naam": str,
    "werkgever_id": str,              # mapped from agent's freeform "werkgever"
    "type_melding": Literal["eerste", "vervolg", "beter"],
    "klacht_kort": str,               # max 280 chars, no PII beyond name
    "vermoedelijke_duur_dagen": int,
    "psychosociaal_flag": bool,       # routes to bedrijfsarts queue if True
    "taal": Literal["nl", "fr"],
}

HUMANNET_FIELDS = {
    "melder_naam":              "#meldingForm\\:naamMelder",
    "werkgever_id":             "#meldingForm\\:werkgeverSelect",
    "type_melding":             "#meldingForm\\:typeRadio",
    "klacht_kort":              "#meldingForm\\:klachtTextarea",
    "vermoedelijke_duur_dagen": "#meldingForm\\:duurInput",
    "psychosociaal_flag":       "#meldingForm\\:psychosocCheckbox",
}

def write_melding(page, summary: dict) -> None:
    for key, selector in HUMANNET_FIELDS.items():
        fill(page, selector, summary[key])
    page.click("#meldingForm\\:opslaanButton")
    assert_visible(page, "text=Melding opgeslagen", timeout_ms=4000)

Burn-out als harde route, niet als kans

In de Belgische en Nederlandse bedrijfsgeneeskunde wordt de prijs van een gemist burn-outsignaal gerekend in jaren. De dienst zei het ons droog tijdens het tweede gesprek: als de agent twijfelt, stuur door naar een mens. Dat betalen wij wel.

Dat hebben we serieus genomen. De psychosociale flag gaat af bij een van deze:

  • De melder gebruikt het woord burn-out, overspannen, épuisement, fatigue chronique, overprikkeld, of iets binnen twee edits van die woorden
  • De melder noemt slaapverlies langer dan twee weken
  • De melder beschrijft een werkconflict en een lichamelijke klacht in dezelfde beurt
  • De melder had een vervolg-melding in de afgelopen 8 weken
  • De confidence van de classifier zit onder 0,7 en het gesprek loopt al langer dan 8 beurten

Een van die signalen, en het gesprek wordt overgedragen aan de dienstdoende bedrijfsarts, met een gestructureerd overdrachtspakket: het volledige transcript, de trigger, de historie van de melder als we die hebben, en de starttijd van het gesprek. De arts neemt het over binnen dezelfde chat. De melder ziet één zin: Ik laat onze bedrijfsarts hier even bij aansluiten. / Je transfère le médecin du travail dans cette conversation. Die zin is grondig A/B-getest. Eerdere versies veroorzaakten paniek. Deze niet.

De trigger gaat af bij zo'n 4,2% van de gesprekken. In de eerste maand duwde de wachtdienst hard terug, vond het te veel. We hielden de lijn vast. Na drie maanden klaagden ze niet meer. Na zes maanden zei een van hen tijdens een koffiepauze dat twee zaken die de agent in week 14 had geflagd, al in langdurig ziekteverzuim zaten. Allebei terug naar parttime werk in week 16, omdat het contact vroeg was geweest.

Waarschuwing

Als je een triage-agent bouwt en de mensen aan de ontvangende kant duwen niet eerst terug, staat je drempel te los. Laat ze er om vragen, en hou dan vast.

De 60-seconden-SLA

De briefing zei zestig seconden van ik wil mij ziekmelden tot een schone samenvatting in Humannet. We zaten in week drie op 60 seconden p50, in maand twee op p90, in maand vijf op p95. Wat de staart binnentrok was niet het LLM. Het LLM is de hele tijd hetzelfde model. Het was de Humannet-sessie.

Concreet: de Humannet-loginsessie verloopt elke 30 minuten, en de re-login heeft een captcha. We bouwden een session pool. Vijf ingelogde browsercontexten, geroteerd, ververst op 25 minuten, captcha buiten kantoortijden opgelost door de nachtdienst-coördinator die daarvoor een toeslag krijgt. Ja, er lost iemand 's nachts vijf captcha's op. Ja, dat is het saaie antwoord. Nee, we hebben niets beters gevonden, en we hebben gezocht.

Hoe we hem in de gaten houden

De agent heeft één dashboard. Het is lelijk en niemand houdt ervan en het werkt. Live aantal gesprekken, taalverdeling, p50- en p95-latency, de laatste 50 overdrachten met de trigger die afging en of de arts de routing accepteerde, de laatste 50 Humannet-writes met groen of rood, en de selector-watch van de dry-run van afgelopen nacht. De operations lead van de dienst checkt het twee keer per dag. Verder kijkt niemand. Dat is prima. Het dashboard van een smalle agent hoeft niemand te overtuigen, het moet alleen het ene ding vangen dat brak voordat de wachtrij het doet.

Stille agent, smalle scope

Er loopt dit najaar een patroon door het agent-discours waar we over nadenken. Verhalen over agents die te breed gaan, netwerken scannen waar ze niets te zoeken hebben, rekeningen oplopen die hun operators niet hadden goedgekeurd. Verhalen over vlaggenschipmodellen die zo gretig proactief zijn dat hun gebruikers de helft van het gesprek bezig zijn ze af te weren. Wij lazen die verhalen en waren blij dat deze agent het tegenovergestelde doet. Hij doet één ding. Hij stelt de vragen in een vaste volgorde, hij schrijft één samenvatting, hij routeert wanneer dat moet. Hij heeft geen tools naast de Humannet-shim en één functie voor de overdracht. Hij surft niet. Hij stuurt geen mail. Hij vat niets samen behalve een verzuim-melding.

Smalle agents die één ding doen, elke dag bekeken door de mensen wier werk ze raken, zijn de saaie vorm van nuttige AI. Het werk zat niet in het model. Het zat in de field mapping, de taallock, de selector-watch, de captcha-pool, de triggerdrempels, de overdrachtszin, en het gesprek met de wachtdienstarts in maand één die ons vertelde dat we het mis hadden. We hadden het mis. We hebben het aangepast.

Hoe maand negen eruitziet

  • 1.260 verzuim-melding-gesprekken per week, eerder 980 via telefoon plus web
  • 47 seconden mediane tijd naar Humannet, 71 seconden p95
  • 4,2% doorgezet naar de bedrijfsarts op triage-flag, waarvan 71% door de arts als correct beoordeeld
  • Nul compliance-escalaties vanuit werkgevers sinds week twee
  • Intake-team van 11 naar 4, met zeven door naar langdurig casemanagement
  • De twee Franstalige intake-medewerkers werken nog steeds bij de dienst. Beiden gaven aan dat ze wilden blijven.

Wat je deze week kan doen

Als je een intake-balie draait, in welke vorm dan ook, is de hefboom die je hebt, met of zonder agent, structuur. Schrijf op welke zeven velden een nette intake écht nodig heeft. Stop met de andere twaalf vragen die er in de loop der jaren ingeslopen zijn. Als een mens met de hand een intake-gesprek binnen twee minuten netjes in het systeem van record kan landen, kan een agent het in 60 seconden. Als een mens dat niet kan, gaat geen enkele agent je redden, want de agent wordt traag op precies de plekken waar je mensen vandaag traag zijn.

Toen we dit bouwden voor de Leuvense dienst, was wat het project bijna stopte de verouderde Humannet-API en de SOAP-envelopes die tegen ons logen. We hebben het opgelost door de UI te besturen als een voorzichtig mens en elke nacht de selectors te controleren. Zit je voor een vergelijkbare bouw, of voor een dertien jaar oud Belgisch of Nederlands systeem dat zich niet wil laten integreren, dan is dat soort smalle, bewaakte AI-agent-werk wat wij doen. Laat ons de wachtrij zien.

Kern

Smalle chat agents winnen op intake als de field map, de taallock en de overdrachtsdrempel vastliggen voordat er één LLM-call gedaan wordt.

FAQ

Hoe bepaalt de agent welke taal hij gebruikt?

Een deterministische fastText-classifier zet de taal vast op de eerste drie berichten met een vertrouwensondergrens. Daaronder vraagt de agent 'NL of FR?' in beide talen.

Waarom Humannet via een browser besturen in plaats van de SOAP-API gebruiken?

Het SOAP-endpoint geeft HTTP 200 terug met error-strings in de XML-body. We logden 600 false-success writes op staging voor we overstapten op een headless browserflow.

Wat triggert de burn-out-routing naar een bedrijfsarts?

Specifieke tokens, slaapverlies langer dan twee weken, conflict-plus-symptoom in één beurt, een vervolg-melding binnen 8 weken, of lage classifier-confidence na 8 beurten. Eén signaal volstaat.

Hoeveel intake-medewerkers zijn hun baan kwijtgeraakt?

Geen. De dienst zette zeven van de elf door naar langdurig casemanagement. Vier bleven op live intake voor edge cases en Franstalige escalaties.

Wat gebeurt er als een Humannet-formulier-selector breekt?

Een nachtelijke dry-run tegen een staging-tenant detecteert de wijziging en mailt de operations lead. In negen maanden drie keer afgegaan, telkens opgevangen voor de ochtendrij.

ai agentschat agentscase studyintegrationsworkflowoperations

Iets bouwen?

Start een project