blog/stop-met-prompten-ontwerp-de-loop.mdx
Alle notities

17 juni 2026

Handmatig prompten schaalt niet: ontwerp de loop die je AI-agent aanstuurt

Twee jaar lang was een goede prompt de hefboom, maar die hefboom verschuift. De teams die nu het meeste uit Claude Code en Codex halen, typen steeds minder zelf in de agent: ze ontwerpen een klein systeem dat de agent voor hen prompt, met een vast ritme, parallelle worktrees, een maker en een checker, en een memory-bestand als ruggengraat. Je leest wat elk onderdeel echt doet, hoe mijn eigen loop er elke ochtend uitziet, voor wie dit nu al interessant is en wat de loop nog steeds niet voor je doet.

Twee jaar lang gold steeds hetzelfde recept als je iets bruikbaars uit een coding agent wilde halen. Schrijf een goede prompt, geef genoeg context mee, lees wat eruit komt, typ de volgende stap. De agent was een tool en jij stuurde hem voortdurend aan, beurt voor beurt. Die modus verdwijnt niet, en voor los, eenmalig werk blijft hij prima. Maar mijn inschatting is dat het niet langer het meest waardevolle is wat je in een sessie kunt doen.

Wat ernaast komt te staan, en bij de teams die in 2026 het meeste uit Claude Code en Codex halen steeds vaker de hoofdrol pakt, is een klein systeem dat de agent voor je prompt. Het systeem zoekt zelf werk op volgens een vast schema, verdeelt het naar een worker en laat een aparte worker het controleren. Vervolgens schrijft het systeem het resultaat naar een memory file die de volgende run kan lezen, en morgen doet het stilletjes hetzelfde nog eens. Jij hebt het één keer ontworpen. Een geplande taak die vanzelf op de klok start (in het vak een cron) prompt de agent. Jij loopt weg.

Ik noem dit in mijn hoofd al een paar maanden loop engineering. Hoe meer ik deze loop op echt klantwerk draai, hoe duidelijker het wordt dat de hefboom aan het verschuiven is. Niet de tools zijn veranderd: de hefboom ligt een niveau hoger.

Van prompt naar loop: wat er precies verschuift

Voordat de onderdelen langskomen, is het handig om de verschuiving zelf scherp te hebben. Handmatig prompten en een loop draaien zijn niet twee smaken van hetzelfde werk. Het is ander werk, met een andere rol voor jou.

Handmatig promptenEen loop draaien
Wie start het werkJij, per sessieEen schema of trigger
Waar de kennis zitIn je hoofd en in losse promptsIn skill-bestanden in de repo
KwaliteitscontroleJij leest elke output zelfEen aparte checker-agent, plus jouw review
Parallel werkenEén gesprek tegelijkMeerdere geïsoleerde worktrees naast elkaar
Wat er tussen sessies overblijftNiets, elke sessie start koudEen memory-bestand dat de state bewaart
Jouw rolAansturen, beurt voor beurtOntwerpen, reviewen, bijsturen

Six cards in a three-by-two grid showing the building blocks of a loop. Card 1 Automations as the heartbeat, runs on cadence or condition, /loop and /goal primitives plus cron, hooks, GitHub Actions. Card 2 Worktrees as parallel without chaos, isolated git checkouts per agent so edits never touch, your review bandwidth is the real ceiling. Card 3 Skills as intent on disk, SKILL.md folders with procedure and checklists, without them the loop re-derives your project from zero every cycle. Card 4 Connectors as the loop touching reality, MCP-shaped, work in both runtimes, the difference between an agent that says here is the fix and a loop that opens the PR itself. Card 5 Sub-agents as maker vs checker, one drafts and one verifies, the model that wrote it grades it too generously. Card 6 Memory as the spine, markdown file or Linear board, the agent forgets between runs but the repo does not. Bottom caption that you design it once, prompt never, both Claude Code and Codex now ship all six.

Wat een loop eigenlijk bevat

Een loop bestaat uit vijf bewegende onderdelen en één stukje state. Zodra je ze kunt benoemen, zie je ze terug in elke tool. De discussie of Codex of Claude Code de juiste keuze is, wordt daarmee een stuk minder spannend: de vorm is in beide vrijwel gelijk.

