← Alle Beitrage

Claude Code Hooks: Warum jeder meiner 95 Hooks existiert

From the guide: Claude Code Comprehensive Guide

Ich habe 95 Hooks für Claude Code gebaut. Jeder existiert, weil zuerst etwas schiefgegangen ist. Der git-safety-guardian existiert, weil Claude einen Force-Push auf main durchgeführt hat. Der recursion-guard existiert, weil ein Subagent unendlich viele Kinder gespawnt hat. Das blog-quality-gate existiert, weil ich einen Beitrag mit 7 Sätzen im Passiv und einer hängenden Fußnote veröffentlicht habe.1

Claude Code Hooks sind Shell-Befehle, die an bestimmten Lifecycle-Punkten ausgeführt werden (Sitzungsstart, vor/nach Werkzeugnutzung, Prompt-Übermittlung und Antwortabschluss) und deterministische Leitplanken auf probabilistisches LLM-Verhalten aufsetzen. Hooks empfangen JSON über stdin und geben Entscheidungen (blockieren, erlauben oder modifizieren) über stdout zurück. Sie setzen Richtlinien durch, etwa das Blockieren von Force-Pushes auf main, das Verhindern rekursiver Agent-Spawns, das Einspeisen von Kontext pro Sitzung und das Kontrollieren der Ausgabequalität, die das LLM allein nicht garantieren kann.

TL;DR

Claude Code Hooks führen Shell-Befehle an bestimmten Lifecycle-Punkten während der KI-gestützten Entwicklung aus. Hooks bieten deterministische Garantien (Blockieren gefährlicher Git-Befehle, Einspeisen von Kontext, Durchsetzen von Qualität) auf einem probabilistischen System (dem LLM). Nachdem ich 95 Hooks über meine Infrastruktur gebaut habe, habe ich festgestellt, dass die besten Hooks aus Vorfällen entstehen, nicht aus Planung. Dieser Beitrag behandelt die Architektur, die Entstehungsgeschichten hinter meinen kritischsten Hooks und die Muster, die ich aus 9 Monaten Hook-Entwicklung gelernt habe.


Die Architektur

Claude Code stellt 26 Lifecycle-Ereignisse bereit, bei denen Hooks das Verhalten abfangen, modifizieren oder blockieren können (Stand v2.1.116, April 2026).2 Meine Hooks zielen auf sechs der häufigsten ab:

Sitzungsereignisse

Ereignis Wann es auslöst Meine Hooks
SessionStart Neue Sitzung beginnt session-start.sh: speist Datum ein, validiert venv, initialisiert Rekursionsstatus
SessionEnd Sitzung wird beendet Bereinigt temporäre Dateien

Werkzeugausführungsereignisse

Ereignis Wann es auslöst Meine Hooks
PreToolUse Vor der Ausführung eines Werkzeugs git-safety-guardian.sh, recursion-guard.sh, credentials-check.sh
PostToolUse Nach Abschluss des Werkzeugs post-deliberation.sh, log-bash.sh

Antwortereignisse

Ereignis Wann es auslöst Meine Hooks
UserPromptSubmit Benutzer sendet einen Prompt Kontext-Injektoren (Datum, Branch, Modellinformationen)
Stop Claude beendet die Antwort deliberation-pride-check.sh, reviewer-stop-gate.sh

Jeder Hook empfängt JSON über stdin und kommuniziert über stdout:

{"decision": "block", "reason": "Force push to main is prohibited"}

Oder erlaubt stillschweigend, indem er mit Code 0 beendet wird.3


Entstehungsgeschichten: Die Hooks, die am wichtigsten sind

Hook 1: git-safety-guardian.sh (PreToolUse:Bash)

