Zum Inhalt springen

Generation is cheap, verification is expensive

In den letzten Monaten ist mir bei der Arbeit mit Coding Agents ein Effekt immer deutlicher geworden: Der Code selbst ist erstaunlich oft nicht mehr das Problem.

Eine Implementierung, für die ich früher vielleicht einen halben Tag eingeplant hätte, entsteht heute unter guten Bedingungen in wenigen Minuten. Ein Agent analysiert den relevanten Ausschnitt, verändert mehrere Dateien, ergänzt Unit Tests, führt Build und Lint aus und liefert anschließend einen technisch plausiblen Patch.

Beeindruckend ist das immer noch. Nur ist die Arbeit damit nicht automatisch erledigt.

Ich muss verstehen, was verändert wurde. Ich muss beurteilen, ob die fachliche Anforderung wirklich getroffen wurde. Ich muss prüfen, ob die Lösung in das bestehende Architekturmodell passt, ob ein vorhandenes Konzept fortgeführt wurde oder gerade unbemerkt ein zweites entsteht. Bei anderen Änderungen interessieren Security, Contracts, Migrationen, Betriebsverhalten oder Performance.

Dadurch entsteht eine merkwürdige Asymmetrie: Was passiert, wenn eine Implementierung fünf Minuten dauert, ein ernsthafter Review aber weiterhin zwanzig, dreißig oder sechzig Minuten Aufmerksamkeit benötigt?

Mit mehreren parallel arbeitenden Agents wird dieser Effekt noch deutlicher.

Wenn Generierung stark skaliert und parallelisiert wird, wird die Verifikation zum eigentlichen Flaschenhals.

Das ist zunächst keine Kostenrechnung. Dazu komme ich im nächsten Artikel. Mich interessiert hier eine andere Frage:

Was bedeutet Verifikation eigentlich, wenn Codegeneration billig und schnell wird?

Denn mit steigendem Durchsatz verändert sich nicht nur, wie wir Software erzeugen. Es verändert sich auch, wo die eigentliche Schwierigkeit liegt.

Generation skaliert schneller als Vertrauen.

Artikel 6 dieser Serie behandelte bereits ein verwandtes Problem: Plausibilität ist kein Wahrheitskriterium. Ein Modell kann überzeugend falsch liegen. Diesen Gedanken möchte ich hier nicht wiederholen, sondern einen Schritt weitergehen.

Wenn ein Coding Agent einen Patch erzeugt, steckt darin implizit eine weitreichende Behauptung:

Diese Änderung erfüllt die Anforderung, passt zum bestehenden System, verletzt keine relevanten Constraints und erzeugt keine unakzeptablen Nebenwirkungen.

Der Patch selbst liefert dafür zunächst noch keinen Beweis. Er ist die Behauptung.

Verifikation muss die Evidenz liefern, aufgrund derer wir bereit sind, diese Behauptung zu akzeptieren.

Das klingt abstrakter, als es im Alltag ist. Wir verwenden bereits eine ganze Reihe solcher Evidenzkanäle. Das Problem besteht eher darin, ihre Aussagekraft nicht miteinander zu verwechseln.

SignalWas es tatsächlich beantwortet
BuildLässt sich der geprüfte Code unter den gegebenen Bedingungen bauen?
TypecheckSind die vom Typsystem erfassten statischen Annahmen konsistent?
LintHält die Änderung die explizit codierten Regeln ein?
Unit TestVerhält sich eine abgegrenzte Einheit für die beschriebenen Fälle wie erwartet?
Integration TestFunktionieren mehrere beteiligte Teile in den geprüften Szenarien zusammen?
E2E / Acceptance TestFunktioniert ein konkreter Flow über mehrere Systemgrenzen hinweg?
Architecture RuleWird eine explizit modellierte strukturelle Grenze eingehalten?
Human ReviewIst die Lösung im gegebenen fachlichen und technischen Kontext plausibel?
Architecture ReviewPassen Verantwortung, Konzepte und Abhängigkeiten weiterhin zum Systemmodell?

Keine dieser Prüfungen ist wertlos. Im Gegenteil: Gute Softwareentwicklung lebt davon, möglichst viele wichtige Eigenschaften mechanisch überprüfbar zu machen. Ihre Aussagekraft besitzt nur Grenzen.

Ein grüner Build beweist keine fachliche Korrektheit. Ein Unit Test beweist nicht, dass eine Business Rule im richtigen Layer liegt. Ein E2E-Test kann einen vollständigen Benutzerfluss absichern und trotzdem nicht bemerken, dass für diesen Flow parallel zum bestehenden Mechanismus ein zweites State-Konzept eingeführt wurde.

Ein grünes Signal beweist immer nur die Frage, die wir tatsächlich gestellt haben.

Damit verändert sich die zentrale Verification-Frage. Nicht: Haben wir Tests? Sondern:

Welche Evidenz brauchen wir für diese konkrete Änderung?

Dafür hilft mir ein Begriff, den ich als Engineering-Modell verwende: die Verification Surface.

Die Verification Surface einer Änderung beschreibt die Menge relevanter fachlicher, technischer, struktureller und betrieblicher Eigenschaften, die durch die Änderung berührt und deshalb sinnvoll überprüft werden müssen.

Entscheidend ist, dass diese Fläche nicht mit der Größe eines Diffs identisch ist.

Eine mechanische Änderung kann 500 Zeilen betreffen. Vielleicht werden Mapper nach einem vorhandenen Schema angepasst, Dateien verschoben oder klar definierte DTO-Konvertierungen geändert. Der Patch ist groß, die Zahl sinnvoller Freiheitsgrade aber klein. Compiler, Tests und wenige gezielte Checks können einen erheblichen Teil der relevanten Fehlerklassen abdecken.

Eine Änderung von zehn Zeilen kann vollkommen anders aussehen.

Verification Surface: kleiner Diff, große Prüffläche

Der Diff ist winzig. Die Verification Surface ist groß.

Dasselbe gilt für zentrale State-Mechanismen, Berechtigungsentscheidungen, Schemaänderungen oder kleine Anpassungen an einem öffentlichen Contract.

Codeumfang und Verification Surface sind nicht dasselbe.

