Koffers pakken voor Berlijn
Thomas Luijken
—
Engineering

Written by
Agents schrijven sneller code dan een team kan reviewen. Wij lossen dat niet op met slimmere agents, maar met strengere guardrails.
Onze agents brengen een GitHub-issue nu van begin tot eind naar een draaiende deployment. We maakten het af op een vrijdagmiddag. Zondagavond had de pipeline al zeven pull requests verwerkt. Hier lees je wat de agents zelf doen, waar we nog ingrijpen en waarom de guardrails belangrijker zijn dan de agents.
Jorrit schreef op LinkedIn dat Baseflow naar Berlijn gaat zodra we onze manier van werken met AI volledig hebben omgegooid. Ik las die post twee keer. Daarna keek ik naar de pipeline die we de afgelopen dagen voor een van onze interne tools hebben gebouwd, en ik zie ons er al staan.
Zo ziet die pipeline er vandaag de dag uit. Elke agent daarin is Claude Code, aangestuurd vanuit onze GitHub Actions-workflows door de open-source claude-code-action van Anthropic. Het staat nog in de kinderschoenen en volgt een uitgesproken filosofie, maar het verstuurt nu al code naar ons cluster zonder dat iemand daarvoor een editor hoeft te openen.
Eén issue, één voorstel, één akkoord
Alles begint met een GitHub-issue. Zodra het wordt geopend, leest een proposal-agent het, kijkt door de codebase en schrijft een kort plan terug: wat er verandert, in welke bestanden, ongeveer hoeveel regels. Een persoon beoordeelt dit plan en reageert in de discussiethread. Is het voorstel te breed, wordt het verkeerde bestand aangepast of is er een scenario over het hoofd gezien? De agent verwerkt de opmerkingen en komt met een aangepast voorstel, zo vaak als nodig is. Pas als het plan klopt, geef je het startsein.
Die goedkeuring is het eerste punt waarop we bewust een mens aan het roer houden. Een agent die begint met programmeren voordat er overeenstemming is over de aard van de wijziging, verspilt in het gunstigste geval tokens, en creëert in het slechtste geval een pull request waar niemand om heeft gevraagd.
Zodra er goedkeuring is, pakt een implementatie-agent de taak op, voert de wijziging door in een aparte branch en opent een pull request. Mocht het proces vastlopen, dan wordt dit in de pull request aangegeven en wordt er om hulp gevraagd. Een developer reageert vervolgens in de discussiethread, waarna de agent het werk vanaf dat punt voortzet.
Review door agents, met een harde grens