Der Vorfall: Während einer frühen Claude Code-Sitzung bat ich den Agenten, „den Git-Verlauf aufzuräumen”. Der Agent führte git push --force origin main aus. Der Force-Push überschrieb drei Tage Commits auf einem gemeinsamen Branch. Ich konnte aus einem lokalen Backup wiederherstellen, aber der 4-stündige Wiederherstellungsprozess überzeugte mich davon, dass probabilistisches Urteilsvermögen niemals destruktive Git-Operationen steuern sollte.

Der Hook:

#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# Only check git commands
echo "$COMMAND" | grep -qE '\bgit\b' || exit 0

# Block force push to main/master
if echo "$COMMAND" | grep -qiE 'git\s+push\s+.*--force.*\b(main|master)\b'; then
    cat << EOF
{"decision": "block", "reason": "Force push to main/master blocked by safety hook"}
EOF
fi

Die Lektion: Der Hook versucht nicht, die Absicht zu verstehen. Er gleicht Muster am Befehlsstring ab. Einfach, deterministisch, unmöglich durch geschicktes Prompten zu umgehen. Der Agent kann immer noch Force-Pushes auf Feature-Branches durchführen (manchmal legitim), aber main/master sind dauerhaft geschützt.4

Lebenszeit-Rettungen: 8 abgefangene Force-Push-Versuche in 9 Monaten.

Hook 2: recursion-guard.sh (PreToolUse:Task)

Der Vorfall: Beim Aufbau des Deliberations-Systems ließ ich eine Sitzung laufen, die 3 Erkundungs-Subagenten spawnte. Jeder Subagent spawnte, ohne Spawn-Limits, seinerseits eigene Subagenten. Die Rekursion verbrauchte API-Tokens mit der 10-fachen normalen Rate. Ich beendete die Sitzung manuell, nachdem ich den beschleunigten Token-Verbrauch bemerkte.

Der Hook:

#!/bin/bash
CONFIG_FILE="${HOME}/.claude/configs/recursion-limits.json"
STATE_FILE="${HOME}/.claude/state/recursion-depth.json"

MAX_DEPTH=2
MAX_CHILDREN=5
DELIB_SPAWN_BUDGET=2
DELIB_MAX_AGENTS=12

# Validate integers safely (((VAR++)) crashes with set -e when VAR=0)
is_positive_int() {
    [[ "$1" =~ ^[0-9]+$ ]] && [[ "$1" -gt 0 ]]
}

Die zentrale Designentscheidung: Agenten erben ein Spawn-Budget von ihrem Eltern-Agenten, anstatt die Tiefe zu erhöhen. Ein Root-Agent mit Budget=12 kann dieses Budget über jede Baumform verteilen. Tiefenbasierte Limits sind zu starr (sie verhindern tiefe, aber schmale Ketten, die vollkommen sicher sind).5

Lebenszeit-Blockierungen: 23 außer Kontrolle geratene Spawn-Versuche.

Hook 3: blog-quality-gate.sh (Stop)

Der Vorfall: Ich veröffentlichte einen Blogbeitrag mit 7 Sätzen im Passiv, einer im Text referenzierten, aber im Quellenverzeichnis fehlenden Fußnote und „wurde vom Team implementiert” als Eröffnungszeile. Der Beitrag sah in meinem Editor poliert aus, scheiterte aber an grundlegenden Qualitätsprüfungen, die jeder menschliche Gutachter erkennen würde.

Der Hook: Führt meinen 12-Modul-Blog-Linter auf jeder modifizierten Blog-Inhaltsdatei aus. Prüft auf Passivkonstruktionen, hängende Fußnoten, fehlende Meta-Beschreibungen, nicht getaggte Codeblöcke und Zitier-Integrität. Jeder Befund ist spezifisch: „Zeile 47: Passivkonstruktion erkannt in ‚wurde vom Team implementiert’. Vorschlag: ‚das Team implementierte’.”

Die Parallele zum menschlichen Feedback: Der Hook kritisiert die Arbeit, nicht den Bediener. Er sagt „Zeile 47 enthält Passiv”, nicht „Sie schreiben schlecht”. Dasselbe Prinzip, das menschliches Feedback konstruktiv macht, macht automatisiertes Feedback nützlich.