Wenn Codeproduktion immer billiger wird, verliert die Zahl geschriebener Zeilen damit noch weiter an Aussagekraft. Interessanter wird, auf wie vielen Ebenen eine Änderung falsch sein kann.

Diese Sichtweise verhindert auch eine andere Fehlentwicklung: Prüftiefe sollte nicht reflexartig mit Diff-Größe wachsen. Ein kleiner Textfix braucht keinen Architecture Review. Eine kleine Änderung an einer Authorization Rule vielleicht schon.

Ein eigenes Erlebnis hat mir diese Unterscheidung zuletzt ziemlich eindrücklich gezeigt.

In einem System existierte bereits ein regulärer Signal Store in +state. Seine Rolle war bewusst definiert. Dort lebte der relevante Business State, dort entstanden reaktive Ableitungen, und Datenflüsse sowie Zustandsveränderungen folgten einem etablierten Modell.

Später erzeugte ein Agent im application-Layer einen zweiten, selbstgebauten Store.

Zwei Stores wären für mich nicht automatisch ein Architekturfehler. Ein Source Store und ein davon getrennter ViewModel Store können vollkommen legitime Responsibilities besitzen. Wenn beide unterschiedliche Aufgaben erfüllen und diese Trennung bewusst modelliert ist, kann genau das die bessere Architektur sein.

Hier war das allerdings nicht der Fall.

Der zweite Store besaß keine eigene fachliche Responsibility. Er nahm bereits vorhandene Ableitungen, transformierte sie erneut und begann damit, State-Verantwortung zu duplizieren. Gleichzeitig mischte die Implementierung reaktive Mechanismen wie computed und effect mit einem deutlich imperativeren Stil.

Es entstanden damit zwei unterschiedliche Formen von Drift.

Die erste war Responsibility Drift: Verantwortung wanderte beziehungsweise verdoppelte sich, ohne dass dafür ein neues fachliches Konzept existierte.

Die zweite war Paradigm Drift: Innerhalb desselben Problemraums begann ein zweites Programmier- und State-Modell zu entstehen.

Lokal war der Code nicht absurd. Er konnte funktionieren. Tests konnten grün sein.

Und genau das machte die Änderung interessant. Der Agent hatte zuvor über ungefähr zehn Aufträge hinweg sehr sauber gearbeitet. Meine Aufmerksamkeit war entsprechend gesunken. Einmal schaute ich weniger tief hin – und plötzlich hatte das System ein zweites State-Konzept.

Mehrere lokal korrekte Änderungen können zusammen systemisch falsch sein und architektonische Probleme erzeugen.

Eine Änderung kann lokal korrekt und trotzdem systemisch falsch sein.

Architekturdrift ist häufig nicht die eine offensichtlich falsche Entscheidung. Sie entsteht aus einer Folge lokal plausibler Entscheidungen, die das System langsam in eine andere Richtung ziehen.

Erfolgreiche Vergangenheit verändert Aufmerksamkeit

Abschnitt betitelt „Erfolgreiche Vergangenheit verändert Aufmerksamkeit“

An diesem Beispiel interessiert mich noch ein zweiter Mechanismus.

Wenn ein Agent zehnmal hintereinander zuverlässig arbeitet, lerne ich daraus. Das ist zunächst sinnvoll. Vertrauen entsteht schließlich aus Erfahrung. Wir arbeiten mit Menschen ähnlich: Wer über Jahre gute Arbeit liefert, wird anders reviewed als jemand, dessen Änderungen regelmäßig grundlegende Probleme enthalten.

Nur besitzt dieses Vertrauen eine Nebenwirkung. Die erfolgreiche Vorgeschichte kann die Tiefe meiner Aufmerksamkeit verändern.

Das bedeutet nicht, dass Menschen faul oder nachlässig werden. Es bedeutet lediglich, dass wir begrenzte Aufmerksamkeit verteilen und dabei Wahrscheinlichkeiten berücksichtigen. Ein System, das sich lange zuverlässig verhalten hat, erscheint weniger prüfbedürftig.

Bei automatisierter Generation kann daraus ein besonderes Problem entstehen, weil die Produktionsrate gleichzeitig steigt.

Zuverlässige Vergangenheit ist kein Beweis für den nächsten Patch.

Eine gute Historie ist Evidenz für die erwartbare Zuverlässigkeit eines Workflows. Sie ersetzt aber nicht die Verifikation einer konkreten Änderung.

Genau an dieser Stelle beginnt eine Form von Schuld, die später noch wichtig wird: Verification Debt.

Architecture Review ist Responsibility Verification

Abschnitt betitelt „Architecture Review ist Responsibility Verification“

Meine Architektur versucht, Schichten bewusst langweilig zu halten. Das gilt besonders für application.

Ich möchte dort im Normalfall keine überraschende Businesslogik finden. Die Schicht aggregiert die relevanten Store-Properties beziehungsweise Use Cases und exponiert einen klaren Contract in Richtung Presentation. Wenn eine Business Rule bereits in der State-Verantwortung liegt, soll sie nicht noch einmal in application entstehen.

Dasselbe Prinzip gilt in andere Richtungen. Business Rules gehören nicht in die Presentation, nur weil dort gerade das passende Event ankommt. UI-Verantwortung wandert nicht in den Store, weil ein Signal dort bequem verfügbar ist. Infrastructure Mapping gehört nicht in State. Und eine neue State-Abstraktion braucht eine erkennbare Responsibility – nicht lediglich die Tatsache, dass man sie technisch bauen kann.

Damit beantwortet Architecture Review eine andere Frage als ein Verhaltenstest.

Ein Test kann Verhalten prüfen. Architecture Review prüft, ob die Verantwortung noch am richtigen Ort liegt.

Das ist der Grund, weshalb ich Architecture Review nicht auf Pattern Matching reduzieren würde.

Patterns sind hilfreich. Layering-Regeln sind hilfreich. Import Constraints sind hervorragend automatisierbar. Sie können beispielsweise verhindern, dass presentation direkt auf infrastructure zugreift.

