KI kann eine Anwendung schreiben. Aber wer sorgt dafür, dass alles dieselbe Sprache spricht?

Stell dir eine kleine Änderung vor: Das Feld slug in einem Content-System soll verpflichtend sein und innerhalb einer Sprache eindeutig bleiben.

Klingt nach fünf Minuten Arbeit. Bis du alle Stellen zählst, an denen diese Entscheidung existiert: Datenbankschema, Migration, Backend-Modell, API-Validierung, DTO, Formular im Admin-Panel, Fehlermeldung, Seitenrouting und Tests.

Du kannst die KI bitten, jede dieser Stellen anzupassen. Oder du kannst die Entscheidung einmal festhalten und den Rest daraus ableiten lassen.

Das sind zwei grundlegend unterschiedliche Vorstellungen von Codegenerierung. Die erste dominiert heute die Schlagzeilen. Die zweite hat mehr als ein Vierteljahrhundert intellektueller Geschichte hinter sich — und genau in diese Tradition gehört GOAT CLI.

Im Zeitalter der KI liegt der Engpass nicht mehr in der Produktion von Code. Er liegt darin, eine Entscheidung über mehrere Schichten einer Anwendung hinweg konsistent zu halten.

„Codegenerator“ ist ein Sammelbegriff, in den wir zu viel hineingepackt haben

Ein „Codegenerator“ kann ein Template sein, das drei Dateien erzeugt, ein Protocol-Buffers-Compiler, ein Makro, ein Tool, das aus einer OpenAPI-Spezifikation einen Client erstellt, oder ein Sprachmodell, das auf einen Prompt antwortet.

Gemeinsam haben sie nur die allgemeine Idee, dass eine Repräsentation in ein Programm oder einen Teil davon transformiert wird. In fast allem, was praktisch relevant ist, unterscheiden sie sich.

Ein deterministischer Generator funktioniert wie eine Maschine. Er erhält ein gültiges Schema und wendet explizite Regeln an. Derselbe Input sollte zum selben Ergebnis führen. Ein Sprachmodell arbeitet eher wie ein sehr schneller Mitarbeiter: Es versteht unvollständige Anweisungen, schließt Lücken und schlägt Lösungen vor, trifft dabei aber auch einen Teil der Entscheidungen für uns.

Dabei geht es nicht darum, welcher Mechanismus „besser“ ist. Wenn wir eine Lösung erst noch suchen, ist die Flexibilität von KI wertvoll. Wenn jedoch eine festgelegte Regel gleichzeitig in Datenbank, API und Benutzeroberfläche gelten soll, ist es ein Nachteil und kein Vorteil, sie dreimal neu zu erraten.

Die große Idee aus dem Jahr 2000 bestand nicht darin, Dateien auszudrucken

Als Krzysztof Czarnecki und Ulrich W. Eisenecker im Jahr 2000 das Buch *Generative Programming: Methods, Tools, and Applications* veröffentlichten, gab es Generatoren natürlich bereits. Entwickler kannten Makros, Compiler, Parser-Generatoren und CASE-Werkzeuge. Zehn Jahre zuvor hatte der FODA-Bericht die Domänenanalyse anhand gemeinsamer und variabler Merkmale beschrieben.

Der Beitrag von Czarnecki und Eisenecker bestand also nicht darin, eine Funktion wie „Datei erstellen“ zu erfinden. Sie führten frühere Ansätze zu einem kohärenten Konzept der halbautomatischen Erstellung von Systemfamilien zusammen.

Zuerst versteht man die Domäne. Danach identifiziert man, was den Produkten gemeinsam ist und was sich zwischen ihnen unterscheiden kann. Man beschreibt zulässige Varianten und Abhängigkeiten. Erst dann werden automatisch die Komponenten ausgewählt und zusammengesetzt, die für ein konkretes System benötigt werden.

Aus dieser Perspektive ist der Generator das Ende des Prozesses, nicht sein Anfang. Der wertvollste Vermögenswert sind nicht tausend erzeugte Codezeilen. Es ist das verdichtete Wissen darüber, warum genau diese Zeilen entstehen sollten.

Diese Verschiebung ist bis heute relevant. „Ich habe 20.000 Codezeilen generiert“ sagt wenig über den Wert aus. „Ich habe die Berechtigungsregel einmal definiert, und sie kann in fünf Schichten nicht auseinanderlaufen“ sagt beinahe alles.

Ein Feld, viele Konsequenzen

