Sechs Anwendungen, sechs E-Mail-Prüfungen, ein Konsistenzproblem

Von hyretic

Vor Coding-Agenten hatte Wiederverwendung einen eingebauten Anreiz. Code selbst zu tippen kostete Zeit, also hast du die vorhandene Bibliothek genommen, statt dieselbe Funktion noch einmal zu bauen. Dieser Anreiz ist weg. Eine zweite, dritte, sechste Implementierung derselben Logik kostet heute fast nichts, und pflegen musst du am Ende trotzdem jede einzelne.

Key Takeaways (TL;DR)

  • Rechne die Betriebskosten mit, nicht nur die Erzeugung: Bevor du eine Funktion generieren lässt, veranschlage die Jahre an Tests, Patches und Sicherheitsfixes, die danach kommen.
  • Konsistenz schlägt lokale Perfektion: Wenn dieselbe Regel in mehreren Anwendungen laufen muss, ist einheitliches Verhalten wichtiger als die jeweils sauberste Einzellösung.
  • Zieh die Grenze an Nuance und Änderungsdruck: Bündle Logik in ein gemeinsames Paket, wenn ihr Verhalten heikel ist und überall gleich sein muss. Triviale, lokale Fragmente lässt du in Ruhe.
  • Bevorzuge Korrekturen an einer Stelle: Wähle die Struktur, in der ein Bugfix einmal passiert und bei allen Nutzern der neuen Version ankommt.

Basiert auf “AI makes code cheap to create, not cheap to own” von Benjamin Cane. Das Original findest du hier: https://bencane.com/posts/2026-08-19-ai-code-cheap-to-create-not-cheap-to-own/

Der Anreiz zur Wiederverwendung war Aufwand, nicht Disziplin

Benjamin Cane baut Zahlungssysteme und schreibt auf seinem Blog Bengineering über die Ökonomie von Software. Die natürliche Bremse gegen doppelten Code war nie Disziplin, sondern Reibung. Wer eine Funktion von Hand schreibt, überlegt zweimal, ob es sie nicht schon als Library gibt. Frameworks, gemeinsame Pakete und knappe Implementierungen waren die Antwort auf diese Reibung.

Agenten haben die Reibung entfernt und damit auch den Anreiz. “Lass den Agenten das einfach bauen” fühlt sich schneller an, weil das Suchen einer passenden Bibliothek, das Lesen ihrer API und das Einbinden länger dauert als ein Prompt, der dieselbe Funktionalität in Sekunden erzeugt. Der Tausch senkt die Kosten aber nicht, er verschiebt sie. Duplizierter Code ist die klassische, messbare Form technischer Schulden, und die entsteht jetzt schneller als je zuvor. Wir alle haben Repos gesehen, in denen dieselbe Hilfsfunktion viermal leicht anders existiert. Neu ist, wie billig die fünfte Kopie dazukommt.

Sechs Implementierungen, sechs Wartungspfade

Cane rechnet es an sechs Anwendungen vor. Sie alle müssen E-Mail-Adressen gegen dieselben firmeninternen Regeln prüfen. Statt ein gemeinsames Paket zu bauen, lässt du den Agenten die Prüfung direkt in jede Anwendung schreiben. Gleicher Prompt, also gleiches Ergebnis? Nicht zwangsläufig. Am Ende stehen sechs Implementierungen, jede leicht anders.

Dann kommt der erste Bug-Report. Die betroffene Anwendung ist schnell repariert: Agent informieren, Fix einbauen, vielleicht ein paar Tests dazu, fertig. Die anderen fünf? Vielleicht haben sie denselben Fehler, vielleicht einen anderen, vielleicht keinen. Weil jede Implementierung anders aussieht, klärt sich das nur durch Nachlesen jeder einzelnen. Das Resultat ist eine Software, in der dieselbe Adresse in drei von sechs Anwendungen akzeptiert wird und in den übrigen nicht. Geht sie bei der Registrierung durch, wird aber beim Login abgewiesen, ist das kein Grenzfall, sondern ein Support-Ticket.

Wie weit “gleicher Prompt” auseinanderläuft, zeigt schon die Frage, was eine gültige Adresse ist. So könnten zwei generierte Varianten aussehen:

// JavaScript (ES2020+), Illustration, kein Code aus der Quelle

// Anwendung A
function isValidEmail(input) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.trim());
}

// Anwendung B, anderer Prompt-Lauf, gleiche Aufgabe
function isValidEmail(input) {
  const value = String(input ?? "").toLowerCase();
  return /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/.test(value);
}

Beide erfüllen die Anforderung. Variante B verlangt eine Top-Level-Domain mit mindestens zwei Zeichen und weist kunde@service.x ab, Variante A akzeptiert die Adresse. Variante A ruft .trim() direkt auf input auf und wirft einen Fehler, wenn dort null ankommt, Variante B fängt das mit String(input ?? "") ab. Solange niemand beide nebeneinanderlegt, fällt der Unterschied erst in der Produktion auf.

Der Agent trägt den Fix nicht zuverlässig in alle sechs Repos