Die schwierigere Frage lautet aber manchmal: Warum existiert diese neue Abstraktion überhaupt? Besitzt dieses Konzept eine eigene Verantwortung – oder modellieren wir dieselbe Verantwortung gerade ein zweites Mal?

Für solche Fragen braucht ein Reviewer ein Modell des Systems.

Heute ist genau dieses systemische Verständnis eine der Stellen, an denen erfahrene Entwickler für mich besonders wertvoll bleiben. Daraus würde ich allerdings keine dauerhafte Grenze zwischen Mensch und Maschine ableiten. Review-Modelle werden besser, Context Retrieval wird besser und Architekturwissen lässt sich zunehmend explizit verfügbar machen.

Die vorsichtigere Aussage lautet:

Systemisches Review benötigt heute häufig mehr und stabileren Kontext als lokales Diff Review.

Regeln helfen – sie kennen nur nicht jede zukünftige Abweichung

Abschnitt betitelt „Regeln helfen – sie kennen nur nicht jede zukünftige Abweichung“

Das Store-Beispiel ist auch deshalb interessant, weil die Umgebung keineswegs ungeregelt war.

Ich arbeite inzwischen mit Layering-Regeln, Agent Files, Skills, spezifischen Review-Instruktionen und mechanischen Checks. Der vorherige Artikel dieser Serie behandelte genau diese Entwicklung: Build, Lint, Tests und E2E werden zunehmend Teil einer Agent Infrastructure, in der ein Coding Agent seine Änderung selbst ausführen und überprüfen kann.

Trotzdem entstand die zweite Store-Abstraktion.

Das widerspricht dem vorherigen Artikel nicht. Es zeigt vielmehr, was explizite Regeln besonders gut können: bekannte Driftklassen.

Ein unerlaubter Import lässt sich über eine Architecture Rule verhindern. Eine falsche Dependency kann an einem Constraint scheitern. Fehlende Tests können in CI auffallen. Naming-Verstöße gehören ins Linting. Falsche Layer-Zugriffe lassen sich mechanisch begrenzen.

Schwieriger sind Divergenzen, für die noch keine Regel existiert: ein zweites konkurrierendes Konzept, eine neue implizite Responsibility, eine unnötige Abstraktion, ein Paradigm Mix oder eine technisch funktionierende Lösung, die einen vorhandenen Mechanismus drei Libraries weiter noch einmal erfindet.

Die Architekturregel müsste dieses Problem bereits kennen, um es präzise verbieten zu können.

Explizite Regeln reduzieren bekannte Driftklassen. Sie können nicht jede neue, lokal plausible Divergenz vorwegnehmen.

Deshalb halte ich die Richtung „mehr ausführbare Architekturregeln“ für richtig, ohne daraus den Schluss zu ziehen, Architecture Review werde dadurch trivial. Rule Review ist zunehmend automatisierbar. System Review bleibt momentan schwieriger.

Ein weiterer Punkt hat meine Arbeit mit Review Agents verändert: Ich möchte möglichst vermeiden, dass der Reviewer zunächst die Rechtfertigung des Implementierungsagents übernimmt.

Der Grund ist überraschend menschlich: Rhetorik ankert.

Ein eloquenter Entwickler kann eine technisch fragwürdige Entscheidung sehr überzeugend erklären. Ich habe das selbst erlebt. Vor einigen Jahren diskutierte ich mit einem fachlich ausgesprochen gebildeten und rhetorisch starken Kollegen über Microservices. Nach einem längeren Gespräch war ich beinahe davon überzeugt, dass das Konzept im Grunde grundsätzlich nicht funktionieren könne.

Irgendwann später saß ich auf dem Fahrrad und dachte:

Moment mal. Das war doch gerade Unsinn.

Nicht weil der Kollege nichts wusste. Im Gegenteil. Gerade seine fachliche Stärke machte die Argumentation überzeugend.

Das Erlebnis ist mir geblieben. Eine gute Erklärung kann meine Bewertung beeinflussen, bevor ich den eigentlichen Gegenstand unabhängig untersucht habe.

Bei AI-generiertem Code gilt dasselbe. Ein Coding Agent kann nach seiner Implementierung wunderbar erklären, warum die gewählte Lösung elegant sei, bestehende Patterns fortführe und alle Requirements erfülle.

Das ist interessante Information. Es ist aber keine Evidenz dafür, dass die Aussage stimmt.

Plausible Begründung ist keine Evidenz.

Deshalb bevorzuge ich für Review Agents eine andere Aufgabenstellung. Nicht: Erkläre, ob die Lösung des Coding Agents sinnvoll ist. Sondern eher:

Requirement
+
Constraints
+
relevanter Systemkontext
+
Diff
unabhängige Prüfung

Die Implementierungsbegründung kann später immer noch hilfreich sein. Ich möchte nur nicht, dass sie die primäre Perspektive des Verifiers bestimmt.

Ein Verifier sollte die Lösung gegen Anforderungen und Constraints prüfen, nicht gegen die Erklärung des Generators.

Independent Evidence braucht unterschiedliche Perspektiven

Abschnitt betitelt „Independent Evidence braucht unterschiedliche Perspektiven“

Damit kommt ein weiterer Begriff ins Spiel: Independent Evidence.

Es ist verführerisch, Unabhängigkeit mit der Zahl beteiligter Modelle gleichzusetzen. Agent A implementiert, Agent B reviewed – also haben wir zwei Perspektiven.

Leider folgt das nicht automatisch.

Ich habe in einem realen Workflow eine Situation erlebt, in der ein Junior mit Agent-Unterstützung implementierte und ein zweiter Junior ebenfalls mit Agent-Unterstützung reviewte. Das Ergebnis sah gut aus. Der Review-Agent fand nichts Wesentliches.

Dann stellte ein erfahrener Reviewer eine einzige kritische Frage. Die Lösung begann auseinanderzufallen. Ein anschließend bewusst stärker konfigurierter Review-Agent fand mehrere ernsthafte Probleme.

Das bedeutet nicht, dass Junioren keine AI verwenden sollten oder dass ein zweites Modell nutzlos wäre. Die interessante Beobachtung liegt woanders:

Ein Review ist nicht unabhängig, nur weil ein zweites Modell beteiligt ist.

