Modellen & evaluatie
Een groene testsuite bewijst niet dat de patch klopt
Bijna een derde van de patches die op SWE-bench Verified slagen, gedraagt zich anders dan de referentie. Wat dat betekent voor wie agents in een pijplijn zet.
Hoe diep wil je dit lezen?
3 blokken met methode, cijfers en voorbehouden — ook los open te klappen.
Wie een agent in een pijplijn zet, komt vroeg of laat bij dezelfde vraag uit: waarop baseer je dat de gegenereerde wijziging goed is? Het gebruikelijke antwoord is de testsuite. Groen is goed. Die aanname is precies wat een aantal recente studies is gaan onderzoeken, en het resultaat is ongemakkelijker dan verwacht.
De meting
Wang, Pradel en Liu stelden een directe vraag: zijn de issues die op SWE-bench als opgelost gelden, ook werkelijk correct opgelost? SWE-bench Verified is de door mensen geschoonde deelverzameling die als betrouwbaarste ijkpunt in het veld geldt, dus dit is de gunstigste omstandigheid voor de benchmark.
Hun methode heet PatchDiff: differentieel patchtesten. In plaats van te controleren of de patch de meegeleverde tests haalt, vergelijken ze het gedrag van de gegenereerde patch met dat van de referentiepatch die de menselijke ontwikkelaar destijds schreef. Twee patches die dezelfde tests halen maar zich verschillend gedragen, kunnen niet allebei goed zijn.
Op drie state-of-the-art issue-oplossers vonden ze:
Van die gedragsafwijkende patches is bij nadere inspectie 28,6% zeker onjuist, en de gerapporteerde slaagpercentages zijn daardoor met 6,2 procentpunt opgeblazen. Let op de rechterkant van de tekening: de fout gaat ook de andere kant op. Het orakel keurt niet alleen te veel goed, het keurt ook af wat klopt.
Waar de zwakke plek zit
De studie wijst niet naar het model of naar de agent, maar naar het orakel: het mechanisme dat bepaalt of een oplossing goed is. Een testsuite is een steekproef uit het bedoelde gedrag, geen specificatie ervan. Slagen zegt dus iets over de bemonsterde gevallen en niets over de rest. Dat model en agent daarnaast ook fout kunnen zitten blijft waar — het punt is dat een groen orakel dat niet zichtbaar maakt.
Wat dat concreet betekent, met een verzonnen maar alledaagse patch. Een issue vraagt om gedrag X bij lege invoer. De agent levert een wijziging die de bestaande tests haalt, door de lint komt en typecheckt.
- Wat de poort ziet — drie groene vinkjes en een diff die netjes leest.
- Wat er ontbreekt — gedrag X is alleen op het gevulde pad geïmplementeerd; de lege invoer loopt door een tak die geen enkele test raakt.
- Wat er ongevraagd bij kwam — een aanroeper verderop krijgt sindsdien een lege lijst terug waar hij voorheen een fout kreeg, en vangt die stilte niet af.
Geen van die drie regels is met de bestaande suite te zien. Dat is geen randgeval maar de gewone vorm van het probleem: de tests dekken wat iemand ooit belangrijk vond, en de patch beweegt daarbuiten.
Waarom dit systematisch is, niet incidenteel
Waarom een doelfunctie dit risico structureel creëert
Er zit een structurele reden onder. Testsuites in echte repositories zijn geschreven om regressies te vangen bij wijzigingen die mensen maken. Ze veronderstellen een auteur die de bedoeling van de code begrijpt en niet doelbewust naar de randen zoekt.
Een optimalisatieproces dat wordt afgerekend op “tests groen” heeft die veronderstelling niet. Het zoekt naar de goedkoopste wijziging die het criterium haalt, en het verschil tussen “de bug opgelost” en “de test tevreden gesteld” is voor zo'n proces niet zichtbaar. Dat is geen kwaadwilligheid; het is wat een doelfunctie doet.
Zodra een maatstaf een doel wordt, houdt hij op een goede maatstaf te zijn.
De reactie van het veld
Hoe de benchmarks zelf hierop reageren
De richting waarin benchmarks zich bewegen past bij die diagnose. SWE-Bench Pro, gepubliceerd in 2025, bestaat uit 1.865 problemen verdeeld over 41 repositories, en kiest expliciet voor taken met een lange horizon: opgaven waar een professionele engineer uren tot dagen aan werkt, vaak met wijzigingen verspreid over meerdere bestanden. De auteurs presenteren het als een besmettingsbestendige testomgeving die de complexiteit van echt softwarewerk getrouwer weergeeft.
Twee dingen vallen daaraan op. Ten eerste dat besmettingsbestendigheid een expliciet ontwerpdoel is geworden — een benchmark die al jaren openbaar is, staat in de trainingsdata van de modellen die erop worden gemeten. Ten tweede dat de moeilijkheid wordt opgezocht in lengte, niet in complexiteit per stap.
Het getal dat het meest verwaarloosd wordt
Dat sluit aan op hoe METR bekwaamheid meet. Hun metriek is de 50%-task-completion time horizon: de tijd die een menselijke expert doorgaans nodig heeft voor taken die het model in de helft van de gevallen tot een goed einde brengt. Die horizon verdubbelt sinds 2019 ongeveer elke zeven maanden.
De verdubbeling is het getal dat geciteerd wordt. Het getal dat ertoe doet zodra je een agent aan een pijplijn hangt, is de 50% in de naam van de metriek. Die horizon is gedefinieerd als de taakduur waarbij het model de helft van de keren slaagt — op taken van precies die lengte faalt het dus net zo vaak als het lukt. Mijn gevolgtrekking daaruit: een architectuur die werk aan die rand uitbesteedt, hoort falen als normale uitkomst te behandelen en niet als incident.
Wat hieruit volgt
Vanaf hier: mijn interpretatie
Alles hierboven is terug te lezen in de bronnen onderaan. Wat nu volgt staat daar niet in: het zijn de gevolgtrekkingen die ik eruit trek voor het inrichten van een pijplijn waarin agents wijzigingen voorstellen. Neem ze als voorstel, niet als bevinding.
- Een poort is een vloer, geen oordeel. Typecheck, build en tests sluiten een klasse fouten uit. Ze tonen niets aan over correctheid. Dat onderscheid hoort in de woorden die je gebruikt, anders sluipt het uit je denken.
- Differentieel testen is onderbenut. Waar referentiegedrag bestaat — de vorige versie, een tweede implementatie, een productielog — is gedrag vergelijken krachtiger dan nog een unittest toevoegen. Precies dat is wat PatchDiff aantoont.
- Maak “plausibel” een eigen categorie. Het onderscheid tussen een patch die slaagt en een patch die klopt, is de kern van deze studie. Als je review dat onderscheid niet kent, kan hij het ook niet vangen.
- Besteed menselijke aandacht asymmetrisch. Niet elke wijziging verdient hetzelfde. De verdeelsleutel die volgt uit deze cijfers is niet de omvang van de diff, maar de kosten van terugdraaien.
Waar dat op uitkomt is niet één betere poort maar een reeks controles die elk een ander soort fout vangen. Als mogelijke opbouw — niet als eis, want de meeste pijplijnen hebben niet alle lagen nodig:
- Testsuite — vangt wat iemand ooit als belangrijk heeft opgeschreven.
- Statische controle — typecheck en lint sluiten een klasse fouten uit die geen enkele test hoeft te raken.
- Gedragsvergelijking — oud tegen nieuw op dezelfde invoer; dit is de laag die in de studie hierboven aantoonbaar ontbrak.
- Toetsing op taakniveau — doet de wijziging wát het issue vroeg, en niet alleen wat de tests vroegen?
- Een mens, bij twijfel — en de verdeelsleutel is niet de omvang van de diff maar de kosten van terugdraaien.
Elke laag erbij kost tijd en onderhoud. De vraag is niet hoeveel lagen je kunt bouwen maar welke fout je op welke plek nog wilt kunnen zien.
Dat laatste is de reden dat op deze site de pijplijn wél autonoom mag mergen op groen, terwijl een vaste lijst gevoelige paden dat nooit mag — de afweging daarachter staat bij de ontwerpkeuzes.
Waar het ophoudt
Drie beperkingen, uitgeschreven
De drie bronnen hierboven zijn preprints. Twee ervan zijn peer-reviewed gepresenteerd, maar geen van de cijfers is onafhankelijk gerepliceerd, en de PatchDiff-studie kijkt naar drie oplossers op één benchmark. Andere modellen, andere scaffolds en andere codebases kunnen andere verhoudingen geven.
Wat hier ook niet uit volgt, is dat agents onbruikbaar zijn voor codewijzigingen. Het tegendeel: de studies gaan over patches die daadwerkelijk problemen oplossen. Wat eruit volgt is smaller en praktischer — dat het bewijs voor correctheid ergens anders vandaan moet komen dan uit het feit dat de meting groen was.
Toets het op je eigen systeem
Laat je eigen systeem uitzoeken of jouw poort correctheid bewijst of alleen afwezigheid van bekende fouten.
Je gaat de verificatie van dit project beoordelen. De vraag is niet of de tests slagen, maar wat slagen hier eigenlijk aantoont. Stap 1 — breng de poort in kaart. Welke geautomatiseerde controles draaien er voordat een wijziging binnenkomt? Noem per controle wat hij uitsluit, en wat hij aantoonbaar NIET uitsluit. Stap 2 — zoek de zwakke orakels. Pak drie recent gewijzigde bestanden met tests. Bedenk voor elk een wijziging die: - alle bestaande tests laat slagen, - en toch waarneembaar ander gedrag geeft dan bedoeld. Lukt dat, dan is de testsuite daar een steekproef en geen specificatie. Schrijf het concrete voorbeeld uit. Stap 3 — stel differentieel testen voor. Waar bestaat er referentiegedrag om tegen te vergelijken: een vorige versie, een tweede implementatie, vastgelegde uitvoer, productielogs? Beschrijf per plek hoe je oud en nieuw gedrag naast elkaar zou zetten, en welk verschil dan een fout betekent en welk verschil onschuldig is. Stap 4 — verdeel de aandacht. Rangschik de onderdelen van dit project niet op omvang maar op de kosten van terugdraaien. Zeg welke wijzigingen op groen door mogen, en welke een mens horen te zien — met de reden erbij. Wees expliciet over wat je niet kunt beoordelen zonder de code te draaien.
Bronnen
- Are "Solved Issues" in SWE-bench Really Solved Correctly? An Empirical StudyWang, Pradel & Liu · arXiv:2503.15223 · 2025
- SWE-Bench Pro: Can AI Agents Solve Long-Horizon Software Engineering Tasks?Deng et al. · arXiv:2509.16941 · 2025
- Measuring AI Ability to Complete Long Software TasksKwa et al. (METR) · arXiv:2503.14499 · 2025