Selbstvalidierende Claude Code Agenten
Selbstvalidierende Claude Code Agenten: PostToolUse-Lint-Hooks, Stop-Hooks und schreibgeschützte Reviewer-Subagenten in Agentendefinitionen verdrahten, damit fehlerhafte Ausgaben nie ausgeliefert werden.
Hören Sie auf zu konfigurieren. Fangen Sie an zu bauen.
SaaS-Builder-Vorlagen mit KI-Orchestrierung.
Problem: Ein Agent liefert Arbeit ab, die auf den ersten Blick gut aussieht. Dann schreit der Linter, ein Export fehlt, und eine ganze Datei wurde übersprungen. Du siehst es erst beim Review, zwanzig Minuten nachdem der Lauf fertig war.
Quick Win: Füge direkt einen PostToolUse-Hook in die Agentendefinition ein. Jede Datei, die dieser Agent schreibt, läuft durch den Linter, bevor du sie je siehst:
# .claude/agents/frontend-builder.md
---
name: frontend-builder
description: Build React components with automatic quality checks
model: sonnet
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: 'npx eslint --fix "$CLAUDE_TOOL_INPUT_FILE_PATH" && npx prettier --write "$CLAUDE_TOOL_INPUT_FILE_PATH"'
---
You are a frontend builder agent. Create React components following
the project's established patterns. Every file you write is automatically
linted and formatted by your embedded hooks.Unlinteter Code ist für diesen Agenten keine Option mehr. Die Prüfung gehört zu dem, was er ist, nicht zu etwas, das du nachträglich anschraubst.
Es gibt drei Stufen eines selbstvalidierenden Agenten. Jede fängt eine andere Klasse von Fehlern ab, und sie stapeln sich sauber.
Mikro ist pro Tool-Aufruf. Ein PostToolUse-Hook auf der Agentendefinition führt einen Linter, Formatter oder Type-Checker direkt nach dem Schreiben einer Datei aus. Alles Kaputte wird Sekunden nach dem Entstehen abgefangen.
Makro ist für den ganzen Job. Wenn der Agent versucht zu beenden, stellt ein Stop-Hook die echten Fragen: Sind die erforderlichen Dateien vorhanden, existieren Exports, wird die Test-Suite grün. Wenn irgendetwas davon scheitert, darf der Agent den Job nicht als erledigt bezeichnen.
Team holt einen zweiten Agenten dazu. Ein schreibgeschützter Reviewer öffnet die Arbeit des Builders mit einem frischen Kontextfenster. Das ist das Builder/Reviewer-Pattern, eine Ebene höher im Stack.
PostToolUse: Mikro-Validierung bei jedem Schreibvorgang
Hooks, die im Agenten-Frontmatter deklariert werden, feuern nur, wenn dieser Agent der Ausführende ist. Scope ist automatisch. ESLint gehört zum Frontend-Builder, Ruff gehört zum Python-Builder, und sie kollidieren nie.
Hier ist ein Python-Agent, der mit Black und mypy verdrahtet ist:
# .claude/agents/python-builder.md
---
name: python-builder
description: Build Python modules with automatic formatting and type checking
model: sonnet
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: 'black "$CLAUDE_TOOL_INPUT_FILE_PATH" && mypy "$CLAUDE_TOOL_INPUT_FILE_PATH" --ignore-missing-imports'
---
You are a Python builder agent. Write clean, typed Python code.
Your hooks automatically format with Black and check types with mypy.Der Gewinn liegt im Scope. Diese Hooks gehören zum Agenten. Nichts sickert in die Projekt-Level-Settings durch. Wenn der Orchestrator diesen Agenten über das Task-Tool hochfährt, kommt die Validierung mit.
Mikro fängt Syntax und Formatierung ab. Es fängt keine Datei ab, die nie geschrieben wurde. Dafür brauchst du einen Stop-Hook.
Stop-Hooks: Makro-Validierung vor dem Abschluss
Stop-Hooks im Agenten-Frontmatter werden zu SubagentStop-Events. Dieses Skript bestätigt, dass jede erforderliche Ausgabedatei existiert und den Inhalt hat, den du angefordert hast:
#!/bin/bash
# .claude/scripts/validate-output.sh
# Validates that agent output meets structural requirements
INPUT=$(cat)
STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
exit 0
fi
# Check that required files exist
REQUIRED_FILES=("src/components/index.ts" "src/components/Button.tsx")
MISSING=""
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "$file" ]; then
MISSING="$MISSING $file"
fi
done
if [ -n "$MISSING" ]; then
echo "{\"decision\": \"block\", \"reason\": \"Missing required files:$MISSING\"}"
exit 0
fi
# Check that index.ts contains exports
if ! grep -q "export" src/components/index.ts; then
echo "{\"decision\": \"block\", \"reason\": \"index.ts has no exports. Add barrel exports for all components.\"}"
exit 0
fi
exit 0Dann verdrahe es in den Agenten selbst:
---
name: component-builder
description: Build component libraries with output validation
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: 'npx prettier --write "$CLAUDE_TOOL_INPUT_FILE_PATH"'
Stop:
- hooks:
- type: command
command: "bash .claude/scripts/validate-output.sh"
---Jetzt sind beide Stufen aktiv. Jeder Schreibvorgang wird formatiert. Die gesamte Ausgabe wird bewertet, bevor der Agent aufhören darf. Wenn der Stop-Hook blockiert, macht der Agent weiter, bis die Prüfungen endlich bestehen.
Schreibgeschützte Validator-Agenten
Die dritte Stufe ist ein Reviewer, der keine Dateien anfassen kann. disallowedTools erzwingt das auf der Tool-Ebene:
# .claude/agents/output-validator.md
---
name: output-validator
description: Validate agent output without modifying files. Use after builder agents complete.
model: haiku
disallowedTools: Write, Edit, NotebookEdit
---
You are a read-only validator. Your job:
1. Read all files the builder created or modified
2. Verify exports, type safety, and error handling
3. Run the test suite with Bash
4. Report issues as a list. Do NOT fix anything.
If all checks pass, say "Validation passed" with a summary.
If issues exist, list each one with file path and line reference.Dateien schreiben ist für diesen Agenten vom Tisch. Lesen und berichten ist alles, was er tun kann. Kombiniere ihn mit einem Builder via Task-Abhängigkeiten:
TaskCreate(subject="Build auth module", description="...")
TaskCreate(subject="Validate auth module", description="Run output-validator on src/auth/")
TaskUpdate(taskId="2", addBlockedBy=["1"])Wann welche Stufe nutzen
Nur Mikro (PostToolUse) passt für kleine, enge Tasks, deren Qualitätsmaßstab bei Linting beginnt und endet. Overhead ist gering. Feedback ist sofort.
Mikro plus Makro (PostToolUse + Stop) passt für Agenten, die mehrere Dateien mit einer strukturellen Form liefern. Der Stop-Hook fängt, was ein Linter nie kann: Dateien, die nie geschrieben wurden, halb fertige Logik, eine Reihe roter Tests.
Alle drei Stufen gehören auf Code-Pfade, die du dir nicht leisten kannst, falsch zu machen. Die maschinengesteuerten Prüfungen erledigen die Fleißarbeit. Ein separater Reviewer gibt dir eine zweite Meinung, die die eigenen Hooks des Builders nicht geben konnten.
Fang die Mikro-Stufe mit dem Agenten an, den du am meisten nutzt. In dem Moment, in dem ein Agent dir halb fertige Arbeit übergibt, bolze einen Stop-Hook dran. Bring den Reviewer ins Spiel, sobald dir wichtig ist, dass das gesamte Lieferable zusammenhält, nicht nur dass jede Datei parsierbar ist. Agenten-Configs können ruhig in deiner CLAUDE.md bleiben, oder sie können als eigene Dateien unter .claude/agents/ liegen, was auch immer zum Projekt passt.
Jenseits einzelner Agenten
Denk an Selbstprüfungen und Team-Prüfungen als Stack, nicht als Alternativen. Rund 90% der Qualitätsfehler werden von den eingebetteten PostToolUse-Hooks plus dem Stop-Skript behandelt, bevor der Reviewer überhaupt eine Datei öffnet. Was für den Reviewer übrig bleibt, ist Integration und Architektur, nicht die Lint-Fehler, die die Hooks bereits geschluckt haben.
Hören Sie auf zu konfigurieren. Fangen Sie an zu bauen.
SaaS-Builder-Vorlagen mit KI-Orchestrierung.