Zwei Modelle können dieselben Annahmen übernehmen. Sie können dieselben Repository-Bereiche nicht finden, dieselbe Architekturregel übersehen, denselben unvollständigen Requirement-Context lesen und dieselbe plausible Story akzeptieren.

Unabhängigkeit entsteht deshalb stärker durch die Prüfperspektive als durch die bloße Identität des Modells.

Der Generator fragt: Wie kann ich diese Anforderung implementieren?

Der Verifier sollte eher fragen: Welche relevante Anforderung, Constraint oder Systemannahme könnte dieser Patch verletzen?

Das ist keine Garantie für Unabhängigkeit. Aber die Aufgaben sind zumindest nicht identisch.

Von starken Modellen erwarte ich inzwischen ausdrücklich Widerspruch.

Ich brauche keinen Reviewer, der mir erklärt, warum meine Idee eigentlich ziemlich gut ist. Wenn ich falsch liege, möchte ich genau das möglichst früh erfahren.

In längeren technischen Diskussionen mit Frontier-Modellen ist mir das bereits mehrfach passiert. Ich beginne mit einer relativ klaren Meinung, das Modell widerspricht an einem bestimmten Punkt, wir diskutieren die zugrunde liegenden Annahmen – und am Ende ändere ich meine ursprüngliche Position.

Das empfinde ich nicht als Scheitern des Workflows.

Das ist der Workflow.

Ich brauche keinen Reviewer, der bestätigt, dass meine Lösung plausibel ist. Ich brauche einen Reviewer, der widerspricht, wenn es dafür einen belastbaren Grund gibt.

Das bedeutet allerdings nicht, jeden Review in maximales Red Teaming zu verwandeln.

Ich habe auch das ausprobiert. Wenn ein Agent den Auftrag erhält, unter allen Umständen Risiken zu finden, findet er Risiken. Irgendwann werden theoretische Edge Cases mit derselben Energie verfolgt wie reale Architekturverletzungen. Der nächste Fix erzeugt zusätzliche Guards, Fallbacks und Abstraktionen, die wiederum neue Angriffsflächen für den nächsten Review liefern.

Das kann Software robuster machen. Es kann sie auch überdefensiv und schwer lesbar machen.

Die bessere Eigenschaft ist für mich deshalb nicht maximale Aggressivität, sondern Kalibrierung: Widersprich, wenn ein belastbarer Grund existiert. Akzeptiere eine Lösung, wenn die vorhandene Evidenz dafür ausreicht.

Independent Evidence führt zu einem verwandten Prinzip: Unterschiedliche Prüfkanäle sollten möglichst nicht nur dieselbe Frage wiederholen.

Ich nenne das Verification Diversity.

Ein implementierungsnaher Unit Test besitzt eine andere Fehlerempfindlichkeit als ein E2E-Test. Eine Architecture Rule sieht andere Probleme als ein fachlicher Reviewer. Ein statischer Typecheck findet andere Defekte als ein Security Review. Ein Review-LLM kann einen Smell erkennen, den kein Test beschreibt. Ein Fachverantwortlicher kann feststellen, dass eine technisch perfekte Implementierung schlicht die falsche Anforderung umsetzt.

Independent Evidence und Verification Diversity

Das Ziel ist nicht, möglichst viele Prüfinstanzen auf jeden Patch zu werfen.

Mehr Verifikation ist nicht automatisch bessere Verifikation. Entscheidend ist, ob unterschiedliche Kanäle unterschiedliche relevante Fehlerklassen sichtbar machen.

Daraus folgt auch, dass die Verification Surface die Prüftiefe bestimmen sollte. Eine Änderung an einem statischen Text besitzt eine kleine Surface. Ein Feature, das Presentation, Application, State, Infrastructure und API berührt, besitzt eine größere. Dann interessieren mich Layering-Grenzen, Slicing, Autarkie, etablierte Patterns, unnötige neue Dependencies und die Frage, ob vorhandene Werkzeuge wiederverwendet oder Self-Made-Solutions eingeführt wurden.

Der Umfang des Diffs ist dafür höchstens ein Signal unter mehreren.

Die Verification Surface ergibt sich stärker aus den berührten Grenzen als aus der Zahl geänderter Zeilen.

Unterschiedliche Testlevel brauchen unterschiedliche Unabhängigkeit

Abschnitt betitelt „Unterschiedliche Testlevel brauchen unterschiedliche Unabhängigkeit“

Aus dem Wunsch nach Independent Evidence sollte man keine neue dogmatische Regel ableiten.

Ich halte beispielsweise wenig von der pauschalen Forderung, dass ein Implementierungsagent seine eigenen Unit Tests nicht schreiben dürfe. Unit Tests besitzen häufig genau die Aufgabe, eine konkrete Implementierung abzusichern. Dafür ist Nähe nicht zwangsläufig ein Problem.

Ein Agent, der eine fachliche Funktion implementiert, kann sehr gut die direkt zugehörigen Unit Tests ergänzen, Randfälle abdecken und lokale Invarianten absichern. Diese Tests werden Teil des Patches und erhöhen die Evidenz für genau diese Implementierung.

Bei Acceptance- beziehungsweise E2E-Tests möchte ich dagegen tendenziell mehr Unabhängigkeit.

Dort interessiert mich weniger, ob eine einzelne Methode funktioniert, sondern ob der erwartete Flow über die relevanten Schichten hinweg funktioniert. Dafür würde ich eher einen spezialisierten Agenten mit Requirements und Systemzugriff arbeiten lassen, der den vollständigen Ablauf aus einer anderen Perspektive prüft.

Auch hier darf man die Aussagekraft nicht überdehnen. Ein E2E-Test beweist nur das erwartete Verhalten, das wir ihm beschrieben haben. Und reale Requirements sind selten vollständig.

Tests können nur gegen Erwartungen verifizieren, die ausreichend explizit vorhanden sind. Fehlende Requirements werden durch mehr Testing nicht automatisch vollständig.

Das ist eine wichtige Grenze von Verifikation überhaupt. Evidenz kann nur eine Behauptung gegen bekannte oder erschließbare Erwartungen prüfen. Wenn niemand weiß, wie sich ein Sonderfall fachlich verhalten soll, kann ein Test diese Entscheidung nicht aus dem Nichts erzeugen.

