blog/afk-met-ralph-50-autonome-iteraties.mdx
Alle notities

25 maart 2026

Een AI-agent vier uur zelfstandig laten programmeren: wat 50 iteraties echt opleveren

Ik liet een AI-agent vier uur zelfstandig doorwerken aan een backlog van 30 kleine taken. Het patroon heet Ralph: Claude Code op een requirements-document, in een shell-loop, en weglopen. Resultaat: 50 iteraties, $14,20 aan API-kosten, 36 schone commits en 6 reverts. Dit is wat werkte, wat kapotging en waar het echte bottleneck zit: jouw reviewtijd.

Er lag bij mij al twee maanden een kleine interne CLI-tool te wachten op onderhoud: gaten in de input-validatie, ontbrekende tests, een paar flags die wel gedocumenteerd maar nooit geïmplementeerd waren, en wat lint-schuld (achterstallige waarschuwingen van de automatische codecontrole). Zo'n 30 kleine taken waarvoor ik nooit een halve dag de tijd had. Vrijwel elk ontwikkelteam heeft zo'n lijstje.

Elke week test ik een AI-onderwerp onder echte omstandigheden. Deze week wilde ik weten of ik dat lijstje kon uitbesteden aan een AI-agent die zelfstandig doorwerkt terwijl ik iets anders doe. Het patroon heet Ralph: je zet Claude Code op een lijst met requirements (in het vak een PRD), stopt dat in een shell-loop en loopt weg. AFK, away from keyboard. De belofte is dat je terugkomt en werkende code aantreft. Ik wilde weten of dat ook echt klopte.

Ik gaf Ralph 50 iteraties en een zaterdagmiddag.

De setup, in 20 minuten

Ralph zelf is nauwelijks een systeem. Er is een PRD.md (het requirements-document met de takenlijst), een progress.txt (wat er al af is) en een shell-loop die Claude Code aanroept met beide bestanden erbij en de opdracht om precies één taak per pass uit te voeren.

Het geheel past op één scherm:

  • Docker Desktop met sandboxes ingeschakeld: afgeschermde omgevingen waarin de agent niets buiten het project kan raken
  • claude geïnstalleerd via de native binary
  • Een PRD met 30 taken die ik in 15 minuten in de plan-modus van Claude heb gedicteerd
  • Een lege progress.txt
  • Een loop-script dat claude --permission-mode acceptEdits in print-modus draait (zonder interactieve chat) en uitkijkt naar een afgesproken completion-signaal

De eerste iteratie draaide in 1m48s en committede een nette verbetering van de testdekking. Ik was bijna geneigd om er meteen mee te stoppen. Het zag er al te goed uit.

Ralph loop architecture and 50-iteration outcome breakdown

Hoe die 50 iteraties er echt uitzagen

Ik liet het 4 uur draaien. De uitsplitsing:

  • 34 iteraties: schoon succes. Pakte een taak, implementeerde die, draaide tests, committede. Geen menselijke tussenkomst nodig. Elke commit was klein, atomisch en liet zich probleemloos terugdraaien als ik het er niet mee eens was.
  • 6 iteraties: afgedwaald naar aangrenzend werk. Pakte een taak, raakte gaandeweg bestanden aan buiten de scope van de taak. De meeste hiervan heb ik behouden, want het waren oprechte verbeteringen, maar een paar heb ik moeten terugdraaien.
  • 5 iteraties: vastgelopen door ontbrekende context. Een taak verwees naar een interne API die ik niet had gedocumenteerd. Claude weigerde terecht om die te verzinnen en stelde een vraag. In een loop betekent "een vraag stellen" zoveel als "een vraag loggen en de iteratie beëindigen zonder te committen".
  • 3 iteraties: te groot. Een taak die ik in één regel had opgeschreven ("voeg input-validatie toe") bleek in werkelijkheid drie dagen werk te zijn. Claude implementeerde de helft, committede en ging verder. Die halve implementatie kostte me meer tijd om te herstellen dan wanneer ik het zelf vanaf nul had gedaan.
  • 2 iteraties: ronduit fout. Las de PRD verkeerd, implementeerde het tegenovergestelde van wat er gevraagd was. Beide binnen 30 seconden teruggedraaid.

