Spec-first-Entwicklung: Erst die Absicht klären, dann schreibt die KI den Code
Wenn Code billig ist, wird die Absicht zum Engpass. Ein praxistauglicher spezifikationsgetriebener Workflow mit OpenSpec, Szenarien zum Review vor dem Coden und Tipps für die Einführung im Team.
Dreißig Jahre lang war Code das knappe Gut. KI-Coding-Agenten haben ihn billig gemacht, und damit wandert der Engpass zu etwas, das sich schwerer kaufen lässt: genau zu wissen, was man eigentlich bauen wollte. Hier geht es um diesen Denkwechsel, einen Workflow, der im Alltag trägt, und die menschliche Seite, wenn ein Team ihn übernehmen soll.
Alle haben geraten
Ein bekanntes Scheitern läuft so ab. Eine Änderung geht raus, und erst im Review oder schlimmer noch in Produktion merkt das Team, dass das Ergebnis nicht dem entspricht, was irgendwer wollte. Die Anforderungen waren über einen Chat-Thread, einen Ticket-Kommentar und die Köpfe einiger Leute verstreut, und jede Quelle sagte etwas leicht anderes.
Konkret übernimmt jemand eine Aufgabe, deren Anforderungen so aussehen:
- ein einzeiliger Ticket-Titel,
- ein Slack-Thread, der im Sand verlaufen ist,
- und eine Annahme, die alle für gemeinsam hielten, die es aber nicht war.
Die Person baut es. Das Review fängt einen Teil der Abweichung ab und lässt den Rest durch, denn der Reviewer sieht nur einen Diff und muss vom Code rückwärts erraten, was gewollt war. Das ist genau die falsche Richtung. Nach dem Release ist der Code die einzige Aufzeichnung dessen, was das Feature tun soll, plus das, woran sich das Team noch erinnert.
Gerade dieser letzte Punkt richtet leise den Schaden an. Kontext verfliegt, sobald das Gespräch vorbei ist. Ein halbes Jahr später kann niemand, weder Mensch noch Agent, sagen, wie sich das System verhalten sollte, sondern nur, was der Code zufällig tut.
Warum Agenten die Rechnung ändern
Agenten haben die Ökonomie über Nacht umgedreht. Jahrzehntelang war Code schreiben der teure, sorgfältige Schritt, und jeder Prozess war darum herum gebaut. Ein Agent dagegen rät schnell und selbstbewusst. Gib ihm einen vagen Prompt, und in Sekunden liefert er plausiblen, sauber strukturierten und völlig falschen Code. Generieren kostet fast nichts mehr. Zu entscheiden, was richtig ist, ist die eigentliche Arbeit.
Das dauerhafte, knappe Artefakt wird damit eine präzise, gemeinsame Beschreibung der Absicht: eine Spezifikation. Nicht als Papierkram, sondern als das, worauf sich Menschen einigen, und als Kontext, den man den Agenten gibt. Das Experiment lautet also: erst die Spezifikation schreiben, sich darauf einigen und dann Menschen und Agenten danach bauen lassen.
Was spezifikationsgetriebene Entwicklung bedeutet
Die Idee: Bevor man eine Änderung umsetzt, hält man ihr beabsichtigtes Verhalten in einer strukturierten Spezifikation fest, die andere reviewen können, und holt sich Zustimmung. Danach lebt die Spezifikation im Repo neben dem Code und dokumentiert, was das System tut und warum.
Drei Einwände kommen sofort, deshalb hier, was es nicht ist:
- Es ist kein Wasserfall. Eine Spezifikation muss nur gut genug sein, um anzufangen, und man überarbeitet sie, während man dazulernt. Denk an ein lebendes Dokument, nicht an einen abgezeichneten Anforderungsordner.
- Es ist nicht schwerfällig. Winzigen Änderungen genügt ein zehnzeiliges Spezifikations-Delta in einem einzigen Pull Request. Der Aufwand wächst nur mit der Größe der Änderung.
- Es ist kein Design-Dokument. Design-Dokumente begründen, warum ein Ansatz gewählt wurde, eine Spezifikation beschreibt, was das System heute tut. Diese Grenze bekommt weiter unten einen eigenen Abschnitt.
Der Nutzen ist einfach: erst das Ziel festlegen, dann Aufwand ins Treffen stecken und diese Einigung behalten, wenn der Chat längst vergessen ist.
Deine Stellenbeschreibung ändert sich
Alles andere beruht auf einem einzigen Umdenken. Deine Kernaufgabe ist jetzt, starke Spezifikationen zu schreiben, sie zu reviewen und Code nur dort von Hand zu ändern, wo die KI es nicht hinbekommt.
Das stellt auf den Kopf, wofür die meisten Entwickler ausgebildet wurden. Früher war Code schreiben der Job. Jetzt ist es das, was du am wenigsten tust. Deine eigentliche Arbeit beginnt, nach Wichtigkeit geordnet, mit der Spezifikation und ihrem Review, und erst danach kommt handgeschriebener Code.
Sechs Prinzipien, die man wiederholen sollte
Wenn gefragt wird, wie viel Spezifikation genug ist, tauchen immer wieder dieselben Antworten auf:
- Erst einigen. Spezifikation schreiben oder aktualisieren, ein schnelles Review holen und erst dann umsetzen.
- Spezifikationen neben dem Code halten. Sie liegen im Repo, werden mit derselben Änderung reviewt und gehören denen, die den Code verantworten.
- Kleine Deltas statt großer Neufassungen. Jede Änderung sagt, was hinzukommt, sich ändert oder wegfällt, statt die ganze Welt neu zu erzählen.
- Verhalten als überprüfbare Szenarien formulieren. Wo sich etwas testen lässt, given/when/then statt Fließtext verwenden.
- Beweglich bleiben. Weicht die Realität von der Spezifikation ab, die Spezifikation anpassen, statt sie verrotten zu lassen.
- Jeder Fähigkeit eine einzige Quelle der Wahrheit geben, einen Ort, an dem ihr aktuelles Verhalten steht.
Die tägliche Schleife
Der Ansatz hängt nicht an Werkzeugen. Einfache Markdown-Dateien in einem Ordner specs/ reichen. Etwas Tooling verringert trotzdem die Reibung, und OpenSpec ist ein Open-Source-Workflow für Spezifikationen, der sich in KI-Coding-Agenten einklinkt und Slash-Befehle passend zur Schleife mitbringt:
- Erkunden, optional. Ist die Form einer Änderung unscharf, lass den Agenten den Code lesen, Optionen abwägen und einen Plan skizzieren, bevor du dich festlegst.
- Vorschlagen. Gib eine einzeilige Beschreibung, und das Werkzeug erzeugt einen Vorschlag, eine kurze Design-Notiz, eine Aufgabenliste und ein Spezifikations-Delta. Letzteres zählt am meisten, weil es zeigt, wie sich die lebende Spezifikation ändern wird.
- Zuerst die Spezifikation reviewen. Darum geht es im Kern. Vorschlag und Delta werden reviewt, bevor es überhaupt Code gibt, denn einen Satz zu ändern ist billig, eine ausgelieferte Implementierung zu ändern nicht.
- Umsetzen. Gegen die vereinbarte Spezifikation bauen, selbst oder mit einem Agenten.
- Prüfen. Die Checks laufen lassen, idealerweise mit Akzeptanzszenarien, die direkt zu Tests werden.
- Archivieren. Das Delta in die lebende Spezifikation einpflegen, damit sie immer die Gegenwart beschreibt, und den Vorschlag in die Historie verschieben.
Wenn du nur einen Schritt behältst, dann den dritten: die Spezifikation vor dem Code reviewen.
OpenSpec mit einem Coding-Agenten einrichten
Aktuelle Coding-Agenten wie Claude Code können diesen Workflow lernen und ihn mit dir zusammen fahren, sodass du nicht jeden Schritt ansagen musst. OpenSpec verpackt dieses Wissen als Agent-Skills und Slash-Befehle. Zwei Befehle binden es an dein Repo und deinen Agenten an:
# install the CLI (drives everything below)
npm install -g @fission-ai/openspec@latest
# scaffold the spec structure AND generate agent skills + slash commands
openspec init --tools claude
Der Schritt init erledigt zwei Dinge. Erstens legt er den Ort für Spezifikationen an: einen Ordner specs/ für lebende Spezifikationen, einen Ordner changes/ für laufende Vorschläge und eine kleine Konfiguration, in der du Stack und Konventionen festhältst. Zweitens installiert er die Agent-Skills. Für Claude sind das Skill-Dateien plus /opsx:*-Befehle, nämlich explore, propose, apply, archive und sync. Die Skills bringen dem Agenten bei, einen Vorschlag zu entwerfen, ein Spezifikations-Delta zu erstellen, danach zu implementieren und das Ergebnis zurück in die lebende Spezifikation zu überführen.
Wie eine Änderung aussieht
Stell dir einen Hintergrundjob vor, der ein konfigurierbares Timeout braucht. Ein Job, der sein Limit überschreitet, soll abgebrochen und als timed_out markiert werden.
Am Anfang steht ein Spezifikations-Delta, also ein Diff gegen die lebende Spezifikation, der genau zeigt, was sich bewegt:
### Requirement: Job timeout
- The system SHALL run a job to completion.
+ The system SHALL cancel a job that exceeds a configurable timeout
+ (default 30s) and record the outcome as `timed_out`.+ #### Scenario: Job exceeds the configured timeout
+ - GIVEN a job configured with a 5s timeout
+ - WHEN the job has run for 5s without completing
+ - THEN the system cancels the job
+ - AND sets its status to `timed_out`
+ - AND emits a `JobTimedOut` event with the job id
Diesen Diff reviewen die Leute, bevor es irgendeine Implementierung gibt. Eine Kollegin kann den Standardwert, den Statusnamen oder das Event hinterfragen, solange es nur ein Satz ist. Sobald alle zustimmen, hat der Build ein eindeutiges Ziel, und das Szenario wird zum Test.
Nach dem Release überführt das Archivieren diese Anforderung in die lebende Spezifikation, als schlichte Aussage darüber, wie sich das System jetzt verhält, ohne übrig gebliebene Plus- oder Minuszeichen. Wer diesen Code als Nächstes anfasst, Mensch oder Agent, liest das und muss nicht raten.
Spezifikation oder Design-Dokument
Beides wird gern verwechselt, was zu Doppelungen und Verwirrung führt. Eine Aufteilung, die sich bewährt hat:
- Ein Design-Dokument erklärt eine Entscheidung: warum dieser Ansatz, welche Kompromisse es gab. Es ist eine Momentaufnahme und darf veralten, denn es ist ein historisches Dokument.
- Eine Spezifikation beschreibt das aktuelle Verhalten, also was das System gerade tut. Sie lebt und darf nie veralten, denn sie dient als Vertrag.
In der Praxis: Optionen im Design-Dokument erkunden und dort entscheiden, das dauerhafte Verhalten in der Spezifikation festhalten und beide verlinken statt duplizieren. Wird dasselbe Verhalten an beiden Stellen gepflegt, das Design-Dokument auf einen Link eindampfen.
Einführung im Team
Eine kurze Checkliste hilft. Für deine nächste Änderung: beschreiben und Vorschlag samt Spezifikations-Delta erzeugen, die Spezifikation vor dem Coden ins Review geben, nach der Freigabe umsetzen und die Szenarien grün bekommen, dann archivieren, damit die lebende Spezifikation der Realität entspricht.
Für das Team: sicherstellen, dass die Repos das Tooling eingerichtet haben, eine kurze Kontextnotiz zu Stack und Konventionen ergänzen, damit Agenten bessere Spezifikationen schreiben, und zuerst die zwei oder drei wichtigsten Fähigkeiten spezifizieren.
Versuch nicht, das ganze bestehende System vorab zu spezifizieren. Schreib Spezifikationen, wenn du Dinge anfasst, dann wächst die Abdeckung dort, wo gearbeitet wird.
Probier es bei der nächsten Änderung
Du brauchst keine große Initiative und keine Anordnung von oben. Schreib bei deiner nächsten nicht trivialen Änderung vor dem Coden auf, was sie tun soll, als ein paar given/when/then-Szenarien. Bitte eine Kollegin, sich zuerst diese Szenarien anzusehen. Dann bauen, die Szenarien grün bekommen und die Spezifikation zusammen mit dem Code einchecken.
Mehr ist es nicht. Mach das ein paarmal, lass deine Pull Requests leise besser werden, und dein Team wird anfangen, dich zu fragen, wo die Spezifikation ist.
Jahrzehntelang galt Code als letztes Wort über das Verhalten, weil ein Mensch jede Zeile geschrieben und verstanden hatte. Das stimmt nicht mehr. Generierter Code ist billig und wegwerfbar, und das dauerhafte, von Menschen verantwortete Artefakt ist die Spezifikation. Teams, die das verinnerlichen, liefern mehr aus als jene, die noch Diffs reviewen und hoffen, dass die Absicht überlebt hat. Einigt euch darauf, was ihr baut, bevor ihr es baut. Im neuen Paradigma ist das kein Prozess-Overhead. Es ist die Arbeit.