Ein guter Verifier kennt die Grenze seiner Autorität

Abschnitt betitelt „Ein guter Verifier kennt die Grenze seiner Autorität“

Genau deshalb gehört für mich zur Verifikation auch die Frage, wer eine Entscheidung überhaupt treffen darf.

Wenn eine fachliche Anforderung unklar ist, entscheidet die Fachseite. Ein Architekt oder Entwickler kann Optionen erklären, technische Konsequenzen sichtbar machen und auf Inkonsistenzen hinweisen. Er besitzt dadurch aber nicht automatisch die fachliche Autorität, eine neue Geschäftsregel zu erfinden.

Umgekehrt ist eine Architekturentscheidung nicht automatisch Sache der Fachseite, nur weil die Änderung aus einem fachlichen Ticket entstanden ist.

In meiner eigenen Arbeit ist diese Grenze relativ klar: Die Fachseite besitzt die fachliche Autorität, Engineering und Architektur die technische.

Gerade bei stärkeren Modellen sehe ich inzwischen erfreulich oft ein Verhalten, das ich ausdrücklich möchte: Das Modell erkennt eine Unklarheit und sagt sinngemäß, dass diese Frage mit den Fachverantwortlichen geklärt werden muss.

Das ist eine gute Antwort.

Artikel 10 hat diese Haltung bereits unter dem Gedanken Stop statt Raten beschrieben. Für Verifikation bedeutet sie:

Ein guter Verifier muss nicht auf jede Frage eine Antwort geben. Er muss erkennen, wann ihm die Autorität für eine Antwort fehlt.

Auch Architekturregeln selbst sind kein Naturgesetz.

Es kann Situationen geben, in denen eine Abweichung sinnvoll ist. Vielleicht verhindert ein Legacy-Contract die saubere Zielarchitektur. Vielleicht existiert eine technische Einschränkung, die ein etabliertes Pattern unpraktikabel macht. Vielleicht wäre eine vollständige Lösung möglich, aber für den konkreten Produktkontext wirtschaftlich nicht vertretbar.

Was ich als Begründung allerdings nicht akzeptiere, ist: Das geht halt nicht anders.

Wenn eine Regel gebrochen werden soll, wird die Regel selbst für mich wieder zum Gegenstand der Analyse. Warum funktioniert sie hier nicht? Welche Alternativen existieren? Gibt es eine bereits etablierte Lösung? Ist die Abweichung lokal begrenzbar? Was bedeutet sie langfristig?

Manchmal lautet die Antwort danach tatsächlich: Wir machen die Ausnahme.

Dann möchte ich sie bewusst treffen. Und wenn die wirtschaftliche Realität eine schlechtere technische Lösung erzwingt, ist das eben Tech Debt. Entscheidend ist, dass wir wissen, dass wir sie eingegangen sind.

Eine bewusste Ausnahme ist eine Entscheidung. Eine unbemerkte Ausnahme ist Architekturdrift.

Das ist kein Plädoyer für bürokratische ADRs bei jeder Kleinigkeit. Es ist ein Plädoyer dafür, relevante Abweichungen nicht versehentlich als normale Implementierungsdetails verschwinden zu lassen.

Damit lässt sich der frühere Gedanke präziser fassen.

Mit Verification Debt meine ich nicht einfach fehlende Tests.

Verification Debt entsteht, wenn Änderungen schneller erzeugt werden, als belastbare Evidenz für ihre fachliche und systemische Korrektheit aufgebaut werden kann.

Das kann mit mehreren parallel arbeitenden Agents passieren. Es kann entstehen, weil Implementierungszeit dramatisch sinkt, während Review-Zeit nicht proportional sinkt. Es kann entstehen, weil ein Team Build, Lint und Unit Tests hervorragend automatisiert hat, aber systemische Änderungen nur oberflächlich betrachtet. Oder weil ein Review-Agent gegen den lokalen Diff prüft, während die relevante konkurrierende Abstraktion außerhalb seines Contexts liegt.

Verification Debt: Generation Rate vs. Verification Capacity

Wichtig ist mir die Einschränkung: Agentic Work erzeugt nicht automatisch Verification Debt.

Wenn Verification proportional mitwächst, muss keine Schuld entstehen. Genau darin liegt der eigentliche Engineering-Auftrag.

Wir sollten nicht nur Generation skalieren. Wir müssen die Fähigkeit skalieren, deren Ergebnisse zu prüfen, einzuordnen und belastbar zu akzeptieren.

Aktuell stoße ich dabei auf eine sehr praktische Grenze.

Ich kann mehrere Coding Agents gleichzeitig starten. Einer implementiert ein Feature, ein anderer führt ein Refactoring durch, ein dritter ergänzt Tests, ein vierter arbeitet an Dokumentation.

Rechnerisch lässt sich dieser Durchsatz beinahe beliebig weiterdenken. Meine eigene Aufmerksamkeit lässt sich so nicht parallelisieren.

Wenn zwei Änderungen unterschiedliche fachliche und architektonische Kontexte besitzen, kann ich nicht beide gleichzeitig ernsthaft durchdenken. Ich kann zwischen ihnen wechseln. Ich kann Reviews delegieren. Ich kann mechanische Prüfungen automatisieren.

Aber systemisches Judgment bleibt momentan eine begrenzte Ressource.

Deshalb ist mein persönlicher Engpass inzwischen erstaunlich oft nicht das Schreiben des Codes.

Ernsthafter Review ist momentan der Engpass.

Das Wort momentan ist dabei wichtig.

Review-Modelle verbessern sich. Repository Retrieval verbessert sich. Architekturregeln werden expliziter. Modelle erhalten größere und stabilere Arbeitsräume. Vielleicht wird ein erheblicher Teil dessen, was ich heute selbst prüfe, in wenigen Jahren zuverlässig automatisierbar sein.

Die allgemeinere These benötigt deshalb keine dauerhafte Human-vs.-AI-Grenze:

Der Bottleneck wandert dorthin, wo Vertrauen noch nicht ausreichend automatisiert werden kann.