Automations zijn het startsignaal. Een schema, een cron, een webhook (een seintje van een ander systeem dat iets is gebeurd), een /loop op een vast ritme, of een /goal die blijft doorwerken tot een voorwaarde die jij hebt geschreven daadwerkelijk waar is. Dit maakt de loop wakker. Zonder dit ben jij nog steeds degene die de run start, en dus nog steeds degene die de agent prompt.

Worktrees zorgen ervoor dat parallel werken niet in chaos ontaardt. Draai twee agents in dezelfde checkout en ze bewerken allebei hetzelfde bestand, waarna je de rest van de ochtend kwijt bent aan het ontwarren van de puinhoop. Een git worktree is een aparte werkdirectory op zijn eigen branch, met dezelfde repo-geschiedenis. Twee agents in twee worktrees kunnen fysiek niet elkaars bestanden aanraken. Zowel Claude Code als Codex spawnt inmiddels zelf worktrees voor parallel werk.

Skills zijn de projectkennis, vastgelegd op een plek waar de agent ze kan lezen. In beide tools werkt dat met hetzelfde soort SKILL.md-mapformaat en hetzelfde triggermodel: de description bovenaan bepaalt wanneer de agent de skill oppakt. Daarover schreef ik vorige week al in je eerste AI-strategie is een skill library. Binnen een loop zorgen skills er ook voor dat je niet elke keer opnieuw moet betalen om dezelfde intentie uit te leggen. De loop start immers bij elke run koud op, en zonder de skill valt hij terug op een zelfverzekerde gok.

Connectors zijn hoe de loop echte systemen aanraakt: koppelingen waarmee de agent zelf GitHub, Linear of je database kan bedienen, in het vak MCP-connectors genoemd, naar de open standaard waarop ze gebouwd zijn. Ze worden steeds vaker vendor-onafhankelijk en dezelfde connector werkt doorgaans in zowel Claude Code als Codex. De reden dat connectors binnen een loop ertoe doen, is dat de loop moet handelen, niet alleen praten. Een agent die zegt "hier is de fix" is een coding tool. Een loop die de PR opent, het Linear-ticket koppelt, en een berichtje naar het kanaal stuurt zodra CI groen wordt, is een klein stukje operations.

Sub-agents zijn het nuttigste structurele element dat je in een loop kunt inbouwen, en het makkelijkst om over te slaan. Je splitst de agent die het werk opstelt van de agent die het beoordeelt. Andere prompt, vaak ander model, soms ander reasoning-budget. Het model dat een functie schreef is veel te welwillend over de vraag of die functie klopt. Een verifier met een andere systeemprompt vangt wat de schrijver zichzelf heeft wijsgemaakt. Binnen een loop, waar jij de run niet zelf bekijkt, is deze splitsing de enige reden dat je daadwerkelijk kunt weglopen.

En dan is er nog het zesde element, dat te dom klinkt om ertoe te doen. Memory. Een markdown-bestand, een Linear-board, een piepklein SQLite-bestand, wat dan ook dat buiten het ene gesprek leeft. De agent vergeet alles tussen runs. De repo niet. Het state-bestand is het dragende onderdeel van elke langlopende loop die ik heb gebouwd. De loops die omvallen, falen meestal omdat iemand de state in de conversatiecontext probeerde te bewaren in plaats van daarbuiten.

Dit is eigenlijk geen tooling-discussie meer

Een jaar geleden betekende een loop een stapel bash-scripts die alleen jij zelf begreep, die op je laptop draaide, en die kapotging zodra je iets updatete. Wat me het meest verraste aan 2026 is dat de onderdelen nu gewoon in de producten zelf zitten. Zowel Claude Code als Codex hebben alle vijf de blokken plus het memory-patroon, met net iets andere namen en her en der andere details. Af of uniform is het nog niet: de implementaties verschillen op punten en er komt elk kwartaal iets bij. Maar de richting is onmiskenbaar, en de vorm is in beide dezelfde.

