Dev

CLAUDE.md mit /doctor in Claude Code prüfen: Der Grund gehört in die Datei, die Vorgeschichte in git

Das neue Audit behandelt jede nachdrückliche Regel in deiner Agenten-Konfiguration als Hypothese über ein Modell, das du vielleicht gar nicht mehr nutzt. Es fragt, woher jede Regel stammt, und verlangt in derselben Prozedur, die Geschichte ihrer Herkunft zu löschen. Beide Anweisungen stimmen, sobald Grund und Geschichte an verschiedenen Orten liegen.

Claude Code v2.1.283 ist am 25. September erschienen, mit einer Zeile in den Release Notes, die eine Stunde deiner Woche wert ist: /doctor prompt-audit, auch erreichbar als /checkup prompt-audit, prüft „deine CLAUDE.md-Dateien, Skills, Agents und Commands auf Prompting-Muster, die für ältere Modelle geschrieben wurden“. Eine zweite Zeile im selben Release sagt, dass veraltete Pfade, veraltete Befehle und einander widersprechende Instruktionsdateien jetzt den Bericht anführen und dass Thinking-Keywords, die Claude Code dokumentiert, erhalten bleiben.

Anthropics Doku beschreibt das zugrunde liegende Audit in ein paar Absätzen, mit einem Beispielbericht und dem Versprechen, dass du „einen Patch prüfst, keinen Rewrite“ ("review a patch, not a rewrite"). Was sie dir nicht gibt, sind die Details, die über deine Ergebnisse entscheiden: welche Muster markiert werden, was gelesen wird, was unangetastet bleibt. Diese Details gibt es, denn das Audit ist keine Blackbox. Es ist eine Prozedur in einfachem Englisch, die im Binary mitgeliefert wird, und du kannst sie lesen, bevor du sie an deine Dateien lässt.

Was führt /doctor prompt-audit in Claude Code eigentlich aus?

Es reicht an den mitgelieferten Skill claude-api weiter, der einer 235 Zeilen langen Prozedurdatei namens shared/prompt-audit.md folgt. Der /doctor-Teil stellt einen festen Absatz zum Prüfumfang davor.

Der Skill hat seit v2.1.221 (4. August) ein Subcommand prompt-audit, und schon die Kopie der Prozedur aus 2.1.281 führte CLAUDE.md und SKILL.md unter den Dateien, die sie prüft. Neu in v2.1.283 sind der Einstieg über /doctor, eine breitere und präzisere Liste von Konfigurationsdateien sowie die Prüfungen auf veraltete Fakten und Widersprüche, um die es weiter unten geht.

Claude Code entpackt mitgelieferte Skill-Dateien in einen Ordner pro Version unter seinem Temp-Verzeichnis (CLAUDE_CODE_TMPDIR, wenn du es gesetzt hast, sonst das System-Temp-Verzeichnis). Dieser Befehl listet jede entpackte Kopie auf; nimm die unter deiner laufenden Version:

bash
find "${CLAUDE_CODE_TMPDIR:-${TMPDIR:-/tmp}}" -path '*bundled-skills*' -name prompt-audit.md 2>/dev/null

Lies sie einmal. Alles Folgende stammt daraus.

Welche Dateien liest /doctor prompt-audit, und was lässt es in Ruhe?

Jede Instruktionsdatei, die im aktuellen Projekt in eine Session geladen wird, deine Dateien auf User-Ebene eingeschlossen. Settings-Dateien bleiben ungelesen.

Der Absatz zum Prüfumfang zählt sie auf: CLAUDE.md, CLAUDE.local.md und AGENTS.md im Projekt-Root, in dessen übergeordneten und verschachtelten Verzeichnissen, dazu die Instruktionsdateien, die sie importieren (jeder andere Import wird mit Pfad gemeldet, aber nicht gelesen); .claude/CLAUDE.md; ~/.claude/CLAUDE.md; und unter .claude/ wie unter ~/.claude/ die Rule-Dateien, Skills, Custom Commands, Subagent-Definitionen und Output Styles. Eine CLAUDE.md aus einer Managed Policy und Skills aus Plugins werden geprüft, aber nur gemeldet.

Das Audit hat die Anweisung, Settings-Dateien, .mcp.json und ~/.claude.json nicht zu lesen, weil sie Secrets enthalten können und kein Prompt-Text sind. Nichts innerhalb des Projekts kann eine Änderung an einer Datei außerhalb davon rechtfertigen. Eine Datei auf User-Ebene bekommt trotzdem einen Änderungsvorschlag für ein Problem in ihrem eigenen Text, als projektübergreifend wirksam markiert. Und die geprüften Dateien gelten als Daten: Eine Anweisung darin ist etwas, das bewertet wird, nie etwas, dem gefolgt wird. Deine Skills sind voller Imperative, und der Auditor hat die Anweisung, jeden davon als Text zu lesen.