Und daraus folgt eine Grenze für Parallelisierung:

Generation darf nicht schneller skalieren als die Fähigkeit des Systems, ihre Ergebnisse belastbar zu verifizieren.

Verschiebt sich Softwareentwicklung tatsächlich zu Verification Work?

Abschnitt betitelt „Verschiebt sich Softwareentwicklung tatsächlich zu Verification Work?“

Diese persönliche Beobachtung passt inzwischen auffällig gut zu einem Teil der aktuellen Forschung. Gleichzeitig ist die Evidenz noch nicht stark genug, um daraus eine universelle Entwicklung aller Softwareteams abzuleiten.

Besonders interessant ist eine 2026 veröffentlichte longitudinale Untersuchung von Annie Vella und Kelly Blincoe. Die Autorinnen befragten professionelle Software Engineers zweimal mit sechs Monaten Abstand; 158 Personen nahmen am ersten Messzeitpunkt teil, 101 am zweiten, für 95 lagen gepaarte Längsschnittdaten vor. 82 Prozent berichteten, weniger Zeit mit dem eigentlichen Schreiben von Code zu verbringen. Die Autorinnen beschreiben einen breiteren Shift von creation zu verification und schlagen dafür die Kategorie supervisory engineering work vor: das Steuern, Bewerten und Korrigieren von AI-Output. Gleichzeitig blieb die wahrgenommene Produktivitätsverbesserung hoch, während bei den gepaarten Teilnehmenden der Anteil derjenigen, die in mindestens einer Dimension eine schlechtere Developer Experience berichteten, von 14 auf 27 Prozent stieg. Mit Stand September 2026 liegt die Arbeit als Preprint beziehungsweise eingereichtes Manuskript vor und sollte entsprechend vorsichtig eingeordnet werden.

Breiter angelegt ist die systematische Literaturübersicht von Agnia Sergeyuk, Ilya Zakharov, Ekaterina Koshchenko und Maliheh Izadi. Sie synthetisiert 90 empirische Studien zur Human-AI Experience in Entwicklungsumgebungen. Die Autoren finden sowohl Produktivitätsgewinne als auch Verification Overhead und Over-Reliance; bei der Qualitätsdimension tauchen wiederkehrend Risiken für Correctness, Maintainability und Security auf. Die Arbeit ist in Empirical Software Engineering erschienen und zeigt zugleich, wie heterogen das Feld ist und wie stark längere, realitätsnahe Evaluierungen weiterhin fehlen.

Eine weitere systematische Review- und Mapping-Arbeit von Mohamed, Assi und Guizani kommt nach 39 peer-reviewten Studien zu einem ähnlich vorsichtigen Bild: Die Mehrheit der untersuchten Arbeiten berichtet Produktivitätsvorteile, insbesondere bei Routineaufgaben und Code-Suche. Für Codequalität ergibt sich dagegen kein einheitlicher Effekt; die Befunde hängen stark von Aufgabe, Messmethode und Kontext ab.

Die Forschung spricht also durchaus für eine Verschiebung von Tätigkeiten. Sie spricht aber nicht für die einfache Gleichung, dass mehr Verification Work automatisch weniger Produktivität bedeutet.

Eine 2025 vorgestellte Untersuchung von Feiyang Xu und Kollegen betrachtet Open-Source-Projekte nach der Einführung von GitHub Copilot. Die Autoren berichten höhere Produktivität insbesondere bei weniger erfahrenen beziehungsweise peripheren Contributors, zugleich aber mehr Rework. Erfahrene Core Developer reviewten in der Analyse 6,5 Prozent mehr Code; ihre eigene Codeproduktivität sank um 19 Prozent. Die Arbeit ist als Konferenzbeitrag beziehungsweise Preprint einzuordnen. Sie ist ein interessantes Signal dafür, dass lokale Produktivitätsgewinne Arbeit innerhalb eines Systems verlagern können, aber keine universelle Effektgröße für AI-unterstützte Softwareentwicklung.

Qualitative Daten zeigen dieselbe mögliche Reibung aus einer anderen Perspektive. Sebastian Baltes, Marc Cheong und Christoph Treude analysierten für einen 2026 veröffentlichten Preprint 1.154 Beiträge aus Reddit- und Hacker-News-Diskussionen zu sogenanntem AI Slop. Ein zentraler Themencluster ihrer Codierung ist Review Friction: Entwickler diskutieren dort zusätzliche Reviewer-Belastung, Vertrauensverlust und Gegenmaßnahmen. Diese Quelle beschreibt Wahrnehmungen und Diskurse in ausgewählten Online-Communities, keine gemessene Produktivitätswirkung in repräsentativen Entwicklungsteams.

Eine weitere 2026er Preprint-Studie von Fawzy, Tahir und Blincoe mit 162 Teilnehmenden vergleicht Verifikationspraktiken zwischen Nicht-Entwicklern, Novices und professionellen Entwicklern. Die Autoren beschreiben eine perception-action gap: Das Bewusstsein für mögliche Probleme AI-generierten Codes ist relativ breit vorhanden, die Fähigkeit, den Code tatsächlich zu bewerten, zu debuggen und zu verifizieren, unterscheidet sich stärker mit Erfahrung und praktischer Programmierpraxis. Auch das ist kein Nachweis dafür, dass ausschließlich erfahrene Entwickler guten AI-Code prüfen könnten. Es stützt aber die wesentlich vorsichtigere These, dass Risikobewusstsein und Verifikationsfähigkeit unterschiedliche Kompetenzen sind.

Wer nur diese Studien auswählt, könnte leicht eine vorgefertigte Geschichte erzählen: AI produziert mehr Code, erfahrene Entwickler müssen alles reparieren und am Ende verlieren alle.

So eindeutig ist die Forschung nicht.

Randomisierte Feldexperimente bei Microsoft, Accenture und einem weiteren Fortune-100-Unternehmen umfassten zusammen 4.867 Entwickler. In der gepoolten Auswertung berichteten Cui und Kollegen rund 26 Prozent mehr erledigte Tasks für Entwickler mit Zugang zu einem generativen Coding Assistant; weniger erfahrene Entwickler zeigten dabei höhere Adoption und stärkere Produktivitätsgewinne. Die Arbeit wurde 2026 in Management Science veröffentlicht und zeigt deutlich, dass AI-Unterstützung in realen Unternehmensumgebungen auch einen positiven Gesamteffekt auf gemessenen Durchsatz besitzen kann.