Elke pull request draait eerst de unittests en een Docker-build. Pas als die allebei slagen, start de review-agent. Die gebruikt de code review-skill uit de open-source BMAD Method, die in drie rondes reviewt: een blind hunter die naar bugs zoekt zonder het issue te lezen, een edge case hunter die elke vertakking en grens langsloopt, en een acceptance auditor die de wijziging toetst aan wat er gevraagd was. Bevindingen gaan op drie stapels: nu fixen, doorschuiven naar een vervolg, of afwijzen.
Moet er iets gefixt worden, dan commit een fix-agent de oplossing en draait de review opnieuw. Hier zit onze favoriete guardrail. We staan twee automatische fixrondes toe. Vindt de derde review nog steeds problemen, dan stopt de pipeline en vraagt om een menselijke reviewer. Twee agents die het oneens zijn, kunnen elkaar eindeloos bezighouden, en daar hoort niemand voor te betalen.
Is de review schoon en blijft de wijziging binnen ons budget van ongeveer 300 regels, dan keurt de agent goed, squash-merget, sluit het gekoppelde issue en start de build. Vanaf dat punt is het heerlijk saai: CI publiceert een geversioneerde image, FluxCD ziet de nieuwe tag in de registry en rolt hem binnen een half uur uit naar het cluster. Niemand raakt een deployment met de hand aan.
Eén weekend verder, in cijfers
Het meeste hiervan was vrijdagmiddag klaar, en toen begon het weekend. Voor de pipeline maakte dat niet uit: hij mergede zijn eerste pull request op vrijdag, nog twee op zaterdag, en op zondag legde de review-agent zeven vervolgissues vast en kreeg het cluster nog vier deployments, terwijl wij vanaf de bank voorstellen goedkeurden.
- 7 pull requests gereviewd, gemerged en uitgerold door de pipeline
- 1 pull request tegengehouden voor een mens en nooit gemerged
- 7 issues vastgelegd door de review-agent, waarvan er vier al live staan
- <2 uur van een vers issue tot draaiend op het cluster
Alle cijfers komen uit de GitHub-historie van de repository en de deploy-commits van FluxCD. De vier issues die live staan, zijn de vier deployments van zondag.
De pull request die niet werd gemerged, is onze favoriet. De eerste poging om een indicator te introduceren in de app, die laat zien wanneer de data voor het laatst ververst is, kwam terug met 620 toegevoegde regels in 18 bestanden, en de fix uit de review veranderde de authenticatie-middleware voor elk HTMX-request in de app. De review-agent loste zijn eigen twee bevindingen op en weigerde daarna alsnog: de PR was te groot en had een enorme blast radius, hier moet een developer naar kijken. We sloten hem, scherpten de scope-regels voor de agents aan en openden een nieuw issue. De tweede poging was 58 regels, had één fixronde nodig en stond binnen twee uur gemerged en draaiend op het cluster.
De voorstel-lus werkt zoals je zou willen. Bij het issue over gelijktijdige synchronisatie sloeg het eerste voorstel van de proposal-agent stilletjes een sync over die al liep. Een developer plaatste in de issue-thread een opmerking en vroeg om in plaats daarvan een uitgeschakelde knop met "Synchroniseren". Het voorstel werd herzien, waarna de developer enkel antwoordde met "ziet er goed uit, bouw maar". De wijziging stond dezelfde middag nog live.
Guardrails waar we blij mee zijn
- Twee correctierondes, dan een developer. De limiet wordt geteld vanaf de commits in de pull request (PR), dus geen enkele agent kan er zomaar voorbijgaan. Tot nu toe hadden twee PR's elk één ronde nodig en geen van beide bereikte de limiet.
- Alleen kleine wijzigingen. Ongeveer 300 gewijzigde regels per PR. Een groter idee komt terug als een voorstel om het op te splitsen, en een grotere PR wordt nooit automatisch gemerged.
- Eenmalige uitvoeringen. Elke agent heeft één taak en een vast aantal beurten. Geen achtergrondwerk, geen wachttijden, geen half afgeronde reviews.
- Alleen samenvoegen bij groen licht. Tests, build, review en elke externe controle. Als de pipeline een controle niet kan lezen, wordt de merge geweigerd in plaats van te gokken of deze check geslaagd is.
- Menselijke signalen winnen. Een titel "work-in-progress", een handmatig toegewezen reviewer of een wijzigingsverzoek schakelt auto-merge voor die PR uit.
- De meest luie oplossing die werkt. Elke agent voert ponytail uit, de open-source skill van Dietrich Gebert, die de standaardbibliotheek verkiest boven aangepaste code, en liever 1 regel code schrijft dan 50. We hebben daar bovenop onze eigen regels voor de scope toegevoegd: geen ad-hoc refactoring, en ontdekte bugs worden vervolgtickets in plaats van scope creep.
Uitgestelde bevindingen worden de voorstellen van morgen
💡 Alles wat de review-agent doorschuift, wordt vastgelegd als nieuw issue, met een label waaruit blijkt dat een agent het heeft voorgesteld. Elk issue start een nieuw voorstel. De backlog onderhoudt zichzelf, en een mens zegt nog steeds ja tegen elk item voordat er code wordt geschreven.
Daarmee is de cirkel voor ons rond. Reviewbevindingen die te groot waren voor de huidige PR verdwenen vroeger in een commentthread. Nu staan ze de volgende ochtend klaar als plan, met een schatting van de omvang en een reden.
Eerlijk: het is nog vroeg
De pipeline is pas een paar dagen oud en we hebben er al delen van herschreven. De ingebouwde automatisering van GitHub, die issues sluit via bijvoorbeeld "closes #12", sloeg stilletjes drie merges over; daarom sluiten we issues nu expliciet. Ook kwam het voor dat de review-agent zijn taak beëindigde terwijl zijn eigen hulp-agents nog aan het werk waren; de drie reviewrondes worden daarom nu na elkaar uitgevoerd. Elk van deze aanpassingen verliep via een kleine pull request (PR) door diezelfde pipeline: een uitstekende manier om je eigen vangrails te testen.
Er valt nog genoeg te verfijnen: de kwaliteit van de voorstellen, de toegestane kosten voor een review, en hoe we hetzelfde proces kunnen toepassen op repositories van klanten die andere regels hanteren. We blijven delen wat we gaandeweg leren.
Begin bij je eigen regels
Pak de laatste pull request die bij jullie werd tegengehouden en schrijf op waarom. Te groot, te riskant, een check die faalde: elke reden die je opschrijft, is een regel die een agent kan volgen. Een reden die alleen in iemands hoofd zit, kan een agent niet toepassen.
En werken jullie al met agents in je pipeline? Ik hoor graag hoe jullie dit aanpakken.