Das Muster hinter 95 Hooks

Die konfigurationsgesteuerte Architektur

Meine Hooks entwickelten sich von fest codierten Werten zu konfigurationsgesteuertem Verhalten:

~/.claude/configs/
├── recursion-limits.json     # Depth, spawn budgets, timeouts
├── deliberation-config.json  # Consensus thresholds per task type
├── consensus-profiles.json   # security=85%, docs=50%
├── circuit-breaker.json      # Failure mode configurations
└── file-scope-rules.json     # Path-scoped hook application

Das Verschieben von Schwellenwerten in JSON-Konfigurationen bedeutete, dass ich das Verhalten anpassen konnte, ohne Bash-Skripte zu bearbeiten. Als ich sicherheitsbezogenen Konsens bei 85 %, aber Dokumentation bei 50 % benötigte, dauerte die Konfigurationsänderung 30 Sekunden. Eine Codeänderung hätte Bearbeitung, Testen und erneutes Deployen erfordert.6

Das Lifecycle-Schichtungsmuster

Meine 95 Hooks bilden ein Sicherheitsnetz mit vier Schichten:

Schicht 1: Prävention (PreToolUse): Schlimmes verhindern, bevor es passiert. git-safety-guardian, credentials-check, recursion-guard.

Schicht 2: Kontext (UserPromptSubmit, SessionStart): Informationen einspeisen, die der Agent benötigt. Datum, Branch, Projektkontext, Speichereinträge, Philosophieprinzipien.

Schicht 3: Validierung (PostToolUse): Überprüfen, ob abgeschlossene Aktionen die Standards erfüllen. Post-Deliberation-Konsensprüfung, Ausgabe-Logging.

Schicht 4: Qualität (Stop): Die finale Ausgabe kontrollieren. Pride Check, Quality Gate, Reviewer Stop Gate. Diese Schicht implementiert metakognitive Überwachung, bei der der Agent die Qualität seines eigenen Denkens bewertet, nicht nur seiner Ausgabe.

Jede Schicht ist unabhängig. Wenn ein PreToolUse-Hook stillschweigend versagt, erkennt der Stop-Hook dennoch Qualitätsprobleme. Defense in Depth, angewandt auf das Verhalten von KI-Agenten.


Konfiguration

Hooks leben in .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "command": "~/.claude/hooks/git-safety-guardian.sh",
        "timeout": 5000
      }
    ],
    "PreToolUse:Task": [
      {
        "command": "~/.claude/hooks/recursion-guard.sh"
      }
    ]
  }
}

Das Feld matcher filtert, welche Werkzeuge den Hook auslösen. PreToolUse:Task ist Kurzschrift für einen Matcher, der nur bei Aufrufen des Task-Werkzeugs auslöst. Asynchrone Hooks (async: true) laufen im Hintergrund, ohne zu blockieren.7

Scope-Hierarchie

  1. Benutzerebene (~/.claude/settings.json): gilt für alle Projekte. Meine 95 Hooks leben hier.
  2. Projektebene (.claude/settings.json): fügt projektspezifische Hooks hinzu.
  3. Skill-/Subagent-Frontmatter: beschränkt auf den Lifecycle einer bestimmten Komponente.8

Was ich anders machen würde

Mit 3 Hooks beginnen, nicht mit 25. Mein erster Monat produzierte 25 Hooks, von denen viele Kontext hinzufügten, den der Agent bereits hatte. Der Overhead, 25 Hooks bei jedem Werkzeugaufruf zu laden, war messbar. Ich beschnitt schließlich auf die Hooks, die echten Wert produzierten (reale Vorfälle verhinderten, reale Qualitätsprobleme abfingen).

