Wie ich KI wirklich anweise, Software zu bauen
- ai-workflow
- prompting
- developer-tools
- field-notes
Der entscheidende Schritt ist nicht, die KI zu bitten, Code zu schreiben. Es ist ein echtes Gespräch mit einem denkenden Modell über die Idee zu führen, es die Spezifikation schreiben zu lassen, und dann diese Spezifikation an einen Coding-Agenten weiterzugeben. Zwei Phasen, zwei völlig unterschiedliche Aufgaben.
Die meisten Entwickler verwenden KI-Coding-Tools auf dieselbe falsche Art. Sie öffnen einen Chat, tippen einen vagen Satz ein und erwarten, dass am anderen Ende funktionierende Software herauskommt. Wenn das nicht klappt, geben sie dem Modell die Schuld. Das Modell ist nicht das Problem. Der Workflow ist es. Ich nutze KI-gestützte Entwicklung schon lange genug in der Produktion, um ein System zu haben, und die Kernerkenntnis ist einfach: Prompting hat zwei unterschiedliche Phasen, und fast niemand trennt sie.
Phase eins ist ein Gespräch mit einem denkenden Modell (Claude Opus 4.8, GPT-5.5) über die Idee. Nicht über Code. Über Constraints, Edge Cases, deinen Stack, deine Konventionen, was dieses Feature tun soll und was nicht. Am Ende dieses Gesprächs bittest du das Modell, eine präzise Build-Spezifikation für einen Coding-Agenten zu schreiben. Phase zwei ist, diese Spec dem Agenten (Claude Code, Cursor) zu übergeben und ihn planen und ausführen zu lassen. Das denkende Modell ist der Architekt. Der Coding-Agent ist der Baumeister.

