AIDive

Shopifys 4 Gates in Claude Code: Nur Tests zahlten sich aus

Von AIDive · Veröffentlicht am

Coding-AgentsAutomatisierung & Workflows

Intro: das Gate, das „fertig“ ablehnt

Ein Gate, so wie Shopify das Wort benutzt, ist eine Prüfung, die eine von KI geschriebene Änderung bestehen muss, bevor sie weiterkommt. In Claude Code nachgebaut, hat sich nur das erste ausgezahlt: die Akzeptanztests. Shopify hat vier Gates veröffentlicht und keine Zahlen. Dieses Experiment baut sie auf einem echten Repository nach, lässt fünfzig Anfragen laufen, jeweils mit einem anderen abgeschalteten Gate, und zählt, was jedes gefangen hat und was es gekostet hat.

Helix ging am 21. September 2026 an die Öffentlichkeit. Es schickt jeden Checkpoint der Reihe nach durch vier Gates: Tests, Design-Review, zwei Reviewer und einen Engineer. Der Beitrag nennt keine Bestehensquote. Die Reviewer sind der Teil, den die meisten kopieren, und in diesen fünfzig Läufen bewegte sich die Bestehensquote nur, wenn die Tests im Spiel waren. Die Reviewer brachten nichts, bei ungefähr dreifachen Kosten.

Zwei weitere Ergebnisse stammen aus demselben Bench. Ein Hook, der angeblich nicht umgangen werden kann, hat in seiner eigenen Dokumentation drei Ausgänge. Und als Tests und Reviewer sich widersprachen, tat der Agent etwas, das niemand eingeplant hatte. Die Zählung beginnt beim Fall ganz ohne Gate.

Vier Gates, null Zahlen, ein Bench

Das Bench-Repository ist tinydb, eine echte Dokumentendatenbank, mit 226 grünen Tests auf dem verwendeten Commit.

Helix ist Shopifys internes Tool, um die mobilen Apps zurück auf nativen Code zu bringen. Der Beitrag formuliert die Regel unmissverständlich: Jeder Checkpoint durchläuft der Reihe nach vier Gates.

Gate Was es laut Shopifys Beitrag tut
Behaviour Führt Tests aus, bei denen jeder relevante Fall bestehen muss
Design Lässt ein zweites Modell als perfektionistischen Design-Reviewer auftreten
Review Zwei unabhängige Reviewer-Agenten mit isoliertem Kontext; die Schleife wiederholt sich, bis beide zustimmen
Engineer Ein Mensch schließt die Schleife

Der Satz, der das Design verkauft, lautet: „An attempt is allowed to be wrong. It is not allowed to ship until it isn't.“ Das Design-Gate entfällt bei einer Bibliothek, und laut Beitrag überspringt eine reine Logikänderung es einfach.

Was der Beitrag nie liefert, ist eine Zahl. Die Shop app wurde in 12 Wochen neu gebaut, und die Shopify app hat mehr als 300 Screens, das ist die ganze Buchführung. Es gibt keine Bestehensquote, keine Kosten und keine Zahl durchgerutschter Fehler.

Der Bench besteht aus fünf Anfragen, so getippt, wie Entwickler sie tippen: Push- und Pull-Operationen, eine Between-Abfrage, eine Tabellenumbenennung, eine sortierte Suche und eine Schreib-Cache-Größe. Hinter jeder Anfrage stehen fünf versteckte Anforderungen, die der Agent nie sieht, also das, was ein sorgfältiger Senior-Engineer erwarten würde. Das ergibt insgesamt 25 Anforderungen.

Der Worker ist Sonnet 5.5, headless ausgeführt. Fünf Konfigurationen mal fünf Aufgaben mal zwei Wiederholungen ergibt 50 Läufe. Ein Vorbehalt gilt: Die expliziten Fassungen dieser Anfragen bestehen auf Anhieb, deshalb wurden die Prompts auf das gekürzt, was Leute tatsächlich tippen.

Ganz ohne Gate bestehen 35 der 50 Anforderungen. Das sind 70%, bei drei vollständig sauberen Läufen von zehn.

Die Sortieraufgabe zeigt, wie die Fehlschläge aussehen. Der Agent hat jedes Dokument mit dem Sortierfeld indiziert, und sobald ein Dokument es nicht hat, stürzt die ganze Suche ab. Fünf Anforderungen, null bestanden, ein fehlender Schlüssel.

