Claude Code richtig konfigurieren: vom Default zum Engineering-Partner
Welche Einstellungen bei Claude Code wirklich etwas bringen: schlanker Kontext, korrekte Hooks, Permission-Modi, Effort-Steuerung und Subagents — mit den echten Mechanismen statt kursierender Halbwahrheiten.
von Jean Pierre Kolb ·
Die Standard-Einstellungen von Claude Code sind gut genug, um sofort produktiv zu sein — und genau das ist die Falle. „Gut genug" lässt überraschend viel liegen: Geschwindigkeit, vor allem aber Kontrolle. Claude Code ist keine Blackbox, die du hinnimmst, wie sie kommt, sondern eine konfigurierbare Engineering-Plattform. Die Qualität, die am Ende herauskommt, hängt nicht nur am Modell, sondern mindestens genauso am System, das du drumherum baust.
Dieser Artikel ist kein Einstieg. Er richtet sich an Leute, die Claude Code bereits täglich benutzen und konstanter, verlässlicher arbeiten wollen. Ich gehe die Schrauben durch, die sich wirklich lohnen — in vier Blöcken: Kontext, Sicherheit & Automatisierung, Arbeitsweise am Agenten und mehr Perspektiven durch Modelle und Subagents. Bei jeder Einstellung nenne ich den echten Mechanismus, denn zu einigen davon kursieren hartnäckig Konfigurationen, die schlicht nicht funktionieren. Alle Beispiele kannst du direkt übernehmen.
Block 1 — Kontext gezielt füttern
Alles beginnt mit dem, was Claude in jeder Sitzung sieht, bevor du das erste Wort tippst. Wer hier großzügig ist, glaubt, dem Modell einen Gefallen zu tun. Das Gegenteil ist der Fall.
CLAUDE.md klein halten
CLAUDE.md ist dein permanenter Sitzungskontext: Der Inhalt landet in jeder Unterhaltung im Prompt, bevor irgendetwas anderes passiert. Die Versuchung ist groß, diese Datei zur Enzyklopädie auszubauen — Architektur, Konventionen, Domänenwissen, Onboarding, Deployment-Schritte, API-Verträge, Projekthistorie. „Mehr Kontext, bessere Antworten", so die Annahme.
Sie stimmt nicht. Große Sprachmodelle gewichten nicht jeden Teil eines langen Dokuments gleich; Informationen in der Mitte langer Texte gehen zuverlässig unter — der bekannte „lost in the middle"-Effekt. Je größer CLAUDE.md wird, desto wahrscheinlicher übersieht Claude ausgerechnet die Regel, die dir wichtig war. Du zahlst also doppelt: mehr Tokens pro Sitzung und weniger verlässliche Beachtung.
Die Faustregel lautet deshalb: In CLAUDE.md gehört nur, was in jede einzelne Sitzung gehört.
- Technologie-Stack
- übergreifende Coding-Prinzipien
- harte architektonische Leitplanken
- projektweite Regeln
- Verweise auf weiterführende Dokumente
Alles andere wandert aus. Eine konkrete Zahl als Gesetz zu setzen, wäre unseriös — aber wenn deine CLAUDE.md in den fünfstelligen Zeichenbereich wächst, ist das ein verlässliches Alarmsignal, dass zu viel Situatives darin klebt.
Detailwissen modular auslagern — mit den echten Mechanismen
Die Frage ist dann: Wohin mit dem Rest? Claude Code bietet dafür zwei saubere Wege, und es lohnt sich, sie nicht zu verwechseln.
@-Importe in CLAUDE.md. Eine Zeile, die nur aus @pfad/zur/datei.md besteht, zieht diese Datei beim Sitzungsstart mit ein. So bleibt die Haupt-CLAUDE.md als Inhaltsverzeichnis schlank, und die Details liegen in fokussierten Dateien:
# Projekt-Konventionen
Stack: NestJS, PostgreSQL, TypeScript (strict).
Architektur: Clean Architecture, Repository-Pattern ist Pflicht.
Details bei Bedarf:
@docs/architecture.md
@docs/testing-strategy.md
@docs/api-contracts.mdDas ist immer noch permanenter Kontext — die importierten Dateien werden mitgeladen. @-Importe ordnen also, sie reduzieren nicht. Für echtes Bedarfs-Laden brauchst du den zweiten Weg.
Skills — geladen, wenn sie gebraucht werden. Ein Skill ist kein beliebiges Markdown, das irgendwo herumliegt und automatisch mitgelesen wird. Ein Skill ist ein Verzeichnis unter .claude/skills/ mit einer SKILL.md, und die trägt im YAML-Frontmatter zwingend name und description:
.claude/skills/
├── nestjs-conventions/
│ └── SKILL.md
├── migration-playbook/
│ └── SKILL.md
└── code-review-checklist/
└── SKILL.md---
name: nestjs-conventions
description: Konventionen für NestJS-Module — wann laden und wofür
---
## Modul-Struktur
domain/ · application/ · infrastructure/ · presentation/
## Regeln
- Business-Validierung nutzt niemals class-validator.
- Das Repository-Pattern ist verpflichtend.
- Lifecycle-Hooks gehören ausschließlich in die Application-Schicht.Der entscheidende Unterschied: Claude liest die description und lädt den Skill nur, wenn er zur aktuellen Aufgabe passt — beim NestJS-Modul die NestJS-Konventionen, beim Pull-Request-Review die Review-Checkliste. Der Rest bleibt draußen. Das ist Lazy Loading für Projektwissen: weniger Rauschen, weniger Tokens, und deutlich geringere Gefahr, dass Regeln aus unzusammenhängenden Projektteilen sich vermischen.
Merksatz:
@-Importe strukturieren permanenten Kontext, Skills laden ihn bedarfsgerecht. Die kleineCLAUDE.mdplus ein gepflegter Skill-Bestand schlägt jede Monster-Datei — und zwar unabhängig davon, wie clever deine Prompts sind.
Dasselbe Muster funktioniert übrigens global: Ein schlankes ~/.claude/CLAUDE.md für deine persönlichen, projektübergreifenden Grundregeln, und projektspezifisches Wissen bleibt im jeweiligen Repo.
Block 2 — Sicherheit und sichere Automatisierung
Der zweite Block ist der, an dem die meisten Setups entweder zu ängstlich (ständige Freigabe-Prompts) oder zu leichtsinnig (alles erlaubt) sind. Beides lässt sich präzise austarieren — wenn man weiß, wie die Mechanismen wirklich greifen.
settings.json: Berechtigungen richtig setzen
Claude verbringt viel Zeit mit harmlosen Dingen: Dateien lesen, Git-Historie prüfen, Tests laufen lassen, das Projekt durchsuchen. Nichts davon ist destruktiv, aber im Default fragt der Agent trotzdem nach. Die Lösung ist eine allow-Liste für risikolose Lese- und Verifikationsbefehle, während alles Verändernde hinter manueller Freigabe bleibt:
{
"permissions": {
"allow": [
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(npm test:*)",
"Bash(npm run lint:*)",
"Bash(npm run typecheck:*)"
],
"deny": [
"Bash(git push:*)",
"Bash(git reset --hard:*)",
"Bash(rm -rf:*)"
]
}
}Der Effekt ist sofort spürbar: Statt zwanzig harmloser Freigaben pro Sitzung genehmigst du nur noch das, was tatsächlich etwas verändern kann. Das fühlt sich viel mehr nach Pair Programming an als nach Fernsteuerung.
Wichtig ist zu verstehen, wie diese Regeln matchen — hier scheitern viele gut gemeinte Konfigurationen. Das Muster in Bash(...) wird als Präfix-Glob auf den tatsächlichen Befehls-String angewandt, den Claude ausführen will. Bash(git diff:*) trifft also jeden Befehl, der mit git diff beginnt. Was daraus nicht folgt: Regeln wie Bash(drop table:*) oder Bash(delete from ...) sind wirkungslos. SQL läuft praktisch nie als nackter Shell-Befehl, sondern eingebettet — etwa psql -c "drop table users". Der reale Befehls-String beginnt dann mit psql, nicht mit drop table, und die Regel greift ins Leere. Wer gefährliches SQL abfangen will, braucht dafür einen Hook, der den Befehlsinhalt inspiziert — womit wir beim nächsten Punkt sind.
Hooks — der korrekte Weg
Hooks sind kleine Shell-Programme, die Claude Code vor oder nach einem Tool-Aufruf startet. Sie sind eines der stärksten und zugleich am häufigsten falsch verdrahteten Features. Der Kern, den man kennen muss:
- Ein Hook bekommt seine Daten als JSON auf
stdin— nicht als Positionsargument. Der auszuführende Befehl steckt in.tool_input.command. - Blockiert wird ein
PreToolUse-Hook mit Exit-Code2. Was der Hook nachstderrschreibt, bekommt Claude als Begründung. Exit0heißt „kein Einwand" (die normale Freigabe-Logik läuft weiter), jeder andere Code gilt als Hook-Fehler und blockt nicht.
Ein Hook, der den Befehl aus $1 liest und mit exit 1 blocken will, tut also schlicht nichts. So sieht ein Guard aus, der wirklich greift:
#!/usr/bin/env bash
# PreToolUse hook: refuse obviously destructive shell commands.
# Claude Code passes the tool call as JSON on stdin.
input=$(cat)
command=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')
dangerous='rm -rf /|mkfs|dd if=.*of=/dev/|DROP TABLE|TRUNCATE|DELETE FROM.*WHERE 1=1'
if printf '%s' "$command" | grep -qiE "$dangerous"; then
echo "Blocked: refusing to run a destructive command." >&2
exit 2 # exit code 2 tells Claude Code to block the call
fi
exit 0Registriert wird er in settings.json. Der matcher filtert hier auf den Tool-Namen (Bash), nicht auf einen Befehl:
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/guard.sh"
}]
}]
}
}Statt über Exit-Codes kann ein Hook auch mit 0 beenden und ein JSON-Objekt zurückgeben, das die Entscheidung explizit macht (permissionDecision: "deny" mit Begründung) — feiner, aber für den simplen Blockierfall ist Exit 2 völlig ausreichend.
Zwei Dinge noch zur Einordnung: Der matcher ist nur bei PreToolUse/PostToolUse ein Tool-Namen-Filter. Bei Stop- oder Notification-Hooks matcht er auf andere Felder (etwa den Auslöser), ein leerer Matcher bei einem Stop-Hook bedeutet also nicht „jedes Tool". Und ein Notification-Hook, der dir per notify-send bzw. osascript Bescheid gibt, wenn Claude fertig ist, spart dir das ständige Starren aufs Terminal — banal, aber der Wegfall des Kontextwechsels ist in der Praxis erstaunlich viel wert.
acceptEdits gezielt — und die Permission-Modi verstehen
acceptEdits nimmt die Rückfrage vor jeder Dateiänderung weg und lässt den Agenten spürbar schneller wirken. Beim ersten Mal fragt man sich, warum das nicht immer an ist. Die Antwort: weil „schnell" hier trügt.
Der Modus ist goldrichtig für Aufgaben, die mechanisch und automatisch überprüfbar sind — JavaScript nach TypeScript ziehen, any-Typen ersetzen, Dateien umbenennen, Importe aktualisieren, Formatierung, Tests für bestehende Funktionalität generieren, Doku editieren. Hier fängt die Testsuite einen Fehler zuverlässig ab.
Für alles, was Urteilsvermögen verlangt, bleibt die manuelle Freigabe an: neue Features, architektonisches Refactoring, Authentifizierung, Zahlungsflüsse, die Datenbankschicht — kurz, jede Aufgabe, deren „fertig" sich nicht in Sekunden maschinell prüfen lässt. Der Grund ist nicht Misstrauen ins Modell, sondern eine simple Erfahrung: Ein Agent, der ohnehin gerade in den Dateien editiert, „hilft" schnell mal mit, indem er nebenbei Services umbaut, die niemand angefasst haben wollte. Technisch nicht kaputt, oft sogar plausibel — aber nicht besser als die bewusst gewählte Architektur. Aus fünf Minuten Aufräumen werden dann dreißig Minuten Review.
Die Regel dahinter: acceptEdits nur dort, wo Tests einen Fehler zuverlässig erkennen. Kann kein Test dir sagen, dass etwas schiefging, ist der zusätzliche Klick der manuellen Freigabe gut investiert.
acceptEdits ist dabei nur einer von mehreren Permission-Modi. Es lohnt sich, die ganze Leiter zu kennen:
| Modus | Verhalten |
|---|---|
default | Fragt vor verändernden Aktionen nach; Lesen läuft durch |
acceptEdits | Genehmigt Dateiänderungen und gängige Dateibefehle automatisch |
plan | Nur-Lesen; Claude erkundet und schlägt einen Plan vor, ohne zu ändern |
auto | Ein Klassifizierer prüft jede Aktion gegen eine Blockliste (Research-Preview) |
dontAsk | Verweigert Prompts automatisch; nur vorab erlaubte Tools laufen |
bypassPermissions | Überspringt alle Prüfungen — nur in Container/VM vertretbar |
Zwei Ergänzungen für den Alltag: Die eingebaute Bash-Sandbox (/sandbox) hegt Shell-Befehle per OS-Primitiven ein und reduziert Prompts, ohne Sicherheitsprüfungen abzuschalten. Und wenn du weniger Rückfragen willst, ohne blind alles durchzuwinken, ist der auto-Modus mit seinem Klassifizierer der ehrlichere Weg als bypassPermissions. Letzteres (--dangerously-skip-permissions) gehört ausschließlich in eine echte Isolationsgrenze — dazu gleich mehr.
Umgebungen unterschiedlich behandeln — der echte Mechanismus
Deine lokale Entwicklungsmaschine ist nicht die Produktion. Es liegt nahe, unterschiedlichen Umgebungen unterschiedliche Rechte zu geben — lokal großzügig, produktionsnah streng. Nur läuft das nicht über eine Umgebungsvariable, die auf eine Profildatei zeigt (eine solche gibt es nicht), und der Befehl heißt schlicht claude, nicht claude code. Der echte Mechanismus ist die Settings-Hierarchie, und die ist mächtiger:
~/.claude/settings.json— deine Benutzer-Defaults über alle Projekte.claude/settings.json— Projekt-Einstellungen, eingecheckt, für das ganze Team.claude/settings.local.json— lokale Übersteuerung, git-ignoriert, pro Maschine
Diese Ebenen werden automatisch gemerged (spätere übersteuern frühere). Der geteilte, sichere Grundstock liegt also im eingecheckten settings.json, und jede Maschine ergänzt in settings.local.json ihre lokalen Freiheiten (etwa docker compose down oder npm run db:reset ohne Rückfrage) — ganz ohne Alias-Akrobatik. Willst du für einen einzelnen Lauf bewusst eine bestimmte Datei ziehen, gibt es die --settings-Flag:
claude --settings .claude/settings.ci.jsonFür Teams und Organisationen kommt ganz oben noch die Managed-Policy hinzu: /etc/claude-code/managed-settings.json (Linux) wird mit höchster Priorität gelesen und überschreibt alles darunter — ideal, um zentrale Leitplanken zu verankern, die niemand lokal aushebeln kann. Und wenn du das gesamte Konfigurationsverzeichnis verschieben willst, setzt du CLAUDE_CONFIG_DIR auf den neuen Pfad (das steuert das Verzeichnis, nicht eine einzelne Datei).
Praxis: Permission-Regeln steuern, was laufen darf und ob vorher gefragt wird. Sie sind aber keine Wand: Ein Befehl, der durchkommt, kann alles erreichen, was der Prozess erreichen kann. Wer dem Agenten echte Autonomie geben will — Stichwort
bypassPermissions—, kombiniert die Rechte deshalb mit Isolation (Container, VM, Sandbox-Runtime). Wie das sauber geht, steht im ausführlichen Beitrag Claude Code im Container.
Block 3 — Arbeitsweise am Agenten
Konfiguration ist die eine Hälfte. Die andere ist, wie du im laufenden Betrieb mit dem Agenten umgehst — hier holst du ohne jede Einstellung Zeit heraus.
Context Rot erkennen und abbrechen
Jede lange Sitzung erreicht irgendwann einen Punkt, an dem die Qualität kippt. Die Symptome sind bemerkenswert konstant: Der Agent schlägt Ideen vor, die du längst verworfen hast; er will Code ändern, den er vor fünf Minuten selbst geschrieben hat; er fragt nach Kontext, der mehrfach durchgekaut wurde. Das ist Context Rot — der Kontext ist so voll und widersprüchlich geworden, dass frische Signale untergehen.
Weitermachen hilft nicht; es wird nur teurer. Die schnellste Lösung ist fast immer ein sauberer Neustart. Claude Code gibt dir dafür die Werkzeuge:
/contextzeigt dir, wie voll das Kontextfenster tatsächlich ist — oft der Auslöser, es zu bemerken./compactfasst die Unterhaltung zusammen und gibt Platz frei, ohne den roten Faden ganz zu verlieren./clearstartet komplett frisch.
Statt eine faulende Sitzung mühsam am Leben zu halten, schreibst du beim Neustart lieber eine kurze Übergabe. Das kostet keine fünf Minuten und ist verlässlicher als das Kopieren des ganzen Verlaufs:
## Kontext
### Ziel
Ein Satz zum Ziel.
### Erledigt
- Datei A: fertig
- Datei B: fertig
### Bereits verworfen
- Ansatz X
- Ansatz Y
### Nächster Schritt
Eine konkrete Aufgabe.Meine persönliche Schwelle: Wenn drei Nachrichten in Folge das Projekt nicht voranbringen, starte ich ohne Zögern neu.
Die Zwei-Korrekturen-Regel
Eng verwandt und mindestens so wertvoll: Wenn du Claude in derselben Unterhaltung zweimal zur selben Sache korrigiert hast, hör auf. Nicht, weil das Modell stur wäre, sondern weil die Unterhaltung ineffizient geworden ist — jede weitere Klarstellung bringt nur noch marginale Besserung, und ihr dreht euch im Kreis.
In fast allen Fällen ist eine von drei Ursachen schuld, und keine löst sich durch die dritte Korrektur:
- Die Aufgabe ist zu groß. Zerlege sie. Drei kleine, klar umrissene Probleme schlägt Claude zuverlässiger als ein verschachteltes großes.
- Das erwartete Ergebnis ist unklar. Beschreibe es nicht — zeig es. Ein konkretes Beispiel schlägt jede abstrakte Anweisung.
- Der Startpunkt ist zu dünn. Statt „bau einen Service" skizzierst du das Interface, definierst die Grenzen oder legst ein grobes Gerüst vor. Claude ist dramatisch verlässlicher darin, eine vorhandene Struktur zu füllen, als eine von Grund auf zu erfinden.
Der klügste Prompt ist manchmal keine weitere Korrektur, sondern der Neuanfang mit besserem Startmaterial.
Aufwand zur Aufgabe passen
Nicht jede Aufgabe verdient dieselbe Denktiefe. Ein Tippfehler braucht keine fünfminütige Planungsphase, eine Datenbankmigration sehr wohl. Auch hier kursiert eine Einstellung, die es nicht gibt: einen Slash-Command /effort sucht man vergeblich. Real sind gleich mehrere Hebel, die zusammenspielen:
- Die
--effort-Flag beim Start steuert die Reasoning-Tiefe über die Stufenlow,medium,high,xhigh,max. - Der Plan Mode (per Shift+Tab durchgeschaltet oder
--permission-mode plan) zwingt Claude, erst zu analysieren und einen Plan vorzulegen, bevor er irgendetwas ändert. - Thinking-Keywords im Prompt („think hard", „ultrathink") vertiefen das Nachdenken punktuell.
- Und die Modellwahl (
/model) ist der gröbste, oft wirksamste Hebel überhaupt.
Grobe Zuordnung:
| Aufwand | Wofür |
|---|---|
| Niedrig — sofort umsetzen, keine Planung | Utility-Skripte, winzige Bugfixes, Wegwerf-Werkzeug |
| Mittel — kurzer Plan, dann Code | Alltags-Features, Routine-Refactoring |
| Hoch — ausführliche Planung vorab | Neue Komponenten, öffentliche APIs, größere Architekturänderungen |
| Maximal — Plan-Modus, Freigabe, dann Umsetzung | Auth, Kern-Infrastruktur, Schema-Migrationen, Sicherheit, produktionskritisches |
Ein netter Nebeneffekt: Schon die Entscheidung, ob eine Aufgabe die maximale Stufe verdient, macht ihr Risiko klarer. Fühlt sich max übertrieben an, ist die Aufgabe kleiner als gedacht — fühlt es sich richtig an, tust du gut daran, langsamer zu machen.
Block 4 — Mehr Perspektiven: Modelle und Subagents
Der letzte Block dreht die Perspektive um. Statt ein Modell nach der „besten" Lösung zu fragen, lässt du mehrere dasselbe Problem aus verschiedenen Blickwinkeln angehen — besonders wertvoll bei teuer umkehrbaren Entscheidungen: Anwendungsarchitektur, Modulgrenzen, Datenbankdesign, Service-Verträge, ereignisgetriebene Systeme, große Refactorings.
Modelle als Review-Panel
Der Trick ist ein Wechsel der Denkweise, kein Feature. Du stellst dieselbe Frage bewusst mit unterschiedlichem Fokus — und, wo sinnvoll, unterschiedlichen Modellen der aktuellen Reihe (Opus 4.8, Sonnet 5, Haiku 4.5, gewechselt per /model):
Entwirf dieses System mit Verlässlichkeit und expliziten Verträgen als oberster Priorität.
Entwirf dasselbe System mit Entwicklungsgeschwindigkeit und Wartbarkeit als Priorität.
Löse dasselbe Problem mit so wenig Komplexität und Abstraktion wie möglich.Die Ergebnisse decken sich selten. Meist entsteht eine konservative Architektur, eine auf Tempo optimierte und eine überraschend elegante, minimalistische Variante. Du suchst dabei keinen Konsens, sondern Trade-offs. Zum Schluss lässt du in einer weiteren Sitzung die stärksten Ideen aus allen Vorschlägen unter deinen Projekt-Randbedingungen synthetisieren. Wer allein arbeitet oder nicht ständig einen zweiten erfahrenen Kopf für Design-Reviews zur Hand hat, kommt damit einem echten architektonischen Resonanzboden erstaunlich nahe.
Subagents — der saubere Weg dorthin
Das manuelle Modell-Panel ist nützlich, aber umständlich. Claude Code hat für genau diese Muster ein eigenes Feature, das viele nicht auf dem Schirm haben: Subagents. Ein Subagent ist eine Markdown-Datei unter .claude/agents/, die mit isoliertem Kontext und optional eigenem Modell eine abgegrenzte Aufgabe übernimmt:
---
name: architecture-critic
description: Unabhängiger Reviewer für Architekturvorschläge
model: opus
---
Du bist ein skeptischer Senior-Architekt. Bewerte den vorgelegten Entwurf
kompromisslos entlang von Trade-offs: Kopplung, Testbarkeit, Betriebskosten,
Reversibilität. Nenne die schwächste Annahme zuerst.Der Gewinn ist doppelt. Erstens läuft ein Subagent in eigenem Kontext — er belastet deine Hauptsitzung nicht mit seinem Wust an Zwischenschritten und wirkt so aktiv gegen Context Rot. Zweitens kannst du mehrere parallel starten, jeden mit anderem Fokus oder Modell, und bekommst echte unabhängige Perspektiven statt einer im selben Kontext gefärbten Meinung. Das Review-Panel von oben wird damit vom manuellen Copy-Paste zum wiederholbaren, sauber getrennten Ablauf — und ist zugleich der bessere Umgang mit begrenztem Kontext.
Fazit
Keine dieser Einstellungen ist kompliziert. Zusammen aber verwandeln sie Claude Code von einem hilfreichen Autovervollständiger in etwas, das einem verlässlichen Teammitglied nahekommt: eine schlanke CLAUDE.md und modulare Skills statt einer Monster-Datei, klare Sicherheitsgrenzen über korrekt verdrahtete Hooks und die echte Settings-Hierarchie, eine bewusste Arbeitsweise gegen Context Rot, und mehr Perspektiven durch Modelle und Subagents.
Die größere Lektion steckt darunter: Die Qualität deines KI-Assistenten hängt nicht allein am Modell, sondern mindestens genauso am System, das du drumherum baust. Investier in dieses System, und der Gewinn summiert sich mit jeder Sitzung. Wer den Sicherheitsteil ernst nehmen und dem Agenten echte Autonomie geben will, findet die dazu passende Isolationsschicht im Beitrag Claude Code im Container.