- Zur Behauptung des agentischen Codings, man könne „Code durch Spezifikationsdokumente ersetzen“, wird auf eine grundlegende Grenze hingewiesen: Wenn eine Spezifikation hinreichend präzise wird, muss sie letztlich auf dieselbe Form wie Code hinauslaufen
- Ein Blick auf OpenAIs Projekt Symphony zeigt, dass die betreffende SPEC.md keine Spezifikation ist, sondern de facto Pseudocode im Markdown-Format
- Tatsächlich traten bei einem Versuch, auf Basis der Symphony-Spezifikation eine Haskell-Implementierung zu erstellen, zahlreiche Bugs und Zuverlässigkeitsprobleme wie unendliches Warten des Agenten auf
- Spezifikationsarbeit verlangt ursprünglich tieferes Nachdenken als Programmieren, doch im aktuellen Branchenklima der Geschwindigkeitsoptimierung entsteht eine Struktur, in der massenhaft von KI erzeugte Spezifikationen minderer Qualität produziert werden
- Das Prinzip „garbage in, garbage out“ gilt unverändert auch für Coding-Agenten; mit Dokumenten ohne Klarheit und Detail ist eine zuverlässige Codegenerierung unmöglich
Zwei Missverständnisse des agentischen Codings
- Befürworter des agentischen Codings stützen sich auf zwei zentrale Missverständnisse
- Missverständnis 1: Spezifikationsdokumente sind einfacher als der entsprechende Code — eine Outsourcing-Perspektive, in der Ingenieure zu Managern von Spezifikationsdokumenten werden und Arbeit an ein Team von Agenten delegieren
- Missverständnis 2: Spezifikationsarbeit ist notwendigerweise überlegter als Programmierarbeit — die Behauptung, dass der Umweg über Spezifikationsdokumente die Qualität erhöht und bessere Engineering-Praktiken fördert
Code, der vorgibt, eine Spezifikation zu sein: Analyse des Falls Symphony
- OpenAIs Projekt Symphony wird als aus einem Spezifikationsdokument (SPEC.md) erzeugter Agenten-Orchestrator vorgestellt, doch der tatsächliche Inhalt der SPEC.md kommt eher Pseudocode im Markdown-Format als einer Spezifikation nahe
- Enthaltene Inhaltstypen in SPEC.md:
- Prosaischer Dump eines Datenbankschemas — Auflistung von Feldern wie
session_id, thread_id, codex_input_tokens usw.
- Prosaische Umformung von Code — Formeln wie
available_slots = max(max_concurrent_agents - running_count, 0) für Nebenläufigkeitskontrolle sowie Retry-Backoff-Formeln (delay = min(10000 * 2^(attempt-1), agent.max_retry_backoff_ms))
- Redundante Abschnitte wie „Config Fields Summary (Cheat Sheet)“, die ausdrücklich hinzugefügt wurden, um die Codegenerierung des Modells zu unterstützen
- Abschnitte wie „Reference Algorithms“ mit Funktionen wie
start_service(), die faktisch Code selbst sind
- Zu behaupten, ein Spezifikationsdokument sei ein Ersatz für Code, obwohl sich dieses Dokument selbst wie Code liest, ist irreführend
- Will man ein Spezifikationsdokument hinreichend präzise machen, muss man es zwangsläufig in Codeform überführen oder in stark strukturierter formaler englischer Sprache verfassen
Dijkstras Argument der „schmalen Schnittstelle“
- Unter Verweis auf Dijkstra wird argumentiert, dass die Wahl einer Schnittstelle nicht bloß eine einfache Arbeitsaufteilung ist, sondern zusätzliche Kosten für Zusammenarbeit und Kommunikation über die Schnittstelle hinweg erzeugt
- Als historische Beispiele werden genannt, dass die griechische Mathematik auf sprachliche und visuelle Aktivitäten beschränkt stagnierte, die islamische Algebra mit der Rückkehr zu einem rhetorischen Stil verfiel und dass Westeuropa sich aus dem „vergeblichen Versuch verbaler Präzision“ der mittelalterlichen Scholastik löste und dank formaler Symbolsysteme von Vieta, Descartes, Leibniz, Boole u. a. Fortschritte machte
- Agentische Coder können der für Engineering-Arbeit nötigen „schmalen Schnittstelle“ (= Code) nicht entkommen; sie können diese Arbeit nur in eine Form überführen, die oberflächlich anders aussieht, aber dieselbe Präzision verlangt
Instabilität: Zuverlässigkeitsprobleme der spezifikationsbasierten Codegenerierung
- Wie im Symphony-README empfohlen wurde Claude Code gebeten, eine Implementierung in Haskell zu erstellen — das funktionierte nicht
- Zahlreiche Bugs traten auf, Korrekturen per Prompt waren nötig (im Commit-Verlauf nachvollziehbar)
- Selbst wenn es ohne Fehlermeldung „funktionierte“, wartete der
codex-Agent bei einem einfachen Linear-Ticket („leeres git-Repository erstellen“) endlos ohne Fortschritt
- In Dijkstras Worten zeigt sich, dass Symphonys „vergeblicher Versuch verbaler Präzision“ weiterhin keine zuverlässige Implementierung erzeugen kann
- Das Problem ist nicht auf Symphony beschränkt — selbst Spezifikationen wie YAML, die extrem detailliert, weit verbreitet und sogar mit Konformitätstest-Suites ausgestattet sind, werden von den meisten YAML-Implementierungen nicht vollständig eingehalten
- Symphonys Spezifikation erreicht bereits ein Sechstel der Größe der enthaltenen Elixir-Implementierung; würde man sie weiter ausbauen, käme man in eine Situation wie in Borges’ „Von der Strenge der Wissenschaft“ — der Fabel von einer Karte in der Größe des Reichs, die am Ende nutzlos wird
- Gegen das Argument „In einer populäreren Sprache wäre das Ergebnis besser“ wird eingewandt, dass Schwierigkeiten eines Agenten bei der Erzeugung von Haskell-Code auf eine mangelnde Generalisierungsfähigkeit über die Trainingsdaten hinaus hindeuten
Slop: Qualitätsprobleme von KI-generierten Spezifikationen
- Spezifikationsarbeit sollte ursprünglich schwieriger als Programmieren sein; ihr Zweck ist es, vor Beginn des Codings ein Projekt aus einer reflektierten und kritischen Perspektive zu betrachten
- Doch in einem Branchentrend, der Arbeit in Tech-Unternehmen reduzieren und entwerten will, ist ein Ansatz, der von der Annahme ausgeht, „Spezifikationsarbeit sei leichter als Programmieren“, zum Scheitern verurteilt
- Wer Liefergeschwindigkeit optimieren will, kann die schwierige und unbequeme Arbeit, die das Schreiben von Spezifikationen verlangt, nicht leisten
- Abschnitt 10.5 der Symphony SPEC.md (der
linear_graphql-Extension-Contract) ist ein typisches Beispiel für Slop — Output eines Agenten, dem Konsistenz, Ziel und Verständnis des Gesamtbilds fehlen, obwohl die Sätze „wie eine Spezifikation aussehen“
- Einzelne Regeln werden aufgelistet, etwa dass
query eine nichtleere Zeichenfolge sein muss und genau eine GraphQL-Operation enthalten darf, doch der Gesamtkontext fehlt
- Selbst wenn solche Spezifikationsdokumente von Menschen geschrieben wurden, sind sie zwangsläufig Slop — weil sie nicht auf Konsistenz oder Klarheit, sondern auf Lieferzeit optimiert wurden
- Dass Code-Snippets ohne Syntax-Highlighting als
text gekennzeichnet wurden, ist ebenfalls ein Anzeichen für KI-generierte Dokumente — vermutlich ein Ergebnis davon, dass das Modell der Anfrage wörtlich statt ihrem Sinn gefolgt ist
Fazit
- Spezifikationen wurden ursprünglich nicht als Zeitsparinstrument konzipiert
- Wenn die Optimierung der Lieferzeit das Ziel ist, ist es vorteilhafter, Code direkt zu schreiben, statt über ein zwischengeschaltetes Spezifikationsdokument zu gehen
- Das Prinzip „garbage in, garbage out“ gilt unverändert — wenn Dokumenten Klarheit und Details fehlen, gibt es keine Welt, in der Coding-Agenten diese Lücken zuverlässig füllen könnten
- Coding-Agenten können keine Gedanken lesen, und selbst wenn sie es könnten, könnten sie nichts ausrichten, wenn das Denken selbst verworren ist
6 Kommentare
Das scheint genau dasselbe zu sein wie bei der modellgetriebenen Entwicklung.
Gab es spezifikationsgetriebene Entwicklung, also SDD, nicht schon immer?
Bei Python- oder JavaScript-basierten Lösungen scheint eine zufriedenstellende Implementierung allein anhand eines detaillierten Spezifikationsdokuments möglich zu sein. Ich arbeite im C/C++-basierten Spiele-/Medizinbereich, und in letzter Zeit denke ich oft, dass schon die Automatisierung nur auf Basis eines detaillierten Spezifikationsdokuments ein zu großes Risiko ist – von einer vollständigen Delegation an einen FULL AI AGENT ganz zu schweigen.
Hacker-News-Kommentare
Ich stimme nicht zu, dass ein Coding-Agent keine Details ergänzen kann, wenn man ihm unklare Dokumentation gibt
LLMs sind im Kern Sprach-Interpolations-/Extrapolationsmaschinen und sehr gut darin, fehlende Details zu ergänzen
Es gibt viele Fälle, in denen sie allein aus einer kurzen, knappen Beschreibung funktionsfähigen Code erzeugen
Allerdings sind solche Detailergänzungen nicht immer korrekt, und um Zuverlässigkeit sicherzustellen, muss man wichtige Teile explizit einschränken
Derzeit gibt es zwar eine Kultur des Codens, aber eine Kultur ultragenauer Spezifikationen gibt es außerhalb von Orten wie der NASA kaum
Je kürzer und gebräuchlicher der Code ist, desto besser funktioniert es, aber bei komplexen Beschreibungen bricht es leicht zusammen
Letztlich bedeutet die Anerkennung, dass „die Detailergänzung falsch sein kann“, dass zuverlässige Generierung schwierig ist
Es gibt zum Beispiel Programmsynthese-Sprachen wie Synquid
Sie zeigen, welche Grenzen mathematisch exakte Spezifikationen bei der Programmerzeugung haben
Das zentrale Problem ist die sogenannte specification gap, also der Nachweis, dass ein Programm die Spezifikation tatsächlich korrekt umsetzt
Natürliche Sprache ist zu mehrdeutig und daher ungeeignet, um Programme zu definieren
Dass ein LLM plausible Details ergänzt, löst diese Lücke nicht
Mathematische Spezifikationssprachen sind präzise, haben aber eine steile Lernkurve und sind viel schwieriger und arbeitsintensiver, als einfach ein Prompt in Markdown zu schreiben
Das Modell erinnert sich an meine Interessen oder füllt Lücken aus eigenem Wissen und erzeugt so vollständige Apps, Spiele oder Whitepaper
Manchmal ist es „genau das, was ich wollte“, manchmal „genau das Gefühl, das ich meinte“
Beim Umgang mit Bedeutung, Kontext und Nuancen ist es Menschen in manchen Punkten sogar überlegen
KI wird zunehmend klüger und kompetenter
Es erschafft also nicht wirklich völlig neue Details, sondern greift eher auf Trainingsdaten zurück
Ich kann der Aussage „Eine ausreichend detaillierte Spezifikation ist Code“ etwas abgewinnen
Das entspricht der Argumentation von Brooks' No Silver Bullet
Aber die meisten Menschen wollen gar nicht diesen Detailgrad
Wenn man sagt: „Erstelle mir mit AI eine To-do-App“, meint man in Wirklichkeit: „Erstelle eine App, die besser ist als das, was ich mir vorgestellt habe“
Aber dieser Ansatz lässt sich nicht gut auf andere Arten von Software übertragen
Letztlich muss man genau diese Unterschiede als Spezifikation ausdrücken
Aber in Bereichen wie Datenbanken, Dateisystemen und paralleler Berechnung, in denen Korrektheit und Performance wichtig sind, ist die Implementierung viel schwieriger als die Spezifikation
Dass AI dort Code erzeugt, der formale Verifikation besteht, ist eine große Herausforderung
Um Geld zu verdienen oder konkurrenzfähig zu sein, braucht man konkrete Anforderungen
Aus Sicht der Informationstheorie setzt vibe coding voraus, dass ein Decoder existiert, der aus einem kleinen Prompt-Raum einen Raum nützlicher Programme rekonstruieren kann
Das Kompressionsverhältnis ist dabei genau der Nutzen von vibe coding
Ein Prompt wie „Team-Kommunikations-App auf Basis von IRC-Kanälen“ ist ohne Kenntnis von Slack nicht entschlüsselbar
Deshalb ist es wichtig zu erkennen, was fehlt
Um effektiv mit AI zu coden, sollte man Prompts in kurze Einheiten aufteilen und bestehende Dokumentation oder bereits ausprobierten Code mitliefern
Laut Algorithmic Information Theory entspricht die Informationsmenge einer Zeichenkette der Länge ihrer am stärksten komprimierten selbstenthaltenden Darstellung
Die Bedingung „selbstenthaltend“ gilt allerdings nur dann, wenn die Gewichte des Modells als Codebuch fungieren
Menschen setzen viel mehr geteilten Kontext voraus als LLMs und überschätzen daher oft die Grenzen des Decoders
Aber bei Systemen mit starken Einschränkungen und klaren Schwerpunkten könnte sich das Kompressionsverhältnis von vibe coding explosiv erhöhen
Natürliche Sprache bietet Menschen, für die Programmiersprachen weniger zugänglich sind, ein neues Interface
LLMs nehmen einem das Denken nicht ab, aber sie eröffnen einen neuen Weg, Ideen in funktionierende Systeme zu verwandeln
Bald werden Menschen wohl so etwas wie LLMSpeak entwickeln, einen technischen englischen Dialekt für bessere Modellleistung und Token-Effizienz
Er würde Mehrdeutigkeit reduzieren, Tokens sparen und komplexe Konzepte in einzelne Wörter komprimieren
Vielleicht entstehen sogar grammatische Regeln wie das Oxford comma, um die Eindeutigkeit zu erhöhen
Wenn man ohnehin so detailliert spezifiziert, gibt es keinen besonderen Grund mehr, Prompts zu verwenden
Letztlich muss man alles wieder in menschlicher Sprache definieren, daher ist die Token-Ersparnis begrenzt
Siehe Lojban-Wiki, Video mit einem Lojban-Sprecher
Der Versuch eines künstlichen Dialekts könnte wie Esperanto scheitern
Eine solche Sprache könnte eher nützlich sein, wenn LLMs untereinander kommunizieren
Programmiersprachen übernehmen diese Rolle bereits
Eine Spezifikation (spec) ist wie ein Umschlag (envelope), der alle Programme umfasst, die die jeweiligen Bedingungen erfüllen
Diesen Umschlag zu erstellen ist schwieriger, als ein einzelnes Programm zu schreiben
So wie LLMs jedes Mal anderen Code erzeugen, erlaubt eine Spezifikation sowohl gute als auch schlechte Implementierungen
In der Praxis wird eine Implementierung, sobald sie übernommen ist, zur faktischen Spezifikation der nächsten Version
In einer Brownfield-Umgebung mit vorhandenem Code sind Spezifikationen nicht sauber, weshalb LLMs damit nur schwer zurechtkommen
Es gibt eine kombinatorische Explosion, weil man bedenken muss, wie jede Zeile einer Spezifikation mit den anderen Zeilen interagiert
Aus Sicht des Compilers ist allerdings auch Code nur eine Spezifikation
Letztlich ist „Code ist einfacher als Spezifikation“ also eine relative Aussage
Eine Spezifikation wie „speichert Benutzerzugangsdaten“ umfasst alles von bcrypt bis zu Klartext-Cookies
Menschen haben einen Instinkt dafür, dass „man das nicht tun sollte“, aber ein Agent weiß das nicht, wenn es nicht explizit gesagt wird
Um Sicherheit zu gewährleisten, muss man deshalb auch spezifizieren, was nicht getan werden darf
Wenn Performance oder Sicherheit wichtig sind, muss man diese Eigenschaften ausdrücklich festlegen
Ein Satz wie „Dieses Programm muss O(n) sein“ ist zum Beispiel viel einfacher als die Implementierung selbst
Es scheint, als würden verschiedene Menschen spec unterschiedlich verwenden
Für mich definiert spec das „Was“, plan das „Wie“ und build packet die konkreten Einzelschritte
In den meisten Fällen ist das „Was“ das Entscheidende
Als Spezifikation zu beschreiben, dass Daten von A nach B gehen, über C erhalten bleiben und bei D in Form von E als F dargestellt werden, ist viel einfacher, als das in Rust-Code umzusetzen
Wenn man agentisches Engineering betreibt, werden Spezifikationsdokumente oft länger als der Code
Natürliche Sprache ist unvollständig, Code dagegen präzise
Der Zweck einer Spezifikation besteht darin, Funktionalität auch über mehrere Iterationen der Entwicklung hinweg zu erhalten
Wasserfallartige Designdokumente waren wirksamer als Tests oder Kommentare
Auf diese Weise konnte ich sogar vollständige vibe-coding-Projekte glatt refaktorisieren oder in andere Sprachen übertragen
Im Moment fühlt es sich fast so an, als würden wir zum Entwicklungsstil der 70er und 80er Jahre zurückkehren
Ein Satz wie „Implementiere ein TCP-Interface“ ist viel kürzer als der tatsächliche Code
Letztlich kann auch natürliche Sprache hinreichend komprimiert sein, wenn sie auf ein klares Schema abgebildet werden kann
Die Richtung Spec → LLM ist ineffizient und verschwenderisch
Viel realistischer ist LLM → Spec
Wenn eine Spezifikation in kompilierbarer Form vorliegt, kann ein LLM dieses Feedback nutzen, um besseren Code zu erzeugen
Versuche, so etwas wie „validated English“ zu schaffen, erhöhen eher die Komplexität
Am Ende zählt der tatsächlich funktionierende Code
Code enthält viel mehr als eine Spezifikation
In den meisten Projekten bestehen 90 % aus Framework- oder Infrastruktur-Code und nur 10 % aus Geschäftslogik
Eine Spezifikation ist viel knapper, weil sie Sprach- oder Framework-Details nicht behandelt
Dann entsteht Code, der fast auf demselben Niveau wie die Spezifikation liegt
Auch Fachexperten können ihn lesen, und er ist leicht zu testen
Der tatsächliche Code ändert sich jedoch ziemlich stark
Der Konflikt zwischen der Sicht auf Spezifikationen als Management-Tool und als Engineering-Tool erzeugt kognitive Dissonanz
Manager sehen Spezifikationen als Delegationstickets, Entwickler nutzen sie als Denkwerkzeug, um Gedanken zu präzisieren
Manche Entwickler beginnen aus Bequemlichkeit mit der Denkweise des Managements, merken dann aber schnell, worum es wirklich geht
Mit Hype oder Investorengesprächen kann man sich eine Weile über Wasser halten, aber letztlich wollen Nutzer ein echtes Produkt
Als Nächstes erfinden sie wohl auch noch Waterfall und Agile neu.
Als C-Embedded-Entwickler erstelle ich Spezifikationen so, dass sich fast der gesamte Ablauf für Feature/Subfeature anhand von Charts nachvollziehen lässt.
Nach einer ausführlichen Prüfung der Spezifikation und der endgültigen Freigabe
erzeuge ich Code, der der Spezifikation vollständig 1:1 entspricht, und verwende diesen.
Wenn man anhand der Spezifikation prüft, ist die Lesbarkeit deutlich besser als bei einem Code-Review.