·7m leestijd·1,306 woorden·

De spec die je niet las

Een agent je spec laten schrijven is prima. Die spec vluchtig doorlezen en hem doorsturen naar een andere agent om van te bouwen, is hoe je eindigt met architectuurbeslissingen die je niet kunt uitleggen.

Er circuleert momenteel een werkwijze. Vraag een agent om een spec te schrijven. Lees de spec. Geef hem door aan een agent om er een plan van te maken. Geef dat plan door aan een agent om er code van te maken.

Gestructureerd. Gedocumenteerd. Op elk moment een duidelijke overdracht.

Het probleem zit in dat woord "lees". De meeste mensen scannen.

Spec-first werkt echt

Voordat ik bij de valkuil kom: de reden om überhaupt een spec te schrijven is sterk.

Een prompt is een wens. Je beschrijft in grote lijnen wat je wilt en laat elke onduidelijke beslissing stilzwijgend over aan de agent. Een spec is anders. Die maakt beslissingen expliciet. Welke landen gelden voor de btw-logica? Sessies of tokens? Wat gebeurt er als een betaling halverwege mislukt?

Addy Osmani, engineering lead bij Google Chrome, verwoordde de grens precies: "Als je te weinig specificeert, kan de AI iets onverwachts doen; als je te veel specificeert, kun je het net zo goed zelf schrijven." De spec is wat leeft tussen die twee manieren om de mist in te gaan.

Een agent is ook echt goed in het boven water halen van wat je nog niet hebt doorgedacht. Vraag hem alle aannames op te sommen die hij zou moeten maken voordat hij ook maar één regel code schrijft, en je krijgt een lijst die schuurt. Dat schuren is informatie. Je gooit geen tijd weg, je haalt de wrijving naar boven die anders later als een productiebug opduikt.

Het twee-stappen-probleem

En hier lopen de meeste spec-gedreven werkwijzen stilletjes vast.

Je vraagt een agent een spec te schrijven. Die levert iets grondigs op: doelen, beperkingen, acceptatiecriteria, een datamodel, benoemde randgevallen. Goed opgemaakt en zelfverzekerd. Je scant het. Sectie 1 ziet er goed uit. Sectie 2 ziet er goed uit. Sectie 3 noemt een cachingstrategie die redelijk klinkt. Goedgekeurd.

Die cachingstrategie is nu jouw architectuur.

Jij hebt hem niet gekozen. Je hebt geen alternatieven afgewogen. Je weet niet waarom de agent voor cache-aside koos in plaats van write-through, of dat onderscheid überhaupt relevant is voor jouw belastingpatroon. Maar het staat nu in de spec, dus de coding-agent voert het uit met vol vertrouwen, want specs zijn gezaghebbend.

Wat je hebt gedaan, is begrip delegeren, niet alleen uitvoering. Je hebt een documentlaag geschoven tussen jou en een beslissing die de agent nam. Die laag laat het er uitzien alsof jij betrokken was. Maar dat was je niet.

Dit is hetzelfde probleem, één stap eerder in de pijplijn. We kennen het al op codeniveau: als je de code niet kunt uitleggen, had je hem niet mogen opleveren. Hetzelfde geldt hier. Als je de spec niet kunt verdedigen, had je hem niet mogen goedkeuren. De coding-agent weet het verschil niet. Die voert uit wat de spec zegt, en de spec zegt wat de schrijvende agent heeft besloten.

Waar de spec eigenlijk voor is

Een spec is geen document dat je oplevert. Het is bewijs dat je de taak begreep voordat je hem overdroeg.

De waarde zit niet in het formaat of de lengte. Die zit in één ding: de persoon die hem goedkeurde, kan een kamer binnenlopen en elke beslissing daarin verdedigen zonder het document erbij te hoeven pakken.

Als je dat niet kunt, is de spec niet van jou. De agent heeft hem geschreven. Jij hebt hem voor gezien getekend. Dat is geen eigenaarschap. Dat is een notarishandtekening.

Hoe je het wél doet

Drie stappen. Op volgorde.

1. Gebruik de agent om te ontdekken wat je nog niet hebt besloten

Vraag niet meteen om een spec. Vraag eerst om vragen. Geef de agent je ruwe idee, en dan:

text
Before writing anything, list every assumption you would need to make
and every decision I haven't yet specified.

De uitkomst is jouw werklijst. Elk punt is een beslissing die jij zelf moet nemen, in je eigen hoofd, voordat de spec echt van jou kan zijn. Werk die lijst door. Beantwoord elk punt. Vraag daarna de agent de spec te schrijven op basis van jouw antwoorden, niet op basis van zijn eigen invulling.