Warum ein vager Prompt plausiblen Brei erzeugt
Ein Sprachmodell wird immer etwas produzieren. Das ist das Problem. Bitte es, "eine Lesezeichen-Funktion hinzuzufügen", und es wird Code schreiben, selbstbewusst, basierend auf welchen Annahmen es auch immer aus seinen Trainingsdaten auffüllt. Es weiß nicht, dass du auf Next.js 15 App Router bist, dass du Prisma mit MySQL verwendest, dass deine Auth NextAuth v5 ist, dass du auf Hetzner über Ploi deployst, oder dass du Class-Komponenten vor sechs Monaten verbannt hast. Es trifft vernünftige Annahmen und produziert plausiblen Brei: syntaktisch korrekten Code, der nicht zu deinem Projekt passt.
Signaldichte ist die Variable. Jeder Constraint, den du weglässt, ist eine Entscheidung, die das Modell ohne dein Wissen für dich trifft. Die einzige Lösung ist, den relevanten Kontext zu kodieren, bevor Code geschrieben wird, und der zuverlässigste Weg dafür ist ein strukturiertes Gespräch gefolgt von einer schriftlichen Spec.
Phase eins: Gespräch mit dem denkenden Modell
Ich öffne Claude oder ChatGPT und beschreibe die Idee in einfacher Sprache. Kein Prompt. Eine Beschreibung. Was ich bauen will, warum, wer es nutzt, welche Constraints bestehen. Ich bitte das Modell, mir Fragen zurückzustellen: Was könnte schiefgehen? Welche Edge Cases übersehe ich? Was soll dieses Feature explizit nicht tun? Dieses Gespräch bringt Annahmen ans Licht, von denen ich nicht wusste, dass ich sie mache.
Dann gebe ich dem Modell einen Meta-Prompt: eine strukturierte Anweisung, die es anweist, eine Build-Spezifikation für einen Coding-Agenten zu erstellen, wobei mein gesamter Stack und meine Konventionen kodiert werden. Hier ist der Meta-Prompt, den ich verwende:
You are a senior software architect and technical writer.
I need you to turn the following idea into a precise build specification
for an AI coding agent (Claude Code / Cursor).
MY STACK:
- Next.js 15 (App Router, TypeScript, Tailwind CSS 4)
- Database: MySQL via Prisma 6. Schema in prisma/schema.prisma.
- Auth: NextAuth v5 with JWT strategy. Session helpers in src/lib/auth.ts.
- Deploy: Hetzner VPS managed by Ploi, Cloudflare CDN in front.
- No class components. No pages/ directory. No getServerSideProps.
IDEA:
[describe your feature here in plain language]
CONSTRAINTS:
- [any non-obvious edge cases, business rules, or perf requirements]
PRODUCE:
1. A one-paragraph summary of what will be built and why.
2. A list of every file that will be created or modified, with a one-line
description of the change.
3. Numbered acceptance criteria the agent can verify by running
'npx tsc --noEmit' and 'npm test'.
4. Any migration steps needed (Prisma schema changes, seed data, env vars).
5. Explicit out-of-scope items so the agent does not overshoot.
Output the spec in markdown. Do NOT write any code yet.Der entscheidende Constraint in diesem Meta-Prompt ist "Do NOT write any code yet." Du willst, dass das denkende Modell Architekturarbeit macht, keine Implementierung. Wenn es anfängt, Code zu schreiben, ist es in den falschen Modus gewechselt. Halte es bei der Spec.
Phase zwei: die Agenten-Spec
Was aus dem denkenden Modell herauskommt, ist ein Markdown-Dokument, auf das der Coding-Agent tatsächlich reagieren kann. Es nennt jede Datei, die sich ändern wird, listet überprüfbare Akzeptanzkriterien auf und nennt, was außerhalb des Umfangs liegt. Der Agent muss nicht mehr raten. So sieht eine echte Spec für eine Lesezeichen-Funktion aus:
# Build Spec: Bookmark Feature
## Summary
Add a per-user bookmark system so authenticated users can save posts.
Bookmarks are stored in MySQL, surfaced in a new /bookmarks page,
and toggled from individual post pages via a server action.
## Files
- prisma/schema.prisma add Bookmark model (userId, postSlug, createdAt)
- prisma/migrations/... generated migration, run before deploy
- src/app/bookmarks/page.tsx new page, server component, lists user bookmarks
- src/app/actions/bookmarks.ts server actions: toggleBookmark, getUserBookmarks
- src/components/BookmarkButton.tsx client component, optimistic UI
- src/app/blog/[slug]/page.tsx import and render BookmarkButton
## Acceptance Criteria
1. 'npx prisma migrate dev' runs without error on a clean dev database.
2. 'npx tsc --noEmit' passes with zero errors.
3. 'npm test' passes: unit tests for toggleBookmark cover unauthenticated
call (must throw), duplicate toggle (idempotent remove), and success path.
4. Visiting /bookmarks as an unauthenticated user redirects to /login.
5. Clicking BookmarkButton on a post toggles the filled/outline icon
without a full page reload (optimistic update via useOptimistic).
## Out of Scope
- Bookmark folders or tags.
- Public bookmark lists.
- Any change to the existing post rendering pipeline.Beachte, dass die Akzeptanzkriterien maschinell überprüfbar sind. Der Agent kann npx tsc --noEmit und npm test ausführen und ein Pass oder Fail erhalten. Er muss keine Ermessensentscheidungen darüber treffen, ob das Feature fertig ist. Die Spec definiert fertig.
- Jede aufgelistete Datei gibt dem Agenten eine Scope-Grenze. Er weiß, was er anfassen soll und was er in Ruhe lassen soll.
- Der Out-of-Scope-Abschnitt ist genauso wichtig wie der In-Scope-Abschnitt. Er verhindert, dass der Agent ungefragt Features hinzufügt.
- Der Migrationsschritt ist explizit. Der Agent wird keine Datenbankänderungen erraten.
- Akzeptanzkriterien, die auf echte Befehle verweisen, geben dem Agenten eine Selbstverifikations-Schleife.
Markdown-Gedächtnis: die AGENTS.md-Datei
Hier ist eine Tatsache über KI-Coding-Agenten, die die meisten Menschen auf die harte Tour lernen: Sie haben kein Gedächtnis zwischen den Sitzungen. Der Agent, der letzte Woche dein Auth-Middleware gebaut hat, weiß heute nicht, dass es existiert. Ohne persistenten Kontext wird er ein anderes Muster erfinden, deine Namenskonventionen verletzen oder eine Bibliothek importieren, die du verbannt hast.
Die Lösung ist eine AGENTS.md-Datei im Projektstamm. Das ist keine Dokumentation für Menschen. Es ist Arbeitsgedächtnis für den Agenten, das zu Beginn jeder Sitzung geladen wird. Es kodiert deinen Stack, deine Konventionen, die auszuführenden Befehle und die zu vermeidenden Muster. Da es im Repository lebt und versionskontrolliert ist, bleibt es aktuell, während das Projekt sich weiterentwickelt.