In die andere Richtung ging das bekannte METR-Experiment von 2025. 16 erfahrene Open-Source-Entwickler bearbeiteten 246 reale Aufgaben in ihnen seit Jahren bekannten Repositories. Mit den damals verfügbaren AI-Tools benötigten sie im Mittel 19 Prozent länger. Besonders interessant war die Wahrnehmungslücke: Die Entwickler glaubten selbst, schneller gewesen zu sein. Ein Teil der zusätzlichen Zeit floss unter anderem in Prompting und Review des generierten Outputs.

Nur darf auch diese Zahl nicht eingefroren werden.

METR veröffentlichte im Februar 2026 neue Daten zu späteren Modellgenerationen. Diese deuteten eher auf mögliche Beschleunigung hin, waren wegen Selektionsproblemen und Schwierigkeiten bei der Zeitmessung parallel arbeitender Agents jedoch nicht robust genug für eine präzise neue Effektgröße. Die Forscher änderten deshalb selbst ihr Studiendesign.

Genau das ist für mich der wissenschaftlich interessantere Befund. Aufgabentyp, Erfahrung, Codebase, Modellgeneration, Tooling, Quality Bar, verfügbare Verification Infrastructure und Workflow verändern das Ergebnis.

Die derzeit plausibelste Zusammenfassung ist wesentlich nüchterner:

Es gibt wachsende Evidenz dafür, dass sich ein Teil der Entwicklerarbeit von Creation zu Steering, Review und Verification verschiebt. Ob daraus ein Netto-Produktivitätsgewinn oder zusätzliche Last entsteht, ist stark kontextabhängig.

Damit komme ich zurück zum zweiten Store.

Ein erfahrener Entwickler hätte diese konkrete Implementierung vermutlich nicht deshalb schneller erkannt, weil er zehn Zeilen Code schneller lesen kann. Sein Vorteil liegt an einer anderen Stelle.

Er besitzt häufig ein Systemmodell.

Er weiß, dass bereits ein Store existiert. Er kennt dessen Responsibility. Er erkennt, dass die neue Abstraktion fachlich nichts Eigenständiges modelliert. Und er sieht vielleicht auch, dass drei andere lokale Änderungen für sich genommen plausibel wirken, zusammen aber ein neues Architekturparadigma etablieren.

Genau diese Art von Wissen verändert den Wert von Erfahrung.

Der Wert eines systemverstehenden Entwicklers liegt heute zunehmend weniger darin, den Patch schneller schreiben zu können, sondern darin, zu erkennen, was die Summe vieler Patches mit dem System macht.

Das Wort heute ist wieder entscheidend.

Es gibt keinen technischen Grundsatz, nach dem ein AI-System niemals ein ausreichend gutes Systemmodell besitzen könnte. Review Agents sind bereits jetzt erstaunlich stark, wenn sie guten Context erhalten. Sie finden falsche Layer-Zugriffe, verletzte Contracts, fehlende Tests, verdächtige Error-Handling-Pfade und inkonsistente Implementierungen.

Die Schwierigkeit steigt, wenn die relevante Frage lautet: Diese Abstraktion funktioniert – aber existiert dieses Konzept nicht bereits in einem anderen Slice, und erzeugen wir dadurch langfristig zwei konkurrierende State-Modelle?

Dafür muss der Agent den relevanten Vergleichsmechanismus zunächst finden, seine semantische Beziehung verstehen und anschließend beurteilen, ob die Ähnlichkeit beabsichtigte Trennung oder unnötige Duplikation darstellt.

Das ist eine deutlich größere Verification Surface als ein lokaler Diff Review.

Review-Automatisierung skaliert nur mit erreichbarer Evidenz

Abschnitt betitelt „Review-Automatisierung skaliert nur mit erreichbarer Evidenz“

Daraus würde ich trotzdem nicht ableiten, dass AI-Review nur oberflächlich sei.

Im Gegenteil. Ich arbeite inzwischen gern mit spezialisierten Review Agents und lasse sie bewusst gegen Requirements, Architekturregeln und Diffs laufen. Gerade bei expliziten Constraints können sie enorme Mengen mechanischer Review-Arbeit übernehmen.

Der entscheidende Punkt ist ein anderer:

Review-Automatisierung skaliert nur so weit, wie relevante Evidenz und Context für den Reviewer erreichbar werden.

Das verbindet diesen Artikel mit dem vorherigen über AI-freundliche Software.

Dort lautete eine Frage: Kann der Agent Build, Lint, Tests und E2E selbst ausführen?

Hier lautet sie: Was beweisen diese grünen Ergebnisse eigentlich – und welche Qualitätsdimensionen bleiben danach noch offen?

Ein ausführbarer Arbeitsraum ist deshalb eine wichtige Grundlage für starke Verifikation. Er definiert aber noch nicht, welche Verifikation für eine konkrete Änderung ausreichend ist. Diese Entscheidung hängt von der Verification Surface ab.

Der Titel dieses Artikels lautet:

Generation is cheap, verification is expensive.

Mit expensive meine ich hier noch nicht primär Euro, Dollar oder Token.

Verifikation benötigt Aufmerksamkeit. Sie benötigt Judgment. Sie benötigt den relevanten Context. Sie benötigt manchmal unabhängige Modellläufe, manchmal echte Laufzeitumgebungen, manchmal Security-Expertise und manchmal eine fachliche Entscheidung, die kein Agent allein treffen sollte.

Generation kann innerhalb weniger Minuten vier plausible Lösungen erzeugen. Die Frage, welche davon akzeptabel ist, verschwindet dadurch nicht.

Vielleicht wird genau diese Entscheidung in Zukunft ebenfalls immer stärker automatisiert. Das wäre eine logische Fortsetzung der Entwicklung. Aber solange Generation schneller skaliert als die Fähigkeit zur belastbaren Prüfung, verschiebt sich lediglich der Engpass.