Concreet: de in-sessie-primitive die je moet kennen is /goal, in beide tools. Je schrijft een verifieerbare stopconditie ("alle tests in test/auth slagen en lint is schoon") en de agent blijft over meerdere beurten doorwerken tot een apart klein model beslist dat de conditie klopt. De agent die de code schreef, is niet degene die beoordeelt of het klaar is. Hier zie je de maker-en-checker-splitsing toegepast op de stopconditie zelf, en het is momenteel de nuttigste loop-primitive die in beide tools zit.

De implicatie is dat je kunt stoppen met discussiëren over welke tool. Kies degene die je team al gebruikt, en ontwerp een loop waarvan de vorm een overstap zou overleven. Mijn inschatting is dat de vijf blokken duurzamer zijn dan de producten eromheen. Het product is het substraat.

Hoe mijn loop er elke ochtend echt uitziet

Dit is de vorm die al een paar maanden standhoudt in productie, bij twee van mijn projecten. Opzettelijk onspectaculair. Het interessante is dat het één loop is, één keer ontworpen, en dat ik geen enkele afzonderlijke stap erin nog heb geprompt sinds ik de skills schreef.

Flow diagram of a morning loop running on a real repo. At 06:00 a cron schedule fires the /loop daily run inside a headless worktree. At 06:02 a triage skill called dollar-sign triage-overnight reads CI failures, open issues and recent commits, writes its findings to a memory file findings dot md. At 06:05 that findings file is the on-disk spine of the loop, surviving between runs. At 06:10 the loop spawns N worktrees, one per finding worth fixing, isolated so edits never collide. At 06:15 a maker sub-agent in each worktree drafts the fix. At 06:20 a verifier sub-agent grades the draft against the spec and the skill conventions. At 06:25 connectors open the PR via the GitHub MCP, update Linear, ping Slack when CI goes green. At 06:30 anything the verifier rejected or judgement-flagged lands in a human-gated triage inbox. At 06:35 findings dot md is updated with done, escalated, in-progress and fresh counts. A dashed card on the far left shows tomorrow the same loop picks up here, state survives. Bottom panel summarises that you designed this whole morning of triage plus drafting plus review plus PR-opening once, you did not prompt any individual step, and all five blocks are visible in this single loop.

Stap voor stap, in praktische termen.

Om 06:00 start een cron een Claude Code-sessie in een headless worktree op de repo, dus zonder scherm of iemand die meekijkt. De sessie roept één skill aan, $triage-overnight. Die skill weet hoe hij de CI-fouten van gisteravond moet lezen (CI is de geautomatiseerde straat van tests en checks die bij elke codewijziging draait), plus de open Linear-tickets en het diff sinds de laatste succesvolle loop-run. Hij schrijft zijn bevindingen naar een findings.md-bestand in de root van de repo, met een korte gecategoriseerde lijst (broken-test, dependency-flag, bug-report, content-task).

Voor elke bevinding die het waard is om automatisch aan te pakken, spawnt de loop een geïsoleerde worktree. Binnen elke worktree stelt een maker-sub-agent de fix op. Een verifier-sub-agent met een andere systeemprompt toetst het concept aan de projectskill-bestanden en de bestaande tests. De output van de verifier is de poort: als het slaagt, gebruikt de loop de GitHub-connector om een PR te openen (een pull request, een voorstel tot codewijziging dat jij kunt reviewen voordat het live gaat) en de Linear-connector om het ticket bij te werken. Als het faalt, verhuist de bevinding naar een triage-inbox, zodat ik hem later kan bekijken.

Het allerlaatste dat de run doet is findings.md herschrijven met tellingen (done, escalated, in-progress, fresh) zodat de run van morgenochtend weet welke state hij heeft geërfd. De hele loop kost 25 tot 40 minuten, afhankelijk van hoeveel bevindingen het waard zijn om te proberen. Qua tokens kost het me ongeveer evenveel als een langlopend ChatGPT-gesprek, meer als er een sub-agent op een zwaar model draait.

Het addertje dat je al kunt zien is dat de waarde van dit hele systeem in de verifier zit. Als de verifier slordig is, verstuurt de loop om zes uur 's ochtends onbeheerd slordige PR's, wat precies het tegenovergestelde is van wat ik wil. De verifier-prompt is het meest herziene stukje tekst in de loop, en dat hoort ook zo.

