Stop met vriendelijk vragen aan je agent
7m leestijd

Stop met vriendelijk vragen aan je agent

Je CLAUDE.md is een suggestie. Hooks zijn een muur. ADRs en custom lint-regels zijn de ontbrekende laag ertussen: het verschil tussen hopen dat je agent zich gedraagt en het onmogelijk maken om dat niet te doen.

Je hebt een prachtige CLAUDE.md geschreven. Een hele middag erover gedaan. Mappenstructuur gedocumenteerd, je regel dat DTO's bij elkaar staan, je "nooit default exports" voorkeur, je testconventies, alles erop en eraan.

De agent las het. Een minuut of tien gedroeg hij zich keurig.

Ergens rond tool call dertig maakte hij stilletjes een default export aan, plaatste een Zod-schema inline naast een route handler, en gooide er voor de zekerheid nog een console.log bij. Je merkte het pas in code review, en tegen die tijd had het patroon zich al over vier files verspreid.

Dit is precies het gedrag dat je zou moeten verwachten, geen falen van de agent. En de oplossing is niet een beter geschreven CLAUDE.md.

Het waarschijnlijkheidsprobleem

Alles wat je in een prompt zet, inclusief CLAUDE.md en AGENTS.md, is een probabilistische instructie. Het model leest het, weegt het, en volgt het meestal op. Meestal is niet altijd. En op een lange taak met tientallen tool calls werkt "meestal" de verkeerde kant op.

Ik schreef daar eerder over. Het hooks-stuk maakte het punt dat voor dingen die elke keer moeten gebeuren, je het niet in een prompt zet. Je zet het in een hook.

Maar hooks zijn de muur aan het einde van de gang. Ze blokkeren gevaarlijke commando's, draaien formatters, killen slechte merges. Ze leren je niets. Ze brengen geen intentie over. Ze zeggen "nee" zonder ooit te zeggen "waarom."

Tussen de prompt (probabilistisch) en de hook (eindmuur) zit een laag die de meeste teams niet hebben gebouwd. Twee tools wonen in die laag. Architecture Decision Records en custom lint-regels.

ADRs: de waarom-laag

Een CLAUDE.md probeert alles te zijn. Stack, conventies, woordenlijst, do's en don'ts, projectstructuur. Het groeit naar 400 regels, en de agent leest het één keer aan het begin van de sessie en kan het middenstuk al niet meer ophalen tegen de tijd dat het ertoe doet.

Een Architecture Decision Record is het tegenovergestelde. Eén beslissing. Twee pagina's. Context, de alternatieven die je hebt overwogen, de beslissing, de gevolgen. Opgeslagen als markdown in docs/adr/, genummerd, onveranderlijk.

Het format is gepopulariseerd door Michael Nygard rond 2011, ruim voor al deze AI-onzin. Het overleeft omdat het één eigenschap heeft die niets anders heeft: het legt de redenering vast op het moment dat de beslissing genomen werd. Zes maanden later, als iemand (of iets) zich afvraagt waarom alle DTO's in src/dtos/users/ staan en niet naast de route, ligt het antwoord twee klikken verderop.

Dit is wat verandert als je een agent ADRs geeft. In plaats van te raden naar je conventies op basis van de code (waar hij het nieuwe patroon én de oude legacy ziet en beide ongeveer even zwaar weegt), kan hij de beslissing lezen.

Hij kan docs/adr/ doorzoeken, het record vinden dat zegt "we plaatsen DTO's bij elkaar omdat X, Y, Z," en dat respecteren. Niet als een regel die hij kan vergeten, maar als gedocumenteerde context die hij on-demand opnieuw kan ophalen.

Het andere onderschatte aspect: agents zijn uitstekend in het schrijven van ADRs. Richt Claude op je bestaande codebase en zeg "scan dit op beslissingen die niet gedocumenteerd zijn en schrijf ADRs op basis van de patronen die je vindt." Hij produceert een eerste versie die voor 80% klopt. Jij corrigeert. Nu is je tribal knowledge een bestand, geen gevoel.

Dit is ook een verdediging tegen code waar straks niemand meer aan durft te komen. Code versteent wanneer niemand zich nog herinnert waarom hij er staat. Een ADR is een thermometer in het gesteente.

Lint-regels: de hoe-laag

ADRs leggen het waarom uit. Lint-regels handhaven het hoe.

Generieke ESLint dekt syntax en de gebruikelijke valkuilen. Hij weet niet dat in jouw project Zod-schema's in src/dtos/ wonen en nooit inline in routes. Hij weet niet dat de presentation-laag nooit uit infrastructure mag importeren. Hij weet niet dat je console.log verbiedt omdat je een structured logger gebruikt.

Je kunt dat allemaal documenteren. De agent doet het toch verkeerd, want documentatie is een suggestie.

Custom lint-regels zijn anders. Ze laten de build falen.

De interessante kanteling, uit een recent Just Understanding Data-stuk, is dat voor AI-agents foutmeldingen ophouden fouten te zijn en onderwijsprompts worden. Als de agent een Zod-schema inline plaatst en de linter terugschiet:

text
DTO moet in src/dtos/<feature>/ staan. Zie ADR-0014.
Voorbeeld: zie src/dtos/users/create-user.dto.ts