Die praktische Konsequenz daraus ist für mich ziemlich klar: Coding Agents sollten nur so weit parallelisiert werden, wie das Verification-System mit dem entstehenden Durchsatz umgehen kann. Gleichzeitig lohnt es sich, mindestens so bewusst in Review Agents, Acceptance Tests, Architecture Rules und andere Verification Infrastructure zu investieren wie in die eigentlichen Coding Agents. Und bei Änderungen mit großer systemischer Verification Surface setze ich heute weiterhin gezielt Menschen ein, die das betroffene System wirklich kennen.

Ob der letzte Punkt dauerhaft menschlich bleibt, ist offen. Das Prinzip dahinter ist allgemeiner.

Je billiger Generation wird, desto wichtiger wird die Frage, welche Evidenz wir für die Akzeptanz einer Änderung verlangen.

Wir sollten deshalb nicht nur messen, wie viel Code ein Agent erzeugen kann. Wir sollten verstehen, wie aus einem generierten Patch eine verifizierte akzeptable Änderung wird.

Denn genau dort entsteht die nächste Frage.

Wenn Verifikation Aufmerksamkeit, Modellläufe, Tests, E2E, reale Infrastruktur und menschliches Judgment benötigt – was kostet dann eigentlich eine Änderung, der wir ausreichend vertrauen können?

Das ist die ökonomische Perspektive.

Und sie gehört in den nächsten Artikel.

Code wird billiger. Vertrauen nicht automatisch. Der Bottleneck wandert dorthin, wo Vertrauen noch nicht ausreichend automatisiert werden kann.

Annie Vella, Kelly Blincoe – „The Impact of AI Coding Assistants on Software Engineering: A Longitudinal Study“, 2026.
Longitudinale Mixed-Methods-Untersuchung professioneller Softwareentwickler mit zwei Messzeitpunkten im Abstand von sechs Monaten. Relevant für den beschriebenen Shift von Creation zu Verification sowie den Begriff supervisory engineering work. Mit Stand September 2026 als Preprint beziehungsweise eingereichtes Manuskript einzuordnen.

Agnia Sergeyuk, Ilya Zakharov, Ekaterina Koshchenko, Maliheh Izadi – „Human-AI experience in integrated development environments: a systematic literature review“.
Systematische Literaturübersicht über 90 Studien, erschienen in Empirical Software Engineering. Relevant für Produktivitätsgewinne, Verification Overhead, Over-Reliance sowie Risiken für Correctness, Maintainability und Security. Die Review zeigt zugleich ein heterogenes Forschungsfeld und fordert längere und breitere Evaluierungen.

Amr Mohamed, Maram Assi, Mariam Guizani – „The Impact of LLM-Assistants on Software Developer Productivity: A Systematic Review and Mapping Study“.
Synthese von 39 peer-reviewten Arbeiten. Die Mehrheit berichtet Produktivitätsgewinne, während die Ergebnisse zur Codequalität widersprüchlich und stark kontextabhängig bleiben.

Feiyang Xu, Poonacha K. Medappa, Murat M. Tunç, Martijn Vroegindeweij, Jan C. Fransoo – „AI-assisted Programming May Decrease the Productivity of Experienced Developers by Increasing Maintenance Burden“ / „GenAI as a coding partner“.
Analyse von Open-Source-Entwicklung nach Copilot-Einführung; berichtet unter anderem mehr Review- und Rework-Arbeit bei Core Developers. Als Konferenzbeitrag beziehungsweise Preprint einzuordnen. Die Ergebnisse sind ein Hinweis auf mögliche Arbeitsverlagerung, keine universelle Effektgröße.

Sebastian Baltes, Marc Cheong, Christoph Treude – „An Endless Stream of AI Slop: How Developers Discuss the Burden of AI-Assisted Software Development“, 2026.
Qualitative Analyse von 1.154 Reddit- und Hacker-News-Beiträgen. Relevant für wahrgenommene Review Friction, Vertrauensverlust und Maintenance-Belastung. Die Datengrundlage bildet Entwicklerdiskussionen ab und darf nicht wie eine repräsentative Produktivitätsmessung interpretiert werden.

Ahmed Fawzy, Amjed Tahir, Kelly Blincoe – „From Prompting to Verification: How Experience Shapes Vibe Coding Practices“, 2026.
Survey-Preprint mit 162 Teilnehmenden aus unterschiedlichen Erfahrungsgruppen. Relevant für die beschriebene perception-action gap: Risikobewusstsein und tatsächliche Fähigkeit zur Prüfung AI-generierter Software sind nicht dasselbe.

Kevin Zheyuan Cui, Mert Demirer, Sonia Jaffe, Leon Musolff, Sida Peng, Tobias Salz – „The Effects of Generative AI on High-Skilled Work: Evidence from Three Field Experiments with Software Developers“. Management Science, online veröffentlicht am 27. Februar 2026. Veröffentlichung und DOI.
Randomisierte Feldexperimente bei Microsoft, Accenture und einem Fortune-100-Unternehmen mit insgesamt 4.867 Entwicklern. Die gepoolte Auswertung berichtet einen deutlichen Produktivitätsgewinn und dient hier als wichtige Gegenevidenz gegen eine pauschale Belastungsthese.

Joel Becker, Nate Rush, Elizabeth Barnes, David Rein / METR – „Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity“.
Randomisiertes Experiment mit 16 erfahrenen Open-Source-Entwicklern und 246 realen Tasks in vertrauten Repositories. Die frühen 2025er Tools verlangsamten die untersuchten Entwickler im Mittel um 19 Prozent. METR warnt selbst vor einer Generalisierung; spätere Daten aus 2026 deuten auf veränderte Effekte hin, sind aber nicht robust genug für eine neue präzise Effektgröße.

Die Begriffe Verification Surface, Verification Debt und Verification Diversity werden in diesem Artikel als Engineering-Modelle verwendet. Die zitierten Studien belegen nicht diese konkrete Terminologie. Sie liefern empirische Anknüpfungspunkte für Verification Overhead, veränderte Tätigkeitsverteilungen, Review-Belastung und kontextabhängige Produktivität.