# Hooks: Automatische Leitplanken für deinen Agenten

> Lerne, wie du mit Hooks in Claude Code automatische Leitplanken einziehst — Linter nach jeder Änderung, Schutz vor destruktiven Befehlen, Events wie PreToolUse und PostToolUse.

- URL: https://thevibe-coding.de/kurs/hooks-automatische-leitplanken
- Typ: kurs | Veroeffentlicht: 2026-07-17 | Aktualisiert: 2026-07-17
- Autor: VIBE CODING | Site: VIBE CODING — thevibe-coding.de

---

# Hooks: Automatische Leitplanken für deinen Agenten

"Bitte lass nach jeder Änderung den Linter laufen" — steht in deiner CLAUDE.md, und trotzdem vergisst Claude es in jeder dritten Session. Der Grund ist simpel: Anweisungen im Kontext sind **Bitten**. Das Modell befolgt sie meistens. Meistens reicht aber nicht, wenn dein Content-Bot nachts unbeaufsichtigt läuft.

Für alles, was **immer** passieren muss, gibt es Hooks: Shell-Kommandos, die Claude Code selbst ausführt — automatisch, bei jedem passenden Ereignis, ohne dass das Modell mitentscheiden darf.

## Was Hooks sind

Ein Hook ist ein Eintrag in der `settings.json` deines Projekts (`.claude/settings.json`) unter dem Schlüssel `"hooks"`. Du legst fest: Bei **welchem Ereignis** soll **welches Kommando** laufen. Claude Code führt es dann verlässlich aus — das Modell kann es weder vergessen noch überspringen.

Die wichtigsten Ereignisse:

| Event | Wann es feuert | Typischer Einsatz |
|-------|----------------|-------------------|
| `PreToolUse` | Bevor Claude ein Werkzeug nutzt | Gefährliche Befehle blockieren |
| `PostToolUse` | Nachdem ein Werkzeug gelaufen ist | Linter/Formatter nach Dateiänderungen |
| `SessionStart` | Beim Start einer Session | Umgebung prüfen, Status laden |
| `Stop` | Wenn Claude fertig ist | Abschluss-Checks, Benachrichtigungen |

Ein `PreToolUse`-Hook kann eine Aktion sogar **verhindern**: Beendet sich dein Kommando mit Exit-Code 2, wird das Werkzeug blockiert und Claude bekommt deine Fehlermeldung als Feedback.

## Beispiel 1: Linter nach jeder Dateiänderung

Zurück zur Content-Fabrik. Dein Bot-Projekt hat ESLint konfiguriert, und du willst, dass jede von Claude geänderte Datei sofort geprüft wird — nicht erst, wenn der Bot nachts mit einem Syntaxfehler abstürzt.

In `.claude/settings.json`:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --no-warn-ignored \"$CLAUDE_PROJECT_DIR\""
          }
        ]
      }
    ]
  }
}
```

Was hier passiert:

- `"PostToolUse"` — der Hook feuert **nach** jedem Werkzeug-Einsatz
- `"matcher": "Edit|Write"` — aber nur bei den Werkzeugen, die Dateien ändern
- `"command"` — das Shell-Kommando; `$CLAUDE_PROJECT_DIR` zeigt auf dein Projektverzeichnis

Meldet ESLint einen Fehler, sieht Claude die Ausgabe direkt und korrigiert nach — noch in derselben Session, ohne dass du es anstoßen musst. Aus "bitte denk an den Linter" wird ein Regelkreis, der sich selbst schließt.

## Beispiel 2: Warnung vor destruktiven Befehlen

Dein Bot-Projekt enthält eine `queue.json` mit allen geplanten Posts und eine `.env` mit dem Bot-Token. Beides darf niemals einem übermütigen Aufräum-Befehl zum Opfer fallen. Ein `PreToolUse`-Hook prüft jeden Bash-Befehl, bevor er läuft:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard.sh"
          }
        ]
      }
    ]
  }
}
```

Im Skript `.claude/hooks/guard.sh` steckt die eigentliche Logik: Der Hook liest den geplanten Befehl aus der Hook-Eingabe (Claude Code übergibt sie als JSON auf stdin) und blockiert, was gefährlich aussieht:

```bash
#!/bin/bash
befehl=$(jq -r '.tool_input.command // ""')

if echo "$befehl" | grep -qE 'rm -rf|queue\.json|\.env'; then
  echo "Blockiert: Befehl beruehrt geschuetzte Dateien ($befehl)" >&2
  exit 2
fi

exit 0
```

Exit-Code 2 heißt: Werkzeug-Aufruf abgebrochen, Fehlermeldung geht an Claude. Der Agent muss sich einen anderen Weg suchen — oder dich fragen. Exit-Code 0 heißt: freie Fahrt. Vergiss nicht, das Skript ausführbar zu machen (`chmod +x .claude/hooks/guard.sh`).