Der Hook, der „fertig“ ablehnt, und seine drei Ausgänge

Ein Stop hook ist ein Skript, das Claude Code jedes Mal ausführt, wenn der Agent versucht, seinen Turn zu beenden. Anthropics eigener Leitfaden benennt das Problem, das er adressiert: Claude hört auf, wenn die Arbeit fertig aussieht. Ohne eine Prüfung, die es ausführen kann, ist „sieht fertig aus“ das einzige verfügbare Signal, und du wirst selbst zur Verifikationsschleife.

Der Hook steht in der Settings-Datei des Projekts, unter hooks, Stop, als ein Befehl mit Timeout. Hier ist es ein einzeiliger Wrapper, der das Gate-Skript aufruft. Der Vertrag ist der Exit-Code: 0 lässt den Turn enden, 2 blockiert ihn, und alles, was das Skript auf die Standardfehlerausgabe geschrieben hat, geht als Begründung zurück an den Agenten.

In der Praxis läuft das so. Der Agent fasst seine Änderung zusammen und hält an. Der Hook führt die Akzeptanztests aus, einer schlägt fehl, und der Turn endet nicht. Der Agent liest den Fehler als Hook-Feedback, in diesem Fall ein Test, der einen Typfehler erwartete und keinen bekam, korrigiert den Code und hält wieder an. Diesmal bleibt das Gate still.

Eine Regel im Prompt ist ein Ratschlag. Ein Hook nicht. Trotzdem listet dieselbe Dokumentationsseite drei Auswege auf.

Ausgang Was die Dokumentation sagt
Das Limit Nachdem Stop hooks den Turn 8 Mal in Folge fortgesetzt haben, übergeht Claude Code den nächsten Block und beendet den Turn. Der Zähler wird jedes Mal zurückgesetzt, wenn der Agent ein Tool aufruft, und eine Umgebungsvariable erhöht ihn.
Der Timeout Standardmäßig 600 Sekunden für einen Command hook, und ein Hook, der in den Timeout läuft, liefert keine Entscheidung. Eine langsame Testsuite öffnet das Gate von selbst.
Das Flag Die Hook-Eingabe enthält stop_hook_active, true, wenn die Session gerade wegen eines Stop hook weiterläuft. Die Docs sagen, man solle es prüfen, damit man nie auf einer Bedingung blockiert, die sich nicht auflösen kann.

Das Gate hier protokolliert dieses Flag und ignoriert es. Es gibt nach sechs Blocks von selbst auf, damit die Schleifen zählbar bleiben.

Es gibt noch einen weiteren Ausgang, den niemand dokumentiert. Nachdem der Agent einmal blockiert wurde, suchte er nach den Tests: Er führte cat auf das Hook-Skript aus und durchsuchte die ganze Festplatte nach der Testdatei. Nur die Allow-Liste hielt ihn auf. Deshalb liegen die Akzeptanztests außerhalb des Repository-Baums, die Settings verbieten das Lesen des Hooks und der versteckten Tests, und der Agent sieht den Fehler, aber nie die Datei.

Gate 1: die Akzeptanztests

Das Akzeptanztest-Gate ist eine Menge von Tests, unabhängig vom Implementierer geschrieben, die definieren, was „fertig“ bedeutet. Shopifys erstes Gate sind nicht die eigenen Tests des Agenten. Ein Subagent erzeugt pro Checkpoint Testfälle im Integrationsstil und drängt auf Randfälle jenseits des Happy Path, und diese Tests definieren, was bewiesen heißt.

Der Writer ist hier deshalb ein separates headless Sonnet. Er sieht die Anfrage und das Repository vor der Änderung, nur lesend, kann keinen Code ausführen und soll pro Verhalten, das ein sorgfältiger Senior erwarten würde, einen Test schreiben: fehlende Felder, falsche Typen, Grenzwerte, Persistenz, den Cache und unverändertes bestehendes Verhalten. Er schreibt zwischen 23 und 53 Tests, im Schnitt 39, in etwa 40 Sekunden. Die Datei landet außerhalb des Repositorys, sodass der Agent bei einem fehlschlagenden Test die Assertion liest und nie den Test.

