Ich habe lange überlegt, was ich hier eigentlich schreiben soll. Wie man Claude Code installiert und einrichtet? Let me google it for you. Wie Agentic Engineering - the new kid in hype town - funktioniert? Das wäre als würde ich professionellen Software Engineers - ja, damit meine ich Dich - erklären, wie ihr Job funktioniert. Warum ich das so sage? Spoiler: Die Secret Sauce ist nicht der Prompt.
Probieren wir stattdessen etwas dazwischen, um die meisten abzuholen und Dir dennoch etwas mitzugeben, was dir weiterhilft. AI Tooling ändert sich im Minutentakt, Prinzipien bleiben etwas länger.
TLDR: Code = Kontext. Struktur > Tooling. Feedback > Raten. Iteration > One-Shot.
Setup
Fasse mich (MacUser) kurz. Mehr Details in der Doku.
# Installieren
brew install --cask claude-code
# cd my-repo, starten und deinen Pair Programmer begrüßen
claude
Starte Claude Code niemals mit dem CLI Flag --dangerously-skip-permissions. Stellst du Settings richtig ein, brauchst du das nicht.
~/.claude/settings.json # User (global, vererbt)
my-project/.claude/settings.json # Projekt (lokal)
Die Settings kannst du direkt im CLI mit dem Slash Command /config einrichten. Ich hab mir die Settings hier generieren lassen (siehe Appendix).
Mit /sandbox isolierst du Claude Codes Bash-Zugriffe auf OS-Ebene — Dateisystem- und Netzwerk-Isolation mit sinnvollen Defaults, weniger Approval-Fatigue. Zugriffsversuche außerhalb werden sofort sichtbar. Selbst bei erfolgreicher Prompt Injection (z.B. durch ungeprüfte Skills, WebSearch, Doku, MCPs): kein Zugriff auf SSH-Keys, und Credentials können nicht nach außen geschleust werden. Solider Schutz, ohne Aufwand — mehr mit Devcontainern.
Spieglein, Spieglein an der Wand
… Wer hat die schönste Codebase im Land?
“Das ist historisch gewachsen”, fügte der Entwickler hinzu. Der Spiegel schwieg. Diplomatisch.
LLMs sind — vereinfacht — Pattern-Completion-Engines. Gegebenen Kontext, was kommt am wahrscheinlichsten als Nächstes? Das wird ihren Fähigkeiten nicht gerecht, trifft aber den Kern für die Praxis: Sie verstärken was sie vorfinden — ob gut oder schlecht. Ein paar Szenarien:
-
Fehlende Standards: Es gibt keine erkennbare Konvention. Mal findet Type Validation statt, mal nicht. Mal ein try/except, mal nicht. Inkonsistente Datenmodelle: mal spuckt ein Endpoint rohe Dicts aus, mal ein Pydantic Model. Was bleibt dem LLM übrig? Es macht, was ein introvertierter Junior Developer machen würde, es improvisiert, ohne zu fragen. Jede neue Improvisation führt zu mehr Inkonsistenz.
-
Spaghetti Code: Hier existiert durchaus Konsistenz — nur eben konsistenter Mist (Asche auf mein Haupt 😅). Eine Datei mit 900 Zeilen, in der Routing, Business Logik und Datenzugriff ineinander verwoben sind. Das Pattern, das das LLM liest: “alles gehört hierhin, alles darf alles anfassen.” Sagst du “füge ein neues Feature hinzu”, macht es genau das — weitere Funktionen in derselben Datei, denselben Dependencies, und aus 900 werden 1.100 LOC. Drei Endpoints duplizieren fast identische Logik? Das LLM legt beim vierten eine vierte Kopie an. Es erkennt das Muster “hier wird kopiert” und reproduziert es pflichtbewusst.
-
Saubere Architektur: Es gibt einen bestehenden API-Endpoint mit Input-Validierung, sauberer Fehlerbehandlung und einem zugehörigen Test? Der nächste Endpoint wird genauso gebaut. Klare Ordnerstruktur, konsistente Namenskonventionen, explizite Interfaces zwischen Modulen — die Struktur selbst kommuniziert, wie hier gearbeitet wird. Nicht über Dokumentation, nicht über Prompt oder Context Engineering, sondern über den Code. Das gilt für neue Teammitglieder genauso wie für ein LLM: wer eine saubere Referenzimplementierung vorfindet, muss nicht raten.
In allen drei Fällen tut das LLM dasselbe: es folgt dem Kontext. Der Output ist ein Spiegel deiner Codebase.
💡: Wenn der Agent etwas anders macht als erwartet: Frag ihn, warum. Der Reflex, an CLAUDE.md oder Prompts zu drehen, ist verlockend. Aber meistens zeigt die Antwort, dass Architektur oder Konventionen im Code nicht klar genug sind. Das ist ein Hebel.
Architektur & Design
Ein Kollege — Softwarearchitekt, C#, DDD — meinte, mit einer klaren Architektur, einer klaren Struktur, muss man dem LLM gar nicht mehr viel erzählen. Er hatte Value Objects definiert, mit eingebauter Validierung. Klare Boundaries. Und danach lief Code Generierung für ihn fast reibungslos. Kein Prompt/Context Engineering. Kein Spec-Driven Development. Kein fancy Tooling. Die Architektur war der Kontext.
Das klingt einfach. Ist es nicht — es ist nur eine andere Art von Aufwand. Statt dem LLM zu erklären, was es tun soll, schaffst du eine Struktur, in der es gar nicht anders kann, als das Richtige zu tun. Weniger Erklärung, mehr Führung durch Design.
Dahinter stecken zwei Mechanismen, die zusammenwirken.
Struktur als Kontext
Je größer der Lösungsraum, desto mehr Spielraum zum Improvisieren — und desto höher die Wahrscheinlichkeit, dass das Ergebnis nicht dem entspricht, was du dir vorgestellt hast. Jede Design-Entscheidung, die im Code sichtbar ist, verengt diesen Raum. Nicht durch Erklärung, sondern durch Struktur.
Das wirkt auf mehreren Ebenen:
-
Modul-Boundaries. Ousterhout (A Philosophy of Software Design) nennt es „Deep Modules”: eine klare Verantwortlichkeit, eine schmale öffentliche API — Methoden, Signaturen, Typen — und die eigentliche Komplexität dahinter verborgen. Matt Pocock hat das auf den AI-Kontext übertragen: Du steckst den Rahmen ab, das LLM füllt das Innere. Es muss nicht entscheiden, wie etwas strukturiert sein soll. Das hast du bereits getan.
-
Types as Contracts. In TypeScript sind es Types, in C# Value Objects, in Python Pydantic Models — das Vehikel ist egal. Entscheidend ist: wenn ein Funktionssignatur
TranslationMemoryEntryerwartet stattdict, dann ist der Lösungsraum für das LLM radikal kleiner. Es kann gar kein rohes Dict einfügen. Der Type erzwingt Struktur. -
Konsistenz als Signal. Wir sprachen beim Spiegel darüber: eine konsistente Codebase ist Kontext. Einheitliche Naming Convention, eine klare Ordnerstruktur, eine Referenzimplementierung die zeigt “so machen wir das hier” — all das kommuniziert Regeln, ohne dass du sie aufschreiben musst.
Der Mensch designt die Boundaries. Das LLM implementiert innerhalb dieser Boundaries. Das ist die Arbeitsteilung.
Schnelles Feedback
Struktur allein reicht nicht. Denn ein LLM kann innerhalb der richtigen Struktur trotzdem semantisch falschen Code produzieren — Code, der kompiliert, der sich an das Interface hält, aber inhaltlich nicht das tut, was er soll.
Hier kommen Feedback-Loops ins Spiel: Type Validation, Tests, Linting. Alles, was dem LLM — oder genauer: dem Agenten, der iterativ arbeitet — sofort sagt, ob der letzte Schritt korrekt war oder nicht.
Gene Kim argumentiert mit einem Prinzip aus der Signalverarbeitung: Wenn die Frequenz der Code-Produktion steigt, muss die Frequenz des Feedbacks mindestens genauso schnell steigen. Sonst entstehen Fehler, die du erst Tage später entdeckst — wenn der Kontext längst weg ist. Das Nyquist-Shannon-Theorem beschreibt genau das: die Abtastrate muss zur Signalfrequenz passen — sonst geht Information verloren. Wer selten testet, verliert Kontrolle. Dave Farley bringt es auf den Punkt: In einer AI-getriebenen Welt wird Verifikation zum Bottleneck — Code-Generierung ist billig, Verhalten verstehen und validieren ist der harte Teil.
Konkret: Wenn ein Agent in Minuten produziert, wofür du Stunden gebraucht hättest, dann reicht ein manueller Review am Ende nicht mehr. Du brauchst eine Testsuite mit hoher Coverage, Type Checks, Linting, Pre-Commit-Hooks und ne CI/CD Pipeline.
Sei ruhig pedantisch. Der Agent nimmt’s dir nicht übel.
Struktur ohne Feedback? Code sieht korrekt aus — ist es nicht. Feedback ohne Struktur? Tests grün — trotzdem Spaghetti. Du brauchst beides. Struktur definiert das Was. Feedback prüft das Ob.
Arbeitsweise
Die folgenden Taktiken haben sich im Laufe der Zeit bewährt. Sie haben aber wenig mit KI zu tun. Es sind eher Brot und Butter des Software Engineering.
Aufgaben nachschärfen
Kläre das Was und zerlege es bei Bedarf in Arbeitspakete.
Refinement: Issues/Items/Stories entstehen schnell. Manchmal sinds nur Gedanken, Ideen, Sachen die nebenbei anfallen. Aber ist die Aufgaben selbsterklärend? Könnte ein anderer Developer übernehmen? Ist es aus dem Kontext (Code) ersichtlich was gemacht werden muss und vielleicht auch schon wie es erreicht werden kann? Wenn nicht, kann das zu ungewollter Kreativität führen. Im Scrum Meeting diskutiert ein Team darüber. Arbeitest du allein, widmest du der Aufgabe selbst nochmal mehr Zeit, um das Ziel klarzuziehen.
Bei komplexeren Themen bzw. komplexeren Codeänderungen nutze ich dazu einen generierten Skill, der ein Agent Team übers Issue, Code usw. aus mehreren Perspektiven schaut und dann miteinander diskutiert, bis das Was und die Acceptance Criteria (AC) absolut klar sind.
Decomposition: Daumenregel: Würd ich länger als nen Tag brauchen, besser zerlegen (Sub-Issues) nach Abstraktionsgrenzen, Slice pro Verantwortlichkeit, Modul-Boundary… Kleine Arbeitspakte haben zwei Vorteile: Der AI Agent arbeitet fokussierter und ich habe weniger Kopfschmerzen beim Review. Nen Diff von 100 LOC liest sich leichter als 10k LOC.
Hab das auch mit einem Agent Skill probiert. Beim ersten Mal zerlegte er’s in kleine Pakete (soweit so gut), aber am Ende kam ein Big Bang issue, wo alles miteinander verbunden werden musste. Der Skill braucht auch ein Refinement ;).
Implementieren
Test Driven Development (TDD): Red-Green-Refactor erzeugt die nötigen Feedback Loops sofort und du vermeidest “Verschlimmbesserungen”. Es zwingt dich, aber auch den Agent zur Disziplin. Das gilt bei neuen Features aber auch bei kleineren Anpassungen. Ich kombiniere es mit Behavior Driven Development (BDD). Einfache Gherkin Notierung in den Tests helfen dem Agent, aber auch mir. Ein Caveat von Kent Beck: Agents löschen manchmal Tests statt sie zu fixen, um sie „bestehen” zu lassen. Also: Tests im Diff prüfen, nicht nur die Ergebnisse.
👆: Tests zuerst.
Ok. Hin- und wieder mags Tasks geben, wo das Overkill wäre. Da tut’s auch ein One-Shot. Abwägen.
Änderungen verstehen
Du magst das Code Schreiben outsourcen. Aber die Verantwortung trägst du. Ergo musst du ihn verstehen.
Ob du nun Claude Code im Ghostty Terminal auf der linken Seite deines Bildschirm hast und die Änderungen in deinem IDE mit Argus-Augen anschaust (bitte mach das vor dem Commit^^) und/oder dir den PR auch nochmal in GitHub oder Azure DevOps genauer anschaust (ja, mach beides) und ggf. Kommentare hinterlässt. Egal. Schaue es dir an. Versteh es. Denn Cognitive Debt entsteht nun noch schneller als Technical Debt und ist schwerer zu erkennen. Du merkst es erst, wenn du drei Wochen später einen Bug fixen sollst und nicht mal weißt, warum der Code so aussieht — geschweige denn, wo du ansetzen musst. (Anthropics eigene Studie zeigt: Entwickler, die AI zum Verstehen nutzen statt zum reinen Delegieren, behalten ihr Verständnis — Cognitive Debt ist kein Naturgesetz.)
💡: Mit dem GitHub Workflow
claude-code-review.ymlschaut ein zusätzliches Paar Augen 👀 auf die Code Änderungen. Findet manchmal paar Blind Spots, die mir nicht aufgefallen sind.
CLAUDE/SKILL.md pflegen
Du hast etwas gefunden, was für dich gut funktioniert? Mach’s reproduzierbar. Hilf deinem Team, dem AI Agent und dir selbst. Packs in einen Skill oder in CLAUDE.md. Mehr dazu im Appendix.
Fazit
Was bleibt, wenn sich das Tooling nächste Woche wieder ändert? Architektur. Tests. Klarheit darüber, was gebaut werden soll und warum. Diese Prinzipien sind nicht neu — sie sind nur relevanter geworden. KI-gestützte Entwicklung macht sie nicht obsolet. Sie macht sie dringlicher.
Der Spiegel lügt nicht. Wenn der Output nicht stimmt, liegt es selten am Tool. Die Codebase, die Aufgabe, die Struktur — das ist der Kontext, mit dem der Agent arbeitet. Und den gestaltest du.
Die Secret Sauce ist nicht der Prompt. Es ist Software Engineering.
Appendix
Settings
Meine settings.json:
{
"cleanupPeriodDays": 7,
"env": {
"CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL": "1",
"DISABLE_TELEMETRY": "1",
"DISABLE_ERROR_REPORTING": "1",
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"includeCoAuthoredBy": false,
"permissions": {
"allow": ["Bash(find:*)", "Bash(git diff:*)", "Bash(git log:*)"],
"deny": [
"Read(**/.env)",
"Read(**/.envrc)",
"Bash(sudo:*)",
"Bash(su:*)",
"Bash(ssh:*)"
],
"ask": ["Bash(rm:*)", "WebSearch", "Bash(curl:*)", "Bash(wget:*)"],
"disableBypassPermissionsMode": "disable"
}
}
Davon nennenswert:
disableBypassPermissionsMode: “disable” bedeutet, dass Claude zwar mit--dangerously-skip-permissionsgestartet werden kann, das aber keinerlei Wirkung hat. Angezeigt wird dann auch: “Bypass permissions mode was disabled by settings”includeCoAuthoredBy:falseverhindert, dass in Git Commits & PRsco-authored-by Claudeerscheint.cleanupPeriodDaysDie Anzahl der Tage nachdem deine lokalen Session-Daten gelöscht werden. Serverseitige 30 Tage Data Retention ist davon unberührt.
💡: Claude for Work (Team/Enterprise) ist SOC 2 Type I & Type II & ISO 27001 zertifiziert.
CLAUDE.md
Die CLAUDE.md ist dein System Prompt an Claude Code. Diese Datei ist quasi ein README für den AI Agent oder ne Art Mini-Briefing am Anfang einer neuen Coding Session.
💡: CLAUDE.md = AGENTS.md. AGENTS.md wird von anderen Agent CLIs (Codex, Copilot …) genutzt. In einem Tool-heterogenen Team nutz einfach beides via Symlink ;).
ln -s CLAUDE.md AGENTS.md
Claude Code als auch Codex haben den Slash Command /init. Dieser exploriert das aktuelle Repository und generiert CLAUDE.md. Diese Datei enthält eine Projektübersicht, build & test commands usw.
💡: Ein Slash Command ist letztendlich nur ein wiederholt ausführbarer Prompt.
Best Practices zum Schreiben einer CLAUDE.md findest du hier.
💡: Studie zu AGENTS.md fand heraus, dass generierte AGENTS.md die Performance von AI Agents um ca. 3% verschlechtern. Während von Developern gepflegte AGENTS.md die Performance des Agents um ~4% erhöhen.
Zusammenfassend würde ich in die CLAUDE.md aufnehmen, was sich nicht in Config, Tooling oder Code selbst abbilden lässt. Das ist ein iterativer Prozess. Schauen, wo der Agent daneben liegt und dann ggf. die Datei anpassen. An der Stelle lohnt es sich auch den Agent zu fragen, warum er etwas anders als gewünscht angegangen ist. Vielleicht sind Architektur, Design, Struktur nicht so klar abgebildet. Hier lohnt es sich ggf. mehr Energie in die Codebase selbst zu stecken — klarere Architektur, explizitere Patterns, Types etc.
Architektur/Clean Code > CLAUDE.md
CLAUDE.md ist vererbbar.
~/.claude/
└── CLAUDE.md # User: gilt global für alle Projekte
# persönlich, nicht im Repo
my-project/
├── CLAUDE.md # Projekt: gilt fürs gesamte Repo
│ # im Repo, geteilt mit dem Team
│
├── src/ # optional — in größeren Repos mit
│ ├── backend/ # eigenständigen Modulen sinnvoll
│ │ └── CLAUDE.md # Modul: gilt nur in diesem Subtree
│ └── frontend/
│ └── CLAUDE.md # Modul: gilt nur in diesem Subtree
User- und Projekt-Level werden bei jedem Start geladen (Inheritence). Modul-Level erst on-demand — also nur wenn Claude in dem Subtree tatsächlich arbeitet. Arbeitet Claude im Backend, sieht es die Frontend-CLAUDE.md nicht. Relevante Ebenen werden zusammengefügt, spezifischere ergänzen die allgemeineren. User-Level ist privat. Projekt- und Modul-Level landen im Repo, geteilt mit deinem Team.
SKILL.md
Ein Skill ist eine Markdown-Datei in .claude/skills/, die Claude beibringt, wie es eine bestimmte Aufgabe erledigen soll. Skills werden automatisch geladen, wenn Claude erkennt, dass sie zum aktuellen Task passen. Du kannst sie aber auch via /name-des-skills explizit starten.
Jeder Skill besteht aus zwei Teilen: YAML-Frontmatter (Name + Beschreibung, wann der Skill greifen soll) und Markdown-Inhalt mit den eigentlichen Anweisungen.
.claude/skills/
└── explain-code/
├── SKILL.md # Anweisungen + Frontmatter
├── template.md # Optional: Vorlage zum Ausfüllen
└── example-output.md # Optional: Referenz-Output
Wann lohnt sich ein Skill? Wenn du ein wiederkehrendes Problem einmal sauber gelöst hast und das Pattern reproduzierbar machen willst — für dich, dein Team und den Agent. Der Skill kodifiziert dein Wissen. Ohne Skill improvisiert der Agent jedes Mal neu.
Einmal lösen -> Code -> Wiederverwenden.
Wie bei CLAUDE.md: global (~/.claude/skills/) oder projektspezifisch (my-project/.claude/skills/). Mehr dazu in der Doku.