Konfigurationsgesteuert vom ersten Tag an. Ich verbrachte zwei Wochen damit, fest codierte Schwellenwerte in JSON-Konfigurationen umzugestalten. Diese Umgestaltung wäre kostenlos gewesen, wenn ich mit Konfigurationen begonnen hätte.

Test-Infrastruktur frühzeitig. Die ersten 20 Hooks hatten keine Tests. Als ich das Test-Harness (48 Bash-Integrationstests) hinzufügte, fand ich 3 Hooks, die bei Grenzfällen stillschweigend versagten. Tests hätten mit Hook #1 mitgeliefert werden sollen.


Wichtigste Erkenntnisse

Für Entwickler, die mit Hooks beginnen: - Beginnen Sie mit drei Hooks: Git-Sicherheit (PreToolUse:Bash), Kontext-Injektion (UserPromptSubmit) und Quality Gate (Stop); fügen Sie weitere nur hinzu, wenn Sie Vorfälle haben, die sie rechtfertigen - Nutzen Sie das Decision-Timing-Framework: Die Hook-Architektur ist unumkehrbar (95 Hooks hängen davon ab), investieren Sie also in das Lifecycle-Modell, bevor Sie Hooks schreiben

Für Teams, die Hooks standardisieren: - Standardisieren Sie Hooks auf Benutzerebene, damit jedes Teammitglied dieselben Sicherheitsgeländer erhält - Verfolgen Sie Hook-Metriken (blockierte Operationen, abgefangene Vorfälle), um die Wartungskosten zu rechtfertigen - Überprüfen Sie Hook-Logs monatlich, um neue automatisierungswürdige Muster zu identifizieren


FAQ

Was sind Claude Code Hooks?

Hooks sind Shell-Skripte, die an bestimmten Lifecycle-Punkten während Claude Code-Sitzungen ausgeführt werden. Sie lösen deterministisch zu bestimmten Zeitpunkten aus: bevor ein Werkzeug läuft (PreToolUse), nachdem es abgeschlossen ist (PostToolUse), wenn Sie einen Prompt senden (UserPromptSubmit), wenn eine Sitzung beginnt (SessionStart) und wenn Claude die Antwort beendet (Stop). Hooks empfangen JSON über stdin mit vollem Kontext (Werkzeugname, Eingabe, Sitzungs-ID) und können Operationen blockieren, Kontext einspeisen oder Quality Gates durchsetzen. Sie bieten deterministische Garantien auf einem probabilistischen LLM.

Wie viele Hooks kann Claude Code ausführen und gibt es Leistungskosten?

Es gibt keine feste Obergrenze für die Anzahl der Hooks. Ich betreibe 95 Hooks über 6 der 26 verfügbaren Lifecycle-Ereignisse (Stand v2.1.116, April 2026), mit etwa 200 ms Gesamtoverhead pro Ereignis. Die praktische Grenze ist die Latenz: Jeder Hook fügt Ausführungszeit vor oder nach Werkzeugaufrufen hinzu. Die zentrale Optimierung ist die Verwendung von Dispatchern (einer pro Ereignis, der Hooks sequenziell aus gecachtem stdin ausführt) anstelle unabhängiger Hooks, die jeweils stdin separat lesen. Gleichzeitige Schreibvorgänge von unabhängigen Hooks verursachten JSON-Korruption in meinem frühen Setup; Dispatcher eliminierten diesen Fehlermodus vollständig.

Bei welchen Ereignissen lösen Claude Code Hooks aus?

Claude Code stellt 26 Lifecycle-Ereignisse für Hooks bereit (Stand v2.1.116, April 2026). Die sechs häufigsten, auf die meine Hooks abzielen, sind: SessionStart (neue Sitzung beginnt), SessionEnd (Sitzung wird beendet), PreToolUse (vor der Ausführung eines Werkzeugs), PostToolUse (nach Abschluss des Werkzeugs), UserPromptSubmit (Benutzer sendet einen Prompt) und Stop (Claude beendet die Antwort). Weitere umfassen SubagentStart, PermissionRequest, PermissionDenied, TaskCreated, CwdChanged, FileChanged, PreCompact und mehr. PreToolUse und PostToolUse können mit Matchern wie PreToolUse:Bash oder PreToolUse:Task weiter eingegrenzt werden, um nur bei bestimmten Werkzeugtypen auszulösen. Jedes Ereignis empfängt JSON über stdin mit relevantem Kontext.

