← Blog

Chat agents

Chat-agent voor advocaten-intake: triggers die werken

Vrijdag 16:00, de stagiair is op vakantie en een nieuwe cliënt noemt een zittingsdatum over elf dagen. Het intakeformulier deed zijn werk. Daarom zag niemand het.

Jacob Molkenboer· Oprichter · A Brand New Company· 7 jun 2026· 9 min
Crèmekleurige envelop met limoengroen lint op donkergroen leren onderlegger, koperen bel, gevouwen formulier.

Een vrijdagmiddag bij een middelgroot Amsterdams advocatenkantoor. Een nieuwe intakemail komt binnen op het algemene info-adres. De cliënt schrijft: "Mijn werkgever heeft me ontslagen en de kantonrechter heeft een zitting op 18 juni." De stagiair die normaal de intake doorneemt, is op vakantie. De partner zit in de rechtszaal. De senior medewerker zit bij een getuigenverhoor. De mail blijft staan.

De zittingsdatum is over elf dagen.

Dit is het probleem dat een intake-agent hoort op te lossen. Niet door de juridische vraag te beantwoorden. Niet door tarieven te noemen. Niet door een terugbelafspraak te beloven. Maar door het enige te doen wat echt telt: zien dat er een deadline in de inbox is geland, en een mens erbij halen voordat de deadline dat doet.

Wat de intake-agent niet mag doen

Voordat we ook maar iets aansloten, hebben we opgeschreven wat de agent onder geen enkele omstandigheid mag. De Nederlandse Orde van Advocaten heeft duidelijke regels over wat juridisch advies is en wie dat mag geven. Een taalmodel staat niet op die lijst. De agent vertelt een potentiële cliënt dus nooit of die een zaak heeft, welk wetsartikel van toepassing is, wat de volgende stap is, of wat het gaat kosten.

Wat de agent wél doet, is smaller en nuttiger. Hij verzamelt feiten. Hij stelt de vragen die de paralegal toch al als eerste zou stellen. Hij herkent de drie signalen die betekenen dat er vandaag een mens bij moet, niet morgenochtend. En hij levert een schone, gestructureerde overdracht, zodat de mens al weet wat er ligt op het moment dat die instapt.

De drie overdrachtstriggers

Bijna elke advocaten-intake die er echt toe doet, bevat in het eerste bericht minstens één van drie signalen. We hebben deze drie gekozen omdat ze concreet zijn, door een machine herkenbaar, en bijna altijd samenhangen met urgentie. Gaat er één af, dan pauzeert het gesprek en wordt er een echte paralegal opgepiept.

Een deadline-woord of datum

Het Nederlandse procesrecht draait op data. Verjaring, dagvaarding, zitting, beslag, termijn, hoger beroep, cassatie. Elk van deze woorden impliceert een klok. De meeste intakeberichten met zo'n woord bevatten ook een concrete datum, in ISO-formaat ("12-06-2026"), Nederlands voluit ("12 juni 2026"), of relatief ("over twee weken"). De agent markeert beide vormen.

Een getal dat financieel oogt

Bedragen wijzen om twee redenen op urgentie. Ten eerste betekent een bedrag meestal dat er al een wederpartij is die iets claimt. Ten tweede liggen er procedurele drempels: onder de €25.000 is de kantonrechter bevoegd, daarboven de rechtbank. Dat hoeft de agent niet te weten. Hij markeert simpelweg elk eurobedrag boven €1.000 en elk getal dat eruitziet als een zaaknummer (het C/13/... formaat van de rechtbank Amsterdam, het ECLI:NL: voorvoegsel uit gepubliceerde jurisprudentie, het 200.... formaat van de gerechtshoven).

Een naam van de wederpartij

Dit is de lastigste en de waardevolste. Een cliënt die de naam noemt van zijn werkgever, verhuurder, het bedrijf van zijn ex-partner of de gemeente, heeft je het werk al uit handen genomen: je weet wie er aan de andere kant zit. Het kantoor moet de conflicttoets draaien voordat er een inhoudelijk gesprek begint. Als de agent een wederpartij eruit haalt, is de overdracht niet onderhandelbaar: niemand op kantoor mag antwoorden voordat de conflicttoets is afgerond.

