Skip to content
Applied ML with Coffee
Go back

Entwickeln mit Claude Code

Entwickeln mit Claude Code

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:

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:

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.yml schaut 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:

💡: 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.


Share this post on:

Next Post
Deploying a FastAPI app on Google Cloud Run