Het patroon dat drie iteraties overleefde

Ik heb loops zoals deze drie keer opnieuw gebouwd voor drie verschillende projecten, en de verrassende les is dat de ontwerpkeuzes die ertoe doen niet de voor de hand liggende zijn.

  • Eén memory-bestand verslaat er vijf. Ik probeerde de state te verdelen over meerdere markdown-bestanden (één per bevindingstype) en de loop raakte steeds in verwarring over welk bestand leidend was. Alles samenvoegen tot één findings.md met gecategoriseerde secties maakte het geheel veel makkelijker te doorgronden.
  • Skills worden geladen op basis van description, niet van naam. Een heldere, saaie description bovenaan de SKILL.md ("gebruik dit bij het trieren van nachtelijke CI-fouten, open Linear-tickets en recente commits") presteert beter dan een slimme naam. Beide tools kiezen skills automatisch door de description te matchen met de taak, dus een strakke description is een gratis upgrade.
  • De verifier heeft een echte spec nodig. Tegen de verifier zeggen "check of de fix goed is" is nutteloos. Zeggen "de fix moet een regressietest bevatten, mag geen bestanden buiten de falende module aanraken, en moet npm run check doorstaan" is het verschil tussen een verifier die werk verzet en een verifier die alleen maar wat aanrommelt.
  • Tokenkosten zitten in de verifier, niet in de maker. Verrassend genoeg vrat de verifier in mijn vroege loops het meeste budget op omdat hij bij elke run de volledige repo-context laadde. De verifier beperken tot het diff plus de relevante skill-bestanden verlaagde de kosten per run met ongeveer 70 procent zonder het resultaat te veranderen.
  • De triage-inbox is de veiligheidsklep. De loop zal uiteindelijk een keer verkeerd oordelen. De triage-inbox is de plek waar dat terechtkomt. Als jouw loop geen human-gated inbox heeft, draai je geen loop: je draait een ongemodereerde autopublisher.

Voor wie dit nu interessant is, en voor wie nog niet

De eerlijke vraag die een beslisser hierbij hoort te stellen is niet "moeten wij dit bouwen" maar "wat levert dit op, en zijn wij er klaar voor". Het antwoord hangt vrijwel volledig af van wat er al ligt.

Een loop is nu interessant als je een eigen codebase hebt met terugkerend, controleerbaar werk eromheen: dagelijkse CI-triage, dependency-onderhoud, content-QA, rapportages. Softwarebedrijven, bureaus met meerdere klantrepo's, en eigenlijk elke organisatie waar een developer wekelijks uren kwijt is aan werk dat een checklist zou kunnen beschrijven. De winst zit niet in spectaculaire nieuwe features, maar in het terugwinnen van precies die uren, elke week opnieuw, plus het feit dat het werk niet meer blijft liggen als de betreffende persoon vrij is.

Een loop is nog niet interessant als de basis ontbreekt. En hier past een nuchtere Nederlandse observatie: veel bedrijven die ik hier van binnen zie, missen die basis nog. Geen tests, geen CI, tickets die in mailboxen leven, documentatie die alleen in hoofden zit. Een loop versterkt wat er ligt, inclusief de rommel. Zonder tests heeft de verifier niets om tegen te toetsen, en zonder ticketsysteem heeft de triage-skill niets om te lezen. In dat geval is de realistische eerste stap niet de loop, maar de basis: tests op de kernfunctionaliteit, CI die bij elke wijziging draait, en één plek waar werk wordt bijgehouden. Dat is geen omweg. Het is dezelfde weg, en je hebt er ook zonder loop direct profijt van.

En als je helemaal geen eigen software hebt, is dit artikel vooral context voor gesprekken met je leveranciers. De vraag "draait hier een geautomatiseerde controle op, of kijkt er elke keer een mens naar" wordt de komende jaren een normale vraag om aan je bureau of softwarepartij te stellen.

Wat de loop nog steeds niet voor je doet

De loop verandert het werk. Hij haalt de engineer niet weg. En drie dingen worden juist scherper naarmate de loop beter wordt, niet makkelijker.