Dus: ~68% schone winst, ~12% nuttige afwijking, ~20% had mijn ingrijpen nodig. Dat laatste getal, die 20%, is het getal dat je moet onthouden.

Waar het echt uitblinkt

De loop is niet overal even sterk in. Dit zijn de drie categorieën waarin hij op zijn best presteerde:

Testdekking aanvullen. Taken van het type "zoek het grootste bestand zonder dekking, schrijf tests tot de dekking boven de 80% uitkomt, commit". De agent leest de coverage-output, kiest een doel, schrijft een testbestand, draait de testsuite, committeert. Van de 12 iteraties met dit patroon slaagden er 11. De dekking van het project ging van 41% naar 78%.

Lint en dode code opruimen. Taken van het type "los de volgende eslint-fout op" of "verwijder de volgende ongebruikte export". Bijna machinaal perfect. Over 8 iteraties ruimde de loop 240 lint-waarschuwingen en 31 ongebruikte exports op.

Gedocumenteerde maar niet-geïmplementeerde features. Taken waarbij de spec al ergens vastlag: in een man page, een --help-blok of een TODO-comment. Claude kon zowel de spec als de omringende code lezen, implementeren en committen. Werkte in 5 van de 6 pogingen.

Het patroon: taken waarbij succes meetbaar is vanuit de repo zelf (tests slagen, lint schoon, dekking omhoog) en waarbij de spec compleet genoeg is om ertegen te toetsen. Ralph is een feedbackloop-machine: hij heeft een feedbackloop nodig om te kunnen afsluiten.

Waar het misging

Drie categorieën waarbij ik twee keer zou nadenken voordat ik de loop erop losliet:

Architectuurbeslissingen. Taken die begonnen met "bepaal of..." of "herstructureer X naar Y" gingen slecht. De agent heeft geen context om over iteraties heen een mening te vormen. Hij kiest de meest verdedigbaar ogende optie, implementeert die, en voor je het weet zit je met een refactor die je niet wilde. Ik verloor een iteratie aan de vraag of we de config van JSON naar TOML moesten verplaatsen: hij koos TOML, deed het werk, en ik draaide het geheel terug.

Alles wat dwars door de codebase snijdt. "Voeg telemetrie toe aan alle commands" vereiste dat 12 bestanden coherent werden aangepast. De agent deed 9 daarvan goed en vergat de overige 3. De halfgeïnstrumenteerde staat was erger dan helemaal geen instrumentatie.

Taken met ongeschreven constraints. Interne naamgevingsconventies, ongeschreven securityregels, "we gebruiken hier geen library X": niets daarvan staat in de PRD. De agent installeert zonder aarzelen het package dat volgens zijn eigen inschatting het beste bij de klus past. Ik betrapte één iteratie op het npm install'en van een package dat op de blocklist van de organisatie staat.

Samengevat in één overzicht:

Geef aan de loopHoud bij jezelf
Testdekking aanvullen met een meetbaar doelArchitectuurbeslissingen ("bepaal of...")
Lint-waarschuwingen en dode code opruimenWijzigingen die dwars door de hele codebase snijden
Features waarvan de spec al ergens vastligtTaken met ongeschreven regels en conventies

De cijfers waar het mij echt om gaat

Over 4 uur en 50 iteraties:

  • 36 commits die ik as-is heb doorgevoerd
  • 8 commits die ik met kleine aanpassingen heb doorgevoerd
  • 6 commits die ik heb teruggedraaid
  • 0 commits die main braken (de loop draait tests voordat er gecommit wordt)
  • API-kosten: $14,20