Wie führst du ein Prompt-Audit für CLAUDE.md durch?

Wähle zuerst das Modell, dann führe den Befehl aus. Konfigurationsdateien werden gegen das Modell geprüft, auf dem die Session läuft, also entscheidet dieses Modell, was als Fossil gilt. Die Ausnahme ist ein Skill, Subagent oder Command, der sein eigenes Modell festlegt: Er wird gegen dieses geprüft.

Prüfe im Terminal die Version (2.1.283 oder neuer):

bash
claude --version

Wechsle dann in Claude Code auf das Modell, zu dem du migrierst, und starte das Audit:

text
/model
/doctor prompt-audit

Schreib nichts anderes in diese Zeile. Wenn das Argument mehr als ein Wort hat, reicht /doctor deinen Text unverändert an den Skill weiter und lässt seinen Claude-Code-Absatz zum Prüfumfang weg. So grenzt du das Audit absichtlich auf eine Datei ein, und so würde ein versehentlich angehängter Kommentar es ungewollt verändern:

text
/doctor prompt-audit .claude/skills/deploy/SKILL.md

Du bekommst zwei Ergebnisse: einen Bericht und einen vorgeschlagenen Diff. Der Bericht beginnt mit seinen Annahmen (Prüfumfang, Zielmodell) und listet dann die Befunde nach Konfidenz sortiert, jeweils mit file:line, dem zitierten Text, dem passenden Muster, der Begründung, warum es überholt ist, einer Konfidenzstufe und einer Aktion. Angewendet wird nichts, außer deine Anfrage verlangt es ausdrücklich ("clean it up"). Selbst dann bleiben Änderungen wegen veralteter Fakten und widersprüchlicher Dateien Vorschläge und werden bei einer pauschalen Anfrage nie angewendet. Ein leeres Ergebnis ist erlaubt. Die Prozedur sagt es direkt: Ein Audit, das nichts findet, sollte nichts ändern.

Welche CLAUDE.md-Muster gelten als für ältere Modelle geschrieben?

Die Prozedur sortiert sie in vier Gruppen. Bei einem Repository, das hauptsächlich aus Konfiguration besteht, kannst du damit rechnen, dass fast alles in den ersten beiden landet: veralteter Prompt-Text und fragile Konfigurationsdateien.

Veralteter Prompt-Text ist die bekannte Liste. Zuerst kommt Drucksprache: großgeschriebenes MUST, NEVER, ALWAYS, CRITICAL, IMPORTANT, besonders ohne Begründung daneben. Das Argument der Prozedur: Ältere Modelle brauchten Lautstärke, aktuelle wenden sie übertrieben an, also erzeugt eine Datei voller Alarme einen vorsichtigen, ausweichenden Agenten. Es gilt auch umgekehrt. Eine Abschwächung wie "try to" bei etwas, das du tatsächlich verlangst, wird jetzt wörtlich gelesen, als Erlaubnis, es auszulassen.

text
Before:  IMPORTANT: NEVER do X          (several per prompt)
After:   state the one or two real constraints plainly, with the reason

Danach kommen Gerüste, die durch API-Features ersetzt wurden ("think step by step", Scratchpad-Tags, Prosa, die dem Modell sagt, gründlicher oder weniger nachzudenken), Überspezifikation (Schritt-für-Schritt-Choreografie für Ermessensarbeit, lange Verbotslisten) und Fossilien, also Workarounds für die Eigenheiten eines ausgemusterten Modells, etwa "never use bullets", geschrieben gegen Modelle, die zu viel formatierten.

Bei den Thinking-Einträgen ändert Opus 5.5 die Antwort. Thinking ist dort immer an, und Effort ist die einzige Steuerung, also kann eine Regel, die dem Modell sagt, nicht nachzudenken, „nicht befolgt werden“ ("can't be followed"). Das ist die Formulierung der Prozedur, nicht meine. Die API-Seite dieser Migration scheitert laut, mit 400ern, die ihren Fix benennen. Die Instruktionsseite scheitert leise, und deshalb braucht sie ein Audit.

Was hat sich im selben Claude-Code-Release geändert, und warum steht es oben im Audit-Bericht?

