Dieses Kapitel ist anders als die übrigen: Es ist keine Erklärung, sondern eine Arbeitsanweisung. Es steht hier in der Form, in der man es einem Coding-Agenten gibt — als Datei im Projekt, die geladen wird, wenn die Aufgabe ansteht. Sie dürfen diese Datei Ihrem Agenten geben. Genau dafür ist sie geschrieben.
Zum Hintergrund: Was ein Skill ist und wie er sich von einer Projekt-Instruktionsdatei unterscheidet, steht im Abschnitt über Skills. Was die einzelnen Schritte inhaltlich bedeuten, steht in Testing, Code-Qualität und Design by Contract. Hier steht nur die Reihenfolge — und die ist der eigentliche Inhalt.
Warum die Reihenfolge das Wesentliche ist¶
Ein LLM erzeugt bereitwillig Code für jede Aufgabe, und zwar sofort. Das ist genau das Problem: Ohne vorher festgelegtes Erfolgskriterium gibt es keinen Maßstab, an dem sich das Ergebnis messen ließe — außer dem eigenen Eindruck beim Lesen, und der ist bei gut formatiertem Code notorisch milde. Die Reihenfolge unten dreht das um. Sie stellt sicher, dass das Erfolgskriterium vor dem Code existiert, und dass der Agent etwas hat, wogegen er iterieren kann, ohne dass jemand zuschaut.
Für Sie selbst gilt dieselbe Reihenfolge übrigens auch. Der einzige Unterschied ist, dass ein Agent sie wörtlich befolgt.
Die Anweisung¶
Alles ab hier ist der Text, den der Agent bekommt.
Auftrag¶
Entwickle das beschriebene Feature testgetrieben. Halte die Schritte in der angegebenen Reihenfolge ein und halte nach jedem Schritt an, um das Zwischenergebnis zeigen zu lassen. Schreibe keinen Implementierungscode, bevor Schritt 3 abgeschlossen ist.
Schritt 1 — Designdokument¶
Schreibe, bevor irgendetwas anderes passiert, DESIGN.md:
Ziel in zwei bis drei Sätzen. Was soll danach möglich sein, was ausdrücklich nicht?
Erfolgskriterium. Woran erkennt man, dass es funktioniert? Formuliere das so, dass es prüfbar ist — “die Simulation terminiert bei jeder Startkonfiguration” ist prüfbar, “der Code ist sauber” nicht.
Aufteilung in Dateien/Module mit je einem Satz zur Verantwortlichkeit.
Abhängigkeiten: welche Bibliotheken, und warum diese. Bevorzuge die Standardbibliothek. Wenn das Projekt bereits eine Bibliothek für diesen Zweck benutzt, nimm diese.
Offene Fragen: alles, was du geraten hast. Rate weiter, aber schreibe auf, dass du geraten hast.
Stelle Rückfragen, bevor du weiterarbeitest, wenn das Ziel mehrdeutig ist.
Schritt 2 — Datentypen und Schnittstellen¶
Schreibe die Typen und Signaturen, ohne Implementierung. Funktionskörper sind ... oder raise NotImplementedError.
Datenstrukturen als
dataclassoderEnum, nicht als Dictionary mit verabredeten Schlüsseln.Vollständige Type Hints an allem, was öffentlich ist.
Docstring an jeder öffentlichen Funktion: was sie tut, was sie voraussetzt, was sie zurückgibt.
Trenne Logik von Ein-/Ausgabe. Funktionen, die rechnen, drucken nicht und fragen nicht.
Halte an. Die Schnittstelle ist die teuerste Entscheidung im ganzen Vorgang; sie wird jetzt geprüft, nicht später.
Schritt 3 — Tests zuerst¶
Schreibe Tests gegen die Signaturen aus Schritt 2. Sie müssen fehlschlagen — führe sie aus und zeige, dass sie fehlschlagen, und zwar aus dem richtigen Grund (nicht wegen eines Tippfehlers im Test).
Pro beschriebenem Verhalten ein Test, benannt nach dem Verhalten (
test_leere_eingabe_liefert_null), nicht nach der Funktion.Jeder Test enthält mindestens ein
assertüber ein Ergebnis. Ein Test, der nur prüft, dass ein Aufruf nicht abstürzt, zählt nicht.Nimm
@pytest.mark.parametrizefür Varianten desselben Verhaltens, statt den Test zu kopieren.Mindestens ein Test pro Fehlerfall aus dem Designdokument (
pytest.raises).Randfälle: leer, eins, viele, negativ,
None.Zufall und Zeit werden injiziert, nicht importiert — ein
random.Random(seed)als Parameter, keine globalerandom-Funktion.
Schritt 4 — Implementieren bis grün¶
Implementiere jetzt, und zwar minimal: das Einfachste, das die Tests grün macht. Keine Funktionen, die kein Test verlangt. Keine Konfigurierbarkeit auf Vorrat.
Läuft ein Test wiederholt nicht durch, zerlege das Problem in kleinere Teile statt größere Änderungen zu versuchen. Ändere niemals einen Test, damit er zur Implementierung passt, ohne das ausdrücklich zu sagen und zu begründen.
Schritt 5 — Refaktorisieren¶
Jetzt, mit grünen Tests als Netz: Duplikate zusammenfassen, Namen verbessern, lange Funktionen teilen. Nach jeder Änderung die Tests laufen lassen. Das Verhalten ändert sich hier nicht — wenn ein Test rot wird, war es kein Refactoring.
Schritt 6 — Zusagen härten¶
Type Hints vervollständigen, auch in den Tests.
Wo eine Vorbedingung im Designdokument steht, sie als Contract oder als frühes
raise ValueErrorausdrücken — nicht als Kommentar.assertnur für Dinge, die nach eigener Überzeugung immer wahr sind, nie für Nutzereingaben.Docstrings an die tatsächliche Implementierung angleichen.
Schritt 7 — Werkzeuge¶
Führe aus und behebe, was sie melden:
uv run ruff format .
uv run ruff check . --fix
uv run mypy .
uv run pytest -qUnterdrücke keine Meldung mit # type: ignore oder # noqa, ohne in derselben Zeile zu begründen, warum.
Schritt 8 — Selbstreview¶
Beantworte zum Schluss schriftlich:
Welche Annahme in
DESIGN.mdist am wahrscheinlichsten falsch?Welcher Teil des Codes ist am schwersten zu verstehen, und warum?
Welches Verhalten ist nicht getestet?
Was würde passieren bei zehnfacher Eingabemenge?
Welche Entscheidung hast du getroffen, ohne gefragt zu werden?
Diese fünf Antworten sind das Wertvollste am ganzen Durchlauf. Kürze sie nicht ab.
Wie man das benutzt — und was es nicht leistet¶
Legen Sie den Text ab Schritt 1 in Ihrem Projekt ab, etwa als .claude/skills/python-tdd/SKILL.md oder unter dem Namen, den Ihr Werkzeug erwartet, und verweisen Sie beim Beauftragen darauf. Dieses Repository macht genau das: Die Skill-Datei liegt neben dem CLAUDE.md des Skripts und verweist auf dieses Kapitel.
Drei ehrliche Einschränkungen:
Die Schritte kosten Zeit und Token. Für eine Aufgabe, die in zehn Zeilen erledigt ist, ist das Verfahren Overkill — dann ist Lesen billiger als Testen (siehe das Ende der Anleitung zum Vibe Coding).
Grüne Tests sind kein Korrektheitsbeweis, erst recht nicht, wenn derselbe Agent Test und Implementierung geschrieben hat. Das Gegenmittel steht in Testing: Mutation Testing als Schiedsrichter, und ein Blick von Hand auf die Tests zu den Fehlerfällen.
Der Schritt, den man nicht delegieren kann, ist Schritt 1. Wer das Erfolgskriterium nicht formulieren kann, bekommt ein Ergebnis, das irgendein Kriterium erfüllt.