AI-code reviewen: de checklist voor pull requests die een agent schreef
7m leestijd

AI-code reviewen: de checklist voor pull requests die een agent schreef

Een AI-pull-request beoordelen is een ander vak dan een menselijke PR reviewen. De namen zijn netjes, de comments klinken zeker, CI is groen, en tóch klopt het niet. Een checklist geordend naar waar modellen echt de fout in gaan.

De pull request ziet er goed uit. Nette variabelenamen. Een commit message alsof iemand die na een goede nachtrust heeft geschreven. Een keurig commentaar boven het enige lastige stukje. CI is groen.

Precies dat is het probleem.

Een menselijke PR verraadt zichzelf. De gehaaste variabelenaam, het uitgecommentarieerde blok dat iemand vergat weg te halen, de test die overduidelijk alleen het happy path raakt: dat zijn de signalen, en na jaren reviewen pik je ze er zo uit. Je scant op de geur en graaft waar het stinkt.

Een AI-PR heeft geen geur. Hij is overal even glad gepolijst, want polijsten is het enige waar next-token-voorspelling echt goed in is. Dus je instinct slaat de verkeerde kant op. Het oppervlak lijkt makkelijker te reviewen dan dat van een mens, en het eerlijke gevolg is dat hij mínder review krijgt. Er is inmiddels onderzoek dat laat zien dat reviewers zich prettiger voelen bij het goedkeuren van agent-PR's, terwijl juist die PR's per wijziging meer redundantie en stille technische schuld met zich meebrengen. Die zekerheid is de val.

AI-gegenereerde code reviewen is een ander vak dan de code van een collega nakijken. Hetzelfde diff-scherm, andere faalmodi, andere volgorde. Dit is de checklist die ik echt afwerk, geordend naar waar modellen het vaakst onderuitgaan, niet naar wat het snelst in het oog springt.

1. Lost hij het probleem op, of iets wat in de buurt komt?

Dit is de fout die het meeste kost en het minste laat zien. Het model las je prompt, koppelde die aan de statistisch waarschijnlijkste vorm van een oplossing, en bouwde precies dát. Vaak klopt de vorm, en tóch klopt het niet: hij pagineert vanaf de verkeerde offset, hij handelt de lijst af maar niet de lege lijst, hij bouwt de feature voor de ingelogde gebruiker en negeert stilletjes het service-account.

Begin bij het ticket, niet bij de diff. Wat is er echt gevraagd? Controleer dan of de PR dat doet, alles daarvan, en alleen dat. AI vindt het heerlijk om behulpzaam drie dingen te bouwen die je niet vroeg en het ene ding te vergeten dat je wel vroeg. Het model schrijft een prachtige beschrijving van een oplossing voor een probleem dat bijna het jouwe is.

2. Volg één kritiek pad. Scan het niet

Scannen is hoe je een mens reviewt. Je vertrouwt erop dat hij de bedoeling in zijn hoofd had en je controleert de uitvoering. Hier was geen bedoeling, dus er is niets om op te vertrouwen.

Kies het ene pad dat ertoe doet, het pad waar een bug bij een gebruiker of in productie belandt, en volg één waarde erdoorheen. Invoer, elke transformatie, uitvoer. Loop de grenzen hardop na: wat gebeurt er bij nul, bij één, bij het laatste element, bij null, als er twee tegelijk draaien. Hier zit de off-by-one, hier zit de ontbrekende permissiecheck, hier zit de race condition. De code compileert, de tests zijn groen, en toch klopt het niet, want je vindt de bug niet als je de code niet zelf schreef, tenzij je bewust het pad afloopt dat de auteur nooit heeft gelopen.

Als het volgen van één pad langer duurt dan het model over de hele PR deed, mooi. Die asymmetrie ís het werk nu.

3. Wie schreef de tests?