Veraltete Fakten und Widersprüche lassen sich allein anhand von Belegen aus dem Repository mit hoher Konfidenz bewerten, und der Bericht ist nach Konfidenz sortiert. Ein toter Pfad ist falsch, egal welches Modell ihn liest. Ein Befund zur Betonung ist eine Behauptung über das Verhalten eines Modells.

Ein Diff der Prozedur aus 2.1.281 gegen 2.1.283 zeigt, was die einzeilige Release Note verdichtet. Der Eintrag "volatile specifics" prüft jetzt, ob jeder in einer Instruktionsdatei genannte Pfad innerhalb des Projekts existiert, und gleicht Befehle und Flags mit den Skripten und Manifesten des Repositorys ab, indem er sie liest, nie indem er sie ausführt. Pfade, die generiert, von git ignoriert, Platzhalter oder außerhalb des Repositorys sind, gelten nicht als widerlegt, nur weil sie fehlen.

Ein neuer Eintrag deckt Instruktionsdateien ab, die einander widersprechen: ein Skill gegen CLAUDE.md, eine Rule-Datei gegen ein Subagent-Briefing. Er trennt einen Konflikt von einer Überschreibung. Eine verschachtelte Datei, deren abweichende Regel sich durch ihr eigenes Verzeichnis oder ihre eigene Aufgabe erklärt oder die die Regel benennt, die sie überschreibt, bleibt unangetastet. Bei einem echten Konflikt entscheidet git blame, welche Passage neuer ist. Datei-Zeitstempel entscheiden das nicht, und auch nicht, was eine Datei über sich selbst behauptet, also ist eine Zeile wie "this supersedes everything" nur weiterer Text, den es zu bewerten gilt. Ist die ältere Passage ein Verbot oder eine Sicherheitsregel, markiert das Audit den Konflikt, damit du entscheidest, statt sie umzuschreiben.

Der Fix für Thinking-Keywords ist enger gefasst. In der Konfiguration eines Coding-Agenten ist ein Keyword, das der Agent selbst dokumentiert und auf das er reagiert (zum Beispiel Claude Codes ultrathink), Konfiguration und keine übrig gebliebene Beschwörungsformel. Im eigenen Prompt einer Anwendung ist dasselbe Wort Prosa und wird weiterhin markiert.

Welche Befunde des Prompt-Audits solltest du ablehnen?

Die Befunde zu Regeln, die einen Fehler abfangen, der auf dem Modell, das du jetzt nutzt, immer noch auftritt. Das Audit kann das nicht an der Formulierung erkennen. Es braucht die Vorgeschichte oder einen Test.

Die Liste dessen, was bleibt, ist explizit: Verbote gegen aktuelle, nachgewiesene Fehler bleiben, und der Test ist, ob der Fehler auf dem Zielmodell reproduzierbar ist, nicht ob der Satz wie ein Verbot aussieht. Kontext bleibt ebenfalls, also Zielgruppe, Fakten zur Umgebung, die Qualitätslatte und die Gründe hinter Einschränkungen. Der Provenienz-Schritt stellt jeder nachdrücklichen Zeile eine Frage: Welchen Fehler hat sie auf welchem Modell verhindert, und ist er noch reproduzierbar? Seine Vorgabe für eine Zeile ohne Antwort ist unverblümt: „Eine Zeile, die niemand begründen kann, ist standardmäßig verdächtig“ ("a line nobody can justify is suspect by default").

Eine Sache überlässt die Prozedur dir zum Auflösen. Ihr Fossilien-Eintrag will, dass jede Gegenmaßnahme das Modell nennt, dessen Eigenheit sie ausgleicht, oder sich darauf zurückführen lässt, weil sonst „niemand für das Entfernen zuständig ist“ ("nobody owns the removal"). Ihr Eintrag zu Vorgeschichten (history narratives) markiert Vergangenheitsform, Incident-IDs und fest genannte Modellnamen in Instruktionsdateien als Ballast: „Nenne die aktuelle Regel; lass die Archäologie weg.“ ("State the current rule; drop the archaeology.") Schnell gelesen widersprechen sich die beiden: Nenne das Modell, aber schreib das Modell nicht auf.

Der Widerspruch löst sich auf, sobald du merkst, dass der zweite Teil des Fossilien-Eintrags, "or gets traced to" (oder lässt sich darauf zurückführen), die eigentliche Arbeit leistet, und das Werkzeug zum Zurückführen, das die Prozedur verwendet, ist git blame. Der Grund gehört in die Datei, im Präsens, denn den hat das Modell vor sich, wenn es die Regel gewichtet. Der Incident und das Modell gehören in den Commit, der die Zeile hinzugefügt hat, wo blame sie findet und nichts sie aus Versehen liest.