GOAT beschreibt sich als Generator und Werkzeugsammlung zum Erstellen datengetriebener Anwendungen. Sein zentrales Artefakt ist die Datei herd/_model.goat.

Das Modell kann Anwendungsmetadaten, Sprachen, Rollen, Entitäten, Felder, Beziehungen, Einschränkungen, Berechtigungen sowie Module wie CRUD, SEO oder SSR enthalten. Auf dieser Grundlage erzeugt der Generator Elemente über mehrere Schichten hinweg: Go-Modelle, Repositories und DAOs, DTOs, APIs, SQL-Migrationen, Formulare, Admin-Ansichten und ein Angular-Frontend.

Entscheidend ist nicht, dass das Tool „viel schreiben“ kann. Entscheidend ist, dass ein Feldtyp mehr bedeuten kann als nur einen Spaltentyp.

web_slug kann Entscheidungen zu Speicherung, Validierung, Serialisierung und Darstellung transportieren. Eine Beziehung wie owner kann Konsequenzen in SQL, API, Formular und Admin-Panel haben. Lese- oder Schreibberechtigungen müssen nicht auf beiden Seiten des Netzwerks separat neu erstellt werden.

Genau hier zeigt sich die Nähe zum generativen Programmieren: Das Modell beschreibt keine einzelne Implementierungszeile. Es beschreibt die Absicht in einer domänenspezifischen Sprache, und der Generator überträgt deren Konsequenzen.

Die Nische von GOAT CLI: zwischen Scaffolder, Framework und KI-Agent

Ein Scaffolder ist am ersten Tag hervorragend. Er erstellt Verzeichnisse, Konfigurationen und grundlegende Komponenten. Später verschwindet er häufig aus dem Prozess, während die Anwendung manuell weiterentwickelt wird. Der Wert des Starters sinkt mit jedem Commit.

Eine Low-Code-Plattform hält Konsistenz länger aufrecht, tut dies jedoch häufig dadurch, dass sie den Code verbirgt oder den Nutzer an ihre Umgebung bindet. Ein CRUD-Framework wiederum stellt gemeinsames Verhalten zur Laufzeit bereit, verbindet aber nicht immer ein einziges Modell mit Datenbank, API und unabhängigem Client.

Ein KI-Agent ist am flexibelsten. Er kann mit nahezu jedem Stack arbeiten und ungewöhnliche Funktionen implementieren. Per Definition verfügt er jedoch nicht über eine einzige formale Semantik der Domäne. Wenn wir ihn dreimal bitten, dieselbe Regel zu implementieren, erhalten wir drei plausible Vorschläge — aber nicht zwingend einen einzigen Vertrag.

GOAT liegt zwischen diesen Kategorien:

  • es ist langlebiger als ein einmaliger Starter, weil das Modell auch bei späteren Änderungen eine Rolle spielt;
  • es bietet mehr Kontrolle als eine typische No-Code-Plattform, weil das Ergebnis normaler Code bleibt, der geprüft, geändert und committed werden kann;
  • es deckt mehr Schichten ab als ein Generator für einen einzelnen Client oder ein ORM;
  • es bietet weniger Freiheit als KI, dafür aber mehr Vorhersagbarkeit für Entscheidungen, die bereits im Modell festgehalten wurden.

Kurz gesagt: GOAT besetzt die Nische der model-first Full-Stack-Codegenerierung für datengetriebene Anwendungen, deren Eigentümer den Code behalten wollen.

„Der Code gehört dir“ beendet die Lock-in-Diskussion nicht

Transparenter generierter Code ist ein wichtiger Vorteil. Das bedeutet jedoch nicht automatisch, dass keinerlei Abhängigkeit besteht.

Wenn ein Team aufhört, den Generator zu verwenden, kann es die erzeugte Anwendung weiterentwickeln. Es verliert jedoch die Möglichkeit, zukünftige Änderungen kostengünstig aus dem Modell zu propagieren. Die eigentlichen Werte bestehen daher gleichzeitig aus dem Code, dem Modell und dem Wissen über das Werkzeug.

Daraus ergeben sich Fragen, die man jedem Generator stellen sollte, nicht nur GOAT:

  1. Welche Dateien können sicher manuell bearbeitet werden?
  1. Was passiert bei der nächsten Generierung mit einer manuellen Änderung?
  1. Wie funktionieren Migrationen zwischen verschiedenen Versionen des Generators?
  1. Kann der Unterschied ganz normal in Git geprüft werden?
  1. Wie wird die Konsistenz zwischen Datenbank, Backend und Client getestet?
  1. Wie viele Ausnahmen kann das Modell aufnehmen, bevor die DSL zu einem zweiten, schlechter dokumentierten Framework wird?