Waarschuwing

Mislukte conflicttoetsen zijn de manier waarop advocatenkantoren hun beroepsaansprakelijkheidsdekking verliezen. Als de agent een wederpartij oppikt en een mens antwoordt vóór de toets is gedraaid, heeft de agent het erger gemaakt, niet beter. Bouw de overdracht zo dat het antwoordpad geblokkeerd is totdat de toets klaar is.

Het extractieschema

De taak van de agent bij elke beurt is om een gestructureerd object bij te werken. We sturen het gesprek door een model met afgedwongen structured output. Het schema is bewust kort. Elk veld koppelt aan een afnemer verderop in de keten: het case-management-systeem, de conflicttoets-job, de paralegal-queue.

{
  "matter_type": "arbeidsrecht | huurrecht | familierecht | ondernemingsrecht | other | unknown",
  "language": "nl | en",
  "client": {
    "name": "string | null",
    "email": "string | null",
    "phone": "string | null"
  },
  "counterparty": {
    "name": "string | null",
    "type": "person | company | government | unknown"
  },
  "dates": [
    { "raw": "string", "iso": "string | null", "kind": "zitting | termijn | beslag | other" }
  ],
  "amounts": [
    { "raw": "string", "eur": "number | null" }
  ],
  "case_refs": ["string"],
  "summary": "string, max 280 chars, factual, no advice"
}

Het model vult in wat het ziet en laat de rest op null staan. Het schema wordt op tool-call-niveau afgedwongen, dus het model krijgt geen kans om er proza tegenaan te gooien. Zodra een agent vrije tekst mag produceren, gaat downstream code op strings pattern-matchen, en is het systeem binnen weken broos. Structured outputs zijn hier geen nice-to-have. Ze zijn het contract tussen het model en alles wat erna komt.

De triggerdetector

Zodra het extractie-object is bijgewerkt, draait de detector. Dat is gewone code, geen model. De reden om hier code te gebruiken is auditbaarheid. Een partner leest de detector in dertig seconden door en snapt precies wanneer het kantoor wordt opgepiept.

type Intake = {
  counterparty: { name: string | null };
  dates: { iso: string | null; kind: string }[];
  amounts: { eur: number | null }[];
  case_refs: string[];
};

const DEADLINE_KINDS = new Set(["zitting", "termijn", "beslag"]);

export function shouldHandoff(intake: Intake, now: Date): {
  handoff: boolean;
  reasons: string[];
} {
  const reasons: string[] = [];

  if (intake.counterparty.name) {
    reasons.push(`counterparty:${intake.counterparty.name}`);
  }

  for (const d of intake.dates) {
    if (!d.iso) continue;
    const days = (new Date(d.iso).getTime() - now.getTime()) / 86400000;
    if (DEADLINE_KINDS.has(d.kind) && days <= 21) {
      reasons.push(`deadline:${d.kind}:${Math.round(days)}d`);
    }
  }

  for (const a of intake.amounts) {
    if (a.eur !== null && a.eur >= 1000) {
      reasons.push(`amount:${a.eur}`);
    }
  }

  if (intake.case_refs.length > 0) {
    reasons.push(`case_ref:${intake.case_refs[0]}`);
  }

  return { handoff: reasons.length > 0, reasons };
}

Het venster van 21 dagen voor zittingsdata is een keuze van het kantoor, geen juridische. Ze wilden dat elke zitting binnen drie weken de bel zou laten rinkelen. Andere kantoren hanteren andere vensters. Het is een config-waarde, geen constante.

Specifieke aandachtspunten voor het Nederlands

De agent is standaard tweetalig NL/EN. Ongeveer 30% van de intake bij dit kantoor is in het Engels (expats, grensoverschrijdend arbeidsrecht, IP-zaken). We hebben niets getraind. We hebben het model in de prompt opgedragen de taal in het eerste bericht te detecteren en daar vervolgens aan vast te houden. Het schema vult zich op dezelfde manier; de antwoorden van de agent volgen de cliënt.

