Agentische Softwareentwicklung, aber in gut (mit SDD)
Prompt für Prompt die perfekte App vibe-coden? Funktioniert so nicht, meine ich – und ich zeige euch hier, wie agentische Softwareentwicklung richtig geht.
Spec Driven Development ist kein Vibe-Coding
So sehe ich das. Selbst wenn ich, nach den ersten umgesetzten Features, aufhöre, den Code zu lesen. Erstmal sehe ich mir natürlich an, was Claude Code oder Codex aus meinen Anforderungen gemacht haben, und justiere hier und da noch meine Regeldateien nach. Dann kommt aber der Punkt, an dem ich merke, dass die Architektur eingehalten wird und die Qualität mehr als ausreichend ist – für alles, was mir an Code erzeugt wird.
Doch wo ist der Unterschied? Im Gegensatz zum Vibe-Coding, wie ich es von Freunden und Kollegen kenne, bei dem man dem Agenten so lange Prompts schickt, bis das gewünschte Ergebnis erreicht ist, geht es hier um einen nachhaltigen Prozess, den man jederzeit anpassen kann. SDD-Frameworks wie OpenSpec erzeugen in diesem Prozess eine Änderungshistorie und weitere Artefakte in Form von Textdateien. Klingt erstmal nicht sehr aufregend, aber ich glaube, euch überzeugen zu können, dass das einen gewaltigen Unterschied macht.
Context is King
Hört man ja immer wieder in letzter Zeit. Mit Context ist hier gemeint, dass man in einem Prompt genug, die richtigen, aber auch nicht zu viele Informationen an ein LLM schicken sollte, um eine gute und nicht halluzinierte Antwort zu bekommen.
Durch interne Memory-Systeme haben die Systeme von Anbietern wie OpenAI oder Anthropic inzwischen viel Wissen über den Nutzer. Aber auch das kann Probleme verursachen, wenn der Agent beispielsweise zwei Projekte vermischt und von falschen Umständen ausgeht. Oder Privates mit Beruflichem vermengt.
Genau hier sind die Artefakte – also die oben genannten Textdateien, die klar einem Projekt zuzuordnen sind – der große Unterschied. In meinem Claude Code CLI habe ich zum Beispiel gerade die interne Memory-Funktion deaktiviert, da sie mehr als nur einmal auf projektfremden oder stark veralteten Informationen aufgebaut hat.
Context wird auch mit jedem Prompt vom Nutzer erzeugt; beendet man die Session, ist dieser aber verloren. Natürlich kann man sich Context auch in seine CLAUDE.md oder AGENTS.md schreiben, oder in andere Dateien oder eine Datenbank, auf die der Agent Zugriff hat. Im SDD wird dann aber auch noch sichergestellt, dass diese automatisch aktuell gehalten werden.
Der SDD-Prozess und die Artefakte
Ich beschreibe hier den Prozess von OpenSpec. Andere Frameworks wie GitHub Spec Kit oder BMAD weichen in Teilen ab, aber grundsätzlich bleibt die Idee die gleiche.
Folgende Funktionen bilden den Prozess ab.
1. Propose
Wir beginnen mit dem ersten Change – ein Spec-Change, wie das in OpenSpec genannt wird. Das kann beispielsweise eine Aufforderung sein wie „Bau mir eine Web-App, mit der ich gegen eine KI Schach spielen kann”. Das Framework fängt hier an, mit einem zu planen. Es stellt Fragen, zum Beispiel welche Technologie gewählt werden soll, ob ein Backend notwendig ist, welche KI der Schachpartner werden soll. Diese Feedback-Runde lässt sich mit klassischem Stakeholder-Management vergleichen und soll dieses nicht ersetzen – sie kann sogar ideal gemeinsam mit den Stakeholdern durchlaufen werden. Ziel ist, für alle ein gemeinsames Verständnis davon zu schaffen, was überhaupt gemacht werden soll. Und mit „alle” meine ich auch potenzielle spätere Umsetzer des Ganzen, wie KI-Agenten oder menschliche Entwickler. Auf der Anforderungsseite kommen andere Unternehmensbereiche dazu, wie die Marketingabteilung oder jemand aus dem Business-Intelligence-Bereich.
In diesem Prozessschritt entsteht dann erstmal ein Artefakt, das proposal.md heißt und in dem das alles zusammengefasst ist. Danach werden daraus automatisch eine design.md, eine tasks.md und mindestens eine neue Spec erstellt. Dazu später mehr im Detail.
Es kann auch sein, dass das Framework direkt vorschlägt, die Änderung in mehreren Spec-Changes umzusetzen. Beim oben gewählten Beispiel wäre das sehr wahrscheinlich und auch sinnvoll.
Nachdem alle erzeugten Artefakte inhaltlich geprüft und gegebenenfalls noch angepasst wurden, ist der Change bereit für die Umsetzung.
So sieht ein Requirement in einer Spec aus. Das Beispiel stammt aus der Authentifizierung eines anderen Projekts:
### Requirement: Refresh tokens rotate and detect reuse
The system SHALL persist only hashes of refresh tokens, SHALL bind them to an
account and token family, SHALL rotate the presented token on every successful
refresh, and SHALL revoke the entire family when an already-rotated token is
presented.
#### Scenario: Rotated refresh token is replayed
- **WHEN** a client presents a refresh token that was already replaced
- **THEN** the system revokes the token family and returns an unauthorized
problem without issuing credentials
#### Scenario: The same refresh token is presented concurrently
- **WHEN** two requests present the same valid current refresh token at the same time
- **THEN** at most one rotation succeeds and replay handling revokes the family
before the losing request returns unauthorized
2. Apply
Dieser Prozessschritt ist die Umsetzung. Da wir hier von agentischer Entwicklung sprechen, gehe ich davon aus, dass dies auch von einem anderen KI-Agenten erledigt wird. Die „Denkarbeit” wurde ja schon im ersten Schritt geleistet, die tasks.md kann Stück für Stück abgearbeitet und abgehakt werden.
Theoretisch kann dieser Schritt natürlich auch von einem Menschen übernommen werden.
3. Verify
Hier prüft das Framework, ob die Umsetzung zur Spezifikation passt. Ich lasse in diesem Schritt meist auch ein Code-Review parallel laufen und prüfe die Umsetzung per Hand, sofern sinnvoll und nötig. Bei sicherheitsrelevanten Änderungen sehe ich mir den produzierten Code immer noch detailliert selbst an.
4. Update
Sollte in Schritt 3 etwas nicht stimmen – ich merke, dass sich vielleicht die Bedienung des UIs schlecht anfühlt, das Design nicht passend umgesetzt wurde oder sonst etwas nicht meinen Erwartungen entspricht –, gibt es einen optionalen Zwischenschritt: das Update. Diesen Schritt einzuhalten stellt sicher, dass Änderungen in die in Schritt 1 erstellten Artefakte eingearbeitet werden.
An dieser Stelle überlege ich auch, ob ich in meinen Projekt-Regeldateien wie der AGENTS.md etwas anpasse, um zu verhindern, dass etwas Ähnliches in folgenden Spec-Changes wieder vorkommt.
Sollte ein Update notwendig gewesen sein, geht es zurück zu Schritt 2.
5. Sync
Dieser Schritt prüft, ob im aktuellen Spec-Change eine schon vorhandene Spec betroffen ist, und sorgt dafür, dass das neue Systemverhalten dort aktualisiert wird.
6. Archive
Der aktuelle Spec-Change wird in einen Ordner archive verschoben, wodurch auch die Historie aller bisherigen Änderungen sichergestellt wird.
openspec/
├── changes/
│ ├── add-spectator-mode/ ← in Arbeit, noch nicht archiviert
│ │ ├── specs/ ← das Delta: was dieser Change am Verhalten ändert
│ │ ├── design.md
│ │ ├── proposal.md
│ │ └── tasks.md
│ └── archive/ ← abgeschlossene Changes, datiert
│ ├── 2026-09-03-add-app-skeleton/
│ ├── 2026-09-04-add-table-ui/
│ ├── …
│ └── 2026-09-08-tell-a-full-room-its-full/
└── specs/ ← das aktuelle Systemverhalten
├── app-delivery/
├── estimation-rounds/
├── game-sessions/
├── …
└── table-ui/
Die Ordnernamen im Archiv sind die Änderungshistorie: datiert, chronologisch und nach Inhalt benannt.
Greenfield vs. Brownfield
Meist beginnt man ein Projekt ja nicht schon mit einem Framework wie OpenSpec, entsprechend fehlen dann die Specs, die das Systemverhalten und die Features samt ihrer Funktion beschreiben. Ein Sync wird dann schwierig – es ist ja nichts vorhanden, gegen das ein Sync funktionieren würde.
Dafür bietet OpenSpec eine Lösung in Form einer weiteren Funktion, die optional vor allen anderen Schritten oder losgelöst davon genutzt werden kann.
0. Explore
Hier wird die vorhandene Codebasis auf Abläufe und Zusammenhänge geprüft. Anforderungen können herausgearbeitet, Specs initial erstellt werden. Auch für das Finden von Bugs kann das sehr hilfreich sein – oder um allgemein ein Verständnis für eine „fremde” Codebasis zu bekommen.
Vor- und Nachteile von SDD
Gegen Vibe-Coding gewinnt SDD in fast jedem Punkt. Das ist aber ein leichter Gegner, den ich mir selbst ausgesucht habe. Der interessantere Vergleich ist sauber geführte konventionelle Entwicklung, also Tickets, Reviews, ADRs und ein Team, das weiß, was es tut. Da sieht es weniger eindeutig aus, und da gibt es dann auch echte Nachteile.
Agentenunabhängigkeit
Wie vorher schon einmal angesprochen, ist der Agent, der am Ende das Schreiben des Codes erledigt, hier austauschbar. Durch die genaue Spezifikation kann an dieser Stelle ohne Probleme auf ein fast beliebiges anderes Modell oder einen anderen Agenten gewechselt werden, wenn es beispielsweise darum geht, Token und Kosten zu sparen. Die „Denkarbeit”, also das Propose, kann von einem großen und teuren Modell übernommen werden, das Abarbeiten dann von einem lokalen Modell, das über Nacht läuft. Ich glaube, dass gerade solche Ansätze in Zukunft immer wichtiger werden.
Qualität
Die Qualität der Architektur und des Codes steigt, da ein Agent schnell ein zusammenhängendes Bild der Software bekommt, ohne sich durch hunderte oder tausende Dateien zu lesen. Die Change-History hilft dabei, alte Entscheidungen nachzuvollziehen, die sonst nur als Code-Changes in der Git-History zu finden wären.
Kosten
Auch hier sehe ich, je nach Use Case, Einsparpotenzial. Das Verhalten des Systems ist schnell nachvollziehbar, unnötiges Lesen des Codes kann entfallen. Natürlich erfordert der ganze Prozess zusätzlichen Aufwand und damit auch Tokens, aber man kommt direkt zum gewünschten Ziel, ohne große Umwege.
Review-Last
Den Code lese ich irgendwann nicht mehr im Detail, das habe ich oben geschrieben. Die Specs muss ich aber lesen, und davon fällt einiges an. In dem Projekt weiter unten sind das 331 Requirements in drei Wochen, also grob sechzehn pro Tag. Davon hängt am Ende die Qualität ab und ob das rauskommt, was ich mir vorgestellt habe. Dass die Prüfgenauigkeit nachlässt, je mehr zu prüfen ist, kennt man von Code-Reviews, und bei Specs ist das nicht anders. Wenn ich das Propose einfach durchwinke, bekomme ich am Ende sauber spezifizierte Zufallsfeatures.
Spec-Drift
Sync entscheidet agentisch, ob eine bestehende Spec von einem Change betroffen ist. Übersieht er einen Fall, sagt die Spec X und der Code macht Y. Bei klassischer Dokumentation ist das ärgerlich. Hier ist es gefährlicher, weil die Spec mein Hauptzugang zum System ist. Wenn ich den Code nicht mehr lese, fällt mir die Abweichung ja auch nicht auf. Hier hilft es, immer mal wieder ein Spec-Review durchzuführen; manchmal weist OpenSpec einen auch selbst darauf hin, dass etwas nicht ganz stimmt. Meist reicht ein striktes Verify aber vollkommen.
Kleinkram
SDD für eine CSS-Korrektur ist Unfug. Erst wenn eine Änderung das Systemverhalten betrifft, nutze ich SDD.
Artefakte
Man bekommt im Prozess Artefakte erzeugt, die man vielfältig nutzen kann und die eine Wissensbasis für das Projekt aufbauen.
- Sie lassen sich direkt für Dokumentation nutzen oder in ein Wiki überführen, das auch technikfremde Kollegen verstehen.
- Es können Code-Kommentare erzeugt werden, die nicht nur die Funktion des betroffenen Codes beschreiben, sondern auch das große Bild – und auch diese lassen sich automatisiert aktuell halten.
- Das Systemverhalten eines Projekts kann direkt in anderen Projekten genutzt werden, zu denen es Schnittstellen gibt, und so eine systemübergreifende Dokumentation entstehen.
- Neue Mitarbeiter finden eine aktuelle Übersicht über ein Projekt und können es sich von einer KI schnell erklären lassen, ohne sich durch schlecht dokumentierten Code zu quälen.
- Auch Re-Writes eines Projekts in einer anderen Programmiersprache oder mit anderen Frameworks werden stark vereinfacht.
Praxisbeispiele
Ich habe in den letzten Monaten mehrere SDD-Frameworks ausprobiert, am Ende bin ich bei OpenSpec hängen geblieben. Für mich scheint es für unterschiedlichste Projekttypen am besten geeignet zu sein. Dabei waren diese Website mit selbst geschriebenem Blog-System, ein paar kleinere Web-Projekte (Static/Single Page), als Hobby-Projekt ein Retro-Game mit der Engine Godot und GDScript sowie ein Projekt, das ich für diesen Artikel – und weil ich es selbst benötige und testen wollte – geschrieben habe. Den Quellcode samt aller Specs und archivierter Changes findet ihr hier: github.com/thomas-negele/planningpoker
Dieses Projekt habe ich explizit in einem mir fremden Tech-Stack umgesetzt: das Backend in Go, das Frontend mit Svelte. Oder besser „umsetzen lassen”? Immerhin sind alle Funktionen so, wie ich sie wollte, und weitere aus meinem Backlog werden folgen. Wenn ein Go- oder Svelte-Profi dazu eine Einschätzung geben will: nur raus damit. Ich bin mir recht sicher, dass keine größeren Issues zu finden sein werden.
Warum habe ich das nicht in meinen vertrauten Tech-Stacks umgesetzt? Damit wollte ich mir auch selbst zeigen, dass jetzt jeder alles kann.
Auch ein weiteres Projekt, das noch nicht öffentlich ist, entwickle ich gerade auf dem beschriebenen Weg. Hier handelt es sich um eine größere Plattform, die auf viele Nutzer ausgelegt ist und entsprechend skalieren soll: ein Backend in Spring Boot und Kotlin, ein Backoffice zur Verwaltung, ein Public-Web-Client und native Mobile-Apps für iOS und Android. Die Specs decken das Gesamtprojekt ab, das in einem Mono-Repo lebt. Jedes Feature wird systemübergreifend im Backend und in allen Clients umgesetzt. CI/CD bis hin zur Testumgebung ist ebenfalls Teil der Specs. Nach meiner Erfahrung hätte so ein Projekt mehrere Teams über Monate beschäftigt; ich konnte es allein in Tagen umsetzen, meist nebenbei, während ich an anderen Projekten gearbeitet habe. Gerade bei so einem Projekttyp fällt sehr viel Abstimmungsaufwand zwischen Teams einfach weg: Die Specs und deren Changes sind die Single Source of Truth, ich steuere nur noch das Gesamtprojekt. Meine Entscheidungen sind hier wichtig, der Code ist günstig, der Tech-Stack fast egal geworden.
Ein paar Zahlen? 21 Tage, davon 18 mit Commits. 36 abgeschlossene Spec-Changes, 46 Capabilities, 331 Requirements. Konkret sind das 77 HTTP-Endpunkte, 19 Seiten im Web-Frontend, 18 Datenbank-Migrationen, dazu die Mobile-App für beide Plattformen und der Admin-Bereich. Aufwand in Summe ca. 80 bis 100 Stunden. Applikationscode und Testcode im Verhältnis 1:1.
Abschließende Anmerkung
Im berühmten Paper „Programming as Theory Building” von Peter Naur geht es darum, dass Software nicht der Code oder die Dokumentation ist, sondern eher das mentale Modell, das in den Köpfen der Entwickler lebt. Das Paper ist von 1985; von agentischer Softwareentwicklung war man damals noch weit entfernt. Ich nehme jetzt mal das mentale Modell aus den „Köpfen” der KI-Agenten mit in die Gleichung – und da erkenne ich Spec Driven Development als die Brücke und die Specs im Projektverzeichnis als das mentale Modell. Die Specs selbst sind vielleicht sogar eher Dokumentation; aber die Change-History, die ein KI-Agent aus der Historie der Spec-Changes und der Git-Historie zusammensammeln und „verstehen” kann, entspricht für mich dem mentalen Modell eines Entwicklers. Abzüglich der Emotionen versteht sich, die ein Entwickler am Release-Tag oder nach zweitägiger Bugsuche mit sich trägt.
Auch war Softwareentwicklung nie das Schreiben von Code. Der Part war vielleicht der zeitaufwendigste, aber nicht der wichtigste – auf jeden Fall der austauschbarste. Sei es durch ein anderes Entwicklungsteam oder einen anderen Tech-Stack.
Viel wichtiger war – und daraus entstanden die meisten Probleme, wenn es nicht ordentlich umgesetzt wurde – eine saubere Anforderungsanalyse, das Schaffen eines gemeinsamen Verständnisses für alle Beteiligten, danach das Prüfen gegen die Anforderungen und das Anpassen der Prozesse und Standards in einem Team oder Projekt. Genau das, was SDD-Frameworks wie OpenSpec ideal abbilden.
Und zu guter Letzt, weil oft das Argument kommt, wer denn noch der Owner des Codes sei, wenn man ihn nicht mehr selbst schreibt: Dazu die Gegenfrage – wer ist denn der Owner des Codes, der vor ein bis zwei Jahren geschrieben wurde? Was ist, wenn der Entwickler das Unternehmen verlässt, der den Microservice fast allein aufgesetzt hat? Ob da nicht saubere Specs und deren History mehr helfen, lasse ich mal mit einem Augenzwinkern so stehen.
// kontakt
Über diesen Artikel sprechen
Wenn der Artikel bei dir eine Frage, ein Projekt oder Widerspruch ausgelöst hat: schreib mir direkt, ich freue mich auf Feedback.
Kontakt aufnehmen