Das sind keine Vorwürfe. Das ist der Preis reifer Automatisierung. Ein Generator beseitigt Komplexität nicht; er verschiebt sie aus vielen Implementierungen in das Modell, die Transformationen und den Regenerierungsprozess.

Wann ein solches Modell den größten Nutzen bringt

GOAT dürfte besonders interessant für Anwendungen sein, in denen sich Entitäten, Beziehungen, Formulare, Berechtigungen, CRUD-Operationen, Admin-Panels, öffentliche SSR-Seiten und SEO-Anforderungen wiederholen. Je mehr Schichten dieselbe Entscheidung respektieren müssen, desto größer ist der Wert einer einzigen Quelle der Wahrheit.

Nicht jede Software passt in dieses Muster. Wenn der Kern eines Produkts ein ungewöhnlicher Echtzeit-Editor, ein Optimierungsalgorithmus oder eine stark experimentelle Benutzeroberfläche ist, deckt das Datenmodell möglicherweise nur einen kleinen Teil des Problems ab. Ein Generator sollte nicht so tun, als sei die Domäne stabil, wenn das Team sie noch erforscht.

Das ist die wichtigste Lehre aus dem generativen Ansatz: Automatisiert werden sollte nicht das, was lediglich ähnlich aussieht, sondern das, was dieselbe ausreichend ausgereifte Entscheidung repräsentiert.

KI und GOAT müssen nicht miteinander konkurrieren

Forschung zu Program Synthesis definiert das Problem weit: Es geht darum, ein Programm zu finden, das einer in einer Spezifikation ausgedrückten Absicht entspricht. Moderne LLMs haben die Kosten des Übergangs von einer unpräzisen Beschreibung zu einer ersten Implementierung drastisch gesenkt. Sie haben jedoch nicht die Notwendigkeit beseitigt, das zu formalisieren, was konsistent bleiben soll.

Der interessanteste Workflow könnte hybrid sein:

  1. Menschen und KI untersuchen das Problem, erstellen Prototypen und entdecken Domänenkonzepte;
  1. stabile Konzepte werden in ein explizites Modell überführt;
  1. ein deterministischer Generator leitet daraus wiederholbare Artefakte ab;
  1. KI hilft bei der Implementierung ungewöhnlicher Logik und bei der Überprüfung von Änderungen;
  1. Tests entscheiden, ob das Gesamtsystem den Vertrag erfüllt.

KI ist gut in einem breiten Aufgabenbereich und bei unvollständigen Anweisungen. Ein domänenspezifischer Generator ist gut in einem engen Aufgabenbereich und bei starken Garantien für Wiederholbarkeit. Der Versuch, das eine durch das andere zu ersetzen, nimmt uns die Vorteile beider Ansätze.

Frag nicht, wie viel Code entstanden ist

Im Jahr 2000 verglichen Czarnecki und Eisenecker generatives Programmieren mit dem Übergang von der manuellen Herstellung einzelner Produkte zur Produktion ganzer Produktfamilien. Heute mag die Fabrikmetapher weniger spektakulär klingen als „eine Anwendung aus einem einzigen Prompt“. Dafür ist sie ehrlicher.

Eine Fabrik funktioniert hervorragend, wenn klar ist, was sie produzieren soll, welche Varianten zulässig sind und wie die Qualität kontrolliert wird. Sie funktioniert schlecht, wenn jedes einzelne Stück ein Experiment ist.

Deshalb lautet die richtige Frage nicht: „Kann GOAT meine Anwendung generieren?“ Die richtige Frage lautet:

Welche Entscheidungen in meiner Anwendung sind bereits stabil genug, dass ich sie einmal festhalten — und ihre Konsequenzen nie wieder manuell synchronisieren möchte?

Wenn die Antwort Datenbank, API, Admin-Panel und Frontend umfasst, konkurriert GOAT nicht nur um eingesparte Programmierzeit. Es konkurriert um etwas Wertvolleres: um die Anzahl der Stellen, an denen ein Projekt aufhören kann, mit sich selbst mit einer Stimme zu sprechen.


Zur Diskussion

Bevorzugst du einen Generator, der sich in einer engen Domäne vorhersehbar verhält, oder einen Agenten, der fast alles kann, dafür aber eine sorgfältigere Überprüfung erfordert? Oder beginnt sinnvolle Softwareentwicklung erst dann, wenn beide Werkzeuge zusammenarbeiten?

Ausgewählte Bibliografie