Allein mit Tests steigt die Bestehensquote von 70% auf 84%: 42 von 50 Anforderungen und sechs vollständig saubere Läufe statt drei.

Aufgabe Ohne Tests Mit Tests
Sortierte Suche 5 von 10 10 von 10
Schreib-Cache-Größe 8 von 10 10 von 10
Push und Pull 4 von 10 4 von 10

Der Absturz bei fehlendem Feld in der Sortieraufgabe ist genau die Art Fall, nach der der Writer fragt. Bei der Cache-Aufgabe verlangte der Writer einen Value Error für eine Cache-Größe unter eins.

Die Push-und-Pull-Aufgabe bewegt sich nicht. Sie verfehlt drei Anforderungen, zwei davon betreffen ein Dokument ohne das Feld, und die Anfrage sagte dazu nichts. Der Writer legt sich genau dort nicht fest, wo der Prompt schweigt: Sein Test akzeptiert einen Fehler oder ein stilles No-op, deshalb kann das Gate keine Anforderung zurückholen, die niemand formuliert hat.

Über die 30 Läufe mit Test-Gate hinweg schickte das Gate den Agenten 28 Mal zurück, weil eine echte Anforderung fehlschlug, und fünf Mal, obwohl alle bestanden. Einer dieser fünf war die Umbenennungsaufgabe: Der Writer wollte Namen ablehnen, die keine Strings sind, niemand hatte das verlangt, und der Agent verlor dadurch eine Runde.

Die erste Version dieses Gates führte die eigenen Tests des Implementierers erneut aus. Sie ließ jeden Lauf beim ersten Stopp durch, während eine versteckte Anforderung fehlschlug, denn die Tests eines Agenten testen das, was er gebaut hat.

Der Preis des Gates sind $0.20 pro Lauf statt $0.085 und 60 Sekunden statt 33.

Gate 3: zwei Reviewer, wie Shopify es geschrieben hat

Das Review-Gate ist ein Paar von Reviewer-Agenten, jeder in einem frischen Kontext. Shopifys Formulierung: Zwei unabhängige Reviewer-Agenten mit isoliertem Kontext prüfen den neuen Code, jedes Finding muss behoben werden, und die Schleife wiederholt sich, bis beide Reviewer zustimmen. Anthropics Leitfaden erklärt, warum Isolation wichtig ist: Ein Reviewer in einem frischen Kontext sieht nur den Diff und die Kriterien, die man ihm gibt, nicht die Überlegungen, die zur Änderung geführt haben.

Jeder Reviewer ist hier ein headless Sonnet mit Nur-Lese-Tools und höchstens 15 Turns. Er liefert sein Urteil als strukturiertes JSON: ein approve-Flag und Findings, jeweils mit der Schwere blocking oder minor. Zwei Reviewer laufen parallel auf der Anfrage und dem vollständigen Diff, ihre Findings werden zusammengeführt, und das Gate blockiert, wenn einer von beiden etwas Blockierendes findet. Ein Paar kostet pro Stopp zwischen 3 und 6 Cent.

Konfiguration Bestandene Anforderungen Bestehensquote Blocks
Kein Gate 35 von 50 70% keine
Nur Reviewer 34 von 50 68% 1 in 10 Läufen
Nur Tests 42 von 50 84% 6 in 10 Läufen (3 berechtigt, 3 falsch)
Reviewer nach den Tests 41 von 50 82% 2 in 10 Läufen, beide berechtigt

Nur Reviewer landen zwei Punkte unter gar keinem Gate, und Reviewer nach den Tests landen zwei Punkte unter den Tests allein.

Die Sortieraufgabe erklärt die Zahl. In einem Lauf blockierten beide Reviewer: Das Sortieren indiziert das Dokument, ein Dokument ohne dieses Feld löst einen Key Error aus, und die ganze Suche schlägt fehl. Der Agent behob es und bestand fünf von fünf.

In zwei anderen Läufen sahen beide Reviewer exakt denselben Absturz und stuften ihn als minor ein. Ein Dokument ohne das Sortierfeld löst einen nackten Key Error aus, und der Docstring dokumentiert das. Beide Reviewer stimmten zu, und beide Läufe endeten bei null von fünf. Dasselbe Modell, derselbe Diff, derselbe Bug, zwei verschiedene Schweregrade. Die Reviewer lagen nie falsch, wenn sie blockierten. Das Problem ist, was sie durchwinken.