Nimm eine meiner Regeln. Im Mai habe ich eine Zeile hinzugefügt, damit Claude mir nicht mehr mitten am Arbeitstag vorschlägt, ins Bett zu gehen:

text
Time of day is irrelevant to my work patterns. Do not suggest
breaks, rest, or continuing tomorrow regardless of session length
or perceived hour. Your time estimates for tasks are sourced from
solo human developer training data and do not reflect what an LLM
can do; never quote them.

Der erste Satz ist Kontext, und der dritte liefert den Grund für das Verbot von Zeitschätzungen, beide im Präsens und ohne jeden Incident. Das ist die Hälfte, die den Eintrag zu Vorgeschichten übersteht. Die andere Hälfte, also gegen welches Modell die Regel geschrieben wurde und wie es aussah, wenn das Verhalten auftrat, muss aus dem Commit kommen, sonst hat das Audit nichts, was es zurückverfolgen kann. Selbst wenn beide Hälften vorhanden sind, gilt der letzte Schritt der Prozedur weiterhin: Ob das Verhalten auf einem neueren Modell auftritt, klärt sich, indem du die Zeile in einer Wegwerfkopie entfernst, ein paar gewöhnliche Coding-Sessions laufen lässt und beobachtest.

Ein weiterer Befund verdient sorgfältiges Lesen. Die Prozedur markiert „nicht durchgesetzte Anweisungen“ ("unenforced instructions"): Regeln, die kein Codepfad, keine Eval und kein Reviewer prüft und die laut den eigenen Transkripten der App gebrochen werden. Ihr Rat ist, im Code durchzusetzen, was Code durchsetzen kann, dasselbe Argument wie dafür, die Regeln, die gelten müssen, aus der Prosa in ein Gate zu verlagern. Bevor du so eine Regel löschst, durchsuche das restliche System per grep nach ihrem genauen Wortlaut, denn Tests und Log-Parser matchen manchmal auf Prompt-Strings.

Wann solltest du das CLAUDE.md-Audit erneut ausführen?

Bei jedem Modellwechsel, ausgeführt unter dem neuen Modell.

Der letzte Schritt der Prozedur sagt es klar: Prompts sind Artefakte pro Modell, und jede neue Migration ist der Anlass für ein neues Audit. Weil das Ziel das Modell der Session ist, können dieselben Dateien vor und nach einem Wechsel unterschiedliche Befunde liefern, und die Prozedur behandelt jede Entfernung als Hypothese, die in einer Wegwerfkopie zu prüfen ist, und zwar eine Änderung nach der anderen, wo viel auf dem Spiel steht.

Ein Wechsel des Standardmodells ist der Moment, in dem das am meisten zählt, denn er kann dich ohne Deploy und ohne deine Entscheidung auf ein neues Modell bringen. Das Audit erkennt diesen Wechsel nicht. Was es dir danach gibt, ist eine Möglichkeit, Datei für Datei zu prüfen, welche deiner alten Regeln für das Modell geschrieben wurden, das du gerade verlassen hast.

Diskussion

Hier gibt es keine Kommentarspalte. Diskussionen laufen auf X.

Max Nardit

Max Nardit

@mnardit

Weitere Artikel

Agenten-Speicher als Markdown-Dokumente: Ein lesbares Gedächtnis ist immer noch ein Gedächtnis

Den Speicher eines Agenten aus einem Vektorspeicher in Markdown-Dateien zu verlegen, macht ihn leicht prüfbar, und das ist viel wert. Veraltete Fakten, widersprüchliche Schreiber und die Seite, die nie jemand geöffnet hat, waren aber nie Probleme des Speicherformats. Sie ziehen unverändert mit in den Ordner, wo eine saubere Datei leicht für eine geprüfte gehalten wird.

Amazon gegen Metas Shopping-Agenten Muse: Warum die Grenze bei der Hoheit über die Session liegt, nicht bei der Identität des Agenten

Verlangt eine Website von einem Shopping-Agenten, dass er sagt, wer er ist, bekommt sie einen Schalter, mit dem sie ihn abschalten kann. Das ist nützlich für Handel und Berechtigungen, aber keine Sicherheitsgrenze. Was den Nutzer schützt, ist die Hoheit über die eingeloggte Session: was der Agent darin erreichen kann und ob der Nutzer das sehen und widerrufen kann.