← Alle Playbooks
Playbook· setup

Hooks gegen Halluzinationen

Sieben konkrete Claude Code Hooks die das Modell daran hindern Sachen zu erfinden, gegen Konventionen zu verstossen oder destructive Befehle auszufuehren.

30 min

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:

  1. Read-before-Edit Guard (sofort, hoechster Impact)
  2. Bash Safety Guard (sofort, schuetzt vor Katastrophen)
  3. Sender-Reputation + n8n Webhook Guards (wenn Du Mails oder Workflows triggerst)
  4. SessionStart + PreCompact Reminders (Quality-of-Life, kein Risk)
  5. 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.