Vibe Coding vs. Agentic Engineering: was den Code noch prüft, wenn die Session vorbei ist
Simon Willison zieht die Grenze bei einem Menschen, der den Code reviewt hat und ihn erklären kann. Dieses Review passiert einmal, der Code ändert sich aber weiter, nachdem der Chat zu ist. Wenn Agentic Engineering etwas anderes sein soll als ein netterer Name, dann liegt der Unterschied in einer Prüfung, die ohne jemanden im Raum läuft und die man aus dem richtigen Grund hat scheitern sehen.
Inhalt
Simon Willison hat die sauberste Definition von Vibe Coding, die ich kenne: „building software with an LLM without reviewing the code it writes“. Er sagt auch, wo es aufhört. Wenn du den Code reviewt, gründlich getestet und sichergestellt hast, dass du jemand anderem erklären kannst, wie er funktioniert („reviewed it, tested it thoroughly and made sure you could explain how it works to someone else“), dann ist das Softwareentwicklung, und daraus folgt seine eigene Regel:
I won't commit any code to my repository if I couldn't explain
exactly what it does to somebody else.
Eine gute Regel. Schau dir aber an, wo sie die Grenze zieht. Jedes Kriterium ist eine Aussage über einen Menschen zum Zeitpunkt des Commits: Er hat reviewt, er hat getestet, er könnte es erklären. Dieser Moment ist echt, und er ist eben ein Moment. Der Code ändert sich danach weiter, und mit Coding-Agents kommen die meisten späteren Änderungen aus Sessions, die die erste nie gesehen haben.
Simon Willisons Grenze für Vibe Coding betrifft einen Menschen beim Commit
Willisons Praxis hört beim Commit nicht auf. Sein Guide zu Agentic Engineering hat ein Kapitel namens „First run the tests“, in dem steht: „Automated tests are no longer optional when working with coding agents“. Test-first-Arbeit beschreibt er als den Aufbau einer Regressions-Suite, die mit dem Projekt wächst. Nichts von dem, was folgt, korrigiert ihn also. Es verschiebt etwas, das in seiner Praxis steckt, in die Definition, weil sich in der Definition entscheidet, was das Wort „Engineering“ bedeutet.
So würde ich trennen. Willisons Vibe Coding kann genau bleiben, was es ist: nicht reviewter Code. Ob ein Mensch eine Änderung verstanden hat, ist eine Frage, ob Agents sie geschrieben und ausgeführt haben, eine andere. Die Frage, die zählt, sobald der Code ausgeliefert wird, ist eine dritte: Was im Repository prüft diese Änderung noch, wenn keiner hinschaut? Ein Test mit etwas, das ihn ausführt, ein Build-Schritt, der abbricht, eine Lock-Datei mit Verifier. Jedes davon hat drei Teile: eine gespeicherte Aussage, einen Auslöser und einen Abbruch. Ein Review-Protokoll hat nur den ersten, es ist also ein Beleg und keine Prüfung. Wenn Agentic Engineering eine eigene Sache sein soll und nicht nur ein netterer Name für dieselbe Arbeit, dann unterscheidet es sich bei dieser dritten Frage.
Nichts davon ist neu für jemanden, der schon eine CI-Pipeline betrieben hat. Neu ist, wer den Kontext zwischen den Änderungen trägt. Ein Mensch, der eine Änderung reviewt hat, wusste, warum der Code so gebaut war, und wusste es auch später noch. Eine Agent-Session weiß es nur, bis das Fenster zugeht, und die nächste Session fängt ohne dieses Wissen an.
Etwas Verwandtes habe ich in „Ein Prompt ist keine Invariante“ vertreten: Eine Regel, die das Modell nur liest, wird abgewogen, eine Regel, die das Harness ausführt, bindet tatsächlich. Dort ging es um Regeln dafür, was ein Agent darf. Hier geht es um den Code, den der Agent hinterlässt, und um zwei Fragen, die der frühere Text nicht gestellt hat: ob die Prüfung nach der Session noch da ist und ob jemand sie hat scheitern sehen.
Der Design-System-Sync dieser Website: ein korrekter CSS-Fix ohne Prüfung dahinter
Mein Beispiel ist klein und stammt von mir selbst. Die Komponenten und Tokens dieser Website liegen in einer separaten Design-System-Quelle, und die Website trägt eine Kopie, die ein Sync-Skript herüberholt. Am 13. Oktober hat ein Commit Findings aus zwei getrennten Modell-Reviews auf das Layout der Website angewendet. Ein Fix ging direkt in das kopierte CSS: Eine einspaltige Regel verlor einen Spezifitätskampf gegen die zweispaltigen Regeln darüber, und so behielten auf schmalen Bildschirmen manche Elemente einen Trenner, den sie nicht haben sollten.
Der Fix war korrekt und klein genug, um ihn in einem Satz zu erklären. Ungeprüft war das Repository auch nicht, derselbe Commit hat die Layout-Checks angefasst, die die Website ohnehin ausführt. Was fehlte, war eine bestimmte Aussage: dass sich die kopierten Dateien nur über den Sync ändern. Geprüft hat das nichts. Der Fix lebte in der Kopie, kam nie in der Quelle an, und der nächste Sync aus der Quelle hätte die Datei ersetzt und ihn kommentarlos verworfen.
Sechs Tage später kamen zwei Prüfungen dazu. Der Sync schreibt für jede kopierte Datei einen Hash in eine Lock-Datei, und der Build führt zuerst einen Verifier aus. Eine Kopie, die nicht mehr zu ihrem Hash passt, stoppt also den Build, lokal und beim Hoster. Außerdem lehnt der Sync selbst ein eingehendes Bundle ab, das Regeln fallen lassen würde, die die Website schon hat, und listet diese Regeln auf. Der Commit hält fest, dass die zweite Prüfung gegen das Bundle vom 13. Oktober lief und dort die verlorene Regel benannt hat.
Die Lock-Prüfung hatte ich nie scheitern sehen, bis ich diesen Text geschrieben habe. Also habe ich eine Kommentarzeile an das kopierte CSS angehängt und den Verifier laufen lassen. Er brach mit Exit 1 ab und nannte die Datei als außerhalb des Syncs geändert. Ich habe die Datei wiederhergestellt, und er lief wieder durch. Vor diesem Lauf war das Lock eine Prüfung, an die ich geglaubt habe.
Beide Prüfungen sind enger, als sie klingen. Das Lock fängt jede Byte-Änderung in der Kopie, sagt aber nichts darüber, ob die Quelle stimmt. Der Sync-Guard sucht nach Regeln, die verschwinden. Ändere eine Deklaration in einer Regel, die ihren Selektor behält, und der Guard lässt sie durch; erst das Lock würde beim nächsten Build merken, dass sich die Kopie bewegt hat. Diese Grenzen sind in Ordnung, solange ich sie kenne. Das Problem ist eine Prüfung, deren Grenzen niemand aufgeschrieben hat, denn dann wirkt ein grüner Build aussagekräftiger, als er ist.
Tests, die ein KI-Agent in derselben Session schreibt, prüfen den Code gegen sich selbst
Der naheliegende Einwand: Agents verifizieren doch schon. Die Seite „Common workflows“ von Claude Code empfiehlt: „run the new tests and fix any failures“, außerdem solle man ein Refactoring mit „run tests for the refactored code“ prüfen und einen generierten PR vor dem Einreichen reviewen. Diese Rezepte laufen innerhalb der Session. Die Tests, die dabei entstehen, bleiben danach im Repository, was besser ist als nichts. Ob sie zählen, hängt von etwas ab, das die Session selten zeigt: ob diese Tests scheitern können.
Ein Test, den das Modell geschrieben hat, das auch den Code geschrieben hat, im selben Kontext, prüft eher, was der Code tut, als was er tun sollte. Meine Lesart ist, dass die Fehler korreliert sind: Wenn der Code die Anforderung falsch versteht, wurde der Test aus demselben Missverständnis geschrieben und stimmt ihm zu. Willisons Red/Green-Kapitel behandelt eine engere Version davon, und die Warnung darin ist kurz:
If you skip that step you risk building a test that passes already
„It’s important to confirm that the tests fail before implementing the code to make them pass.“ Der rote Lauf zeigt, dass der Test mit dem fehlenden Verhalten verbunden ist. Eine falsch verstandene Anforderung repariert er nicht, und er zählt nur, wenn der Test aus dem beabsichtigten Grund scheitert. Ein Test, der an einem Import-Fehler scheitert, hat über das Feature nichts bewiesen. Red/Green sichert das Minimum: Solange du den Test nicht aus dem richtigen Grund hast scheitern sehen, sagt ein grüner Lauf nur, dass Code und Test übereinstimmen.
Die Version mit der kaputten Prüfung habe ich an etwas erlebt, das kein Test war. Mein erster Claude-Code-Hook-Guard rief einen Parser auf, den die Testmaschine nicht hatte, schrieb dessen Fehler nach stderr und endete mit Exit 0. Der Befehl, den er blockieren sollte, lief also, und Claude Code protokollierte einen sauberen Status. Zur Prüfung wurde er erst mit Strict Mode und einem Abbruch bei Fehlschlag, und ich habe den Parser absichtlich kaputt gemacht und zugesehen, wie der Aufruf abgelehnt wurde.
Instruktionsdateien zeigen dasselbe Muster. In 90 Läufen mit AGENTS.md-Zeilen hob die Datei, die den Testbefehl nannte, die Testläufe eines Modells von 0/5 auf 5/5, und das virale „without breaking anything“ zeigte darüber hinaus keinen klaren Effekt. Die Datei unterschied sich von der Baseline in mehr als einem Satz, die Zuschreibung an die Befehlszeile ist also ein Schluss, und einige UI-Läufe führten eine Python-Suite aus, die über die UI nichts sagte. Trotzdem hat die Zeile, die auf eine existierende Prüfung zeigte, mehr bewirkt als die Zeile, die auf Verifikation hoffte.
Agentic Engineering ist ein Label, und das Label trägt die Disziplin nicht
„Agentic Engineering“ kursiert als der seriösere Name für das Programmieren mit Agents. Willison hat im Februar notiert, dass der Begriff auftaucht, vor allem bei Andrej Karpathy und Addy Osmani. Seine eigene Definition ist bewusst schlicht: „the practice of developing software with the assistance of coding agents“. Vibe Coding soll seine ursprüngliche Bedeutung behalten, als Begriff für „unreviewed, prototype-quality LLM-generated code“, und ich bin dafür, beide Wörter zu behalten.
Vorsichtig wäre ich damit, was das zweite Wort verspricht. Einen Workflow umzubenennen ändert nicht, was im Repository liegt. Ein Team kann seine Arbeit Agentic Engineering nennen und trotzdem ausliefern, was ein Vibe Coder ausliefert: Code aus einer Session, Tests aus einer Session, die der Agent geschrieben und bestanden hat, und nichts, das läuft, wenn die Session vorbei ist. Das gilt auch umgekehrt. Ein Wochenend-Skript mit einem Test, den jemand hat scheitern sehen, und einem CI-Job, der ihn ausführt, ist Engineering, egal wie sein Autor den Nachmittag nennt.
Wann Vibe Coding in Ordnung ist und wann der Code seine Prüfungen überlebt hat
Vibe Coding ist in Ordnung für Code, dessen Leben mit der Session endet: ein einmaliges Skript, ein Prototyp, den du wegwirfst. In Willisons Worten: „Projects should be low stakes“, und für risikoarmen Wegwerf-Code würde ich nichts hinzufügen.
Die Lebensdauer ist aber nicht das einzige Maß, und Willisons eigenes Kriterium, wie viel auf dem Spiel steht, ist das bessere. Eine Datenbereinigung, die du einmal ausführst, kann bleibenden Schaden anrichten, und ein langlebiges Spielzeug kann harmlos bleiben. Worauf ich achten würde, ist die Kombination: Code, der wiederverwendet wird, von späteren Sessions geändert wird oder dem man etwas Wichtiges anvertraut. Die Session-Grenze zählt, weil dort der Kontext verloren geht, warum der Code so gebaut ist.
Schief geht es, wenn Wegwerf-Praxis auf Code angewendet wird, der kein Wegwerf-Code geblieben ist: ein Skript, das am Ende auf einem Timer landet, ein schneller Fix an einer kopierten Datei, die sich als genau die Kopie herausstellt, die alle ausliefern. Am Code ändert sich in diesem Moment nichts, nur wie lange er lebt und was von ihm abhängt, und die Session, die ihn geschrieben hat, sieht beides nie.
Mein einziger Rat an jemanden, der Vibe Coding betreibt und das sicher weitermachen will: Achte darauf, wann Code die Session überlebt, die ihn geschrieben hat, und füg an diesem Punkt eine Prüfung hinzu, die ohne dich läuft. Ein Review reicht dafür nicht, ein Satz in einem Prompt auch nicht. Es muss ein Test, ein Build-Schritt oder ein Lock sein, etwas, auf das die nächste Session stößt, ob sie die Vorgeschichte kennt oder nicht. Schreib auf, was die Prüfung nicht abdeckt. Dann mach den Code einmal absichtlich kaputt, genau so, wie die Prüfung es fangen soll, und sieh zu, wie sie scheitert. Wenn sie nicht scheitert, hast du noch keine Prüfung, sondern eine Log-Zeile, die sagt, dass alles in Ordnung ist.
01 / Diskussion
Hier gibt es keine Kommentarspalte. Diskussionen laufen auf X.
02 / Weitere Artikel
Claude Code Worktrees: was claude --worktree isoliert und welche Ports, Datenbanken und Installationen nicht
Getestet mit Claude Code 2.1.316: Zwei Worktrees kollidierten auf demselben Port, Docker Compose plante für jeden ein eigenes Postgres-Volume, Skript-Läufe hinterließen gesperrte Checkouts und übrig gebliebene Branches, und die Standardbasis ließ den nicht gepushten Commit weg.
Claude Ultra ersetzt Max 20x: kein 5-Stunden-Limit für verifizierte Accounts, und laut Anthropic war das Wochenlimit immer 10x
Die 20x im alten Namen beschrieben das 5-Stunden-Fenster, den großzügigeren von zwei Zählern. Laut Anthropic lag das Wochenlimit vom ersten Tag an bei 10x Pro. Die Ultra-Preisseite nennt jetzt die Wochenzahl und streicht die 5-Stunden-Zahl. Für manche ist das ein Gewinn, für alle, die 20x als Wochenvolumen gelesen haben, eine Korrektur.
Prompt-Injection-Beispiele gegen Coding-Agents: wo der Text hineinkam und was ihn aufgehalten hat, falls überhaupt etwas
Neun öffentliche Fälle, sortiert nach der Tür, durch die die Worte des Angreifers kamen. In den meisten hat während des Angriffs nichts gehalten. Die Fixes danach folgten alle einem Muster: Entweder wurde eine deterministische Prüfung neu ausgerichtet, oder eine Fähigkeit fiel weg. Ein Modellurteil, das versagt hat, lässt sich nicht neu ausrichten.