De agent leest die melding, fixt de overtreding, en de volgende keer dat hij vergelijkbare code genereert wordt het patroon versterkt. Na twee of drie iteraties stopt hij met de fout. Niet omdat hij iets in diepe zin geleerd heeft, maar omdat de gestructureerde feedback de volgende generatie vormgeeft.

Eén cruciaal detail: zet inline-disable uit. Als de agent // eslint-disable-next-line kan schrijven om de regel te ontwijken, doet hij dat. Configureer je linter zo dat custom architecturele regels niet vanuit de file zelf het zwijgen opgelegd kunnen worden. Het hele punt is dat de regel niet onderhandelbaar is.

Alvin Sng van Factory.ai zegt het bot: agents schrijven de code, linters schrijven de wet. Lint draait bij opslaan, in pre-commit, in CI, en in de eigen tool-loop van de agent. "Lint groen" wordt de definitie van klaar. De agent corrigeert zichzelf tegen de regels, zonder dat er een mens nodig is voor het saaie werk.

De handhavingsstack

Dit is de hiërarchie die ik elk team dat met agents werkt zou aanraden te bouwen, van zacht naar hard:

LaagMechanismeGarantieKosten
PromptCLAUDE.md, AGENTS.mdProbabilistischGoedkoop
ADRdocs/adr/*.mdSemantische context, doorzoekbaarGemiddeld
LinterCustom ESLint-regelsDeterministisch, blokkeert buildGemiddeld
HookPreToolUse, PostToolUseAbsoluut, blokkeert tool callHoog

Elke laag vangt wat de bovenliggende laag heeft laten passeren. Prompts dekken het normale geval. ADRs geven de agent iets om te raadplegen als hij redenering nodig heeft. Linters blokkeren patronen die door de prompt heen kwamen. Hooks stoppen het zeldzame drama.

De meeste teams hebben laag één. Een handvol heeft laag vier. Bijna niemand heeft de twee in het midden. In dat gat rot je codebase stilletjes weg.

Wat je nu moet doen

Probeer dit niet allemaal tegelijk te bouwen.

  • Begin met één ADR. Pak de conventie waar je de agent deze week het vaakst op hebt gecorrigeerd. Schrijf hem als ADR. Twee pagina's, niet meer. Verwijs ernaar in CLAUDE.md zodat de agent weet dat de map bestaat.
  • Schrijf één custom lint-regel. Pak de volgende meest geschonden conventie. Schrijf hem als ESLint-regel met een gestructureerde foutmelding die de ADR noemt. Severity op error. Inline-disable uit.
  • Kijk wat er breekt. De eerste keer dat de agent tegen de regel aanloopt, probeert hij eromheen te werken. Kijk hoe. Dat vertelt je of je foutmelding lesgeeft of alleen blokkeert.
  • Aanhalen. Elke keer dat je de agent twee keer op hetzelfde corrigeert, is dat een kandidaat voor een ADR of een lint-regel. Schrijf geen derde correctie. Leg hem vast.

De prompt is niet de spec. Dat is CLAUDE.md ook niet. De spec is de verzameling constraints die het systeem daadwerkelijk afdwingt. Alles daarbuiten is hoop.

De agent is niet lui en ook niet kwaadaardig. Hij gokt, heel snel, tegen een model van hoe je code "waarschijnlijk" eruitziet. Als je niet wilt dat hij gokt, stop dan met hopen dat hij je conventies onthoudt. Leg ze vast ergens waar hij wel moet kijken.

Maak het onmogelijk om verkeerd te doen.

(5 van 32)
01Het beste uit Claude Code halen02Superpowers: hoe je Claude Code leert eerst te denken03Claude Code-hooks: deterministische controle over AI-workflows04Het CLAUDE.md-bestand: geef je AI permanent geheugen05Stop met vriendelijk vragen aan je agent06Wat er nieuw is in Claude Code: notities van het Londen-event07Het beste cijfer in Opus 4.8 is geen benchmark08Verouderd geheugen is erger dan geen geheugen09De agent is gewoon een loop10Bouw een MCP-server, en vraag je dan af of die moet bestaan11Skill, subagent, hook of slash command? Kies de juiste12Inloggen op MCP-servers vanuit je shell13De dag dat 'default' ineens 'Manual' heette14Hoe je een goede Claude Code-skill schrijft15Een goede Claude Code-subagent schrijven16Claude Code permissions instellen: de gids die ik miste17Claude Code sandboxen: toestemming is geen muur18Prompt injection voorkomen: verdediging voor wie agents bouwt19Welk Claude-model voor welke programmeertaak20Legacy code refactoren met AI: begin met characterization tests21Je MCP-server beveiligen: authenticatie, scopes en rate limits22Opus 5 is er, en je effort-instellingen kloppen niet meer23Incident response voor AI-agents: wat je doet als je coding agent de fout in gaat24Claude Code /doctor: van installatiecheck naar contextaudit25Context beheren in Claude Code: wanneer /clear en wanneer /compact26Git worktrees uitgelegd: parallel werken met AI-agents zonder botsingen27Claude Code plan mode: beslissen voordat de agent schrijft28Debuggen met een coding agent: geef hem het zoekwerk, de hypothese houd je zelf29Claude Code checkpoints en /rewind: wijzigingen van je agent terugdraaien30Claude Code cross-session messaging: sessies die elkaar berichten sturen31Claude Code-config delen met je team: wat de repo wel en niet afdwingt32Je Claude Code-sessie heeft geen klok