CLAUDE.md: Eine Datei reicht selten, eine lange nie
Eine Auto-generierte CLAUDE.md-File kostet 20 % mehr und liefert 3 % weniger. Was 2026 wirklich reingehört – und wann mehrere besser sind.
Ich habe in meiner „Kennenlernphase“ mit Claude Code eine typisch deutsche CLAUDE.md in meinen Projekten gepflegt: gründlich, vollständig, ordentlich. Tech-Stack ganz oben, Verzeichnisbaum darunter, dazu Coding-Conventions, dann ein Abschnitt mit „Wichtige Hinweise“, in dem alles landete, was Claude in den letzten zwei Wochen falsch gemacht hatte. 270 Zeilen. Sah aus wie ein Onboarding-Dokument für neue Kollegen. Und genau das war das Problem.
Denn CLAUDE.md ist kein Onboarding-Dokument. Sie ist auch keine Doku. Sie ist ein Context-Layer, der bei jeder Session und jedem Turn ins Modell geladen wird. Wer da reinkippt, was er reinkippen will, zahlt zweimal: einmal in Tokens, einmal in Aufmerksamkeit, die Claude nicht mehr auf den eigentlichen Code legt.
Wie eine gute CLAUDE.md heute aussieht, hat sich in den letzten Monaten massiv verschärft. Anthropic baut Memory um, die Forschung liefert harte Zahlen, und im Claude Code CHANGELOG stehen seit Mai 2026 ein paar Einträge, die einen lange schwelenden Verdacht bestätigen. Höchste Zeit für eine ehrliche Bestandsaufnahme.
TL;DR
Die CLAUDE.md wird bei jeder Session und jedem Turn vollständig mitgeladen – sie kostet also dauerhaft Tokens und Aufmerksamkeit, bevor Claude die erste Zeile Code gesehen hat. Schlimmer noch: Modelle befolgen gar nicht alles, was drinsteht. Laut einer Studie über 20 Modelle liegt selbst die Frontier-Klasse bei 500 Instruktionen nur noch bei 68 Prozent Befolgung, und frühe Anweisungen schlagen späte. Das praktische Limit sind rund 150 bis 200 Instruktionen, von denen allein Claude Codes System-Prompt etwa 50 frisst.
Was wirklich reingehört, ist überschaubar. Commands als konkrete CLI-Aufrufe, nicht-default Konventionen, die Claude beim Lesen nicht selbst erkennt, und ein paar Workflow-Nudges. Alles, was ein Linter, Auto Memory oder eine Session ohnehin abdeckt, fliegt raus. Ziel sind unter 200 Zeilen – bei der MEMORY.md ist das seit Mai 2026 sogar hart gekappt.
Mehrere Dateien lohnen in drei Fällen – im Monorepo (eigene Sub-CLAUDE.md pro Paket, lazy geladen), für pfad-spezifische Regeln in .claude/rules/ (deren Frontmatter aktuell quirky ist; globs: läuft zuverlässiger als das dokumentierte paths:) und für lange SOPs, die nach agent_docs/ oder in Skills gehören. Persönliche Präferenzen kommen dagegen nach ~/.claude/CLAUDE.md, nicht ins Projekt-File, das sonst jedes Teammitglied mit den eigenen Macken belästigt.
Anthropic baut Memory gerade zu einem eigenen Subsystem aus, das die CLAUDE.md entlastet. Wer heute noch 600 Zeilen schreibt, arbeitet gegen diese Richtung.
Was CLAUDE.md tatsächlich tut – und was sie kostet
Die Mechanik ist banal und genau deshalb gefährlich, weil sie unterschätzt wird. CLAUDE.md sitzt für die gesamte Session im Kontext. Sie ist nicht evictable, nicht lazy. Eine 5.000-Token-Datei kostet 5.000 Tokens, egal ob du zwei Nachrichten austauschst oder zweihundert. Sabrina Ramonov bringt es in ihrem Post zu CLAUDE.md auf den Punkt: Du wirst auf jeder Interaktion mit der vollen Länge besteuert, bevor Claude überhaupt deinen Code gelesen hat.
Das wäre verkraftbar, wenn Modelle alles befolgen würden, was sie lesen. Tun sie nicht. Die Paper-Arbeit von Jaroslawicz et al. (arXiv:2507.11538) hat über 20 Modelle aus sieben Providern getestet und kommt zu einem unbequemen Ergebnis: Selbst die besten Frontier-Modelle landen bei 500 Instruktionen nur noch bei 68 % Befolgungsgenauigkeit. Mit drei distinkten Degradationsmustern und einem klaren Bias: frühere Instruktionen werden bevorzugt befolgt, spätere tendenziell schlechter. Was am Ende deiner CLAUDE.md steht, wird unzuverlässiger umgesetzt als das, was am Anfang steht.
Die Zahl, die im Anthropic-Umfeld dazu zirkuliert und auf Boris Cherny, Head of Claude Code, zurückgeführt wird: Rund 150 bis 200 Instruktionen sind das Limit, dem Frontier-LLMs zuverlässig folgen. Claude Codes eigener System-Prompt verbraucht davon laut HumanLayers Analyse bereits etwa 50.
Bleiben dir 100 bis 150. Nicht für deinen Tech-Stack. Nicht für deinen Verzeichnisbaum. Sondern für alles, was Claude tatsächlich wissen muss und in einer Session nicht selbst herausfindet.
Was eine moderne CLAUDE.md tatsächlich enthält
Die offizielle Anthropic-Doku unter docs.anthropic.com/en/docs/claude-code/memory nennt mittlerweile ein konkretes Ziel: „target under 200 lines per CLAUDE.md file“. Und seit Mai 2026 ist das nicht mehr nur Empfehlung. Im Claude Code CHANGELOG findet sich der Eintrag, dass die MEMORY.md-Index-Datei jetzt bei 25 KB und 200 Zeilen gekappt wird. Aus „bitte halt dich kurz“ ist eine technische Obergrenze geworden.
Was bleibt also drin? Drei Sachen, sortiert nach abnehmender Wichtigkeit:
Erstens: Commands. Wie testet, baut, typechecked, lintet man dieses Projekt? Welcher Befehl ist der richtige, welcher der falsche? Konkrete CLI-Aufrufe, keine Beschreibungen. Wenn dein Projekt bun statt node verwendet, gehört das hierher.
Zweitens: Nicht-default Konventionen. Alles, was Claude beim Lesen des Codes nicht selbst erkennt. Zustand statt Redux. API-Responses immer im Format { success, data, error }. Named Exports, keine Defaults. Solche Sachen. Aber nur, wenn der Linter sie nicht ohnehin durchsetzt.
Drittens: Workflow-Nudges. „Vor dem Commit immer Typecheck laufen lassen.“ „Lieber einzelne Tests als die ganze Suite.“ Kleine Verhaltens-Stupser, die das Modell in die Lage versetzen, sich selbst zu kontrollieren.
Was draußen bleibt: Code-Style-Regeln, die ein Linter erledigt. Kyle Mistele bringt es trocken auf den Punkt: Schick niemals ein LLM für die Arbeit eines Linters los, LLMs sind im Vergleich zu klassischen Formatern grotesk langsam und teuer. Auch draußen: Code-Snippets, die in drei Wochen veraltet sind, vollständige Verzeichnisbäume, die Claude nach einer Session selbst kennt, und vor allem die langen Listen mit „und übrigens, mach nicht nochmal X“. Die werden vom Modell aktiv ignoriert. Anthropic injiziert vor jeder CLAUDE.md einen System-Reminder, dass der folgende Kontext eventuell irrelevant ist und ignoriert werden soll, wenn er nicht direkt zur Aufgabe passt. HumanLayer hat das per ANTHROPIC_BASE_URL-Logging-Proxy verifiziert. Eine vollgemüllte CLAUDE.md ist also nicht nur teuer, sie wird teilweise gar nicht gelesen.
Die Hierarchie, die kaum jemand richtig nutzt
CLAUDE.md ist nicht eine Datei. Sie ist ein Stapel. Vier Ebenen, alle offiziell dokumentiert:
- Managed Policy
- Pfad:
/Library/Application Support/ClaudeCode/CLAUDE.md (macOS)
/etc/claude-code/CLAUDE.md (Linux)
C:\ProgramData\ClaudeCode\CLAUDE.md (Windows) - Zweck:
Org-weite Policies, nicht ausblendbar - User
- Pfad:
~/.claude/CLAUDE.md (macOS/Linux)
%USERPROFILE%\.claude\CLAUDE.md (Windows) - Zweck:
Persönliche Präferenzen, alle Projekte - Project
- Pfad:
./CLAUDE.md - Zweck:
Team-shared, in Git - Local
- Pfad:
./CLAUDE.local.md - Zweck:
Persönliche Overrides (deprecated, ersetzt durch @-Imports aus ~/)
Beim Session-Start läuft Claude vom aktuellen Verzeichnis nach oben durch den Baum und konkateniert alles, was er findet. Unterordner-CLAUDE.md werden lazy geladen, sobald Claude in dem Subtree arbeitet. Siblings werden nie geladen.
Was das praktisch heißt: Wenn du persönliche Präferenzen hast, wie Claude mit dir reden soll, wie ausführlich er erklären soll, was er nie tun soll, gehört das in ~/.claude/CLAUDE.md, nicht in jede Projekt-CLAUDE.md. Das ist die mit Abstand häufigste Verwechslung, die ich bei mir selbst und bei anderen sehe: persönliche Präferenzen, die im Projekt-File landen und damit jedes Teammitglied mit deinen Macken belästigen.
Wann brauche ich mehrere CLAUDE.md? Drei klare Fälle
Fall eins: Monorepo. Wenn du apps/api/, apps/web/ und packages/shared/ in einem Repo hast, gehört in jedes dieser Verzeichnisse eine eigene, kurze CLAUDE.md, die nur die spezifischen Konventionen für diesen Subtree enthält. Die Root-CLAUDE.md beschreibt dann nur das Repo-Layout in zwei Sätzen und verweist auf die Subdir-Files. Vorteil: Lazy Loading. Arbeitet Claude an der API, lädt er nur apps/api/CLAUDE.md. An der Web-App? Nur apps/web/CLAUDE.md. Du sparst Tokens, das Modell behält den Fokus.
Was hier wichtig ist: Im Mai 2026 wurde ein Bug gefixt, der nested CLAUDE.md in langen Sessions dutzendfach re-injected hat. Sprich: das Problem war real. Eine Zeit lang war Lazy Loading kein Lazy Loading, sondern Spam. Inzwischen funktioniert es, aber die Episode ist eine gute Erinnerung daran, dass Sub-CLAUDE.md keine Theorie sind, sondern produktionsrelevant.
Fall zwei: Pfad-spezifische Regeln, die zu speziell für den Root sind. Hierfür gibt es seit einigen Monaten den offiziellen Mechanismus in .claude/rules/*.md mit YAML-Frontmatter. Die Idee: jede Rule-Datei trägt im Frontmatter ein paths:-Feld mit Glob-Patterns, und die Rule lädt nur, wenn Claude eine passende Datei anfasst. Backend-Regeln im Backend, Frontend-Regeln im Frontend, Test-Konventionen nur wenn Tests editiert werden. So sieht ein realistisches Beispiel aus:
---
paths:
- "src/api/**/*.ts"
- "src/handlers/**/*.ts"
---
# API Conventions
## Request validation
- Every endpoint validates input with Zod before any business logic runs
- Validation errors return HTTP 422, never 400
- Never trust query params or body without parsing through the schema
## Response shape
- Always `{ success: boolean, data: T | null, error: { code, message } | null }`
- HTTP status reflects the outcome category, never embedded in the response body
- Errors include a stable `code` for client-side handling, not just a message
## Auth
- All routes except `/health` and `/auth/*` require a verified JWT
- Use the `requireAuth()` middleware, never check tokens manually in handlers
## Logging
- Log every request with `correlationId` from the `X-Request-Id` header
- Never log request bodies on POST/PUT — they may contain secrets
- Use `logger.error()` only for unexpected failures, not for handled validation errors
## What NOT to do
- Don't add new top-level error shapes — extend the `error.code` enum instead
- Don't bypass the response wrapper for "simple" responses, even health checks use it
- Don't catch errors silently — let them bubble to the global error handlerSo eine Rule lädt nur, wenn Claude eine Datei unter src/api/** oder src/handlers/** öffnet. Im Frontend-Subtree bleibt sie unsichtbar und kostet nichts. Das ist genau der Mechanismus, den eine monolithische CLAUDE.md nicht bieten kann.
Realitäts-Check: Frontmatter ist aktuell quirky. Klingt sauber, ist es in der Praxis aber nur mittel: Mehrere offene Issues im Claude-Code-Repo dokumentieren ein paar unschöne Macken: Die dokumentierte paths:-Syntax als YAML-Liste mit Quotes ("src/api/**/*.ts") lädt in einigen Setups gar nicht, während die undokumentierte globs:-Syntax (globs: src/api/**/*.ts, src/handlers/**/*.ts) zuverlässig funktioniert. In anderen Konfigurationen werden alle .claude/rules/-Dateien global beim Session-Start geladen, unabhängig vom paths:-Feld – Lazy Loading findet dann faktisch nicht statt (Issue #16299). Und Path-Scoped Rules werden bei Write/Create-Operationen nicht in den Kontext injiziert, sondern nur bei Read (Issue #23478) – also genau in dem Moment, in dem Claude eine neue Datei nach deinen Konventionen anlegen soll, weiß er nicht, dass es welche gibt.
Praxis-Empfehlung: Nach jeder Änderung an .claude/rules/ einmal /memory aufrufen und prüfen, was tatsächlich geladen wird. Wenn deine Rule da nicht auftaucht, obwohl du an einer passenden Datei arbeitest, ist es nicht dein Glob-Pattern – es ist der Parser. Workaround in der Issue-Diskussion: globs: statt paths: versuchen, oder unquoted Strings statt YAML-Listen.
Fall drei: lange SOPs und Workflows. Migrations-Playbook, Deployment-Prozess, Datenbank-Schema-Änderungen, das ganze rezeptartige Zeug. Das gehört nicht in CLAUDE.md. Das gehört in agent_docs/ oder in Skills. In der Root-CLAUDE.md steht nur ein Hinweis: „Wenn du an Migrationen arbeitest, lies @docs/migrations.md“. Progressive Disclosure heißt das im Anthropic-Sprech, und es ist die offiziell empfohlene Architektur seit Skills im Q4 2025 als Feature eingeführt wurden.
Wohin die Reise geht: Memory wird first-class
Wer den CHANGELOG der letzten Monate liest, sieht ein klares Muster. Anthropic baut Memory zu einem eigenen Subsystem aus, das CLAUDE.md zunehmend entlastet. Drei Belege:
Erstens: Auto Memory ist seit Claude Code v2.1.59 (26. Februar 2026) Default. Claude schreibt selbst Notizen nach ~/.claude/projects/<project>/memory/. Lädt die ersten 200 Zeilen pro Session. Was bedeutet, dass alles, was Claude in einer Session ohnehin lernt, nicht in CLAUDE.md gehört. Sonst hast du es doppelt.
Zweitens: Der /memory-Command erlaubt jetzt direktes Editieren aller importierten Memory-Files. Memory ist also kein Black-Box-Mechanismus mehr, sondern ein nutzbares Werkzeug. Wer Probleme mit Regeln hat, die Claude scheinbar ignoriert, sollte erstmal /memory aufrufen und prüfen, was tatsächlich im Kontext landet, bevor er die CLAUDE.md weiter aufbläht.
Drittens, und das ist der interessanteste Eintrag: Im Piebald-AI-Repo, das den Claude-Code-System-Prompt mitloggt, taucht seit der Version 2.1.145 (19. Mai 2026) ein eigener Subagent namens „Memory synthesis“ auf. 443 Tokens. Seine Aufgabe: persistente Memory-Files lesen und nur die query-relevanten Teile als JSON zurückgeben, mit zitierten Dateinamen. Mit anderen Worten: Anthropic lädt Memory nicht mehr ungefiltert in den Hauptkontext. Ein Subagent macht vorher Triage.
Das ist eine architektonische Antwort auf das Problem, das wir die ganze Zeit beschreiben. Wer heute eine 600-Zeilen-CLAUDE.md schreibt, kämpft gegen diese Richtung. Wer kurz hält, modular auslagert und sich auf das Wesentliche konzentriert, geht mit ihr.
Mein Take dazu
Ich habe meine aktuelle CLAUDE.md auf 87 Zeilen runtergekürzt. Commands, drei nicht-default Konventionen, zwei Workflow-Nudges, ein Verweis auf agent_docs/. Der Rest sitzt in Skills, in .claude/rules/ mit paths-Frontmatter (mit /memory-Check, ob die Regel tatsächlich greift), in ~/.claude/CLAUDE.md für meine persönlichen Macken. Auto Memory läuft mit, /memory rufe ich alle paar Wochen auf und lösche Duplikate aus dem Projekt-File.
Der Code ist nicht wie durch Zauberhand besser geworden. Aber Claude trifft seltener Entscheidungen, die ich nicht verstehe, weil er weniger widersprüchliche Anweisungen verarbeiten muss. Und die Kosten pro Session sind spürbar runter. Beides war einen Nachmittag Aufräumen wert.
Wenn du heute eine Sache an deiner CLAUDE.md änderst: ruf /memory auf, schau dir an, was tatsächlich in deinem Kontext landet, und frag dich bei jeder Zeile, ob Claude diesen Fehler ohne diese Zeile wirklich machen würde. Wenn nein, raus damit. Was Linter, Auto Memory oder eine Session natürliches Lernen ohnehin abdecken, gehört nicht in deine Instruktionsdatei.
Faustregel zum Mitnehmen: Eine gute CLAUDE.md ist nicht die, die alles abdeckt. Es ist die, die alles weglässt, was Claude auch ohne sie hinkriegt.