Warum Vibe Coding-Prompts zu Chaos führen, und wie man es besser macht

Wenn Sie hören, dass KI Code schreiben kann, denken Sie vielleicht sofort: „Perfekt, Stunden sparen, alles automatisieren!“ – und genau hier beginnt das Problem. Ohne gezieltes Training und klare Regeln produziert die KI zwar Code, doch selten den, den man tatsächlich in Produktion einsetzen möchte. Auf den ersten Blick scheint alles zu funktionieren, doch bei näherem Hinsehen zeigt sich: Wartbarkeit, Struktur und Konsistenz fehlen völlig.

Das Video zu dieser Folge des Projektes

Was passiert, wenn man einfach lospromptet

Viele Entwickler starten mit simplen Prompts wie: „Schreibe mir einen User-Service in TypeScript, mit Aggregate und Repository“ Die KI liefert prompt, doch nach wenigen Zeilen wird schnell klar, dass etwas nicht stimmt: Die Struktur ist anders als vorgesehen, Logik wird ins Frontend generiert, obwohl sie ins Backend gehört, so mancher Code ist nicht testbar, und Sicherheitslücken schleichen sich unbemerkt ein. Am Ende hält man Code in den Händen, der zwar kompiliert, aber langfristig kaum tragfähig ist.

Warum einfache Prompts nicht ausreichen

Das Problem liegt darin, dass eine KI die Regeln sauberer Architektur nicht automatisch kennt. Ein einfacher Prompt beschreibt, was passieren soll, aber nicht, wie die einzelnen Bausteine einer Domain miteinander interagieren, wie Aggregates aufgebaut sind oder welche Services welche Verantwortung tragen.

Vibe Coding-Prompts oder ähnliche Impuls-Ansätze erzeugen oft flache Funktionen, monolithische Methoden und inkonsistente Typisierung. Das Ergebnis ist Code, der schwer zu verstehen, zu testen und zu erweitern ist:

import { randomUUID } from 'crypto';

async function registerUser(input: any) {
  // 1. Validierung
  if (!input.email.includes('@')) {
    throw new Error('Invalid email');
  }
  if (input.password.length < 8) {
    throw new Error('Password too short');
  }

  // 2. Domain-Logik
  const user = {
    id: randomUUID(),
    name: input.name,
    email: input.email,
    passwordHash: hashPassword(input.password),
    createdAt: new Date()
  };

  // 3. Persistenz
  await db.insert('users', user);

  // 4. Nebenwirkungen (z. B. Mail verschicken)
  await mailer.sendWelcomeEmail(user.email);

  // 5. Antwort für den Controller
  return {
    id: user.id,
    name: user.name
  };
}

Ein wirklich wildes Beispiel hörte ich neulich: Ein Freund, der kein Entwickler ist, sondern sich das Coding nebenbei selbst beibringt, hatte auf ChatGPT gehört und den Code nach und nach mit Copy/Paste in seine Lösung eingefügt. Vibe Coding: Wenn es Compile-Fehler oder Laufzeitfehler gab, einfach die Fehlermeldung mit Copy/Paste wieder nach ChatGPT und herausfinden lassen, was die Fehlerursache und der Fix sein könnten.

Architekturverständnis bei ChatGPT? Nur eine Sitzung lang! ChatGPT empfahl meinem Freund in einer Sitzung ein Backend in PHP, aber in der nächsten Sitzung ein API mit backend-seitigem JavaScript. Mein Freund schrieb alles in gutem Glauben hin – und bekam eine Lösung, die serverseitig beides gemischt enthält, komplizierter als sie hätte sein müssen. Er hat es nicht gemerkt und einfach so gemacht wie ChatGPT es vorschlug.

Die Lösung: Zuerst Vorgaben machen, dann loslegen

Wer langfristig sauberen Code von einer KI erwartet, muss mehr tun, als nur einen Prompt zu formulieren. Es ist notwendig, der KI klare Qualitätsregeln zu vermitteln, ihr das Domain-Wissen zugänglich zu machen und konkrete Beispiele zu liefern, an denen sie sich orientieren kann. Jeder DDD-Baustein, ob Service, Aggregate, Value Object, oder Repository, sollte durchdacht sein. Dafür muss die KI muss Vorgaben erhalten, damit alles korrekt umgesetzt wird. Schritt für Schritt lernt sie so, Code zu erzeugen, der wirklich wartbar und konsistent ist.

Das Problem: LLMs starten jeden Dialog bei Null, als wüssten sie von nichts mehr. Was das LLM zu dem Zeitpunkt weiß, ist nur das, was es vom Hersteller gelernt hat. Beispiel DDD: Das LLM wird DDD in einer Weise praktizieren, wie es der Durchschnitt der Menschheit bisher getan hat, nicht wie es in Ihrem Projekt gemacht wird:

import { randomUUID } from 'crypto';

class Email {
  constructor(private readonly value: string) {
    if (!value.includes('@')) throw new Error('Invalid email');
  }
  toString() { return this.value; }
}