Der stärkste Einwand gegen ein gemeinsames Paket: Wenn der Agent die sechs Kopien gebaut hat, kann er auch den Fix in alle sechs Repositories tragen. Duplikation wäre dann wieder billig, nicht nur im Erzeugen, sondern auch im Warten.

Das scheitert an der Divergenz. Sobald die sechs Implementierungen leicht voneinander abweichen, gibt es keinen einzelnen Patch zum Ausrollen. Der Agent muss jedes Repository neu analysieren, den Fehler dort separat finden und separat beheben, und ein Mensch muss jedes der sechs Ergebnisse prüfen. Das ist exakt die Arbeit, die teuer ist. Ein gemeinsames Paket hat auch einen Preis, nämlich Versionierung und das Nachziehen aller Nutzer bei einem Breaking Change. Aber das ist ein planbares Release-Problem, kein “funktioniert diese E-Mail heute oder nicht”.

“The cost of creating code has changed significantly. But the cost of managing it hasn’t.”

Schon der Satz, dass Code billig wurde und Korrektheit nicht, trifft hier nur die halbe Rechnung. Neben der Korrektheit ist auch die Konsistenz nicht billiger geworden. Testen, patchen, absichern, einheitlich halten: Jede dieser Aufgaben skaliert mit der Menge Code, die dir gehört. Der Agent hat die Spalte “Erzeugung” auf null gesetzt und die anderen unberührt gelassen.

Wo die Grenze zwischen Paket und Kopie verläuft

Die Antwort ist nicht, jede Funktion in eine eigene Library zu schneiden. So beschreibt es Cane als “Don’t go DRY crazy”: Wer aus je drei ähnlichen Zeilen ein geteiltes Paket macht, tauscht Duplikation gegen Abhängigkeits-Overhead. Die Grenze verläuft an zwei Fragen.

Wann die Logik geteilt gehörtWann Duplikation reicht
Nuanciertes Verhalten, das überall gleich sein muss (etwa die E-Mail-Prüfung)Simpler, lokal spezifischer Code, der seit Langem stabil ist
Regeln, die sich absehbar ändern und dann überall nachziehen müssenLogik, die nur eine einzige Anwendung braucht

Der Punkt, den kein Prompt für dich entscheidet: ob ein Verhalten überhaupt anwendungsübergreifend konsistent sein muss. Das ist eine fachliche Frage, und sie steht vor der Generierung, nicht danach. Wer generierten Code nur auf Lauffähigkeit prüft, besitzt ihn ohnehin nicht.

4 Schritte zur Umsetzung

  1. Vor dem Prompt die Verbund-Frage klären: Läuft dieselbe Regel in mehr als einer Anwendung und muss sie überall gleich greifen, gehört sie in ein Paket, bevor die erste Zeile generiert wird.
  2. Erst greppen, dann generieren: Eine kurze Suche über die anderen Repositories nach der Funktion, die du gerade bauen lässt, kostet zwei Minuten und spart die fünf stillen Kopien.
  3. Bugfixes auf Streuung behandeln: Taucht ein Fehler in einer generierten Implementierung auf, liste jede weitere Stelle mit derselben Aufgabe und prüfe sie einzeln, statt anzunehmen, der Fix sei überall angekommen.
  4. Die DRY-Grenze im Team festschreiben: Halte fest, ab welcher Nuance und welchem Änderungsrisiko etwas in ein gemeinsames Paket wandert, damit weder jede Hilfsfunktion zur Library wird noch dieselbe Auth-Logik sechsmal existiert.

Der Agent baut die sechste Implementierung so billig wie die erste. Warten musst du sie sechsmal.

Häufig gestellte Fragen (FAQ)

Warum wird KI-generierter Code teuer, obwohl die Erzeugung billig ist?

Weil sich nur die Erzeugungskosten geändert haben, nicht die Betriebskosten. Testen, patchen, absichern und konsistent halten wird teurer, je mehr Code einem Team gehört. Ein Agent, der eine Funktion in sechs Anwendungen einzeln generiert, erzeugt sechs Wartungsobjekte statt einem.

Wann lohnt sich ein gemeinsames Paket statt duplizierter Implementierung?

Wenn die Logik nuanciert ist, in mehreren Anwendungen läuft und sich überall gleich verhalten muss. Dann wird ein Bug an einer Stelle behoben und alle Nutzer der neuen Version bekommen den Fix. Für simple, lokal spezifische und stabile Code-Fragmente lohnt der Paket-Overhead nicht.

Kann ein Coding-Agent Bugfixes zuverlässig über mehrere Repositories verteilen?

Nicht zuverlässig. Sobald die Implementierungen leicht voneinander abweichen, gibt es keinen einzelnen Fix zum Ausrollen. Der Agent muss jedes Repository neu analysieren und ein Mensch muss jedes Ergebnis prüfen. Genau das ist die Wartungsarbeit, um die es geht.

Autor hyretic

Senior Full-Stack Developer mit Fokus auf stabiler Software-Architektur, pragmatischem Engineering und der Realität von KI im Entwickler-Alltag. Seine Wurzeln liegen im praktischen Lösen komplexer Probleme unter realen Bedingungen.

github.com/hyretic-dev

Ähnliche Artikel