Ein Hinweis zur Ehrlichkeit: Ein simpler Muster-Filter ist eine Leitplanke, kein Panzerglas. Kreative Umwege fängt er nicht alle ab. Für die typischen Unfälle — versehentliches Löschen, hastiges Überschreiben — reicht er trotzdem erstaunlich weit.

## Hook oder Skill? Die Abgrenzung

Beide leben im `.claude/`-Ordner, beide automatisieren — und trotzdem sind sie Gegensätze:

| | Skill | Hook |
|---|---|---|
| Was ist es? | Wissen und Anleitungen für das Modell | Shell-Kommando, vom System ausgeführt |
| Wer entscheidet? | Claude (wendet an, wenn es passt) | Niemand — läuft **immer** beim Event |
| Kann vergessen werden? | Ja, wie jede Anweisung | Nein, wird erzwungen |
| Typischer Einsatz | "So schreibst du einen Post" | "Nach jedem Edit läuft der Linter" |

Merksatz: **Skill = Wissen fürs Modell. Hook = Gesetz vom System.** Alles, was verhandelbar ist (Stil, Vorgehen, Prozesswissen), gehört in [Skills](/kurs/super-powers). Alles, was nicht verhandelbar ist (Qualitäts-Checks, Schutzregeln), gehört in Hooks.

Die Kombination macht den Unterschied: Der Skill erklärt Claude, *wie* gute Arbeit aussieht. Der Hook stellt sicher, dass schlechte Arbeit *nicht durchkommt*. In der [5-Phasen-Pipeline](/kurs/fuenf-phasen-pipeline) heißt das: Skills treiben die Phasen, Hooks bewachen die Übergänge.

## Drei Regeln für gute Hooks

**Regel 1: Schnell bleiben.** Ein `PostToolUse`-Hook läuft nach *jeder* passenden Aktion. Ein Linter, der 30 Sekunden braucht, bremst jede Session aus. Prüfe wenn möglich nur die geänderte Datei statt des ganzen Projekts, und miss die Laufzeit, bevor du einen Hook dauerhaft aktivierst.

**Regel 2: Laut scheitern, leise durchwinken.** Wenn alles in Ordnung ist, soll der Hook still sein (Exit-Code 0, keine Ausgabe). Wenn etwas schiefläuft, soll die Fehlermeldung konkret sein — "Blockiert: Befehl berührt queue.json" hilft Claude beim Umplanen, ein nacktes "Error" hilft niemandem.

**Regel 3: Hooks sind Code — behandle sie so.** Die `settings.json` und deine Hook-Skripte gehören ins Git-Repository, damit jede Session (und jedes Teammitglied) dieselben Leitplanken hat. Nach jeder Änderung an einem Hook gilt: einmal absichtlich den Fehlerfall auslösen und prüfen, ob die Leitplanke wirklich greift.

## Übung: Deine erste Leitplanke

Zieh die Linter-Leitplanke in dein Bot-Projekt ein:

1. Lege `.claude/settings.json` mit dem `PostToolUse`-Hook aus Beispiel 1 an (falls die Datei existiert, ergänze nur den `"hooks"`-Block)
2. Starte eine neue Claude-Code-Session und lass Claude eine kleine Änderung an deinem Bot-Code machen
3. Beobachte die Ausgabe: Läuft ESLint automatisch nach der Änderung?
4. Der Härtetest: Bitte Claude, absichtlich eine Datei mit einem Fehler zu schreiben (etwa einer ungenutzten Variable). Greift der Hook? Korrigiert Claude von selbst nach?

**Bonus:** Baue den Guard aus Beispiel 2 ein und bitte Claude testweise, `queue.json` zu löschen. Wenn die Blockade greift und Claude höflich ablehnt statt zu löschen, hast du alles richtig gemacht.

## Zusammenfassung

- **Hooks** sind Shell-Kommandos in der `settings.json` unter `"hooks"` — vom System ausgeführt, nicht vom Modell entschieden
- Die wichtigsten Events: `PreToolUse` (vorher, kann blockieren), `PostToolUse` (nachher, ideal für Linter), `SessionStart` und `Stop`
- **Exit-Code 2** in einem `PreToolUse`-Hook blockiert die Aktion und gibt Claude deine Begründung als Feedback
- Praktische Leitplanken für die Content-Fabrik: Linter nach jeder Dateiänderung, Guard vor destruktiven Befehlen auf `queue.json` und `.env`
- Abgrenzung: **Skill = Wissen fürs Modell** (kann ignoriert werden), **Hook = erzwungene Regel vom System** (kann es nicht)

Mit Subagenten und Hooks hast du jetzt beides: ein Team, das für dich arbeitet, und Leitplanken, die es auf Kurs halten. Zeit für den Blick zurück und nach vorn: [Fazit und Ausblick](/kurs/fazit-und-ausblick).
