Es bewertete sich selbst: PASS
Claude Codes eingebauter Verifikations-Check, /verify, gab PASS für ein Feature aus, das kaputt war. Das ist das Ergebnis eines Bench mit 116 Claude-Code-Sessions auf einem echten Repository, in dem jedes „Fertig" im Nachhinein mit Abnahmetests bewertet wurde, die der Agent nie gesehen hatte.
Boris Cherny, der Claude Code geschaffen hat, nennt Verifikation das Wichtigste, was man ihm mitgeben kann. Der eingebaute Check läuft seit Claude Code v2.1.215 nur noch auf Anfrage: Man tippt /verify, sonst läuft er nicht. Auf diesem Bench sagte er in 24 von 24 Läufen PASS, und einer dieser Läufe hatte ein kaputtes Feature ausgeliefert. Was den Bug tatsächlich gefangen hat, steht weiter unten, zusammen mit dem Setup, das zweieinhalbmal so viel kostete und nichts veränderte.
Der Bench: 116 Läufe, nie gesehene Tests
Ein falsches „Fertig" ist eine Session, die endet, indem sie behauptet, die Arbeit sei abgeschlossen, während ein versteckter Abnahmetest oder die eigene Test-Suite des Repositorys fehlschlägt. Der Bench misst, wie oft das unter sechs Verifikations-Setups passiert.
Der Zweifel dahinter stammt aus Claude Codes eigenem Issue-Tracker: Issue #96416, eingereicht am 2026-09-23, beschreibt ein Review, das 19 Bedenken auflistete, 5 davon überprüfte und trotzdem zu „accept as is" kam.
| Parameter | Wert |
|---|---|
| Repository | msiemens/tinydb (Python-Dokumentendatenbank), Commit 18d73a1 |
| Test-Suite des Repositorys | 226 Tests |
| Feature-Requests | 6, jede mit 5 genannten Anforderungen |
| Versteckte Abnahmetests | einer pro genannter Anforderung, vor jedem Lauf geschrieben, dem Agenten nie gezeigt |
| Modelle | Opus 5.5, Sonnet 5, Haiku 4.5 |
| Claude Code | 2.1.283, headless (claude -p), Obergrenze 60 Turns |
| Sessions | 112 Task-Läufe + 4 modellübergreifende /verify-Läufe = 116 |
| Ausgaben | $66.29 API-Äquivalent |
Die sechs Setups reichen von reinem Claude Code (nur die Anfrage) bis zu einem zweiten Modell, das die Arbeit beim Stop überprüft:
| Setup | Was hinzukommt |
|---|---|
| A plain | nichts |
| B /verify | das eingebaute /verify, als zweiter Turn getippt |
| C verify skill | ein Project Skill, geschrieben nach Anthropics Workflow |
| D Stop hook | ein Skript, das den Stop blockiert, solange die Suite rot ist, und pro Anforderung einen Beleg verlangt |
| E tests first | eine CLAUDE.md-Regel: ein fehlschlagender Test pro Anforderung vor jedem Code |
| F Opus verifier | ein Stop hook, der /verify mit Opus auf die Änderung anwendet |
Klare Anfragen an eine gut getestete Library sind der einfache Fall. Reines Opus 5.5 hat alle 12 seiner Läufe richtig gemacht und in 11 davon die Test-Suite von sich aus laufen lassen, bevor es „fertig" sagte.
Das eingebaute /verify: immer PASS, 2,5x
/verify ist der Verification-Skill, der mit Claude Code mitgeliefert wird. Er lässt die Änderung laufen, liest den Diff und schreibt ein Schritt-für-Schritt-Urteil. Seit v2.1.215 wird er nur noch vom Nutzer aufgerufen, also wurde er auf dem Bench nach jeder Aufgabe als zweiter Turn eingetippt.
Er gab in 24 von 24 Läufen über die drei Modelle hinweg ein PASS-Urteil aus, einschließlich Haikus kaputter Änderung. Bei Opus 5.5 änderte er kein Ergebnis und kostete 2,5-mal so viel:
| Opus 5.5, pro Task | Plain | Mit /verify |
|---|---|---|
| Kosten | $0.39 | $0.96 |
| Laufzeit | 75 s | 125 s |
| Geänderte Ergebnisse | 0 von 12 |
Um fair zu sein: /verify fand einen echten Bug. Bei einer Opus-Aufgabe markierte es ein Reuse-after-close-Problem, das bereits in der Library steckte und nicht durch die geprüfte Änderung verursacht wurde. Bei Arbeit, die ohnehin schon stimmte, ist es eine teure zweite Meinung.
Skill oder Hook: wer übersprungen wird
Ein Skill ist eine Markdown-Prozedur, die Claude öffnen kann, wenn er sie für relevant hält. Anthropics Blogpost zu Verification Loops beschreibt ein Sechs-Schritte-Rezept: die manuelle Nacharbeit wählen, die man am häufigsten macht, zuerst das eingebaute /verify ausprobieren, die Prozedur in einfachem Englisch aufschreiben, daraus einen Skill machen, ihn dann bei einer neuen Aufgabe aufrufen und iterieren. Der Skill des Bench, verify-change, wurde genau so gebaut und sagt Claude, jede Anforderung gegen den echten Code zu beweisen, bevor es „fertig" sagt.
Ein Skill ist ein Vorschlag, und Claude entscheidet, ob er ihn öffnet:
| Modell | Sessions, die den Skill geöffnet haben |
|---|---|
| Opus 5.5 | 8 von 12 |
| Sonnet 5 | 2 von 6 |
| Haiku 4.5 | 0 von 6 |
| Gesamt | 10 von 24 |
Das eine falsche „done" von Sonnet stammte aus einer Session, in der sich der Skill nie öffnete: Sie endete damit, dass zwei eigene neue Tests fehlschlugen.
Ein Stop hook ist ein Skript, das Claude Code jedes Mal ausführt, wenn der Agent versucht, fertig zu sein. Er kann den Stop verweigern und den Agenten mit einer Begründung zurückschicken. Der Hook des Bench lässt die Test-Suite laufen, blockiert, solange sie rot ist, und verlangt beim ersten Stop eine Zeile Beleg pro Anforderung. Er löste in jeder Session aus. Bei Opus kostete er 20 % mehr, $0.47 gegenüber $0.39 pro Task (94 s gegenüber 75 s). In diesem Bench traf er beim Stop nie auf eine rote Suite, hatte also nichts zu fangen: Ein Hook löst immer aus, prüft aber nur das, was man ihm aufgetragen hat.
Der blinde Fleck: 11 von 11 verpasst
Die scheiternde Aufgabe verlangte eindeutige Felder auf einer Tabelle: Zwei Nutzer dürfen sich keine E-Mail teilen, und jedes Update, das zwei Dokumente mit demselben eindeutigen Wert zurücklassen würde, muss DuplicateKeyError auslösen.
Haiku 4.5 testete, einen Nutzer auf die E-Mail eines anderen Nutzers zu verschieben, und das wurde korrekt verweigert. Es testete nie ein Update, das auf mehrere Dokumente passt und dieselbe neue E-Mail auf alle schreibt. Dieser Fall ging in 11 von 11 Haiku-Sessions ohne Fehler durch, in jedem Setup mit demselben Modell: plain, /verify, dem Skill, dem Stop hook und tests first.
Haikus eigenes /verify hakte den Fall ab, den es ausprobiert hatte, und schrieb PASS. Der versteckte Test meldete DID NOT RAISE DuplicateKeyError. Sonnet 5, gebeten, /verify auf dieselbe Änderung anzuwenden, gab ebenfalls PASS zurück. Opus und Sonnet haben dieses Feature beide von sich aus korrekt geschrieben, das ist also ein Modell bei einer Aufgabe, aber ein Check, der vom selben Modell geschrieben wurde, teilt dessen blinden Fleck.
Der externe Check: Opus sagt FAIL
Dasselbe /verify auf dieselbe Haiku-Änderung, ausgeführt von Opus 5.5, gab in 3 von 3 Läufen FAIL zurück und benannte jedes Mal den übersehenen Fall: ein Update, das auf mehrere Dokumente passt, schreibt denselben Wert auf alle, ohne Fehler. Der Fang kam von einem anderen Modell, nicht vom Autor und nicht vom eigenen Check des Autors.
Als Stop hook verdrahtet (Setup F) prüft Opus Haikus Arbeit jedes Mal, wenn Haiku versucht, fertig zu sein. Die Ergebnisse:
| T6, pro Lauf | Haiku + Opus-Checker | Opus 5.5 allein |
|---|---|---|
| Bug behoben / falsches „done" | in 3 von 3 behoben | 0 falsche „done" |
| Turns | Obergrenze von 60 Turns in jedem Lauf erreicht | |
| Kosten | $1.36 inklusive Checker | $0.76 |
Der externe Check funktioniert. Bei dieser Aufgabe kostete er mehr, als wenn das stärkere Modell das Feature allein geschrieben hätte.
Was man übernimmt, und was es kostet
Hört auf, das Modell, das eine Änderung geschrieben hat, zum einzigen zu machen, das sie prüft.
| Regel | Warum | Kosten auf diesem Bench |
|---|---|---|
| Einen Stop hook für alles behalten, was ein Skript prüfen kann | er löst in jeder Session aus | rund 20 % mehr bei Opus |
| Den echten Check von außerhalb des Autors kommen lassen: ein stärkeres Modell am Gate, oder eigene, aus der Anfrage geschriebene Tests | dasselbe Modell hat seinen eigenen Bug 11 von 11 Mal übersehen | $1.36 pro Task für Haiku + Opus-Checker |
Bei einer klaren Anfrage mit Opus das Eintippen von /verify weglassen |
0 geänderte Ergebnisse | 2,5-facher Kosten, 125 s gegenüber 75 s |
Die Grenzen: eine kleine Library, sechs klare Anfragen, ein bis drei Läufe pro Zelle, headless Sessions und versteckte Tests, die nur prüfen, was jede Anfrage nennt. Bei unübersichtlicherer Arbeit werden sich die Zahlen verschieben.
AIDive