Hier ist ein minimales AGENTS.md für meinen typischen Next.js-Stack:
# AGENTS.md - Stack and Conventions
## Stack
- Next.js 15, App Router only. No pages/ directory.
- TypeScript strict mode. No 'any'. Use 'unknown' and narrow.
- Tailwind CSS 4 for styling. No inline style props.
- Prisma 6 with MySQL. Schema: prisma/schema.prisma.
- NextAuth v5 - session helpers in src/lib/auth.ts. Do not re-implement auth.
- Deploy: Ploi on Hetzner, Cloudflare in front.
## Conventions
- Server components by default. Add 'use client' only when necessary.
- Server actions in src/app/actions/. One file per domain (bookmarks.ts, etc.).
- Shared UI in src/components/. Page-specific UI co-located with the page.
- Tests in __tests__/ next to the file under test.
## Commands
npm run dev start dev server
npm run build production build
npm test run vitest
npx tsc --noEmit type-check only
## Do NOT
- Use getServerSideProps, getStaticProps, or pages/api routes.
- Import server-only modules in client components.
- Use process.env directly in components - use src/lib/config.ts.Sobald diese Datei existiert, tippst du deinen Stack nie mehr dem Agenten neu ein. Der Meta-Prompt, den ich zur Generierung von Specs verwende, verweist direkt darauf: Wenn ich meinen Stack im Gespräch mit dem denkenden Modell beschreibe, aktualisiere ich gleichzeitig die AGENTS.md. Die beiden Dokumente bleiben synchron. Das denkende Modell nutzt den Stack, um eine korrekte Spec zu schreiben. Der Coding-Agent liest AGENTS.md, um sie korrekt auszuführen.
Das Ergebnis in einem separaten Durchgang verifizieren
Nachdem der Agent die Implementierung geliefert hat, bitte nicht dieselbe Sitzung, sie zu verifizieren. Der Kontext ist befangen: Er hat ein Modell davon, was er schreiben wollte, und dieses Modell lässt ihn übersehen, was er tatsächlich geschrieben hat. Starte eine neue Sitzung, lade AGENTS.md, lade den Diff, und gib dem Agenten einen Verifikations-Prompt: überprüfe die Änderungen gegen AGENTS.md, melde Verstöße, fehlende Tests, Typfehler und Logikfehler, schlage keine Verbesserungen vor.
Der frische Kontext liest, was tatsächlich da ist. Er hat keine Bindung an die Absicht der vorherigen Sitzung. Kombiniert mit den maschinell überprüfbaren Akzeptanzkriterien aus der Spec fängt dieser Zwei-Phasen-Ansatz die meisten Probleme ab, bevor sie das Review erreichen.
Die vollständige Schleife
Alles zusammenfügen: Du führst ein Gespräch mit einem denkenden Modell über die Idee, produzierst eine Build-Spec mit dem Meta-Prompt, übergibst die Spec dem Coding-Agenten zusammen mit AGENTS.md, der Agent baut und verifiziert sich selbst gegen die Akzeptanzkriterien, dann führst du in einer frischen Sitzung einen separaten Verifikationsdurchgang durch. Fünf Schritte, jeder mit einem klaren Input und Output.
Das ist langsamer als eine Zeile in ein Chat-Fenster zu tippen. Es ist schneller als Code zu debuggen, den der Agent gegen falsche Annahmen geschrieben hat, gegen Typfehler zu kämpfen, die die Spec gefangen hätte, und deinem Team zu erklären, warum die Lesezeichen-Funktion State in einem Context-Provider speichert statt in einer Server Action.
- 01Gespräch mit dem denkenden Modell: beschreibe die Idee, bringe Constraints und Edge Cases ans Licht.
- 02Meta-Prompt: bitte das denkende Modell, eine Build-Spec für den Coding-Agenten zu erstellen.
- 03Spec-Review: iteriere über die Spec, bis die Akzeptanzkriterien maschinell überprüfbar sind.
- 04Agenten-Ausführung: übergib die Spec und AGENTS.md dem Coding-Agenten.
- 05Separater Verifikationsdurchgang: frische Sitzung, AGENTS.md, Diff, Verifikations-Prompt.
Das denkende Modell macht Architekturarbeit. Der Coding-Agent macht Implementierungsarbeit. Du machst Urteilsarbeit: entscheiden, wann die Spec gut ist, wann die Implementierung akzeptabel ist, wann man iterieren soll und wann man ausliefert. Diese Arbeitsteilung ist es, was dieses System zuverlässig macht.