Hooks gegen Halluzinationen
Sieben konkrete Claude Code Hooks die das Modell daran hindern Sachen zu erfinden, gegen Konventionen zu verstossen oder destructive Befehle auszufuehren.
Halluzinationen sind nicht nur ein Modell-Problem, sie sind ein Tool-Problem. Wenn Claude Code blind auf Files editiert ohne sie vorher gelesen zu haben, oder wenn es einen git push --force auf main wagt weil Du das in einer fruehen Konversation mal erwaehnt hattest, sind das Halluzinations-Folgen die Du mit Hooks vermeiden kannst.
In diesem Playbook gibts sieben Hooks die wir bei StudioMeyer im Einsatz haben. Alle sind copy-paste-bereit und lassen sich einzeln aktivieren. Du brauchst kein Plugin-System, alles laeuft ueber ~/.claude/settings.json und kleine Bash-Scripts in ~/.claude/hooks/.
Stand April 2026, alle Hooks getestet auf Claude Code 2.1.x.
1. Read-before-Edit Guard
Das Problem: Claude Code editiert manchmal Files ohne sie vorher mit dem Read-Tool gesehen zu haben. Stella Laurenzo (AMD AI Director) hat in 6852 Sessions belegt dass die Read-zu-Edit-Ratio von 6.6 auf 2.0 gefallen war, mit 33.7 Prozent blind edits. Das fuehrt zu Files die zerlegt werden weil das Modell die existing Struktur nicht kannte.
Die Loesung: PreToolUse-Hook der Edit/Write blockiert wenn das Ziel-File in der Session noch nicht via Read geladen wurde. Bypass via CLAUDE_SKIP_READ_BEFORE_EDIT=1 Env-Var fuer den Notfall.
In ~/.claude/hooks/read-before-edit.sh (Pattern siehe StudioMeyer-Setup-Doku unter ~/.claude/CLAUDE.md). In ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/read-before-edit.sh" }]
}
]
}
}
Effekt: Modell muss IMMER Read aufrufen bevor es editiert. Halluzinations-Edits gehen auf null.
2. Bash Safety Guard
Das Problem: Claude Code kennt destructive Bash-Befehle und kann sie unter bestimmten Promptings ausfuehren. rm -rf /, git push --force auf main, prisma db push --force-reset, DROP DATABASE sind die haeufigsten Falle.
Die Loesung: PreToolUse-Hook der eine harte Allowlist/Blocklist auf Bash-Commands implementiert. Im Skript:
#!/usr/bin/env bash
# read JSON from stdin (claude code passes hook input here)
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
# Hard blocks
if echo "$cmd" | grep -qE 'rm -rf /(\s|$)|git push.*--force.*(main|master)|prisma db push.*--force-reset|prisma migrate reset|DROP DATABASE'; then
echo "BLOCKED: destructive command pattern" >&2
exit 2
fi
exit 0
In settings.json den gleichen PreToolUse Block aber mit "matcher": "Bash" erweitern. Effekt: Selbst wenn Claude meint einen Force-Push zu brauchen, kommt er nicht durch.
3. Sender-Reputation Guard fuer Mails
Das Problem: Wenn Du Test-Mails ueber SMTP/Brevo/Mailgun schickst und der Empfaenger ist +-tagged auf einer Domain die Plus-Addressing rejected (Yahoo, Outlook, GMX, eigene MX), generierst Du Hard Bounces. Sechs Hard Bounces in einer Session, Sender-Reputation kaputt, alle Mails landen im Spam.
Die Loesung: PreToolUse-Hook der mail-intent Bash-Befehle (curl an Brevo, sendmail, swaks) blockiert wenn die Empfaengeradresse ein gefaehrliches Pattern matched.
# in ~/.claude/hooks/sender-domain-block.sh
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
# Mail-intent + dangerous recipient patterns
if echo "$cmd" | grep -qE 'curl.*api.brevo.com|sendmail|swaks'; then
if echo "$cmd" | grep -qE '\+\w+@(yahoo|outlook|hotmail|gmx|t-online|aol)\.[a-z]{2,3}'; then
echo "BLOCKED: +tag plus-addressing on hard-rejecting provider. Use MAIL_TEST_OK=1 to bypass." >&2
exit 2
fi
fi
exit 0
4. n8n Webhook Side-Effect Guard
Das Problem: n8n-Webhooks sind oft side-effect-heavy. Ein simpler curl https://n8n.studiomeyer.io/webhook/signup triggert real einen Welcome-Mail-Send weil im Workflow ein Brevo-Send-Node sitzt. Das hat im April 2026 fuenf Hard Bounces in einer Session ausgeloest.
Die Loesung: PreToolUse-Hook der jeden POST-Request an n8n.studiomeyer.io/webhook/* blockiert. Inspection via GET auf /api/v1/workflows/{id} bleibt erlaubt.
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
if echo "$cmd" | grep -qE 'curl.*-X *POST.*n8n\.studiomeyer\.io/webhook'; then
echo "BLOCKED: n8n webhook POST. Inspect workflow first via /api/v1/workflows/{id}. Bypass with N8N_TEST_OK=1." >&2
exit 2
fi
5. Reindex-after-Edit Reminder
Das Problem: Du editierst Code-Files, aber der Codebase-Memory-Graph (codebase-memory-mcp) wird nicht automatisch neu indexiert. Spaetere Tool-Calls liefern dann veraltete Daten und das Modell macht Decisions auf der falschen Basis.
Die Loesung: PostToolUse-Hook der nach Edit/Write auf Code-Files (.ts, .tsx, .js, .jsx) eine Reindex-Erinnerung in den Output legt.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [{ "type": "command", "command": "echo 'Reminder: index_repository wenn Code-Aenderung war'" }]
}
]
}
}
Das ist softer als ein Block: Reminder am Output, kein Stop. Wirkt trotzdem, weil das Modell die Reminder list in seinem Context sieht.
6. SessionStart Reminder fuer Memory + Codebase
Das Problem: Neue Sessions starten ohne Memory-Context und ohne Codebase-Index. Das Modell faengt an zu raten statt nachzuschauen.
Die Loesung: SessionStart-Hook der einen Reminder ausgibt:
{
"hooks": {
"SessionStart": [
{
"hooks": [{
"type": "command",
"command": "echo 'PFLICHT: nex_session_start + nex_proactive aufrufen. Bei Code-Arbeit: index_repository + get_architecture.'"
}]
}
]
}
}
Der Hook-Output landet automatisch im System-Context der ersten User-Message. Das Modell sieht es vor jeder Antwort.
7. PreCompact Memory-Snapshot Reminder
Das Problem: Wenn Claude Code den Context auto-compactet (bei langen Sessions), gehen Details verloren die noch nicht in Memory geschrieben wurden. Wenn Du dann fragst "was hatten wir besprochen", kommt nur das was im Compact-Summary war.
Die Loesung: PreCompact-Hook der ans Modell erinnert kurz vor Compact ein nex_summarize zu machen, damit das aktuelle Wissen in Memory landet bevor der Context schrumpft.
{
"hooks": {
"PreCompact": [
{
"hooks": [{
"type": "command",
"command": "echo 'Vor Compact: nex_summarize aufrufen damit aktuelle Decisions/Learnings in Memory landen.'"
}]
}
]
}
}
Aktivierungs-Reihenfolge
Wenn Du diese sieben Hooks neu aufsetzt, geh diese Reihenfolge:
- Read-before-Edit Guard (sofort, hoechster Impact)
- Bash Safety Guard (sofort, schuetzt vor Katastrophen)
- Sender-Reputation + n8n Webhook Guards (wenn Du Mails oder Workflows triggerst)
- SessionStart + PreCompact Reminders (Quality-of-Life, kein Risk)
- Reindex-Reminder (wenn Du codebase-memory-mcp produktiv nutzt)
Jeder Hook ist isoliert, Du musst nicht alle haben. Aber 1 und 2 sind die ohne die ich ehrlich nicht mehr arbeite.
Wo Du die fertigen Skripte findest
Die echten Hook-Implementierungen liegen im StudioMeyer-Setup. Die hier gezeigten Snippets sind didaktisch reduziert. Wenn Du die produktiven Versionen brauchst, schau in ~/.claude/CLAUDE.md (Sektion "Claude Code Hooks") oder in der Doku unter nex-hq/docs/claude/claude-code-setup.md.
Was Du danach hast
Sieben Hooks die zusammen verhindern dass Claude Code Files zerschiesst, destructive Befehle ausfuehrt, Mails ins Aus jagt oder veraltete Codebase-Daten nutzt. Setup-Zeit ist circa 30 Minuten wenn Du copy-paste machst, eine Stunde wenn Du jeden Hook anpasst. Die ersten Wochen werden ein paar Bypasses noetig sein wenn Du legitime Falle blockierst, das justierst Du iterativ.
Alle Halluzinations-Probleme sind dadurch nicht weg. Aber die haeufigsten und teuersten sind catched.