Ein Paper vom August maß dieselbe Form auf einem öffentlichen Benchmark. Zero-shot erreichte 77%, ein Reviewer 77% und zwei unabhängige Reviewer 75%, alles im Rauschen von gar keinem Review.

Setup auf LiveCodeBench Score
Zero-shot 77%
Ein Reviewer 77%
Zwei unabhängige Reviewer 75%
Reviewer plus Critic (adversarial review) 87%

Reviewer plus Critic und die Schleife, die nie endet

Adversarial review ist ein Reviewer, kombiniert mit einem Critic, der das Review durch strukturierten Widerspruch prüft, bevor der Haupt-Agent editiert. Dasselbe Paper fand, dass dies die Form ist, die funktioniert. Sie erreichte 87%, wo zwei Reviewer 75% erreichten, und schlug die stärkste Baseline mit fünf Agenten bei 82%.

Benchmark Zero-shot Mit adversarial review Kosten
SWE-bench 71.6 75.2 etwa 4.5x die Tokens

Also kam der Critic ins Gate. Reviewer A prüft. Critic B bekommt die Findings plus den Diff und stempelt jedes Finding als bestätigt oder abgelehnt. Nur ein bestätigtes blockierendes Finding schließt das Gate.

Auf diesem Repository ergab das 39 von 50, also 78%. Das Critic-Paar blockierte in zehn Läufen kein einziges Mal. Während der Validierung lehnte es tatsächlich ein falsches Finding ab, bei dem die Form mit zwei Reviewern geblockt hätte.

Was der Critic nicht beheben konnte, ist die Schleife. Drei Läufe erreichten sechs Blocks am selben Akzeptanztest, und das Gate gab auf, während die echte Anforderung bei jedem Stopp weiter fehlschlug. In zwei davon war der blockierende Test der eigene Fehler des Writers, und der Agent sagte das auch: Er werde den Code nicht für einen Test ändern, den er nicht lesen könne.

Der dritte Fall ist der, den man sich merken sollte. Der Akzeptanztest wollte, dass ein fehlschlagendes Update jedes Dokument unberührt lässt, also schrieb der Agent die Update-Methode der Tabelle um. Die Reviewer blockierten das, weil die Änderung an der Update-Methode nicht verlangt war und die Aufgabe aus zwei neuen Funktionen bestand. Der Agent machte es rückgängig. Seine letzte Nachricht sagte, der Akzeptanztest und das Code-Review verlangten Gegensätzliches, deshalb habe er angehalten, ohne etwas zu ändern. Sechs Blocks später ließ ihn der Zähler laufen.

Die Schwelle, bei der das Gate aufgibt, liegt hier bei sechs. Claude Codes eigenes Limit liegt bei acht aufeinanderfolgenden Blocks und wird bei jedem Tool-Aufruf zurückgesetzt, deshalb hat es in fünfzig Läufen kein einziges Mal ausgelöst.

Gate 4 bist du: was beim Menschen ankam, die Rechnung, das Kit

Das vierte Gate ist der Engineer, und Shopifys Beitrag verspricht, dass die Gates nicht laxer werden, wenn niemand zusieht. Beim Engineer kommt an, was die anderen Gates durchlassen. Die Tabelle unten beantwortet, welches Gate sich bezahlt gemacht hat.

Konfiguration Bestanden von 50 Bestehensquote Kosten pro Lauf Für den Menschen übrig
Kein Gate 35 70% $0.085 15
Akzeptanztests 42 84% $0.20 8
Nur Reviewer 34 68% $0.15 16
Tests mit Reviewern 41 82% $0.28 9
Tests mit Reviewer plus Critic 39 78% $0.28 11

Jede Zeile mit Gate braucht 54 bis 86 Sekunden pro Lauf, gegenüber 33 ohne Gate.

Die Blocks über alle fünfzig Läufe verteilen sich wie folgt. Die Tests schickten den Agenten 28 Mal zu Recht und fünf Mal zu Unrecht zurück. Die Reviewer blockierten drei Mal, nie zu Unrecht, und drei Schleifen gaben auf. Die gesamte Matrix kostete $9.95 an API-Ausgaben zum Listenpreis, wie die CLI sie meldet, und etwa 3136 Sekunden oder 52 Minuten summierte Worker-Zeit.