2. Lees de draft alsof je er straks op wordt afgerekend

Elke sectie waarbij je gevoel zegt "ik vertrouw de agent hier maar op" is een sectie die je niet hebt begrepen. Dat gevoel is geen vertrouwen. Het is een gat.

Behandel die secties zoals je onbekende code in een pull request behandelt. Je keurt een functie niet goed die je niet kunt doorlopen. Keur ook een spec-sectie niet goed die je niet kunt onderbouwen. Vraag de agent waarom hij voor deze aanpak heeft gekozen. Zoek het patroon op als je het niet herkent. Begrijp de afwegingen voordat je verdergaat.

Het doel is niet elk woord in twijfel trekken. Het is een punt bereiken waarop jij de spec aan een collega kunt navertellen zonder het document erbij, inclusief de delen die niet voor de hand lagen.

3. Daag de onduidelijke stukken uit

Gebruik het Architect/Advocaat-van-de-duivel-patroon op de secties waar je het minst zeker over bent. Vraag de agent het sterkste argument tégen zijn eigen aanpak te formuleren. Als zijn tegenargumenten dingen naar boven brengen waar jij nog niet aan had gedacht, ben je nog niet klaar met de spec.

Pas als je elke beperking kunt uitleggen en elke afweging kunt verantwoorden, is de spec echt van jou. Dan pas geef je hem door aan een agent voor het codeplan.

Als je Claude Code gebruikt, doet de Superpowers-plugin de verkenningsfase goed. Die stelt verduidelijkende vragen voordat er code wordt aangeraakt, produceert een gestructureerd ontwerpdocument en wacht op je expliciete goedkeuring voordat er een implementatieplan komt. Handig gereedschap voor stap 1. Maar lees de Superpowers-post er nog eens op na: "plannen erven spec-fouten. Als je ontwerpdocument niet klopt, klopt de implementatie ook niet." Het gereedschap verbetert de kwaliteit van de draft. Het vervangt het lezen ervan niet.

Wat een leesbare spec bevat

Niet elke spec heeft dezelfde onderdelen nodig. Maar sommige dingen moeten expliciet zijn, anders verzint de agent ze.

Wat er in hoortHoe dat eruitziet
Expliciet gemaakte beslissingenNiet "authenticatie afhandelen", maar "JWT-tokens, 24 uur geldig, verlengen bij activiteit"
Benoemde randgevallenNiet "fouten afhandelen", maar "betaling mislukt: één keer opnieuw proberen, gebruiker informeren, nooit twee keer afschrijven"
Beperkingen die je kunt testenNiet "moet snel zijn", maar "API-responstijd onder 200ms bij p95 onder normale belasting"
Wat buiten scope valtVoorkomt dat de agent problemen oplost die je niet hebt gesteld

Wat er niet in hoort:

  • Alles wat je zou omschrijven als "zoek zelf de beste aanpak maar uit." Dat is nog steeds een gat, nu geformaliseerd in een document.
  • Implementatiekeuzes die je niet begrijpt en niet hebt opgezocht.
  • Acceptatiecriteria waarvoor jij, zonder de agent te raadplegen, vandaag geen test zou kunnen schrijven.

De toets is eenvoudig. Vraag jezelf bij elke regel van de spec: heb ík dit besloten, of heb ik het laten gaan? De regels die je hebt laten gaan, zijn de regels die je in productie terugziet.

De stap die de werkwijze niet automatiseert

De twee-agenten-werkwijze is niet verkeerd. Eén agent laten schrijven en een andere laten bouwen is beter dan direct om code vragen. De draft brengt beslissingen boven water. De structuur geeft je iets om tegenin te gaan.

Maar de werkwijze werkt alleen als jij de ene stap doet die hij niet kan automatiseren.

De spec is waar jij verantwoordelijkheid neemt. Niet voor het schrijven ervan, daarvoor heb je de agent. Wel voor het begrijpen ervan. Voor het kunnen uitleggen, aan een collega, een reviewer of jezelf om drie uur 's nachts, waarom het systeem is gebouwd zoals het is gebouwd.

Je vindt de bug niet als je de code niet hebt geschreven. De bouw stuur je ook niet als je het plan niet hebt begrepen.

Als je een spec hebt goedgekeurd die je niet kon verdedigen, was wat je overdroeg niet van jou.

// serie: Praktijkgids(5 van 5)