Die Fehlfunktionen von Claude Code: Was sein agentischer Workflow falsch macht
Die Fehlfunktionen von Claude Code sind meist Probleme mit Grenzen
Der kostspieligste Fehler von Claude Code, den ich erlebt habe, war keine fehlerhafte Codeänderung. Es war eine korrekte Änderung im falschen Repository-Zustand.
Ein Entwickler bat Claude Code: „Aktualisiere die Authentifizierungs-Middleware und führe die Tests aus.“ Der Arbeitsbaum enthielt bereits eine nicht eingecheckte Migration aus einer anderen Aufgabe. Claude untersuchte genügend Dateien, um die Middleware zu verstehen, änderte die richtige Implementierung, führte einen Formatierer aus und meldete Erfolg. Der entstandene Diff war technisch plausibel, vermischte aber zwei voneinander unabhängige Änderungen und machte die spätere Prüfung nahezu unmöglich.
Das ist die unbequeme Erkenntnis hinter vielen Fehlfunktionen von Claude Code: Das System tut häufig genau das, wozu sein Workflow es anregt. Das Problem ist, dass ein Agent mit Dateisystemzugriff, Shell-Zugriff, Gedächtnis in Anweisungsdateien und einem im Gespräch formulierten Ziel nicht von sich aus die Grenzen respektiert, die Entwickler voraussetzen.
Einige Kritikpunkte beschreiben tatsächliche Produktschwächen. Andere beschreiben bewusste Abwägungen, die gefährlich werden, wenn man sie als unsichtbare Standardeinstellungen behandelt. Die hilfreiche Frage ist nicht, ob Claude Code „autonomer“ oder „weniger autonom“ sein sollte. Sie lautet, wo die Autonomie endet, wie diese Grenze dargestellt wird und ob der Entwickler nachvollziehen kann, was passiert ist.
Die überraschende Standardeinstellung: Kontext bedeutet keine Isolation
Claude Code ist darauf ausgelegt, in einem realen Arbeitsverzeichnis zu arbeiten. Es kann das Repository untersuchen, Dateien bearbeiten, Werkzeuge aufrufen und auf Grundlage von Befehlsausgaben schrittweise weiterarbeiten. Das ist wesentlich nützlicher, als ein Modell anhand eines abstrakten Prompts einen Patch ausgeben zu lassen.
Das bedeutet auch, dass das aktuelle Verzeichnis Teil des effektiven Zustands des Agenten ist.
In der Praxis kann Claude Code auf Folgendes stoßen:
- Nicht eingecheckte Änderungen aus einer anderen Aufgabe
- Generierte Dateien, die maßgeblich wirken
- Lokale Konfiguration, die von der CI abweicht
- Zugangsdaten oder Umgebungsvariablen, die über Werkzeuge zugänglich sind
- Worktrees, verschachtelte Repositorys oder über symbolische Links eingebundene Verzeichnisse
- A
CLAUDE.mdEine Anweisungsdatei, die das Verhalten verändert, ohne im Prompt aufzutauchen - Build-Skripte, die auf das Netzwerk zugreifen oder destruktive Bereinigungen durchführen
Der Agent bemerkt diese Umstände möglicherweise, aber sie zu bemerken ist nicht dasselbe, wie Isolation durchzusetzen. Ein Modell kann sagen: „Ich habe Änderungen gefunden, die nicht zu dieser Aufgabe gehören“, und trotzdem fortfahren, wenn die Anfrage des Nutzers klar erscheint.
Eine disziplinierte Sitzung beginnt mit einer expliziten Zustandsprüfung:
git status --short
git branch --show-current
git diff --stat
pwd
Ich bevorzuge es außerdem, die Grenze bereits im ersten Prompt festzulegen:
Work only on the request in this session. Do not modify existing unrelated changes.
Before editing, report the current branch, dirty files, and the files you intend to change.
Do not commit, reset, checkout, or delete files.
Das wirkt repetitiv, bis eine Sitzung schiefläuft. Anweisungen für Agenten sind keine Zugriffskontrollen. Sie sind Verhaltensvorgaben, und Verhaltensvorgaben wirken probabilistisch.
Die Produktabwägung ist nachvollziehbar: Jede Aufgabe in eine wegwerfbare Sandbox zu zwingen, würde gängige Workflows langsamer und umständlicher machen. Dennoch überträgt die Standardeinstellung dem Nutzer zu viel Verantwortung dafür, den Repository-Zustand vor dem Delegieren zu verstehen.
CLAUDE.md Ist mächtig und deshalb leicht misszuverstehen
Projektanweisungen gehören zu den besten Funktionen von Claude Code. Sie halten Testbefehle, architektonische Einschränkungen, Namenskonventionen und Erwartungen an Reviews einmal fest, statt sie in jedem Prompt zu wiederholen.
Sie schaffen aber auch verborgene Kopplungen.
Ein Repository kann Anweisungen enthalten, die Claude dazu auffordern:
- Einen bestimmten Paketmanager auszuführen
- Ein Verzeichnis gegenüber einem anderen zu bevorzugen
- Snapshots zu aktualisieren
- Änderungen an generierten Dateien zu vermeiden
- Einen Bereitstellungs- oder Datenbankbefehl zu verwenden
- Weitere Anweisungsdateien zu lesen
Der Nutzer sieht die Aufgabe, aber der Agent sieht die Aufgabe zusammen mit einer Anweisungshierarchie. Wenn Sie das Verhalten überrascht, prüfen Sie die tatsächlich wirksamen Anweisungen, statt anzunehmen, das Modell habe den Prompt ignoriert.
Halten Sie Projektanweisungen kurz und handlungsorientiert:
# Repository instructions
- Run `npm test` for the unit suite.
- Run `npm run lint` before describing the work as complete.
- Do not edit files under `generated/`; update the source and regenerate only when requested.
- Never run production deployment commands.
- Preserve unrelated working-tree changes.
Vermeiden Sie vage Ziele wie „Triff immer die beste Architekturentscheidung“ in dieser Datei. Allgemeine Anweisungen erweitern den Ermessensspielraum des Agenten genau dort, wo Sie vorhersehbares Verhalten wünschen.
Kontrollgrenzen: Bestätigung ist kein Sicherheitsmodell
Das Berechtigungssystem von Claude Code bietet nützliche Steuerungsmöglichkeiten, doch man überschätzt leicht, welche Garantien es bietet.
Eine Bestätigungsabfrage beantwortet meist eine eng umrissene Frage: Soll diese Tool-Aktion jetzt ausgeführt werden? Sie beantwortet nicht unbedingt folgende Fragen:
- Ist der Befehl semantisch sicher?
- Hat das Modell die Nebenwirkungen des Befehls verstanden?
- Liegt der Zielpfad innerhalb des vorgesehenen Projekts?
- Wird ein Skript weitere Befehle aufrufen?
- Überträgt der Befehl Quellcode oder Geheimnisse über das Netzwerk?
- Lässt sich die Änderung rückgängig machen?
Ein scheinbar harmloser Befehl kann weitreichendes Verhalten verbergen:
npm run test
Das Skript könnte einen Cache löschen, einen Container starten, auf einen entfernten Dienst zugreifen oder einen Postinstall-Hook ausführen. Claude Code kann um Erlaubnis bitten, den Befehl auszuführen, aber es kann einen Shell-Befehl nicht in eine vollständig verifizierte Grenze für zulässige Aktionen verwandeln.
Berechtigungen auf Projektebene können wiederkehrende Abfragen reduzieren:
{
"permissions": {
"allow": [
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(git diff -- *)"
],
"deny": [
"Bash(rm *)",
"Bash(git reset *)",
"Bash(git checkout *)",
"Read(.env)",
"Read(.env.*)",
"Read(secrets/**)"
]
}
}
Betrachten Sie dies als Dokumentation von Richtlinien und als Verringerung von Reibung, nicht als Sandbox. Muster sollten eng gefasst sein. Die Freigabe von Bash(npm *) ist bequem, erlaubt aber jedes npm-Skript, einschließlich solcher, die Sie möglicherweise nicht geprüft haben.
In der Praxis ergibt sich folgende Aufteilung:
| Grenze | Wobei sie hilft | Was sie nicht löst |
|---|---|---|
| Tool-Bestätigung | Verhindern einer unmittelbar unerwünschten Aktion | Verborgene Auswirkungen innerhalb genehmigter Befehle |
| Berechtigungsregeln | Wiederkehrende, vorhersehbare Richtlinien für die Tool-Nutzung | Semantische Interpretation von Skripten |
| Planung mit rein lesendem Zugriff | Verringern vorschneller Änderungen | Fehlerhafte Analyse oder unbemerkter Repository-Zustand |
| Container oder Worktree | Isolation von Dateisystem und Umgebung | Fehlerhafte Änderungen innerhalb der isolierten Umgebung |
| Menschliche Prüfung | Überprüfen von Absicht und Qualität | Erkennen sämtlicher Nebenwirkungen zur Laufzeit |
| CI-Prüfungen | Reproduzierbare Verifikation | Schutz lokaler Geheimnisse während der Sitzung |
Verwenden Sie für Arbeiten mit weitreichenden Auswirkungen eine Isolation auf Betriebssystemebene: einen temporären Worktree, einen Container, eingeschränkte Zugangsdaten und eine zur Aufgabe passende Netzwerkrichtlinie. Die Berechtigungsabfragen von Claude Code ergänzen diese Schutzmaßnahmen; sie ersetzen sie nicht.
Die Beobachtbarkeit ist schwächer, als das Protokoll vermuten lässt
Ein Agentenprotokoll vermittelt den Eindruck von Nachvollziehbarkeit, weil es Nachrichten wie „Ich werde die Routen prüfen“, Tool-Aufrufe, Befehlsausgaben und eine abschließende Zusammenfassung enthält. Ein solches Protokoll ist jedoch nicht dasselbe wie ein Audit-Log.
Wichtige Fragen, die dabei häufig offenbleiben, sind:
- Welche Dateien wurden gelesen, aber nicht erwähnt?
- Welche Anweisungsdateien haben die Entscheidung beeinflusst?
- Welche Umgebungsvariablen waren genau sichtbar?
- Hat ein Shell-Skript Kindprozesse aufgerufen?
- Welche Befehle haben den Zustand verändert?
- Was hielt das Modell für verifiziert und was lediglich für abgeleitet?
- Wurde ein fehlgeschlagener Befehl mit einer anderen Interpretation erneut ausgeführt?
Claude Code bietet nützliche interaktive Steuerungsmöglichkeiten wie /status, /permissions, /compact, /clear, /rewindund /doctor. Nutzen Sie diese, aber machen Sie sich ihren Geltungsbereich bewusst. Sie helfen Ihnen, die aktuelle Sitzung zu prüfen oder zu verwalten; sie erstellen nicht automatisch eine dauerhafte Änderungsdokumentation, die sich zur Analyse von Vorfällen eignet.
Erstellen Sie für die Arbeit am Repository eine eigene, schlanke Nachweisdokumentation:
git status --short
git diff --name-only
git diff --check
npm test
git diff --stat
Ein Hook kann Regeln für die Tool-Nutzung durchsetzen. Beispielsweise kann ein PreToolUse Hook einen vorgeschlagenen Bash-Befehl prüfen und besonders riskante Operationen ablehnen:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/reject-dangerous.py"
}
]
}
]
}
}
Ein minimaler Hook könnte die vom Hook-Protokoll von Claude Code bereitgestellte Tool-Eingabe lesen und Befehle ablehnen, die bekanntermaßen destruktive Operationen enthalten:
#!/usr/bin/env python3
import json
import sys
event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")
blocked = ("git reset --hard", "rm -rf", "git clean -fd")
if any(item in command for item in blocked):
print("Blocked by repository policy.", file=sys.stderr)
sys.exit(2)
sys.exit(0)
Die genauen Felder der Hook-Ereignisse und die unterstützte Konfiguration können je nach Version von Claude Code variieren. Prüfen Sie daher das lokale Schema, bevor Sie dieses Muster standardisieren. Das wesentliche Gestaltungsprinzip bleibt gleich: Verankern Sie nicht verhandelbare Schutzmaßnahmen in ausführbaren Richtlinien, nicht nur in Fließtext.
Fehlermuster: Der Agent optimiert auf den Abschluss der Aufgabe
Ein Sprachmodell wird durch die Interaktion von Natur aus dafür belohnt, Fortschritte zu erzielen. Wenn Tests fehlschlagen, neigt es dazu, der Ursache nachzugehen. Wenn ein Typfehler auftritt, neigt es dazu, ihn zu beheben. Diese Schleife ist wertvoll, kann aber aus „die angeforderte Änderung umsetzen“ ein „das Repository mit allen lokal plausiblen Mitteln in einen Zustand bringen, in dem alle Prüfungen bestehen“ machen.
Typische Symptome sind:
- Einen Snapshot aktualisieren, statt das Verhalten zu korrigieren
- Eine Test-Assertion erweitern, um eine Regression zu akzeptieren
- Einen Kompatibilitätszweig hinzufügen, ohne dessen Notwendigkeit zu bestätigen
- Generierte Ausgaben direkt ändern
- Einen Formatierer auf nicht betroffene Dateien anwenden
- Einen bestandenen, eng begrenzten Test als Nachweis dafür werten, dass die Funktion vollständig umgesetzt ist
- Einen fehlgeschlagenen Befehl wiederholen, ohne die zugrunde liegende Annahme zu ändern
Die Lösung besteht darin, Abbruchbedingungen zu definieren, nicht nur Ziele:
Implement the parser change.
Run only the parser unit tests first.
Do not modify tests unless a test is demonstrably incorrect.
Do not update snapshots without showing the before/after behavior.
Stop after two failed repair attempts and summarize the failure.
Finish with the exact files changed and commands run.
Dies verringert die Neigung des Agenten, Unsicherheit in weitere Änderungen umzusetzen.
Ein besonders wirksames Muster ist die Ausführung in zwei Phasen:
- Fordern Sie eine Untersuchung und einen Planvorschlag ohne Änderungen an.
- Prüfen Sie die Dateiliste, die Risiken und die Teststrategie.
- Starten Sie einen zweiten Prompt, der die Implementierung innerhalb dieser Grenzen autorisiert.
Planung ist keine Garantie. Sie ist ein Kontrollpunkt, an dem ein Mensch eine falsche Interpretation erkennen kann, bevor daraus ein Diff wird.
Fehlermuster: Kontextkomprimierung verliert operative Details
Lange Sitzungen sind für die Fehlersuche nützlich, erfordern aber irgendwann eine Verdichtung oder Zusammenfassung. Das Modell behält eine komprimierte Darstellung statt jeder vorherigen Tool-Ausgabe. Übergeordnete Ziele bleiben häufig erhalten. Kleine Einschränkungen bleiben nicht immer ebenso gut erhalten.
Daraus ergibt sich ein häufiger Fallstrick: Zu Beginn der Sitzung sagen Sie „Ändere die Migrationsdateien nicht“, später stößt der Agent auf einen fehlgeschlagenen Schematest und schlägt genau das vor.
Für Arbeiten mit wesentlichen Einschränkungen:
- Wiederholen Sie unveränderliche Vorgaben nach
/compact - Halten Sie die aktuelle Dateiliste in einer sichtbaren Arbeitsnotiz oder einem Issue fest
- Verwenden Sie getrennte Sitzungen für voneinander unabhängige Aufgaben
- Bevorzugen Sie eine neue Sitzung gegenüber einer extrem langen, abschweifenden Sitzung
- Führen Sie erneut
git diff --name-onlyaus, bevor Sie das Ergebnis akzeptieren
Die Abwägung ist einfach. Dauerhaft erhaltener Kontext verbessert die Kontinuität, während frischer Kontext die Vorhersehbarkeit verbessert. Keiner der beiden Ansätze ist grundsätzlich überlegen.
Fehlermuster: „Fertig“ bedeutet lokal plausibel
Claude Code kann Tests ausführen, aber die Ausführung von Tests bedeutet nicht, dass diese ausreichend sind. Es kann den schnellsten relevanten Befehl auswählen, Repository-Anweisungen befolgen oder nach einem Befehl aufhören, der ausreichend erscheint. Ein bestandener Test kann lediglich bedeuten, dass ein einzelner Ablauf in einer einzelnen lokalen Umgebung funktioniert hat.
Legen Sie die Verifikation ausdrücklich fest und verlangen Sie Nachweise:
Before finishing:
- Run `git diff --check`.
- Run `npm test -- --runInBand`.
- Report the exact commands and whether each passed.
- Distinguish tests run from tests not run.
- Do not claim production behavior was verified.
Lassen Sie den Agenten bei API-gestützten Systemen die Strukturen von Anfragen und Antworten prüfen, statt sie aus einem Wrapper abzuleiten. Ein minimaler Aufruf der Claude API könnte so aussehen:
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
system="Return JSON only.",
messages=[
{"role": "user", "content": "Classify this event: login_failed"}
],
)
print(response.model_dump_json(indent=2))
Die Antwort enthält strukturierte Inhaltsblöcke, nicht einfach eine Zeichenfolge. Code, der annimmt, dass response.content[0].text immer das vollständige semantische Ergebnis ist, wird fragil, sobald Tool-Nutzung oder mehrere Blöcke Teil des Workflows werden.
Dies ist ein weiteres Abgrenzungsproblem: Die natürlichsprachliche Zusammenfassung des Modells ist kein Schnittstellenvertrag. Parsen Sie strukturierte Ausgaben, validieren Sie sie und bewahren Sie die unverarbeiteten Anfrage-Metadaten auf, wenn die Fehlersuche dies erfordert.
Welche Kritikpunkte sind Produktmängel?
Einige Verhaltensweisen sollten auf Produktebene verbessert werden:
- Wichtige wirksame Anweisungen und Berechtigungen lassen sich mitunter nur schwer auf einen Blick erfassen.
- Eine natürlichsprachliche Abschlusszusammenfassung wird zu leicht mit einer vollständigen Verifikation verwechselt.
- Die Benutzerführung bei Bestätigungsabfragen kann nicht alle Nebenwirkungen beliebiger Shell-Befehle vermitteln.
- Der Zustand langer Sitzungen und die Kontextverdichtung können Einschränkungen weniger sichtbar machen.
- Der Repository-Zustand wird nicht automatisch von anderen, unabhängigen Arbeiten isoliert.
Andere Verhaltensweisen sind eine nachvollziehbare Folge des gewählten Designs:
- Ein Agent, der bearbeiten und ausführen kann, ist nützlicher als ein Assistent, der ausschließlich Patches erstellt.
- Vor jedem risikoarmen Lesezugriff oder Test nachzufragen, würde den Workflow quälend langsam machen.
- Umfassender Repository-Zugriff ermöglicht die Fehlersuche über die Grenzen von Build, Tests und Quellcode hinweg.
- Schrittweise Fehlerbehebung ist für reale Projekte notwendig, bei denen der erste Befehl häufig fehlschlägt.
Die richtige Antwort ist ein mehrschichtiges Vorgehen: eng begrenzte Berechtigungen, kurzlebige Umgebungen für riskante Aufgaben, explizite Prompts, kurze Sitzungen, ausführbare Hooks und mechanische Überprüfung.
Praktische Empfehlungen
- Prüfen Sie
git status, den Branch und den Diff, bevor Sie Claude Code Schreibrechte erteilen. - Behandeln Sie
CLAUDE.mdals ausführbare Projektrichtlinie und halten Sie sie knapp. - Verwenden Sie eng begrenzte
allowunddenyBerechtigungsmuster; verwechseln Sie diese niemals mit Sandboxing. - Implementieren Sie Kontrollen für destruktive Befehle in Hooks oder in der umgebenden Ausführungsumgebung.
- Trennen Sie bei unvertrauten Änderungen oder Änderungen mit weitreichenden Auswirkungen die Planung von der Implementierung.
- Wiederholen Sie kritische Vorgaben nach der Kontextkomprimierung und vor der abschließenden Überprüfung.
- Verlangen Sie genaue Testbefehle und unterscheiden Sie zwischen „nicht ausgeführt“ und „bestanden“.
- Prüfen Sie
git diff --name-only,git diff --checkund den vollständigen Diff vor dem Zusammenführen. - Verwenden Sie Container, eingeschränkte Zugangsdaten oder kurzlebige Worktrees, wenn Nebenwirkungen von Shell-Befehlen relevant sind.
- Betrachten Sie die Autonomie von Claude Code als eine Fähigkeit, die Sie gestalten müssen, nicht als eine Vertrauenseinstellung, die Sie umschalten.
Die zentrale Kritik ist berechtigt: Ein agentischer Workflow lässt Kontrollgrenzen genau dann implizit, wenn sie explizit sein sollten. Das macht den Workflow jedoch nicht unbrauchbar. Es bedeutet, dass erfahrene Teams die fehlenden Grenzen durch Konfiguration, Isolation, Beobachtbarkeit und Überprüfung ergänzen müssen.
Ein API-Schlüssel für Claude Opus 5.5, Sonnet 5, Haiku 4.5 und Fable 5.1 sowie GPT-6 Modelle. Nutzungsbasierte Abrechnung, kein Abonnement.
API-Schlüssel erhalten →