Wat lastiger is, is Nederlandse datum-parsing. Met "12 juni 2026" gaat het model prima om. Met "aanstaande donderdag" minder, zeker in een gesprek over meerdere beurten waarin "aanstaande donderdag" drie dagen geleden gezegd kan zijn. We hebben dat opgelost door de starttijd van het gesprek in de system prompt te stempelen en het model te vragen relatieve data direct naar ISO te resolven, en ze nooit als relatieve tekst mee te dragen. Als het model twijfelt, blijft het iso-veld in het schema null en wordt de datum behandeld als ruwe context, geen trigger.

De overdracht zelf

Als de detector handoff: true teruggeeft, doet de agent drie dingen op rij:

  1. Hij vertelt de cliënt, gewoon: "Ik pauzeer hier even en laat een collega ernaar kijken. Je hoort binnen [de SLA van het kantoor] van ons." Geen woord over triggers, geen woord over AI, geen woord over urgentie. De cliënt hoeft niet te weten hoe de worst gemaakt wordt.
  2. Hij schrijft het extractie-object en de triggerredenen weg naar het case-management-systeem. De zaak wordt aangemaakt met de status "Wacht op conflicttoets".
  3. Hij piept de dienstdoende paralegal op via het bestaande Slack-kanaal van het kantoor, met een samenvatting van één alinea, het gestructureerde object en een link naar het volledige transcript.

Het Slack-bericht is het deel dat de paralegals daadwerkelijk zien. We hebben meer tijd besteed aan de opmaak daarvan dan aan de prompt van het model. De eerste regel is de triggerreden in gewoon Nederlands. De tweede regel is de deadline, als die er is. De rest staat ingeklapt in een thread. Een paralegal triëert er twintig in de tijd die het vroeger kostte om één mail te lezen.

Hoe we het hebben getest voordat het echte intake raakte

We hebben zo'n 800 historische berichten uit de inbox van de afgelopen achttien maanden teruggespeeld, ter plekke geanonimiseerd. Bij elk bericht wisten we al wat de mens had gedaan: binnen een uur geantwoord, de volgende dag geantwoord, doorgezet naar een partner, of compleet gemist. We hebben de agent en de detector op de ruwe tekst losgelaten en de output gescoord tegen het menselijke dossier.

Op dag één lag de nauwkeurigheid rond de 91%. De missers clusterden zich rond twee faalwijzen: wederpartijen die indirect werden aangeduid ("mijn baas", "de verhuurder van mijn moeder") en data geschreven als Nederlandse rangtelwoorden ("de 18e"). We hebben een wederpartij-resolutiestap toegevoegd die één gerichte vervolgvraag stelt als het extractie-object wél een rechtsgebied bevat, maar geen naam van de wederpartij. We hebben meer Nederlandse datumpatronen aan de schema-beschrijving toegevoegd. Zes weken later ligt de missratio in een rollend venster van dertig dagen onder de 2% en het percentage vals-positieven onder de 5%.

Op zichzelf is dat niets bijzonders. Wat telt is dat de eval-set in de repository staat, dat elke wijziging in model of prompt het laatste nauwkeurigheidscijfer moet verslaan voordat hij live gaat, en dat we binnen een dag weten of er een regressie doorglipt. De reden dat recente verhalen over een model dat regressies introduceert in vertrouwde code zo hard aankomen, is dat de meeste teams die met LLM's bouwen helemaal geen eval-harness hebben. Zit het model in je kritieke pad, dan is de eval-set het enige wat tussen jou en een vrijdag staat waar je geen zin in hebt.

Audit logging

Nederlandse advocatenkantoren staan onder toezicht van de Nederlandse Orde van Advocaten, en het kantoor waarvoor we dit hebben gebouwd, wilde op verzoek precies kunnen laten zien wat de agent tegen welke potentiële cliënt had gezegd. Elk gesprek wordt dus end-to-end opgeslagen, inclusief de versie van de system prompt, het model-id, de temperatuur en het extractie-object bij elke beurt. Krijgt het kantoor ooit de vraag "heeft jullie AI in dit gesprek juridisch advies gegeven", dan kunnen ze binnen een minuut het volledige dossier overleggen.