Das Urteil für ein Repository wie dieses: das Test-Gate behalten, mit einem Writer, der nicht der Implementierer ist, und Tests, die der Agent nicht editieren kann. Mit etwa einem falschen Block von sechs ist zu rechnen, und die Schleife braucht einen Zähler. Das Zwei-Reviewer-Gate in der Form, wie Shopify es geschrieben hat, bewegte die Bestehensquote hier in keiner der beiden Varianten. Wer es behält, sollte es als Hinweis im Feedback behalten, nicht als Hürde.

Eine Falle am Rand. Die Docs beschreiben ein nacktes Flag, das hooks, skills, plugins und memory für skriptgesteuerte Aufrufe überspringt. Bei einem Abo-Login liest es nur einen API-Key und liefert einen Fehler, daher ist jeder Reviewer stattdessen mit einer leeren Settings-Quelle und deaktivierten Hooks isoliert.

Die Grenzen sind real: ein Repository, ein Worker-Modell, fünf Aufgaben, zwei Wiederholungen pro Zelle. Ein Abstand von zwei Punkten zwischen Zeilen ist Rauschen. Die vierzehn Punkte zwischen keinem Gate und dem Test-Gate sind es nicht. Das Design-Gate wurde nicht gebaut, und der Engineer wurde nicht gemessen.

Von Shopifys vier Gates hat sich auf diesem Repository nur das der Tests ausgezahlt. Das gesamte Kit steckt im kostenlosen Paket: die Settings-Datei mit dem Hook und der Deny-Liste, das Stop-Skript, das Gate, die Writer- und Reviewer-Befehle mit ihren Schemas und die Ledger-Vorlage.

Kostenlose Ressourcen

Quellen

Häufige Fragen

Welches von Shopifys vier KI-Gates lohnt den Nachbau in Claude Code?
Das Akzeptanztest-Gate. Bei 50 Läufen auf tinydb hob es die Bestehensquote von 70% auf 84%, während das Zwei-Reviewer-Gate sie nicht bewegte (68% allein, 82% nach den Tests).
Wie hindere ich Claude Code daran, „fertig“ zu melden, bevor die Tests bestehen?
Füge in den Projekt-Settings einen Stop hook hinzu, der deine Akzeptanztests ausführt und bei einem Fehlschlag mit Code 2 endet. Claude Code blockiert dann das Ende des Turns und reicht alles, was das Skript auf die Standardfehlerausgabe geschrieben hat, als Begründung an den Agenten zurück.
Kann man Claude Code mit einem Stop hook wirklich zum Weiterarbeiten zwingen?
Nicht vollständig. Die Hooks-Dokumentation nennt ein Limit von 8 aufeinanderfolgenden Blocks, das bei jedem Tool-Aufruf zurückgesetzt wird, einen Standard-Timeout von 600 Sekunden, der keine Entscheidung liefert, und das Flag stop_hook_active, das man prüfen soll. Füge einen eigenen Block-Zähler hinzu, damit Schleifen vorhersehbar enden.
Verbessern zwei unabhängige KI-Code-Reviewer die Ausgabe des Agenten?
In diesem Test nicht. Zwei Sonnet-Reviewer erreichten allein 68% und nach den Tests 82%, jeweils zwei Punkte unter der Baseline, weil sie in zwei Läufen einen echten Absturz als minor einstuften. Ein Paper maß dieselbe Form auf LiveCodeBench: 77% zero-shot, 75% mit zwei Reviewern, 87% mit Reviewer plus Critic.
Wie viel kostet jedes Gate pro Lauf in Claude Code?
Die Kosten pro Lauf zum API-Listenpreis betrugen $0.085 ohne Gate, $0.20 mit Akzeptanztests, $0.15 mit Reviewern allein und $0.28 mit Tests plus Reviewern. Läufe mit Gate dauerten 54 bis 86 Sekunden gegenüber 33.
Wie verhindere ich, dass der Agent die versteckten Akzeptanztests liest?
Lege die Tests außerhalb des Repository-Baums ab und verbiete in den Settings das Lesen des Hook-Skripts und der Testdateien. Der Agent sieht dann die fehlschlagende Assertion, aber nie die Datei.

Ähnliche Videos