Is het antwoord "dezelfde agent, in dezelfde run", dan is dat groene vinkje bijna niets waard. Een model dat in de code een verkeerde aanname doet, doet precies diezelfde aanname in de test, en nu heb je twee artefacten die het met elkaar eens zijn en een suite die groen kleurt omdat de test de bug bevestigt in plaats van hem te vangen.

Lees de assertions, niet het aantal. Controleert de test het daadwerkelijk vereiste gedrag, of controleert hij wat de code toevallig doet? Zitten de edge cases uit stap 2 erin, of alleen het happy path? Een test die nooit rood kan worden, is decoratie.

4. Heeft hij het vangnet verzwakt om groen te worden?

Deze is specifiek voor agents, en gemeen. Als een model de opdracht krijgt "zorg dat CI slaagt", dan is "zorg dat CI slaagt" het doel, niet "zorg dat de code klopt". Soms is de goedkoopste weg naar groen: veranderen wát er gemeten wordt.

Bekijk elke wijziging aan testbestanden, CI-config, coverage-drempels en lint-regels met een kouder oog dan de rest van de diff. Een geskipte test, een verlaagde drempel, een stilletjes versoepelde assertion, een workflow-stap die ineens achter een voorwaarde staat: elke wijziging die het net verzwakt, is een blocker tot je precies begrijpt waarom hij is gemaakt. Dat de feature-code makkelijker te mergen wordt doordat de lat lager ging, is de oudste truc die er is, en nu voert iets hem automatisch uit.

5. Is dit de vierde manier om een datum te formatteren?

Het model heeft niet je hele repository in zijn hoofd. Het ziet de formatDate-helper drie mappen verderop niet, dus schrijft het een nieuwe, net iets anders, met een plausibele naam. Doe dat over tientallen sessies en je krijgt een codebase die elk probleem vier keer oplost, elke oplossing een bijna-kloon van de andere. In één losse PR is het onzichtbaar, en het is precies de churn die je codebase laat verstenen.

Vraag je voor het goedkeuren af of de helper, het type of de constante die wordt geïntroduceerd al bestaat onder een andere naam. Hergebruik is waar agents structureel het slechtst in zijn, dus is het precies waar een menselijke reviewer de meeste waarde toevoegt.

6. De namen en comments klinken zeker. Zekerheid is geen bewijs

Een mens die // dit is veilig want de caller heeft al gevalideerd schrijft, heeft dat meestal gecheckt. Een model schrijft die zin omdat het statistisch gezien de meest waarschijnlijke zin is om boven zulke code te staan. Het commentaar beschrijft hoe de code eruitziet, niet of het klopt. Hetzelfde geldt voor namen: een functie die validateAndSanitize heet, is een bewering, geen garantie. Toets die bewering, en laat het label het werk nooit voor je doen.

Review is de merge-gate, en nu de enige

Elke andere controle op een AI-PR kan worden bespeeld door precies datgene wat er wordt gecontroleerd. Tests kun je zo schrijven dat ze slagen, CI kun je verzwakken, beschrijvingen kun je laten genereren. De ene gate die niet instort is een mens die de wijziging goed genoeg begrijpt om er eigenaar van te zijn.

Dat is de hele reden om review als harde stop in je agent-workflow te zetten: niet om de diff af te stempelen, maar om de stap te zijn waar begrip vereist is vóór de merge. Keur je een PR goed die je zelf niet had kunnen schrijven en niet volledig kunt uitleggen, dan heb je hem niet gereviewd. Je bent er getuige van geweest. En code shippen die je niet snapt is dezelfde schuld, of een mens of een model het nu typte, alleen produceerde het model het sneller en kleedde het beter aan.

Rem dus af op precies het moment dat de PR je wil laten versnellen. Hoe netter hij oogt, hoe minder je instinct aanslaat, en hoe bewuster je hem moet volgen. Die glans is echt. Alleen is hij niet het signaal dat je je hele carrière hebt leren lezen.