Het meest verrassende cijfer was de review-tijd. Elke commit kostte mij gemiddeld 80 seconden om te lezen en te accepteren of terug te draaien. Dat is, in elk geval in mijn test, het echte bottleneck van AFK-coding: niet de agent, niet de kosten, maar hoe snel jij kunt beoordelen wat hij oplevert. Bij een reviewtempo van 80 seconden per commit betekent een loop van 50 iteraties dus een uur reviewen achteraf.

Sandbox: geen optie, maar een vereiste

Ik draaide het geheel binnen Docker-sandboxes. Twee iteraties probeerden dingen die ik op bare metal niet had gewild: één draaide een destructief opruimscript voor tests dat een tmp-directory wiste die het niet had mogen aanraken; één probeerde een globale CLI-tool te installeren. Beide werden ingeperkt.

Behandel de sandbox als een harde vereiste, niet als een optimalisatie. De schade van één mislukte iteratie op je echte machine weegt zwaarder dan wat je bespaart door containerisatie over te slaan.

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

De rekensom van mijn zaterdag: $14,20 aan API-kosten en een uur reviewtijd voor een backlog die anders nooit aan de beurt was gekomen. Dat is interessant, maar niet voor iedereen op dit moment.

Nu interessant voor teams die de basis op orde hebben: versiebeheer, een testsuite die iets betekent, en iemand die commits daadwerkelijk leest. Denk aan softwarebedrijven en bureaus met een backlog van kleine, goed omschreven taken die nooit urgent genoeg zijn.

Nog niet interessant voor codebases zonder tests. De loop leunt volledig op controleerbare voltooiingscriteria; zonder testsuite kan de agent niet weten of zijn werk klopt, en jij ook niet. Ook niet voor bedrijfskritische systemen waar je geen sandbox omheen kunt zetten, en niet voor teams waar niemand tijd heeft om 50 commits te reviewen. Eerlijk is eerlijk: een flink deel van de Nederlandse softwareteams die ik tegenkom mist die basis nog. Testdekking, CI en documentatie zijn dan de eerste stap, en dat is meteen precies het huiswerk dat dit patroon vereist.

Een realistische eerste stap: één avond, een kleine niet-kritieke repo, tien piepkleine taken in een PRD, sandbox aan. En meet je eigen reviewtijd, want dat wordt jouw bottleneck, niet de kosten.

Wat ik mezelf vooraf had willen vertellen

Drie regels die ik mezelf zou meegeven als ik opnieuw zou beginnen:

  1. Maak je taken agressief klein. "Voeg input-validatie toe" is te groot. "Voeg input-validatie toe voor de --port-flag in server.go, met tests" is goed. De PRD is de enige plek waar de agent de taak kan zien. Als de taak in één regel past, past hij ook in één commit.
  2. Zorg altijd voor een voltooiingscriterium dat de agent zelf kan checken. Tests die slagen, dekking die omhooggaat, lint die schoon is, types die kloppen. Als succes niet controleerbaar is binnen de repo, kan de agent niet weten wanneer hij moet stoppen.
  3. Begroot review-tijd, niet alleen compute-tijd. Een loop van $14 die 50 commits oplevert klinkt goedkoop. Een review van 60 minuten daarbovenop verandert de rekensom.

Waar ik uitkom

Ralph is geen vervanging voor nadenken. Het is een vermenigvuldiger voor backlogs waar je al over hebt nagedacht. Als je 30 kleine, goed gespecificeerde taken hebt liggen die je hebt uitgesteld, is dit de schoonste manier die ik heb gezien om ze weg te werken. Heb je 3 architecturale beslissingen uitgesteld? Dan neemt de loop ze allemaal voor je, en dat pakt slecht uit.

Het meeste debat over tooling rond AI-coding gaat over het model. Ralph herinnert eraan dat de grotere hefboom de loop is: wat de agent leest, wat hij schrijft, wat hem stopt, wat er wordt beoordeeld. Het model is prima. In het systeem eromheen zit het echte engineeringwerk.

Ik laat mijn zaterdagloop volgend weekend opnieuw draaien. Deze keer met een kleinere backlog en een strakkere PRD.