← Alle Lessons
|Prompts, die halten – Coding-Agents richtig briefen
1/9
Prompts, die halten – Coding-Agents richtig briefen
Schritt 1 von 9
Funktioniert ist nicht genug
Warum dein Agent Demos liefert, die glänzen, und Software, die bricht.
Die Situation. Du gibst dem Agenten eine Aufgabe. Er liefert in Minuten etwas, das läuft. Die Demo glänzt. Dann kommt der erste echte Nutzer: ein Name mit Umlaut, eine leere Liste, eine Buchung um 23:59 am Monatsletzten. Und es bricht.
Das ist der Unterschied zwischen Software, die funktioniert, und Software, die hält. Funktionieren heißt: Der Happy Path läuft. Halten heißt: Auch die Ränder sind abgedeckt, die Sicherheitslücken geschlossen, und es gibt einen Beweis dafür.
💡
Diese Lesson baut auf Was Software eigentlich ist und Die Entscheidungen, die dir der Agent überlässt auf. Dort lernst du, WAS du entscheiden musst. Hier lernst du, WIE du es dem Agenten sagst.
Es liegt nicht am Modell. Es liegt am Briefing.
Der Agent ist kein schlechter Handwerker. Er ist ein übermotivierter Geselle, der genau das baut, was du sagst, und alles andere rät. Wenn du nur den Happy Path beschreibst, bekommst du nur den Happy Path. Die Forschung dazu ist deutlich: AI-generierter Code ist funktional gut und sicherheitstechnisch systematisch schwach. Fast die Hälfte fällt durch Standard-Sicherheitstests. Nicht weil das Modell es nicht könnte, sondern weil niemand es verlangt hat.
Die Landkarte: Acht Disziplinen, ein Muster
Beim Bauen mit Coding-Agents gibt es acht wiederkehrende Disziplinen. Jede hat ihr eigenes Prompt-Muster, aber alle folgen derselben Grundstruktur:
Symptom + Evidenz → Hypothesen → Diagnose → erst dann Fix
Deployen und betreiben
DevOps
Plan vor Ausführung → Safety-Grenzen → echte Output-Beweise
Skripte und persönliche Tools
Automation
Task + Sample-Daten → Dry-Run → am Sample verifizieren
Du musst nicht acht Muster auswendig lernen. Du lernst in dieser Lesson eine Anatomie und zwei Prinzipien, die hinter allen acht stecken. Danach gehst du echte Beispiel-Prompts Zeile für Zeile durch, entlang des Ablaufs Planen → Bauen → Absichern, jeweils aus zwei Blickwinkeln. Und am Ende weißt du, was du tust, wenn der Output trotzdem nicht hält.
🇬🇧
Die Beispiel-Prompts in dieser Lesson sind auf Englisch. Coding-Tools performen damit messbar besser. Die Erklärungen bleiben Deutsch, und die Struktur funktioniert in beiden Sprachen.
Takeaway
Faustregel #1: Der Agent baut genau das, was du verlangst, und rät den Rest. "Funktioniert" ist der Default. "Hält" musst du explizit bestellen.
Schritt 2 von 9
Die Prompt-Anatomie
Context, Requirements, Edge Cases, Guardrails, Verify. Wer das einmal verinnerlicht, kann jeden Prompt selbst konstruieren.
Die Situation. Du willst eine Budget-Funktion für deine App. Der schnelle Weg: "Bau mir eine Budget-Funktion." Der Agent liefert. Irgendwas. Vermutlich mit Gleitkommazahlen für Geldbeträge und ohne Gedanken an den Monatswechsel.
Die fünf Bausteine
Jeder gute Coding-Prompt, egal für welche Disziplin, variiert dasselbe Grundmuster:
Baustein
Funktion
Beispiel
Context
Wer, was, warum. Das Szenario.
"Klar, a finance app for German users..."
Requirements
Was konkret entstehen soll, testbar formuliert
Nummerierte, prüfbare Anforderungen
Edge Cases
Die kaputten Ränder, vorab benannt
Umlaute, Monatsgrenzen, leere Zustände
Guardrails
Negativ-Grenzen. Der wertvollste Block.
"Money is never a float", "Never log credentials"
Verify
Der ausführbare Beweis
"Run the tests and show the output"
Vorher / Nachher
So sieht der Unterschied in der Praxis aus. Gleiche Aufgabe, zwei Briefings:
Vorher
Build a budget feature for my finance app. Users should be able to set monthly budgets per category and see how much they've spent.
Nachher
Build the monthly budget feature for Klar, a personal finance app for German users.
CONTEXT:
Users set one budget per category per month (categories: Essen, Transport, Shopping, Abo, Sonstiges). The dashboard shows spent vs. budget with status: ok (<80%), warning (80-100%), over (>100%).
REQUIREMENTS:
1. Create, update, delete a budget for a category and month
2. Status calculation counts only transactions within the budget's month
3. Dashboard returns spent, remaining, percentUsed, status per category
EDGE CASES:
- Transactions at 23:59 on the last day of the month count for THAT month (users are in Europe/Berlin, server runs UTC - handle the timezone)
- A refund (negative transaction) reduces spent
- Exactly 80% is "warning", exactly 100% is still "warning", not "over"
- A category with no budget set shows no status, not 0%
GUARDRAILS:
- Money is integer cents, never float
- Two budgets for the same category and month must be impossible (enforce in the schema)
- Do not build budget sharing or multi-currency - out of scope for v1
VERIFY:
Write unit tests for the status calculation including the boundary cases above. Run them and show the output.
Der zweite Prompt ist länger, klar. Aber er ist kein Roman, er ist eine Stückliste. Jede Zeile verhindert einen konkreten Fehler, den der Agent sonst macht: Float-Geldbeträge, Zeitzonenfehler am Monatsende, spekulative Features, und ein "fertig" ohne Beweis.
⚠️
Häufiger Fehler: Länge mit Qualität verwechseln. Es geht nicht darum, viel zu schreiben. Es geht darum, die fünf Bausteine zu besetzen. Ein Prompt mit drei präzisen Edge Cases schlägt einen mit zehn Absätzen Prosa.
Übung
Aufgabe: Nimm deinen letzten Prompt an einen Coding-Agent (oder schreib den, den du als Nächstes brauchst). Prüfe ihn gegen die fünf Bausteine:
Welche Bausteine sind besetzt?
Welcher fehlt komplett? (Bei den meisten: Edge Cases und Verify)
Ergänze die fehlenden mit je 2-3 Zeilen
Zeitaufwand: ~5 Minuten. Der Frag-KI-Assistent kann deinen Prompt mit dir durchgehen.
Takeaway
Faustregel #2: Fünf Bausteine: Context, Requirements, Edge Cases, Guardrails, Verify. Fehlt einer, hat der Agent freie Hand, und freie Hand heißt raten.
Schritt 3 von 9
Die zwei Prinzipien
Was der Agent NICHT tun soll, ist der eigentliche Hebel. Und ohne Beweis ist nichts fertig.
Die Situation. Du hast einen ordentlichen Prompt geschrieben. Der Agent liefert trotzdem ein Auth-System, das du nie bestellt hast, und meldet "fertig", obwohl der Build rot ist. Beides hat dieselbe Ursache: Zwei Prinzipien fehlen.
Prinzip 1: Constraints schlagen Instruktionen
Ein Agent kann nicht aus Auslassung schließen. Was du nicht verbietest, baut er, wenn es ihm plausibel erscheint. Deshalb ist der Guardrails-Block der wertvollste Teil jedes Prompts: Er kodiert die Fehler, die Agents von selbst machen.
Non-Goals positiv formulieren: Nicht weglassen, sondern hinschreiben. "Do not implement authentication in this phase" muss dastehen, sonst baut der Agent es spekulativ ein.
Sicherheits-Grenzen explizit machen: "Parameterized queries only", "Never log credentials", "Money is integer cents". Das sind keine Selbstverständlichkeiten, das sind die dokumentierten Lücken in AI-Code.
Bei Reviews umgekehrt: Die Negativliste sagt, was der Agent NICHT melden soll ("Do not flag style issues"). Ohne sie produziert er spekulative Warnungen, die du zu ignorieren lernst.
Guardrails-Beispiele aus der Praxis
GUARDRAILS:
- Money is integer cents (bigint), never float
- Every foreign key has an explicit ON DELETE behavior - no defaults by omission
- Error responses never leak internals: no stack traces, no SQL, no file paths
- Do not build multi-currency support - phrase as positive instruction, never by omission
DO NOT FLAG (für Review-Prompts):
- Style and formatting (the linter owns that)
- Issues in unchanged code this diff does not touch
- Theoretical risks requiring unlikely preconditions
Prinzip 2: Verifikation schließt die Schleife
Ohne ausführbaren Check ist "sieht fertig aus" das einzige Stopp-Signal des Agenten. Und "sieht fertig aus" ist genau der Zustand, in dem die Demo glänzt und die Ränder brechen. Jeder Prompt endet deshalb mit einem Beweis, den der Agent selbst erbringen kann:
Code: "Run the tests and show the output."
DevOps: "Paste the actual command outputs." Ein Agent, der die echte Ausgabe zeigt, hat den Befehl ausgeführt.
Skripte: "Run the dry-run first, show me the plan. I approve, then you execute."
Daten: "Print the parsed interpretation of the sample row first. If the parse is wrong here, everything after is garbage."
✅
Merksatz: "Should work now" ohne Output zählt nicht als erledigt. Verlange den Beweis im Prompt, nicht erst im Nachhinein.
Übung
Aufgabe: Formuliere für diese drei Aufgaben jeweils einen Guardrail und einen Verify-Schritt:
Ein Skript, das 2.000 Dateien umbenennt
Ein Login-Formular
Ein Code-Review vor dem Merge
Vergleiche danach mit dem Frag-KI-Assistenten. Er kennt die Muster aus allen acht Disziplinen.
Takeaway
Faustregel #3: Constraints schlagen Instruktionen, und Verifikation schließt die Schleife. Was du nicht verbietest, wird geraten. Was du nicht prüfen lässt, ist nicht fertig.
Schritt 4 von 9
Planen am Beispiel
Der größte Hebel liegt vor dem Code: erst das PRD, dann das Fundament, auf dem der Agent arbeitet.
Die Situation. Du hast eine halbgare Produktidee und willst, dass ein Agent sie baut. Der Reflex: direkt bauen lassen. Der bessere Weg: erst ein PRD (Product Requirements Document) erzeugen, gegen das der Agent bauen kann. Hier ist der Prompt dafür, komplett. Danach nehmen wir ihn auseinander.
Prompt: PRD aus vager Idee
I have a rough product idea. Help me turn it into a PRD that an AI coding agent can build against.
THE IDEA:
"Klar" - a personal finance app for young professionals in Germany. They check their spending several times a day but hate spreadsheets and banking apps. The app should answer one question fast: "How much did I spend today, and am I on track this month?"
PROCESS:
Before writing anything, ask me 5-8 clarifying questions about scope, users, and constraints. Wait for my answers. Only then produce the PRD.
OUTPUT FORMAT (Markdown):
1. Product Overview - one paragraph, one goal
2. Target Users & Use Cases
3. Features & Requirements - each with testable acceptance criteria
4. Technical Constraints - platform, stack, compliance (GDPR - German users)
5. Non-functional Requirements
6. Out of Scope / Non-Goals - explicitly state what we will NOT build in v1
CONSTRAINTS:
- Every requirement must be specific enough to test. Not "the UI should feel fast" but "dashboard renders cached data in under 200ms".
- Phrase every non-goal as a positive instruction ("Do not implement multi-currency support"), never by omission.
- Keep the full PRD under 150 requirements. If it grows beyond that, split into dependency-ordered phases instead.
Die Sektion, die alles entscheidet: PROCESS
"Ask me 5-8 clarifying questions first. Wait for my answers." Diese zwei Zeilen sind der Unterschied zwischen einem Dokument über deine Idee und einem Dokument über die Idee, die das Modell rät. Ohne sie füllt der Agent jede Lücke mit der wahrscheinlichsten Annahme, und du merkst es erst, wenn das Falsche gebaut ist.
Warum die Constraints so aussehen
"Specific enough to test": "Soll sich schnell anfühlen" kann ein Agent nicht bauen und nicht prüfen. "Unter 200ms" kann er beides. Vage Kriterien sind der häufigste Grund, warum PRDs nichts taugen.
"Non-goals as positive instruction": Das Prinzip aus dem letzten Step, hier im Einsatz. Was nicht verboten ist, wird spekulativ gebaut.
"Under 150 requirements": Es gibt eine praktische Obergrenze, wie viele Instruktionen ein Modell zuverlässig befolgt (das Instruction-Ceiling, etwa 150-200). Eine Mega-Spec mit 300 Requirements wird schlechter befolgt als 5 Phasen mit je 50.
💡
Der Workflow dahinter: Idee → PRD → technische Spec → Spec-Review → Zerlegung in Tasks → Implementierung. Jeder Schritt füttert den nächsten, und die Artefakte gehören als Dateien ins Repo (z.B. docs/specs/), nicht in den Chat-Verlauf. Dann kann jede neue Session darauf aufsetzen.
⚠️
Häufiger Fehler: Den Rückfragen-Block streichen, weil er nach Umweg aussieht. Die fünf Minuten Fragen-Beantworten sparen dir die zwei Stunden, in denen der Agent das falsche Produkt baut.
Der zweite Blickwinkel: das Projekt aufsetzen
Das PRD sagt, WAS gebaut wird. Genauso planbar ist, WIE GUT der Agent dabei arbeitet. Ein Agent in einem vorbereiteten Projekt liefert messbar besser als derselbe Agent auf der grünen Wiese. Das Fundament besteht aus drei Dingen: einer Projektkontext-Datei, aktuellem Wissen und einem Arbeitsmodus.
1. Die Projektkontext-Datei (CLAUDE.md / AGENTS.md)
Die wichtigste Einzeldatei für Agent-Qualität: Befehle, Konventionen, Grenzen. Einmal gut angelegt, spart sie in jeder Session die immergleichen Erklärungen, und sie verhindert, dass der Agent Konventionen erfindet.
Prompt: CLAUDE.md erstellen (gekürzt)
Analyze this codebase and generate a CLAUDE.md (agent context file) for it.
PROCESS:
Explore the repository first: package.json, folder structure, test setup, CI config. Base every statement on what you find - do not invent conventions the codebase does not have.
OUTPUT FORMAT - exactly these sections:
1. Commands - full executable commands: dev server, test (single test too), lint, build
2. Project Structure - directory map with one-line purposes, only directories that matter
3. Code Style - show ONE real code snippet from the repo as the canonical example instead of describing style in prose
4. Boundaries - three tiers:
ALWAYS allowed (run tests, edit src/)
ASK FIRST (schema migrations, adding dependencies, touching CI)
NEVER (edit node_modules/, commit secrets, force-push)
CONSTRAINTS:
- Every sentence must constrain behavior. If a line can be removed without changing how an agent acts, remove it.
- Target length: under 60 lines. This file is loaded into every session - it costs context every time.
- Commands must be copy-paste runnable. No placeholders.
2. Aktuelles Wissen bereitstellen
Das Trainingswissen des Modells ist Monate alt, deine Libraries sind es nicht. Vor jedem Feature mit neuen Tools gilt: erst recherchieren lassen, dann bauen. Aktuelle Doku fetchen, verfügbare Skills und CLIs prüfen, Versionsstände klären, und die Ergebnisse als Dateien ins Projekt legen, damit jede Session darauf zugreift. Ein Satz im Prompt reicht oft: "Before implementing, fetch the current docs for [library] and check which major version this project uses - do not rely on training knowledge."
3. Den Arbeitsmodus festlegen
Meilensteine statt Monolith: Pläne mit testbaren Zwischenschritten. Nach jedem Meilenstein ein prüfbarer Zustand, statt eines Riesenwurfs, der am Ende ganz oder gar nicht funktioniert.
Feature-Branch als Sicherheitsnetz: Nicht-triviale Vorhaben auf einen eigenen Branch. Wenn der Agent in die falsche Richtung läuft, ist der Rückweg ein Befehl, kein Abend.
Artefakte ins Repo: PRD, Spec und Plan als Dateien (z.B. docs/), nicht im Chat-Verlauf. Der Chat vergisst, das Dateisystem nicht.
✅
Faustprobe für dein Setup: Starte eine frische Agent-Session und gib nur eine kleine Aufgabe. Muss der Agent dich nach Befehlen, Konventionen oder dem Stack fragen? Dann fehlt es in der CLAUDE.md.
Übung
Aufgabe: Beide Blickwinkel einmal selbst durchspielen:
PRD: Nimm eine eigene Tool- oder App-Idee und schicke den PRD-Prompt an einen Agenten. Tausche nur den THE-IDEA-Block aus, beantworte die Rückfragen ehrlich, und prüfe: Sind die Akzeptanzkriterien testbar? Stehen die Non-Goals explizit drin?
Setup: Lass den CLAUDE.md-Prompt über ein bestehendes Projekt von dir laufen. Streiche danach jede Zeile, die das Agent-Verhalten nicht ändert.
Zeitaufwand: ~20 Minuten
Takeaway
Faustregel #4: Erst Rückfragen erzwingen, dann liefern lassen. Und bevor das erste Feature entsteht: CLAUDE.md anlegen und aktuelles Wissen bereitstellen. Der Agent ist nur so gut wie sein Projektkontext.
Schritt 5 von 9
Bauen am Beispiel
Struktur beschreiben statt hoffen. Erst die Oberfläche, dann das Backend, wo die Guardrails schwerer werden.
Die Situation. Du willst ein Dashboard. "Design a finance dashboard" liefert dir das generische Mittelmaß aus einer Million Trainingsbeispielen. Die Alternative: Du beschreibst Kontext, Richtung, Struktur, Verhalten und Grenzen. Hier der Kern eines echten UI-Prompts:
Prompt: Dashboard (gekürzt)
Design the main dashboard screen for a personal finance app called "Klar". Mobile only (iPhone viewport).
CONTEXT:
Users are young professionals (25-35) in Germany who check spending 3-5 times daily during commute. Primary question: "How much did I spend today and am I on track this month?"
VISUAL DIRECTION:
Typographic-driven, minimal chrome. Light mode. Off-white background. Cards: white with 1px border, no shadows. Accent: deep teal for positive, warm red for overspending.
STRUCTURE (top to bottom):
1. Greeting row with avatar and date
2. Primary metric card: today's spending as large bold number, delta vs. daily budget as colored pill, progress ring for monthly budget
3. Category chips, horizontally scrollable - tapping filters the list
4. Recent transactions: last 5 items, "Alle anzeigen" link
5. Bottom tab navigation: 4 items
BEHAVIOR:
- Skeleton loaders for async data, no spinners
- Transaction amounts: German format (1.234,56 €)
GUARDRAILS:
- Safe area insets respected
- No horizontal scrolling on main content, only on the chips
- Budget progress never shows exact cents, round to nearest euro
Was hier passiert
Context liefert Design-Entscheidungen frei Haus: "3-5 mal täglich beim Pendeln" heißt: eine Zahl dominiert, kein Daten-Dschungel. Der Agent kann daraus ableiten, was groß sein muss.
Structure ist nummeriert und konkret: Nicht "zeige die wichtigsten Infos", sondern fünf benannte Zonen in Reihenfolge. Das ist der Unterschied zwischen Layout und Lotterie.
Behavior deckt die unsichtbaren Zustände ab: Was passiert beim Laden? Welches Zahlenformat? Das vergisst jeder erste Prompt, und es fällt erst beim echten Nutzer auf.
Bevor wir die Seite wechseln, der stärkste Einzel-Effekt im UI-Prompting: ein Basis-Prompt, vier Stil-Absätze, vier komplett verschiedene Ergebnisse. Der Basis-Prompt bleibt immer gleich:
Basis-Prompt
Design a user profile card showing: avatar (64px circle), full name, job title, company, location, 3 stat counters (Projects, Reviews, Team Size), and a "Message" button.
Variante: Glassmorphism
STYLE: Glassmorphism on gradient background (deep purple to dark blue). Card: semi-transparent white (10% opacity), 16px backdrop blur, 1px white border at 20% opacity. Text: white. Stats: frosted pill badges. Must pass WCAG AA contrast check.
Variante: Brutalist
STYLE: Brutalist / Anti-design. Thick 3px solid black border, zero border-radius, zero shadows. Raw white background. Monospace font only. All caps for name and stat labels. Hover: instant color invert, no transition. No icons anywhere - text only.
Gleiche Inhalte, gleiche Struktur, radikal anderes Ergebnis. Die Lehre daraus: Inhalt und Stil sind getrennte Bausteine. Wer das einmal gesehen hat, schreibt nie wieder "mach es modern und clean" und hofft.
Seitenwechsel: dasselbe Muster im Backend
So weit die Oberfläche. Jetzt das Backend dahinter, denn die Budget-Karte aus dem Dashboard braucht eine API, die ihre Daten liefert. Es gilt dieselbe Anatomie, aber die Gewichte verschieben sich: Visual Direction entfällt, dafür werden Edge Cases und Guardrails zum Kern. Der Grund ist messbar: AI-generierter Code ist funktional gut und sicherheitstechnisch systematisch schwach.
Prompt: Budget-API (gekürzt)
Implement the budgets API for Klar against this contract:
[PASTE API CONTRACT - endpoints, schemas, error envelope]
REQUIREMENTS:
- Validate ALL input at the boundary before any logic runs: types, ranges, enum values. Invalid input → 422 with the contract's error envelope, naming the offending field.
- Authorization on every endpoint: a valid login is not enough - verify the caller OWNS the budget they are reading or changing.
- List endpoints paginated exactly as the contract defines, no extra undocumented parameters.
EDGE CASES:
- Updating a budget that was deleted between read and write → 404, not 500
- Amount of 0, negative amounts, amounts above 100,000,000 cents → rejected cleanly
- Two clients changing the same budget simultaneously → last-write-wins is acceptable for v1, state it in a code comment
GUARDRAILS:
- Parameterized queries only - never string-concatenated SQL, also not for "just this one dynamic sort" (use an allowlist for sortable columns).
- Never log request bodies or tokens. Error responses never leak internals: no stack traces, no SQL, no file paths.
- At the end, list every endpoint you implemented: path, auth check applied, validation applied. This list is the review artifact.
Validierung vor Logik: Jede Eingabe wird an der Grenze geprüft, bevor irgendetwas damit passiert. Der Agent baut sonst den Happy Path und validiert nebenbei.
Der IDOR-Check: "Eingeloggt" heißt nicht "berechtigt". Ohne die Ownership-Zeile baut der Agent eine API, bei der Nutzer A das Budget von Nutzer B per ID abrufen kann. Das ist der dokumentierte Standardfehler in AI-Code.
Das Review-Artefakt: Die Endpoint-Liste am Ende macht in Sekunden sichtbar, wo der Agent einen Schutz ausgelassen hat. Beweise einfordern statt Prosa glauben.
⚠️
Faustformel für die Gewichtung: Im Frontend kostet ein vergessener Edge Case einen hässlichen Zustand. Im Backend kostet er Daten. Deshalb: Je näher am Datenbestand, desto schwerer der Guardrails-Block.
Übung
Aufgabe: Beide Seiten einmal selbst bauen:
Frontend: Nimm den Basis-Prompt mit der Profil-Karte und teste ihn in einem UI-Tool deiner Wahl (v0, Stitch, Bolt, Lovable oder direkt im Chat als HTML). Einmal ohne Stil-Absatz, einmal mit Glassmorphism oder Brutalist, einmal mit einer eigenen Stil-Variante (z.B. dein Firmen-Look).
Backend: Beschreibe einen Endpoint aus deinem Projekt nach dem API-Muster oben. Pflichtteile: ein Edge Case, der IDOR-Check und das Review-Artefakt am Ende.
Zeitaufwand: ~15 Minuten
Takeaway
Faustregel #5: Frontend: Struktur als nummerierte Zonen, Stil als eigener Absatz. Backend: Validierung, Ownership und Guardrails sind der Kern. Je näher am Datenbestand, desto schwerer der Guardrails-Block.
Schritt 6 von 9
Absichern am Beispiel
Tests gegen die Spec, Security-Review mit Negativliste. Zwei Prompts, die entscheiden, ob es hält.
Die Situation. Der Agent hat die Budget-Funktion aus Step 2 gebaut. Jetzt willst du Tests. Der Reflex: "Schreib Tests für diesen Code." Genau das ist der Fehler. Der Agent liest den Code und schreibt Tests, die bestätigen, was der Code tut. Wenn der Code einen Bug hat, zementiert der Test den Bug als Feature.
Das eiserne Prinzip: Spec in den Prompt, nie den Code
Tests werden gegen die Spezifikation formuliert. Die Beispiel-Cases mit konkreten Zahlen sind der Anker: Sie verankern, was "richtig" bedeutet, unabhängig davon, was die Implementierung gerade tut.
Prompt: Unit-Tests gegen die Spec
Write unit tests for Klar's budget status function.
SPEC (test against THIS, not against the implementation):
calculateBudgetStatus(budget, transactions, today) returns { spent, remaining, percentUsed, status } where status is "ok" (<80%), "warning" (80-100%), "over" (>100%). Only transactions within the budget's month count. Amounts are integer cents.
EXAMPLE CASES (use these, then extend):
- budget 50000, transactions [12050, 8999] → spent 21049, status "ok"
- spent exactly 40000 → percentUsed 80, status "warning" (boundary belongs to warning)
- spent 50000 exactly → "warning", not "over" (100% is still warning)
- transaction on the 1st at 00:00 and on the last day at 23:59 → both count
- transaction from the previous month → does not count
EXTEND WITH edge cases the spec implies: empty transaction list, budget of 0, negative transaction (refund), month boundary across timezones.
GUARDRAILS:
- Test BEHAVIOR: assert on returned values. Never assert that internal helpers were called.
- Avoid mocks entirely - this is pure logic, it needs none.
- Each test: one behavior, named as a sentence ("counts refunds as negative spend").
VERIFY: run the tests. If any fail against the current implementation, report the failures - do NOT adjust the tests to make them pass. A failing test here means the code violates the spec.
Warum die Zeilen so dastehen
"test against THIS, not against the implementation": Das Gegenmittel gegen Implementation-Mirroring, eine der drei dokumentierten Schwächen AI-generierter Tests. Die anderen zwei: Over-Mocking und schwache Assertions. Alle drei werden hier adressiert.
Die Beispiel-Cases mit echten Zahlen: "spent exactly 40000 → warning" legt fest, wohin die Grenze gehört. Ohne sie entscheidet der Zufall, ob 80% ok oder warning ist, und der Test besiegelt die Zufallsentscheidung.
"Avoid mocks entirely": Zwei Wörter, messbare Wirkung. Pure Logik braucht keine Mocks, und gemockte Tests prüfen am Ende nur die Mocks.
Das Verify mit Eskalation: Schlägt ein Test fehl, wird gemeldet statt angepasst. Ein fehlschlagender Test gegen die Spec heißt: Der Code ist falsch, nicht der Test.
✅
Die Steigerung: Tests zuerst (TDD). Tests vor der Implementierung schreiben lassen, fehlschlagen sehen (Red), die Tests committen, dann implementieren lassen, ohne dass der Agent Testdateien anfasst. Der Zwischen-Commit wirkt pedantisch, macht aber jede Test-Manipulation im Diff sichtbar.
Die zweite Seite: der Security-Review
Tests prüfen, ob der Code tut, was er soll. Der Security-Review prüft, was er nebenbei noch tut: Geheimnisse leaken, Logs mit Daten fluten, Eingaben durchwinken. Der Klassiker dabei ist Data Exposure: ein API-Key, der im Client-Bundle landet, eine Server-Env-Variable, die im Browser auftaucht, Stack Traces in Fehlermeldungen.
Prompt: Security-Review (gekürzt)
Perform a security review of the following code (Klar API layer - financial data for German users):
SCOPE: [PASTE DIFF OR MODULE - review ONLY this code, not the rest of the repo]
REVIEW DIMENSIONS (check each, reference CWE/OWASP per finding):
1. Data exposure - secrets or API keys in code, server-only env variables reaching the client bundle (anything sensitive behind a PUBLIC_/NEXT_PUBLIC_ prefix is a finding), PII in logs, verbose errors leaking stack traces or SQL (CWE-209, CWE-532)
2. Injection - SQL, command injection (CWE-89)
3. Auth & authorization - missing checks, IDOR: does every handler verify the caller OWNS the resource? (CWE-639)
4. Input validation - boundary validation missing or bypassable (CWE-20)
OUTPUT FORMAT per finding:
[CRITICAL|WARNING|SUGGESTION] CWE-XX - file:line - what is wrong - concrete attack or impact - exact fix as code.
If a dimension has no findings, skip it silently. End with a one-line verdict: merge-blocking findings yes/no.
DO NOT FLAG:
- Theoretical risks requiring unlikely preconditions - describe a realistic attack path or drop it
- Issues in code outside the given scope
- Generic "validate all input" advice without a concrete bypassable spot
Env Exposure als eigene Dimension: Der häufigste Anfängerfehler beim AI-Coding: Der Agent braucht einen API-Key im Frontend und nimmt den Weg des geringsten Widerstands, ein PUBLIC_-Prefix. Damit steht der Key in jedem Browser. Die Review-Zeile fängt genau das.
Das Severity-Schema: CRITICAL blockiert den Merge, sonst lernst du, alle Findings zu ignorieren. Lieber streng einstufen und weniger melden.
Die DO-NOT-FLAG-Negativliste: Das Prinzip aus Step 3 im Einsatz. Ohne sie produziert der Review-Agent spekulative Warnungen und das echte Finding geht im Rauschen unter.
Frischer Kontext: Der Review läuft in einer neuen Session oder einem anderen Modell. Der Agent, der den Code geschrieben hat, verteidigt ihn.
Übung
Aufgabe: Beide Seiten einmal selbst fahren:
Tests: Nimm eine kleine Funktion aus deinem Projekt. Schreibe die Spec in 3-4 Sätzen ohne in den Code zu schauen, notiere 3 Beispiel-Cases mit konkreten Zahlen (inklusive einer Grenze: genau 80%, genau 0, leer) und baue den Test-Prompt nach dem Muster oben.
Security: Lass den Review-Prompt über ein kleines Projekt von dir laufen. Achte besonders auf die Data-Exposure-Findings: Taucht ein Key oder eine Env-Variable auf, die nicht in den Client gehört?
Zeitaufwand: ~20 Minuten
Takeaway
Faustregel #6: Tests gegen die Spec, nie gegen den Code, sonst bekommst du einen Spiegel. Und der Security-Review braucht frischen Kontext und eine Negativliste, sonst Rauschen statt Findings.
Schritt 7 von 9
Wenn der Output nicht hält
Der Output ist falsch. Der schlechteste Move: alles neu generieren. Der beste: herausfinden, welcher Baustein gefehlt hat.
Die Situation. Der Agent hat geliefert, aber das Ergebnis stimmt nicht. Der Reflex: "Nochmal, aber besser." Das ist Würfeln mit Extraschritten. Beim zweiten Wurf fehlen dieselben Bausteine wie beim ersten, nur die Zufallsstreuung ist anders.
Schritt 1: Das Symptom auf den Baustein zurückführen
Fast jeder schlechte Output hat eine Adresse in der Anatomie. Lies das Symptom, finde den fehlenden Baustein:
Symptom
Fehlender Baustein
Der Nachtrag
Der Agent hat Features gebaut, die niemand bestellt hat
Guardrails (Non-Goals)
"Do not implement X" explizit ergänzen
Läuft in der Demo, bricht bei Umlauten, leeren Listen, Grenzwerten
Edge Cases
Die kaputten Ränder konkret benennen
Technisch okay, aber am Bedarf vorbei
Context
Wer nutzt es, wie oft, wofür
Agent meldet "fertig", aber es ist kaputt
Verify
"Run it and show the output" verlangen
Output ist vage, wo du Präzision brauchst
Requirements
Testbar machen: Zahlen, Schwellen, Formate
Schritt 2: Gezielt nachbessern, nicht neu generieren
Wenn der Output zu 80% stimmt, ist Neugenerieren Verschwendung: Du verlierst die 80% und würfelst neue Fehler in die anderen 20%. Stattdessen: den fehlenden Baustein als gezielte Folgeanweisung nachreichen. "Keep everything as is. Add handling for empty transaction lists and month boundaries, then re-run the tests."
⚠️
Nie "fix das" sagen. Bei Bugs gilt: Diagnose und Fix trennen. Erst Hypothesen und Beweise verlangen ("List 5 plausible causes, do NOT write any fix yet"), dann gezielt beheben lassen. Ein Agent mit "fix den Bug" patcht Symptome, ein Agent mit Diagnose-Auftrag findet Ursachen.
🔧
Aus der Praxis: Beim Bau genau dieser Lernplattform brach der Deployment-Build. Fix eins: Minifier gewechselt. Fix zwei: verdächtige Library entfernt. Fix drei: Bundler-Einstellung geändert. Drei plausible Patches, der Build brach weiter. Erst der Wechsel von Fixen zu Diagnose fand die echte Ursache: ein Plattform-Feature, das beim Deployment URLs in den Code injizierte und damit das Bundling brach. Ein Schalter in der Config, gelöst. Und die drei Patches flogen wieder raus.
Schritt 3: Nach drei Fehlversuchen die Session wechseln
Wenn ein Agent dreimal erfolglos nachgebessert hat, ist sein Kontext mit falschen Hypothesen und verworfenen Ansätzen kontaminiert. Das Modell verliert den Fokus, jeder weitere Versuch wird schlechter. Das ist Context-Pollution, und der Ausweg ist ein harter Schnitt:
Neue Session starten
Mitnehmen: das Symptom, die gesammelte Evidenz, deinen verbesserten Prompt
Die gescheiterten Ansätze explizit als "ruled out" markieren, damit der frische Agent sie nicht wiederholt
✅
Bonus-Effekt: Jeder diagnostizierte Fehlschlag macht deine Prompts dauerhaft besser. Der Edge Case, der dich heute erwischt hat, wandert als feste Zeile in deinen nächsten Prompt. So entsteht mit der Zeit deine persönliche Guardrail-Sammlung.
Übung
Aufgabe: Denk an deinen letzten missglückten Agent-Output (oder provoziere einen mit einem bewusst vagen Prompt).
Ordne das Symptom mit der Tabelle einem Baustein zu
Schreibe die Nachbesserung als gezielte Folgeanweisung, nicht als Neuanfang
Notiere die Lektion als Guardrail-Zeile für künftige Prompts
Zeitaufwand: ~10 Minuten
Takeaway
Faustregel #7: Schlechter Output ist ein Diagnose-Auftrag, kein Würfel-Auftrag. Symptom dem Baustein zuordnen, gezielt nachreichen, und nach drei Fehlversuchen mit frischem Kontext neu starten.
Schritt 8 von 9
Zusammenfassung
Eine Anatomie, zwei Prinzipien, acht Disziplinen. Hier ist alles auf einer Seite.
Die Anatomie als Checkliste
Vor jedem Prompt an einen Coding-Agent, fünf Fragen:
Context: Weiß der Agent, wer das nutzt und wofür?
Requirements: Ist jede Anforderung testbar formuliert?
Edge Cases: Habe ich die kaputten Ränder benannt? (Leere Zustände, Umlaute, Grenzen, Gleichzeitigkeit)
Guardrails: Steht da, was NICHT passieren darf? Sind die Non-Goals positiv formuliert?
Verify: Endet der Prompt mit einem Beweis, den der Agent selbst erbringen kann?
Aktuelles Wissen statt Trainingswissen: Doku recherchieren lassen, bevor gebaut wird.
Meilensteine mit testbaren Zwischenschritten, nicht-triviale Vorhaben auf Feature-Branches.
Artefakte als Dateien ins Repo: PRD, Spec, Plan. Der Chat vergisst, das Dateisystem nicht.
Die Landkarte mit dem wichtigsten Guardrail pro Disziplin
Disziplin
Der eine Satz, der am meisten rettet
Architektur
"Ask me 5-8 clarifying questions first. Wait for my answers."
UI
Struktur als nummerierte Zonen, Stil als eigener Absatz
Backend
"Money is integer cents, never float" und Berechtigungs-Check in jeder Query
Quality
Die DO-NOT-FLAG-Negativliste, sonst lernst du, Findings zu ignorieren
Testing
Spec in den Prompt, nie den Code. Sonst zementieren Tests jeden Bug als Feature.
Debugging
"Do NOT write any fix yet" - erst Hypothesen, dann Diagnose, dann Fix
DevOps
"Show me the full plan BEFORE executing" und echte Command-Outputs einfordern
Automation
Dry-Run zuerst, Sample-Daten in den Prompt, nie destruktiv
💬
Der Frag-KI-Assistent dieser Lesson kennt alle acht Disziplinen im Detail. Du brauchst einen kompletten Beispiel-Prompt für DB-Migrationen, E2E-Tests oder ein CSV-Skript? Frag ihn. Er baut dir die Vorlage nach der Anatomie und passt sie an dein Projekt an.
Dein Abschlussprojekt
Übung: Ein Prompt, der hält
Aufgabe: Baue einen kompletten Prompt für eine echte Aufgabe aus deinem Alltag, mit allen fünf Bausteinen:
Wähle eine Aufgabe (ein Feature, ein Skript, ein Review)
Schreibe den Prompt entlang der Checkliste oben
Lass den Frag-KI-Assistenten ihn kritisieren: Welcher Baustein ist schwach?
Schicke die finale Version an deinen Coding-Agent und vergleiche das Ergebnis mit deinen bisherigen Versuchen
Zeitaufwand: ~20 Minuten. Das Ergebnis ist deine persönliche Prompt-Vorlage.
Takeaway
Die Kernbotschaft: Du brauchst keine 80 Prompt-Templates. Du brauchst fünf Bausteine, zwei Prinzipien und die Gewohnheit, Symptome auf Bausteine zurückzuführen. Der Rest ist Übung.
Schritt 9 von 9
Begriffe & Fragen
Die Begriffe und Fragen unten sind redaktionell gepflegt und verlinken zu ausführlichen Erklärungen im Glossar und FAQ. Nutze sie zum Nachschlagen und zur Vertiefung.
Begriffe aus dieser Lesson
Agent-Kontext-Datei — Eine Agent-Kontext-Datei (CLAUDE.md, AGENTS.md) liegt im Projekt-Repository und wird vom Coding-Agenten in jeder Session automatisch gelesen. Sie enthält Befehle, Konventionen und Grenzen, damit der Agent nicht rät, wie das Projekt funktioniert.
Edge Case — Ein Edge Case ist eine Eingabe oder ein Zustand am Rand des Erwarteten: die leere Liste, der Name mit Umlaut, die Buchung um 23:59 am Monatsletzten. Software, die nur für den Normalfall gebaut wurde, bricht genau hier.
Guardrails — Guardrails sind die Grenzen und Regeln, innerhalb derer ein KI-System operiert. Sie verhindern unerwünschtes Verhalten: falsche Antworten, sensible Aktionen, Kostenexplosion oder Sicherheitsverstöße.
IDOR — IDOR (Insecure Direct Object Reference) ist eine Sicherheitslücke, bei der ein eingeloggter Nutzer fremde Daten abrufen kann, indem er einfach eine andere ID in die Anfrage setzt. Die App prüft, DASS jemand eingeloggt ist, aber nicht, ob ihm die Daten GEHÖREN.
Spec-Driven Development — Spec-Driven Development heißt: Erst das Dokument, dann der Code. Aus einer Idee wird ein PRD (was und warum), daraus eine technische Spec (wie), daraus ein Plan in testbaren Schritten. Der Agent baut gegen das Dokument statt gegen eine vage Chat-Nachricht.
Passende Fragen
Der KI-Output ist falsch. Einfach neu generieren? Meistens nein. Neu generieren ist Würfeln, du verlierst die 80 Prozent, die stimmen, und bekommst neue Zufallsfehler in den Rest. Besser, herausfinden, welcher Baustein im Prompt gefehlt hat, und gezielt nachreichen. Erst nach etwa drei erfolglosen Versuchen lohnt der harte Schnitt mit frischer Session.
Ist KI-generierter Code sicher? Standardmäßig nein. Untersuchungen zeigen, dass knapp die Hälfte der KI-generierten Code-Beispiele durch gängige Sicherheitstests fällt, und größere Modelle schneiden nicht besser ab. Funktional ist der Code gut, sicherheitstechnisch systematisch schwach. Sicherheit muss explizit in den Prompt.
Kann ich die KI Tests für ihren eigenen Code schreiben lassen? Ja, aber nicht mit „schreib Tests für diesen Code". Dann liest der Agent den Code und bestätigt, was er tut, inklusive aller Bugs. Stattdessen die Spezifikation in den Prompt geben, mit konkreten Beispiel-Zahlen. Tests prüfen, was der Code SOLL, nicht was er tut.
Was gehört in eine CLAUDE.md? Vier Dinge: lauffähige Befehle (Dev, Test, Lint, Build), die Projektstruktur, ein echtes Code-Snippet als Style-Vorbild und Grenzen in drei Stufen (immer erlaubt, erst fragen, niemals). Unter 60 Zeilen, und jede Zeile muss das Agent-Verhalten ändern.
KI-Stratege & Übersetzer zwischen Tech und Business
15+ Jahre Digitalisierung, 4+ Jahre KI. Ich übersetze zwischen
Technologie und Unternehmensstrategie, berate und trainiere
Organisationen auf ihrem KI-Weg. Hier teile ich, was ich dabei lerne.