Leitfaden: Vom Prototyp zur Produktion
Technische Schulden in KI-generiertem Code erkennen
Technische Schulden sind Abkürzungen, die heute Zeit sparen und später bei jeder Änderung Zinsen kosten. Generierter Code erzeugt bestimmte Sorten davon besonders leicht, weil ein Sprachmodell die aktuelle Aufgabe löst, nicht die nächsten Jahre der Anwendung. Dieser Leitfaden ordnet sechs typische Schuldarten, mit Symptomen, die auch ohne Programmierkenntnisse sichtbar sind.

Kurz beantwortet
Typisch für KI-generierten Code sind sechs Schuldarten: Duplikate statt Wiederverwendung, fehlende Abstraktionsschichten, ein Datenmodell ohne Migrationshistorie, Konfiguration im Code, fehlende Tests und Abhängigkeiten ohne Pflegepfad. Erkennbar sind sie an Symptomen wie Fehlern, die an mehreren Stellen einzeln behoben werden müssen, oder Updates, die niemand einzuspielen wagt.
01
Was sind technische Schulden, und warum entstehen sie bei KI-Code anders?
Technische Schulden sind Strukturentscheidungen, die eine Änderung heute schneller machen und jede spätere teurer. In KI-generiertem Code entstehen sie oft beiläufig: Jeder Prompt löst eine Aufgabe für sich, der Code läuft und wird übernommen, und die nächste Aufgabe baut daneben statt darauf. Sichtbar wird die Schuld erst, wenn sich etwas ändern muss.
Dieser Leitfaden gehört zur Reihe Vom Prototyp zur produktionsreifen Anwendung. Er fragt nicht, ob eine Anwendung heute sicher ist, sondern was sie auf Dauer an Änderungen kostet.
Ein Sprachmodell sieht beim Generieren nur den Ausschnitt der Anwendung, der in seinem Kontext liegt. Existiert eine passende Funktion in einer anderen Datei, schreibt es womöglich eine neue. Das Ergebnis funktioniert, und deshalb fällt nicht auf, dass die Anwendung mit jeder Iteration schwerer zu ändern wird. Eine Auswertung von GitClear zeigt einen passenden Trend: Wie oft neu geschriebener Code eine Funktion an anderer Stelle aufruft, sank seit 2023 um 35 Prozent, von 343 auf 223 Aufrufe je tausend geänderter Zeilen (GitClear, 2026). Das ist ein Zusammenhang, kein Ursachennachweis. Was die Studien im Einzelnen messen, beschreibt Was Studien über die Qualität KI-generierten Codes zeigen.
- 01Promptlöst eine Aufgabe
- 02Code läuftwird übernommen
- 03Nächster Promptbaut daneben statt darauf
- 04Änderungtrifft mehrere Stellen
- 05Zinsenjede Änderung wird teurer
02
Welche Schuldarten sind typisch für generierten Code?
Die Übersicht ordnet sechs Schuldarten, die generierter Code leicht erzeugt, weil sie aus lokal richtigen Einzellösungen entstehen. Jede hat ein Symptom, das Sie ohne Codekenntnis beobachten können, und einen Kostentreiber, der bestimmt, wie teuer die Schuld im Betrieb wird. Die folgenden Abschnitte gehen jede Schuldart einzeln durch.
| Schuldart | Sichtbares Symptom | Kostentreiber |
|---|---|---|
| Duplikate statt Wiederverwendung | ein behobener Fehler taucht an anderer Stelle wieder auf | jede Regeländerung vervielfacht sich |
| Fehlende Abstraktionsschichten | ein Anbieterwechsel betrifft die halbe Anwendung | Bindung an Anbieter und Datenstruktur |
| Datenmodell ohne Migrationshistorie | niemand weiß, wie die Produktionsdatenbank entstand | riskante Schemaänderungen, keine identische Testumgebung |
| Konfiguration im Code | für eine andere Umgebung muss Code geändert werden | jede Umstellung wird zur Auslieferung |
| Fehlende Tests | nach jeder Änderung klickt jemand alles durch | manuelle Prüfung wächst mit jeder Funktion |
| Abhängigkeiten ohne Pflegepfad | Updates bleiben liegen | Sicherheitsupdates stauen sich |
03
Woran erkennen Sie Duplikate statt Wiederverwendung?
Am deutlichsten daran, dass ein Fehler an einer Stelle behoben wird und in gleicher Form an einer anderen wieder auftaucht, oder dass zwei Seiten dieselbe Größe unterschiedlich berechnen. Die Ursache: Dieselbe Logik existiert mehrfach, weil Anfragen an das Modell eigene Lösungen erzeugt haben, statt eine vorhandene zu nutzen.
Symptom: Die Umsatzsteuer steht im Warenkorb anders als auf der Rechnung. Eine Prüfung von Telefonnummern greift im Anmeldeformular, aber nicht im Profil. Eine geänderte Fehlermeldung erscheint auf drei Seiten weiter im alten Wortlaut.
Kostentreiber: Jede Änderung einer Geschäftsregel muss so oft umgesetzt und geprüft werden, wie die Regel kopiert wurde, und jede vergessene Kopie ist ein neuer Fehler. Mit wachsender Anwendung sinkt die Chance, alle Stellen zu finden. Werkzeuge zur Duplikaterkennung wie jscpd machen das Ausmaß sichtbar, bevor Sie über Umbauten entscheiden.
npx jscpd src04
Was bedeutet es, wenn Abstraktionsschichten fehlen?
Es bedeutet, dass Oberfläche, Geschäftslogik und Zugriff auf Datenbank oder externe Dienste nicht getrennt sind. Eine Seite fragt die Datenbank direkt ab, ein Knopf ruft direkt das Sprachmodell auf. Das funktioniert, bis sich etwas ändert: Dann betrifft ein Wechsel von Anbieter oder Datenstruktur jede Datei, die ihn direkt kennt.
Symptom: Auf die Frage, ob sich der Maildienst oder das Sprachmodell austauschen lässt, lautet die Antwort „das steckt überall drin“. Eine neue Spalte in der Datenbank zieht Änderungen in vielen Oberflächenkomponenten nach sich. Geschäftsregeln lassen sich nur über die laufende Oberfläche testen.
// Ohne Schicht: jede Komponente kennt Tabelle, Spalten und Filter
const { data } = await supabase
.from("rechnungen")
.select("id, betrag, faellig_am")
.eq("status", "offen");
// Mit Schicht: die Komponente kennt nur die fachliche Frage
const offene = await rechnungen.offene();Kostentreiber: Die Bindung an einen Anbieter oder eine Datenstruktur wächst mit jeder Datei, die sie direkt nutzt. Ein Wechsel, etwa von einem gehosteten auf ein lokal betriebenes Sprachmodell, wird dann vom Konfigurationsschritt zum Umbau. Logik ohne eigene Schicht lässt sich außerdem nur über die Oberfläche testen, was Tests langsam und brüchig macht.
05
Warum ist ein Datenmodell ohne Migrationshistorie eine Schuld?
Weil der Zustand der Datenbank dann nur in der laufenden Produktion existiert. Niemand kann nachvollziehen, wann und warum eine Spalte entstand, keine zweite Umgebung lässt sich identisch aufbauen, und keine Änderung lässt sich geordnet zurücknehmen. Jede weitere Schemaänderung wird damit zum Eingriff am einzigen Exemplar.
Mit und ohne Migrationshistorie
| Kriterium | Ohne Historie | Mit Historie |
|---|---|---|
| Neue Umgebung aufsetzen | von Hand nachbauen, mit Abweichungen | aus den Dateien reproduzierbar |
| Änderung nachvollziehen | Erinnerung einzelner Personen | datierte Datei im Repository |
| Änderung zurücknehmen | improvisiert, mit Datenrisiko | geplant und vorher getestet |
| Übergabe an ein anderes Team | erst Bestandsaufnahme nötig | Schema ist beschrieben |
Symptom: Sätze wie „das haben wir mal im Dashboard geändert“ oder „auf dem Testsystem sieht die Tabelle anders aus“. Fehler, die nur in Produktion auftreten, weil die Testdatenbank eine andere Struktur hat.
Kostentreiber: Jede Schemaänderung braucht vorher eine Bestandsaufnahme und nachher eine manuelle Kontrolle, und das Risiko für Datenverlust steigt mit der Datenmenge. Supabase empfiehlt deshalb, jede Schemaänderung, auch kleine, über versionierte Migrationsdateien zu führen. Wie Sie ein bestehendes Supabase-Schema nachträglich in Migrationen überführen, zeigt Mit Lovable, Bolt oder Replit gebaut.
06
Woran erkennen Sie Konfiguration im Code?
Daran, dass sich Werte, die zwischen Test und Produktion verschieden sein sollten, nur durch eine Codeänderung umstellen lassen: Datenbankadressen, Zugangsdaten, Absenderadressen, Modellnamen, Grenzwerte. The Twelve-Factor App verlangt dafür eine strikte Trennung von Konfiguration und Code und bietet eine einfache Prüffrage an.
Die Prüffrage lautet: Ließe sich der Code jederzeit als Open Source veröffentlichen, ohne Zugangsdaten offenzulegen? Konfiguration umfasst dort alles, was zwischen Umgebungen variiert, und gehört in Umgebungsvariablen statt in Konstanten oder versionierte Konfigurationsdateien (The Twelve-Factor App).
Symptom: Für einen Testlauf tauscht jemand eine Adresse im Code aus und setzt sie vor dem Livegang zurück. Eine Testumgebung verschickt E-Mails an echte Adressen oder schreibt in die Produktionsdatenbank. Ein Zugangsschlüssel lässt sich nicht wechseln, ohne eine neue Version auszuliefern.
Kostentreiber: Jede Umstellung wird zur Auslieferung mit Entwicklerbeteiligung, der Tausch eines Schlüssels zum kleinen Projekt, und Verwechslungen zwischen Umgebungen treffen echte Daten. Je mehr Umgebungen eine Anwendung braucht, etwa Test, Abnahme und Produktion, desto schneller wächst dieser Treiber.
07
Warum bremsen fehlende Tests jede Änderung?
Ohne automatisierte Tests weiß nach einer Änderung niemand, ob der Rest der Anwendung noch funktioniert. Die Folge ist Vorsicht: Änderungen werden gebündelt, aufgeschoben oder von Hand durchgeklickt. Bei generiertem Code kommt hinzu, dass ein Modell bei einer Änderung auch Stellen anfassen kann, um die niemand gebeten hat.
Symptom: Nach jeder Änderung klickt jemand die wichtigsten Abläufe von Hand durch. Behobene Fehler kommen zurück. Die einzige Absicherung gegen Nebenwirkungen ist der Satz „ändere nichts anderes“ im Prompt. Oder es gibt Tests, die grün bleiben, obwohl die Funktion kaputt ist, weil sie nur prüfen, was sie vorher selbst simuliert haben.
Kostentreiber: Der manuelle Prüfaufwand wächst mit jeder Funktion, und aufgeschobene Änderungen stauen sich, darunter Sicherheitsupdates. Ohne Tests lässt sich zudem nicht kontrollieren, was ein KI-Assistent an bestehendem Code verändert hat. Der größte Hebel dieser Werkzeuge, schnelle Änderungen, wird so zum größten Risiko.
08
Welche Abhängigkeiten haben keinen Pflegepfad?
Solche, bei denen niemand weiß, warum sie eingebunden sind, die seit Langem keine neue Version bekommen haben oder deren nächste Version einen Umbau verlangt. Generierter Code bindet Pakete bereitwillig ein, und jedes davon ist eine Wette darauf, dass jemand es pflegt. Manche vorgeschlagenen Pakete existieren nicht einmal.
Wer einen erfundenen Paketnamen registriert, kann Schadcode in Projekte bringen, die den Vorschlag ungeprüft übernehmen. Symptom: Eine lange Liste in package.json, zu der niemand Auskunft geben kann, ignorierte Warnungen beim Installieren, ein Update, das wegen eines großen Versionssprungs liegen bleibt.
npm outdated # installierte, passende und neueste Version je Paket
npm audit # bekannte Schwachstellen in den Abhängigkeiten
npm ls <paket> # über welche Abhängigkeit ein Paket ins Projekt kamKostentreiber: npm outdated zeigt in der Spalte Wanted die höchste Version, die zur angegebenen Versionsspanne passt, und in Latest die aktuelle. Liegt Latest außerhalb der Spanne, steht in der Regel ein größerer Versionssprung an. Je mehr solcher Sprünge sich stauen, desto eher wird ein Sicherheitsupdate zum Umbau, und ein aufgegebenes Paket muss ganz ersetzt werden.
09
Wie schätzen Sie ein, wie schwer die Schulden wiegen?
Nicht jede Schuld muss abgebaut werden. Entscheidend sind drei Fragen: Wird die Anwendung weiter geändert, verarbeitet sie sensible oder geschäftskritische Daten, und fehlt das Fundament aus Migrationen und Tests? Die Checkliste zeigt den Befund, die Entscheidungshilfe, worüber Sie als Nächstes sprechen sollten.
Checkliste
Schnelltest ohne Codekenntnisse
Jeder Haken ist ein Hinweis auf eine Schuld, die einen genaueren Blick lohnt.
Entscheidungspfad
Schulden abbauen oder bewusst tragen?
Alle Fragen und Ergebnisse als Liste
- Soll die Anwendung weiter geändert werden?
- Ja, sie entwickelt sich weiter, weiter mit: Lässt sich das Datenmodell aus Migrationsdateien aufbauen?
- Nein, sie bleibt weitgehend, wie sie ist, weiter mit: Verarbeitet sie personenbezogene oder geschäftskritische Daten?
- Lässt sich das Datenmodell aus Migrationsdateien aufbauen?
- Ja, weiter mit: Schlägt ein Test fehl, wenn Sie absichtlich eine zentrale Regel brechen?
- Nein, Ergebnis: Zuerst das Fundament
- Verarbeitet sie personenbezogene oder geschäftskritische Daten?
- Ja, Ergebnis: Abhängigkeiten und Konfiguration zuerst
- Nein, Ergebnis: Bewusst tragen
- Schlägt ein Test fehl, wenn Sie absichtlich eine zentrale Regel brechen?
- Ja, Ergebnis: Gezielt dort abbauen, wo geändert wird
- Nein, Ergebnis: Tests vor neuen Funktionen
- Ergebnis: Zuerst das FundamentWorüber Sie sprechen sollten: den heutigen Datenbankstand als Ausgangsmigration sichern und daraus eine Testumgebung aufbauen, bevor neue Funktionen dazukommen.
- Ergebnis: Tests vor neuen FunktionenWorüber Sie sprechen sollten: welche Geschäftsregeln kritisch sind und wie Tests genau diese absichern, bevor weitere Änderungen darauf aufbauen.
- Ergebnis: Gezielt dort abbauen, wo geändert wirdWorüber Sie sprechen sollten: Duplikate und fehlende Schichten in den Teilen angehen, die als Nächstes geändert werden, statt alles auf einmal umzubauen.
- Ergebnis: Abhängigkeiten und Konfiguration zuerstWorüber Sie sprechen sollten: bekannte Schwachstellen in Abhängigkeiten schließen, Zugangsdaten aus dem Code holen und klären, wer Sicherheitsupdates einspielt.
- Ergebnis: Bewusst tragenWorüber Sie sprechen sollten: welche Schulden bekannt sind, wo sie liegen und welches Ereignis eine neue Bewertung auslöst, etwa neue Daten oder neue Nutzergruppen.
10
Was bestimmt, wie aufwendig der Abbau wird?
Eine seriöse Pauschale gibt es nicht, weil der Aufwand an der konkreten Anwendung hängt. Bestimmend sind der Umfang der Datenhaltung, die Zahl der Schnittstellen, der Schutzbedarf der Daten, das geplante Änderungstempo und die Frage, ob Migrationen und Tests schon existieren. Wer diese Punkte kennt, kann Einschätzungen vergleichen.
- Umfang der Datenhaltung: Jede Tabelle ohne Migrationshistorie und jede kopierte Regel vergrößert die Bestandsaufnahme.
- Schnittstellen: Jeder direkt eingebundene Dienst ohne eigene Schicht ist eine Stelle, an der ein Wechsel eingreift.
- Schutzbedarf: Personenbezogene oder geschäftskritische Daten erhöhen die Anforderungen an Tests, Protokolle und Updates.
- Änderungstempo: Eine Anwendung, die sich weiterentwickelt, zahlt die Zinsen bei jeder Änderung, eine stabile kaum.
- Vorhandenes Fundament: Existieren Migrationen und aussagekräftige Tests, lassen sich die übrigen Schulden schrittweise abbauen.
Besonders sichtbar werden Schulden, wenn eine Anwendung von einem Team an ein anderes übergeht. Welche Artefakte eine Übergabe in den Regelbetrieb braucht, beschreibt Vom Proof of Concept in den Regelbetrieb.
iiterate Technologies GmbH aus Adenau entwickelt Individualsoftware und KI-Anwendungen von der Architektur über die Umsetzung bis zum Betrieb und übergibt mit Quellcode und Dokumentation. Wenn Sie über Ihre Anwendung sprechen möchten: Kontakt.
Häufige Fragen
Hat jeder KI-generierte Code technische Schulden?
Jeder Code hat Schulden, handgeschriebener auch. Bei generiertem Code entstehen bestimmte Arten leichter, weil jede Anfrage lokal gelöst und funktionierender Code schnell übernommen wird. Ob daraus ein Problem wird, hängt davon ab, wie lange die Anwendung lebt und wie oft sie geändert wird. Für einen kurzlebigen Prototyp können Schulden die richtige Entscheidung sein.
Kann ein KI-Assistent die Schulden selbst wieder abbauen?
Teilweise. Assistenten können Duplikate zusammenführen, Schichten einziehen und Tests schreiben, wenn die Aufgabe klar beschrieben ist. Ohne Tests lässt sich aber nicht prüfen, ob beim Umbau Verhalten verloren ging, und ein Assistent kann dabei neue Duplikate erzeugen. Sinnvoll ist deshalb diese Reihenfolge: zuerst Tests für die kritischen Regeln, dann der Umbau mit Review.
Woran erkennt die Geschäftsführung, dass technische Schulden das Problem sind?
An wiederkehrenden Mustern statt an einzelnen Fehlern: Änderungen dauern zunehmend länger, behobene Fehler kehren zurück, Updates bleiben liegen, und bestimmte Teile traut sich nur noch eine Person anzufassen. Kommen solche Muster zusammen, liegt die Ursache eher in der Struktur des Codes als bei einzelnen Personen. Der Schnelltest in diesem Leitfaden hilft beim Einordnen.
Was kostet es, technische Schulden abzubauen?
Eine pauschale Antwort wäre unseriös, weil der Aufwand an der Anwendung hängt. Die Treiber lassen sich aber benennen: Umfang der Datenhaltung, Zahl der Schnittstellen, Schutzbedarf der Daten, geplantes Änderungstempo und ob Migrationen und Tests bereits existieren. Mit diesen Punkten lassen sich Einschätzungen verschiedener Stellen vergleichen und Prioritäten setzen.
Sind technische Schulden grundsätzlich schlecht?
Nein. Eine bewusst eingegangene Schuld kann richtig sein, etwa um eine Idee schnell zu testen oder einen Termin zu halten. Problematisch sind Schulden, die niemand kennt, und Schulden in Anwendungen, die weiter wachsen. Deshalb lohnt es sich, sie zu benennen, einzuordnen und zu entscheiden, welche getragen und welche abgebaut werden.
Weiterlesen
Quellen
- 01 The Maintainability Gap: 2026 AI Code Quality Research GitClear, 2026 · gitclear.com
- 02 We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs (USENIX Security 2025) arXiv, 2025 · arxiv.org
- 03 III. Config The Twelve-Factor App, o. J. · 12factor.net
- 04 Database Migrations Supabase Docs, 2026 · supabase.com
- 05 npm outdated npm Docs, 2026 · docs.npmjs.com
- 06 npm audit npm Docs, 2026 · docs.npmjs.com
Über Ihr Vorhaben sprechen
Ob Prototyp, internes Werkzeug oder KI-Anwendung: Beschreiben Sie kurz, was Sie bauen oder in den Betrieb bringen wollen.