Der Spickzettel für die Seite nach dem Agentenlauf: Woran man Qualität festmacht, was die Tests wirklich belegen, was die Maschine prüfen kann und worauf man im Diff sieht. Zum Lernen der Methode taugt er nicht; dafür ist das Seminar Clean Code und KI-gestützte Entwicklung da. Das Gegenstück für die Seite davor ist das Blatt Auftrag und Kontext.
Vier Qualitätsziele
Gröber als eine Norm und absichtlich so — genormte Referenz wäre ISO/IEC 25010 in der Fassung von 2023 mit neun Merkmalen (nicht den acht von 2011).
| Ziel | Woran man es erkennt |
|---|---|
| Korrektheit | Das System tut, was es soll — nachweisbar, nicht dem Vernehmen nach |
| Verständlichkeit | Wer es nicht schrieb, sagt in vertretbarer Zeit, was es tut und warum |
| Wandelbarkeit | Eine fachlich kleine Änderung ist auch technisch eine kleine Änderung |
| Produktionseffizienz | Der Betrieb kostet nicht mehr Ressourcen und Aufmerksamkeit als nötig |
Innere Qualität ist der Preis der zukünftigen äußeren: Ein System kann heute tadellos liefern und in zwei Jahren unbezahlbar sein. Die Kurven kreuzen sich früh — wer wirklich nur Wochen plant, darf sparen, aber dieser Fall kommt fast nie vor.
Was sich unter Agenten verschiebt
| Eigenschaft | Mensch | Agent |
|---|---|---|
| Abweichende Benennung | verzeiht sie mit Kontextwissen | findet die Stelle womöglich nicht |
| Weit verstreute Dateien | verliert den Faden | liest sie mühelos zusammen |
| Implizites Wissen im Kopf | fragt den Kollegen | kann nicht fragen |
Praktische Folge: Konsistenz wird wertvoller, und Wissen, das nur in Köpfen existiert, wird teurer.
DRY: Wissen, nicht Syntax
| Fall | Dasselbe Wissen? | Richtige Antwort |
|---|---|---|
| Zweimal geprüft, ob Zeiträume sich überschneiden | ja, dieselbe Regel | zusammenführen |
| Buchung und Kostenstelle prüfen je drei Felder | nein, zufällig gleich | getrennt lassen |
Zufällig gleiche Regeln entwickeln sich unabhängig weiter. Wer sie zusammenführt, koppelt zwei Dinge und verteuert die nächste Änderung. Duplikation ist billiger als die falsche Abstraktion — aber nicht als die richtige.
SRP: nach Änderungsanlass schneiden, nicht nach Zeilenzahl
| Auslöser | Akteur | Was dabei gefährdet wird |
|---|---|---|
| Das Steuerrecht ändert sich | Gesetzgeber | Exportformat und Mailversand |
| Anderes Exportformat nötig | Verwaltung | Steuerlogik und Mailversand |
| Mailversand wird umgestellt | Betrieb | Steuerlogik und Exportformat |
Drei Auslöser, drei Interessengruppen, ein Codeblock — deshalb bei jeder Änderung das Risiko für die anderen beiden. Die Akteure stehen in der Organisation, sie werden nicht geraten.
Modul: Clean Code als Qualitätsmodell
Struktur, Kopplung und SOLID
Parnas 1972: Am Ablauf zu zerlegen ist fast immer falsch — besser entlang der Entscheidungen, die sich ändern werden.
| Kriterium | Ergebnis | Was passiert beim Ändern |
|---|---|---|
| Ablauf des Programms | Controller, Services, Repositories | jede fachliche Änderung fasst alle drei an |
| Was sich ändern wird | Fahrzeuge, Buchung, Abrechnung | die Änderung bleibt in einer Ecke |
Woran man den falschen Schnitt merkt: Jeder Test einer fachlichen Regel braucht eine Datenbank. Dann liegt die Regel in derselben Funktion wie der Zugriff, und sie lässt sich nicht mehr allein durchdenken, weil man sie nicht allein sieht.
Abhängigkeitsrichtung
| Richtung | Beispiel | Folge |
|---|---|---|
| Regel zeigt auf Technik | Buchungsregel kennt das CSV-Format | jede Umstellung reißt an der Fachlichkeit |
| Technik zeigt auf Regel | CSV-Export kennt die Buchungsregel | die Fachlichkeit bleibt unberührt |
Das ist der belastbare Kern der Abhängigkeitsumkehr — er gilt in jeder Sprache und braucht oft kein Interface. Stabil heißt dabei änderungsarm, nicht zuverlässig.
SOLID: dieselben Buchstaben, zwei Lesarten
| Als Diagnose gelesen | Als Bauvorschrift gelesen | |
|---|---|---|
| S | Hat der Baustein mehr als einen Änderungsanlass? | eine Klasse je Methode |
| O | Muss ich Code aufreißen für einen neuen Fall? | Erweiterungspunkte ohne Erweiterung |
| L | Verhält sich die Ersetzung wie das Ersetzte? | Hierarchien ohne Ersetzungsbedarf |
| I | Zwingt die Schnittstelle zu Unnötigem? | eine Schnittstelle je Klasse |
| D | Zeigt die Abhängigkeit in die stabile Richtung? | Fabriken für Objekte, die nie variieren |
Die linke Spalte ist brauchbar, die rechte richtet Schaden an. Kopplung liest man an der Testeinrichtung ab, nicht an der Zahl der Importe — eine Metrik dafür gibt es seit 1974 nicht.
Modul: Struktur, Kopplung und SOLID als Heuristik
Teststrategie für generierten Code
Nicht die Erzeugungsgeschwindigkeit bestimmt das Tempo, sondern die Größe der geprüften Fläche.
| Bereich | Wer prüft | Folge für das Tempo |
|---|---|---|
| Von Tests abgedeckt | die Maschine, bei jedem Lauf | ein Agent darf hier arbeiten |
| Nicht abgedeckt | ein Mensch, mit den Augen | hier liegt der Engpass |
Woraus der Test abgeleitet wird
| Ableitung aus | Der Test prüft | Risiko |
|---|---|---|
| Akzeptanzkriterium | die Anforderung | keines, das ist der Sollfall |
| Fertigem Code | die Umsetzung | bestätigt jedes Missverständnis mit |
Genau der zweite Fall tritt ein, wenn man einem Agenten Code vorlegt und um Tests bittet.
Vier Reichweiten
| Reichweite | Was sie prüft | Preis |
|---|---|---|
| Klein | eine Einheit isoliert | blind für das Zusammenspiel |
| Mittel | ein Modul mit echten Nachbarn | langsamer, näher an der Wirklichkeit |
| Vertrag | die Vereinbarung zwischen zwei Seiten | beide Seiten müssen sie pflegen |
| Groß | den Weg des Nutzers durchs System | aussagekräftig, langsam, störanfällig |
Die Pyramide empfiehlt viele kleine und wenige große — als Ausgangspunkt vernünftig, als Vorschrift nicht. Liegt das Risiko im Zusammenspiel, sind mittlere Tests wirtschaftlicher.
Wann welches Vorgehen
| Vorgehen | Passt, wenn | Risiko |
|---|---|---|
| Test-first | Verhalten bekannt, Code neu | keines; schützt vor Umdeutung |
| Test-after | exploratives Arbeiten | schreibt die Umsetzung fest |
| Characterization | ungetesteter Bestand | hält fest, ohne zu billigen |
Characterization Test nach Michael Feathers, Working Effectively with Legacy Code (2004): Sie beschreiben, was das System heute tut — nicht, dass es richtig ist. Erst festgehaltenes Verhalten lässt sich absichtlich ändern statt versehentlich.
Die Gegenprobe
Die eine Frage, die alles abkürzt: Welche Zeile im Code kann ich verändern, ohne dass ein Test rot wird? Drei Zeilen absichtlich brechen und zählen, was rot wird, genügt als Stichprobe. Das große Vorbild ist Mutationstesten bei Google (Petrović und Ivanković, IEEE TSE 2021, über 24 000 Entwickler) — dort gilt Mutationsvollständigkeit ausdrücklich als weder praktikabel noch wünschenswert.
Beim Regressionstest gilt das Nachweisprinzip: den roten Lauf selbst sehen. Test und Korrektur zusammen zu beauftragen heißt, ihn nie zu sehen.
Modul: Teststrategie für KI-generierten Code
Automatische Prüfungen
| Werkzeug | Prüft | Eigentlicher Wert |
|---|---|---|
| Formatierung | reine Darstellung | verbannt Formatierung aus dem Diff |
| Linting | Muster, die erfahrungsgemäß schiefgehen | fängt Flüchtigkeiten in Masse |
| Statische Analyse | Struktur und Sicherheitsmuster | findet, was kein Mensch systematisch sucht |
Für generierten Code sind alle drei wertvoller als früher — das Volumen steigt, und eine Maschine ermüdet nicht. Der zweite Nutzen gilt nur für Agenten: Ein Übersetzungs- oder Linter-Fehler ist eine maschinenlesbare Rückmeldung, mit der sich der Agent selbst korrigiert. Damit wandert die Prüfung vor den Review statt hinein.
Typen arbeiten lassen
// prüft nichts: jeder Zustand ist darstellbar
type FahrtEntwurf = { zweck?: Fahrtzweck };
// prüft: eine erfasste Fahrt ohne Zweck gibt es nicht
type Fahrt =
| { status: "offen" }
| { status: "erfasst"; zweck: Fahrtzweck };
Fehlermeldungen für Mensch und Agent
// unbrauchbar
throw new Error("Buchung ungültig");
// brauchbar: Erwartung, Beobachtung, Ort
throw new Error(
`Buchung ${id}: bis (${bis}) muss nach von (${von}) liegen`,
);
Der Leser hat keinen Kontext außer diesem Text — beim Agenten gilt das buchstäblich.
Abdeckung richtig lesen
| Befund | Aussage | Belastbar? |
|---|---|---|
| Nicht abgedeckt | mit Sicherheit ungeprüft | ja, harte Aussage |
| Abgedeckt | möglicherweise geprüft | nein, sagt für sich nichts |
Brian Marick: „Ich erwarte eine hohe Abdeckung. Manchmal verlangt ein Manager eine. Ein feiner Unterschied.” Keine Prozentzahl als Ziel ausgeben — sie wird erreicht statt erarbeitet.
Drei Prüfungen für die Pipeline
| Prüfung | Fängt | Besonders bei generiertem Code |
|---|---|---|
| Abhängigkeiten | bekannte Schwachstellen | vorgeschlagene Bibliotheken sind oft überholt |
| Lizenzen | unvereinbare Bedingungen | unbemerkt übernommener Fremdcode |
| Secrets | Zugangsdaten in Änderungen | passiert schnell, setzt sich in der Historie fest |
Zum Kontext: Erfundene Paketnamen sind gemessen. 2025 lagen 16 Modelle zwischen 5,2 und 21,7 Prozent, 2026 fünf Frontier-Modelle zwischen 4,6 und 6,1 — die Rate sinkt, die Streuung verschwindet. Von 127 wiederkehrenden Namen waren 53 registrierbar; reproduzierbar heißt angreifbar.
Architekturregeln als Fitness Functions
| Gegenstand | Beispiel |
|---|---|
| Abhängigkeitsrichtung | Buchungsregeln kennen die Persistenz nicht |
| Verbotene Bibliotheken | keine Fließkommazahlen für Geldbeträge |
| Namensmuster | Prüfregeln liegen im dafür vorgesehenen Verzeichnis |
| Schwellen | Startzeit und Antwortzeit der Abrechnung |
Begriff nach Ford, Parsons und Kua, Building Evolutionary Architectures. Ein Agent kann eine Prosa-Vorgabe übersehen, einen roten Test nicht. Der Anspruch ist Verlagerung, nicht Vollständigkeit.
Modul: Automatisierte Qualitätsprüfungen
Review: der Diff, nicht die Zusammenfassung
| Was unbemerkt bleibt | Warum es später teuer wird |
|---|---|
| Die nebenbei geänderte Konfiguration | wirkt erst im Betrieb, dann überall |
| Die entfernte Prüfung | das Verhalten stimmt, bis der Randfall kommt |
| Die zusätzliche Abhängigkeit | Lieferkette, Lizenz, Pflege auf Dauer |
| Die umbenannte öffentliche Funktion | andere verlassen sich darauf |
Ein lesbarer Diff setzt Vorarbeit voraus: sauberer Ausgangszustand, klein beauftragt, Formatierung automatisiert. Ohne diese drei ist Diff-first ein frommer Wunsch.
Drei Arten, vom Auftrag abzuweichen
| Abweichung | Woran man sie erkennt | Warum sie durchrutscht |
|---|---|---|
| Tut weniger | der schwierige Fall fehlt stillschweigend | das Ergebnis wirkt vollständig |
| Tut mehr | zusätzliche Verbesserungen im Diff | sie sind für sich genommen richtig |
| Tut anderes | nur der Vergleich mit dem Ziel zeigt es | das Ergebnis ist in sich stimmig |
Die dritte ist die häufigste und am schwersten zu erkennen — Überzeugungskraft und Richtigkeit sind entkoppelt.
Fünf Risikokategorien in fester Reihenfolge
| Kategorie | Die Fragen dazu |
|---|---|
| Fachlich | Randfälle, Fehlerbehandlung, unbemerkt geänderte Regel |
| Sicherheit | Eingaben geprüft, Berechtigung an der richtigen Stelle |
| Datenschutz | werden Daten weiter verbreitet als vorher? |
| Schnittstellen | ändert sich etwas, worauf andere sich verlassen? |
| Laufzeit | entsteht ein Aufruf in der Schleife, der vorher einmal geschah? |
Feste Reihenfolge, weil beim freien Lesen zuverlässig die Kategorie übersehen wird, an die man gerade nicht denkt.
KI als zweite Perspektive
| Bedingung | Konkret | Sonst |
|---|---|---|
| Frischer Kontext | nicht derselbe Lauf, der es gebaut hat | er bestätigt die eigenen Annahmen |
| Gezielte Frage | prüfe auf Berechtigungslücken | allgemeine Hinweise ohne Wert |
| Als Ergänzung | nie als Ersatz für den Menschen | fachliches Wissen fehlt ihm |
Wann verwerfen besser ist als nachbessern: Die Änderung beruht auf einem grundlegenden Missverständnis · sie ist so groß, dass niemand sie vollständig gelesen hat · nach jeder Korrekturrunde entstehen neue Probleme woanders · man ertappt sich beim Gedanken, es selbst schneller zu können. Verwerfen ist kein Verlust, sondern der Ertrag der ersten Runde — der zweite Auftrag ist schärfer.
Modul: Review von KI-generierten Änderungen
Verstehen und Refactoring
| Beleg | Aussagekraft | Aufwand |
|---|---|---|
| Quellcode mit Fundstelle | prüfbar, aber blind für Dynamik | Stichprobe genügt |
| Ein Test | was er festhält, ist überprüfbar wahr | schon vorhanden |
| Die Ausführung selbst | beantwortet es endgültig | eine Protokollzeile, 30 Sekunden |
Dynamische Aufrufe, Konfiguration und zur Laufzeit gebildete Namen findet kein Leser — auch kein guter. Bei ausschließenden Aussagen ist die Ausführung der einzige belastbare Weg.
Die vier Angaben im Refactoring-Auftrag
| Angabe | Beispiel |
|---|---|
| Ziel, beobachtbar | Die Abrechnung soll ohne Datenbank testbar sein |
| Invarianten | Die Beträge je Zweck ändern sich nicht, belegt durch Tests |
| Scope | nur das Abrechnungsmodul, die Buchung nicht |
| Abbruchkriterium | mehr als zehn Dateien betroffen: abbrechen und neu planen |
Das Abbruchkriterium fehlt fast immer und ist das wichtigste — ein Umbau, der größer wird als gedacht, ist der Normalfall.
Schrittgröße
| Schrittgröße | Ein Test bricht | Folge |
|---|---|---|
| Ein Refactoring | Ursache in Sekunden gefunden | weitermachen |
| Vierzig Dateien | Suche dauert länger als der Umbau | endet häufig im Verwerfen |
Bei agentischer Arbeit muss die Schrittgröße vorgegeben werden — von sich aus wählt ein Agent die große Lösung, weil ihn jeder zusätzliche Schritt nichts kostet.
Modul: KI-gestütztes Codeverständnis und Refactoring
Typische Fallen
- Die Begründung lesen statt den Code. Sie ist der überzeugendere Teil — und Nachfragen, ob es stimmt, liefert wieder nur einen Vorschlag.
- Grünen Tests glauben, die zufällig nur einen Fall im Bestand haben.
- Eine Abdeckungsquote beauftragen. Sie wird erreicht, und zwar wörtlich. Dasselbe Muster bei der Testmenge und bei jeder Aktivitätszahl: Wird ein Maß zum Ziel, hört es auf, ein gutes Maß zu sein.
- Tests weniger skeptisch prüfen als den Code — sie tragen danach das Vertrauen. Häufigste Schwächen generierter Tests: keine Feststellungen, zu viele Attrappen, an Interna geklammert.
- Erst den Code bauen lassen und dann um Tests bitten.
- Zweihundert Linter-Hinweise je Lauf ausgeben. Sie werden ignoriert und wirken nicht — wenige Regeln, die wirklich gelten, wirken mehr als viele, die nur mahnen.
- Eine Pipeline dulden, die sporadisch grundlos scheitert. Sie erzieht zum Wegsehen, danach wirkt auch der echte Fehlschlag nicht mehr.
- Vollständigkeit am Umfang ablesen statt am schwierigen Fall — und eine stimmige Lösung für eine richtige halten.
- Die Nicht-Ziele nicht mitlesen. Dann fällt das Zuviel gar nicht auf, und die Beweislast dreht sich um: Plötzlich muss das Streichen begründet werden.
- Aufräumen, wo kein Änderungsdruck besteht, und die Zahl der Code-Smell- Befunde für ein Maß der Dringlichkeit halten.
- Ohne Absicherung umbauen und es Refactoring nennen — oder beim Charakterisieren gleich mitkorrigieren, was falsch aussieht.
- Weitermachen, weil schon so viel Arbeit hineingeflossen ist.
- SOLID als Checkliste vor dem Schreiben abarbeiten — oder es pauschal für überholt erklären. Die Diagnosefragen bleiben brauchbar.