Omdat intakegesprekken persoonsgegevens bevatten, zit de audit log achter dezelfde toegangscontroles als het case-management-systeem, met bewaartermijnen die aansluiten op het bestaande privacybeleid van het kantoor. De Autoriteit Persoonsgegevens is duidelijk geweest: AI-verwerking van persoonsgegevens krijgt geen speciale uitzondering op de AVG. Zelfde rechtsgrondslag, zelfde dataminimalisatie, zelfde rechten van betrokkenen als bij elke andere verwerking. We loggen genoeg om het systeem te kunnen verdedigen. Meer niet.

We loggen ook elk geval waarin de detector niet afging, maar de mens de zaak achteraf alsnog als urgent markeerde. Dat log is de echte benchmark van de agent. Het nauwkeurigheidsgetal dat telt, is niet "heeft het model de datum goed geëxtraheerd", maar "heeft de detector iets gemist dat de paralegal wél zou hebben opgepikt".

Wat we hebben gebouwd, en wat we anders zouden doen

Toen we dit bouwden voor een Amsterdamse arbeidsrecht-boutique, liepen we ertegenaan dat het model af en toe de situatie van de cliënt samenvatte op een manier die klonk als het bevestigen van een juridisch standpunt. "Het klinkt alsof je een ontslag op staande voet hebt gekregen." Technisch een parafrase, functioneel een diagnose. Uiteindelijk hebben we een laatste stap toegevoegd die het uitgaande bericht van de agent herschrijft naar pure vraagvorm zodra het extractie-object een ingevuld matter_type bevat. De agent mag weten wat voor zaak het is; hij mag het niet aan de cliënt vertellen. Dezelfde manier van zorgvuldig afbakenen passen we toe op al ons werk met AI-agents.

Doe je intake bij een kantoor, ongeacht de grootte, dan is dit het kleinste wat je vandaag kunt doen: open de laatste vijftig berichten die in je algemene inbox zijn beland, markeer degene die in de eerste alinea een datum, een bedrag of een naam van een wederpartij bevatten, en tel welk deel je team binnen vier uur heeft opgepikt. Dat getal is het gat dat een agent gaat dichten.

Kern

Een intake-agent is er niet om juridische vragen te beantwoorden. Hij is er om ervoor te zorgen dat een mens de urgente vragen ziet, voordat de deadline dat doet.

FAQ

Geeft de chat-agent juridisch advies?

Nee. Hij verzamelt feiten, stelt verduidelijkende vragen en draagt over aan een mens. Hij vertelt een potentiële cliënt nooit of die een zaak heeft, welk wetsartikel van toepassing is, of wat de volgende stap is.

Welke talen ondersteunt de agent?

Standaard Nederlands en Engels. Hij detecteert de taal in het eerste bericht en houdt daaraan vast. Het gestructureerde extractieschema vult zich op dezelfde manier, ongeacht de taal.

Wat gebeurt er nadat een overdracht in gang is gezet?

De zaak wordt aangemaakt met de status 'Wacht op conflicttoets', een dienstdoende paralegal wordt in Slack opgepiept met een gestructureerde samenvatting, en de agent stopt met antwoorden totdat een mens het overneemt.

Hoe meten jullie de nauwkeurigheid van de detector?

Met een eval-set van historische intakeberichten, gescoord tegen wat het kantoor daadwerkelijk heeft gedaan. Elke wijziging in prompt of model moet het laatste nauwkeurigheidscijfer verslaan voordat hij live gaat.

Kan het chattranscript in een procedure worden opgevraagd?

Behandel het als elke andere cliëntcommunicatie. Het kantoor slaat gesprekken end-to-end op, met de volledige system prompt, het model-id en de extractietoestand, juist om die reden.

chat agentsai agentsautomationworkflowoperationscase study

Iets bouwen?

Start een project