Verificatie blijft jouw taak. Een loop die onbeheerd draait, maakt ook onbeheerd fouten. De hele reden dat de maker-verifier-splitsing bestaat, is om de "het is klaar"-claim van de loop iets te laten betekenen. Zelfs met een sterke verifier is "klaar" een claim, geen bewijs. De PR moet nog steeds jouw review halen. De productiedeploy blijft een beslissing, en op een gegeven moment moet jij het diff kunnen lezen en ja kunnen zeggen.

Jouw begrip van de codebase erodeert nog steeds als je het laat gebeuren. Hoe sneller de loop code verstuurt die jij niet zelf hebt geschreven, hoe breder de kloof wordt tussen wat er in de repo staat en het mentale model dat jij daar daadwerkelijk van hebt. Er zijn twee manieren om daarmee om te gaan. De eerlijke: elke dag tien minuten de diffs blijven lezen die de loop verstuurt. De oneerlijke: stoppen met lezen en de kloof "leverage" noemen, tot aan de productiebrand die je niet kunt debuggen omdat je eigenlijk niet weet wat de loop de afgelopen zes maanden heeft gedaan.

Comfort is hier het gevaarlijkst. Wanneer een loop zichzelf draait, wordt het heel verleidelijk om geen mening meer te vormen over wat er wel of niet verstuurd moet worden, en gewoon aan te nemen wat er wordt teruggegeven. De loop ontwerpen werkt als tegengif als je het met oordeel doet, en als versneller als je het doet om het nadenken te vermijden. Zelfde handeling, tegenovergesteld resultaat. De loop weet niet welke van de twee jij doet. Jij wel.

Wat ik dit kwartaal zou doen als ik nog niet was begonnen

De eerlijke volgorde om je eerste bruikbare loop te laten landen, met zo min mogelijk verspilde token-uitgaven.

  1. Kies één terugkerende taak die je nu met de hand doet. Dagelijkse CI-triage, wekelijkse dependency-check, terugkerende content-QA. Iets waarvan je absoluut zou merken als een mens ermee stopte.
  2. Schrijf eerst de skill, niet de automation. Een SKILL.md die vastlegt hoe jij de taak vandaag uitvoert. Voorbeelden, edge cases, het faalpatroon dat je al drie keer hebt betrapt. De skill is het dragende onderdeel.
  3. Voeg de maker-verifier-splitsing toe voordat je parallellisme toevoegt. Eén worker, twee rollen, één worktree. Zorg dat de kwaliteit van één bevinding klopt voordat je opschaalt naar tien bevindingen per run.
  4. Sluit één connector aan die je echt nodig hebt. De meeste loops hebben lange tijd maar precies één connector nodig: GitHub. Linear en Slack komen later. Weersta de drang om op dag één vijf integraties aan te sluiten.
  5. Plan hem in. /loop op een vast ritme, of een GitHub Action met een cron plus workflow_dispatch (zodat je hem ook handmatig kunt starten), zodat de run overleeft nadat jij je laptop dichtklapt.
  6. Lees het memory-bestand elke ochtend gedurende de eerste twee weken. Dit is de niet-onderhandelbare stap. Sla je hem over, dan drijft de loop binnen twee weken af naar werk dat je niet meer kunt vertrouwen.

Waar ik uitkom

Prompt engineering was twee jaar lang de hefboom omdat de tools zichzelf nog niet konden inplannen, uitwaaieren naar geïsoleerde worktrees, of hun eigen output beoordelen. Dat kunnen ze nu wel. Goed prompten blijft een basisvaardigheid, zoals goed kunnen zoeken dat ooit werd. Maar het volgende waar je goed in wilt worden, is het systeem dat boven de agent zit: de loop, met zijn vijf onderdelen, zijn memory-bestand en zijn niet-onderhandelbare verifier.

Bouw de loop, maar bouw hem zoals een engineer die van plan is in de stoel te blijven zitten, niet zoals iemand die op zoek is naar een uitweg.

Als je een tweede paar ogen wilt op welke van je huidige handmatige workflows hier echt van zouden profiteren, of een echte draaiende loop wilt inspecteren, stuur me een bericht. Mail info@jermayads.nl of gebruik jermayads.nl/contact.