class Password {
  constructor(private readonly value: string) {
    if (value.length < 8) throw new Error('Password too short');
  }
  hash(): string { return hashPassword(this.value); }
}

class User {
  constructor(
    public readonly id: string,
    public readonly name: string,
    public readonly email: Email,
    public readonly password: Password,
    public readonly createdAt: Date
  ) {}
}

interface UserRepository {
  save(user: User): Promise<void>;
}

class UserService {
  constructor(
    private readonly userRepository: UserRepository,
    private readonly mailer: Mailer
  ) {}

  async registerUser(name: string, email: string, password: string): Promise<User> {
    const user = new User(
      randomUUID(),
      name,
      new Email(email),
      new Password(password),
      new Date()
    );

    await this.userRepository.save(user);
    await this.mailer.sendWelcomeEmail(user.email.toString());

    return user;
  }
}

Gängige KI-Agenten-Umgebungen umgehen dieses Problem, indem sie der KI wenigstens eine Art "Gedächtnis" mitgeben. Dies besteht aus Markdown-Dateien, die der Benutzer schreiben kann und die jedesmal am Anfang eines neuen Dialogs eingefügt werden. In diesen Markdown-Dateien lassen sich dann z.B. die Produktanforderungen hinterlegen, die Architektur-Regeln oder spezielle Vorgaben wie beteiligte Technologien und Frameworks zu nutzen sind.

So etwas aufzuschreiben, bringt Sie immerhin einen Schritt weiter. Sie werden merken, dass die KI anfängt, sich Ihrem Projekt anzupassen.

Ein guter Start, der noch nicht reicht

Ich habe auch so angefangen: Vorgaben aufgeschrieben, in mehreren Dateien:

  • architecture.md: Vorgaben für die Architektur und Package-Struktur
  • brief.md: Name, Zweck des Projektes, Key Features, Zielgruppen
  • context.md: Aktueller Fokus, neueste Änderungen, nächste Schritte
  • product.md: Warum es das Produkt gibt, welches Problem es löst, wie es funktionieren soll, und welche UX-Ziele es erfüllen muss
  • tech.md: genutzte Technologien, Setup der Dev-Umgebung, technische Randbedingungen, Abhängigkeiten, Tool-Nutzungs-Patterns

Diese Dateien kann man sogar von der KI selbst erstellen lassen (so lange man sie danach einem Review unterzieht und korrigiert). Kilocode, die agentische KI-Umgebung, die ich einsetze, hat dafür sogar ein Schritt-für-Schritt-Rezept: Setting up the Memory Bank. Sehr wertvoll für den Start.

Architektur und DDD, aber bitte deterministisch!

LLMs arbeiten statistisch, nicht deterministisch. Sie sind Text-Voraussage-Maschinen, die das hinschreiben, was am wahrscheinlichsten klingt. Selbst als ich die Vorgaben in obigen Dateien genau erfasst hatte, war der Code, den der Agent erzeugte, immer noch von recht variabler Qualität.

KI-Agenten können ja aber noch mehr, z.B. Tools aufrufen, die deterministisch arbeiten. Also dachte ich mir: Was, wenn ich all mein DDD-Wissen in einen Model Context Protocol-Server packen würde, der den Code gleich so erzeugt, dass er all die Regeln, die ich so mühsam formuliert hatte, einhält? Das erschien mir attraktiv, weil ich dann die Regeln nicht einmal in agentenfreundliche Prosa umzuschreiben brauchte, sondern einfach als Code-Templates mit Platzhaltern für die konkreten Namen der erzeugten DDD-Elemente hinterlegen konnte.

Das MCP-Server-Projekt war geboren, an dem ich jetzt seit drei Wochen arbeite und Ihnen als Open Source zur Verfügung stellen möchte.

Fazit und nächste Schritte

Vibe Coding-Prompts allein erzeugen keine saubere Architektur. Wer langfristig qualitativ hochwertigen Code möchte, muss die KI trainieren, kontrollieren und iterativ verbessern. Nur so entsteht aus anfänglichem Chaos ein klar strukturiertes, wartbares und sicheres System.

In der nächsten Folge werden wir uns ansehen, welche Kriterien wirklich gute Architektur ausmachen – der erste Schritt, um die KI gezielt zu informieren und echte Domänenmodelle zu erzeugen.


Bitte kommentieren Sie weiter unten: Was möchten Sie in dieser Serie noch gern behandelt haben? Welche Fragen haben Sie? Was haben Sie selbst schon probiert? Was davon hat gut geklappt, und was waren Ihre schlimmen Erlebnisse mit KI-Assistenten?

Ich freue mich auf das, was Sie zu sagen haben. Wenn Sie neue Folgen der Serie automatisch per Email haben wollen, abonnieren Sie sie doch gleich hier!

Alte Folge verpasst? Hier geht es zur ersten Folge mit Inhaltsverzeichnis.