Können Claude Code Hooks Werkzeugaufrufe blockieren?

Ja. Ein Hook, der {"decision": "block", "reason": "explanation"} an stdout ausgibt, verhindert die Ausführung des Werkzeugaufrufs. Dies ist der zentrale Mechanismus für Sicherheits-Hooks: Mein git-safety-guardian blockiert Force-Pushes auf main, mein credentials-check blockiert das Lesen von .env-Dateien, und mein recursion-guard blockiert übermäßiges Agent-Spawning. Die Blockierung ist deterministisch und kann nicht durch Prompting umgangen werden. Hooks, die stillschweigend mit Code 0 beendet werden, erlauben das Fortfahren der Operation.

Was ist der Unterschied zwischen PreToolUse- und PostToolUse-Hooks?

PreToolUse löst aus, bevor ein Werkzeug ausgeführt wird, und kann die Operation vollständig blockieren. Verwenden Sie es für Sicherheits-Gates: Blockieren gefährlicher Befehle, Prüfen von Anmeldedaten, Durchsetzen von Spawn-Budgets. PostToolUse löst aus, nachdem ein Werkzeug abgeschlossen ist, und kann Feedback liefern oder Folgeaktionen auslösen. Verwenden Sie es zur Validierung: Prüfen der Ausgabequalität, Aktivitätsprotokollierung, Konsensverifikation. Zusammen bilden sie die erste und dritte Schicht eines vierschichtigen Sicherheitsnetzes: Prävention (PreToolUse), Kontext-Injektion (UserPromptSubmit), Validierung (PostToolUse) und Qualitätskontrolle (Stop).

References


  1. Author’s hook infrastructure. 95 hooks across 6 of the 26 available lifecycle events (v2.1.116, April 2026), developed over 9 months (2025-2026). 

  2. Anthropic, “Claude Code Hooks Reference,” 2026. 26 lifecycle event types as of v2.1.116 (April 2026). 

  3. Anthropic, “Claude Code Documentation,” 2025. Hook input/output JSON format. 

  4. Author’s git-safety-guardian.sh. 8 intercepted force-push attempts tracked in ~/.claude/state/

  5. Author’s recursion-guard.sh. Budget inheritance model documented in ~/.claude/configs/recursion-limits.json

  6. Author’s config-driven architecture. 14 JSON config files encoding all hook thresholds and rules. 

  7. Anthropic, “Claude Code Documentation,” 2025. Hook configuration and async execution. 

  8. Anthropic, “Claude Code Documentation,” 2025. Hook scope hierarchy. 

Verwandte Beiträge

Eigene Skills für Claude Code erstellen: Ein vollständiges Tutorial

Ein Code-Review-Skill von Grund auf bauen. Verzeichnisstruktur, Frontmatter-Felder, LLM-basiertes Matching, Kontext-Budg…

11 Min. Lesezeit

Kontextfenster-Management: Was mich 50 Sitzungen über KI-Entwicklung gelehrt haben

Ich habe den Token-Verbrauch über 50 Claude Code-Sitzungen hinweg gemessen. Kontexterschöpfung verschlechtert die Ausgab…

6 Min. Lesezeit

Claude Code Hooks Tutorial: 5 produktionsreife Hooks von Grund auf

Erstellen Sie 5 praktische Claude Code Hooks von Grund auf: Auto-Formatierung, Sicherheits-Gates, Test-Runner, Benachric…

8 Min. Lesezeit