Agents Claude Code Auto-Validants
Agents Claude Code auto-validants : câble des hooks lint PostToolUse, des hooks Stop, et des sous-agents réviseurs en lecture seule dans les définitions d'agents pour que le mauvais code ne soit jamais livré.
Arrêtez de configurer. Commencez à construire.
Templates SaaS avec orchestration IA.
Problème : Un agent rend un travail qui semble bien au premier coup d'œil. Puis le linter crie, un export est manquant, et tout un fichier a été sauté. Tu le remarques seulement pendant la revue, vingt minutes après la fin de l'exécution.
Victoire rapide : Ajoute un hook PostToolUse directement dans la définition de l'agent. Chaque fichier que cet agent écrit passe par le linter avant que tu le voies jamais :
# .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.Le code non linté n'est plus une option pour cet agent. La vérification lui appartient, ce n'est pas quelque chose qu'on ajoute après coup.
Il y a trois niveaux dans un agent auto-validant. Chacun intercepte une classe différente de bug, et ils s'empilent proprement.
Micro, c'est par appel d'outil. Un hook PostToolUse dans la définition de l'agent exécute un linter, un formateur, ou un vérificateur de types juste après qu'un fichier a été écrit. Tout ce qui est cassé est détecté secondes après que ça arrive.
Macro, c'est pour le travail entier. Quand l'agent essaie de terminer, un hook Stop pose les vraies questions : les fichiers requis sont-ils là, est-ce que les exports existent, est-ce que la suite de tests est verte. Si quelque chose échoue, l'agent n'a pas le droit de déclarer le travail terminé.
Équipe fait appel à un deuxième agent. Un réviseur en lecture seule ouvre le travail du constructeur avec une fenêtre de contexte propre. C'est le pattern constructeur/réviseur, un niveau plus haut dans la pile.
PostToolUse : Validation Micro à Chaque Écriture
Les hooks déclarés dans le frontmatter d'un agent ne se déclenchent que quand cet agent est celui qui tourne. La portée est automatique. ESLint appartient au constructeur frontend, Ruff appartient au constructeur Python, et ils n'entrent jamais en collision.
Voici un agent Python câblé à Black et mypy :
# .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.L'avantage, c'est la portée. Ces hooks appartiennent à l'agent. Rien ne fuite dans les paramètres au niveau du projet. Quand l'orchestrateur démarre cet agent via l'outil Task, la validation part avec lui.
Micro intercepte la syntaxe et le formatage. Il n'intercepte pas un fichier qui n'a jamais été écrit. Pour ça, tu as besoin d'un hook Stop.
Hooks Stop : Validation Macro Avant Complétion
Les hooks Stop dans le frontmatter d'un agent deviennent des événements SubagentStop. Ce script confirme que chaque fichier de sortie requis existe et contient le contenu que tu as demandé :
#!/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 0Puis câble-le dans l'agent lui-même :
---
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"
---Maintenant les deux niveaux sont actifs. Chaque écriture est formatée. La totalité de la sortie est évaluée avant que l'agent ait le droit de s'arrêter. Si le hook Stop bloque, l'agent continue jusqu'à ce que les vérifications passent enfin.
Agents Validateurs en Lecture Seule
Le troisième niveau est un réviseur qui ne peut pas toucher les fichiers. disallowedTools applique ça au niveau de la couche d'outils :
# .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.Écrire des fichiers est hors de question pour celui-ci. Lire et rapporter, c'est tout ce qu'il peut faire. Associe-le à un constructeur via des dépendances de tâches :
TaskCreate(subject="Build auth module", description="...")
TaskCreate(subject="Validate auth module", description="Run output-validator on src/auth/")
TaskUpdate(taskId="2", addBlockedBy=["1"])Quand Utiliser Chaque Niveau
Micro seulement (PostToolUse) est le bon choix pour les tâches petites et bien délimitées dont le seuil de qualité commence et s'arrête avec le linting. Le surcoût est faible. Le feedback est instantané.
Micro plus macro (PostToolUse + Stop) convient aux agents qui livrent plusieurs fichiers avec une forme structurelle attachée. Le hook Stop intercepte ce qu'un linter ne fait jamais : des fichiers qui n'ont jamais été écrits, de la logique laissée à moitié faite, une suite de tests rouges.
Les trois niveaux appartiennent aux chemins de code que tu ne peux pas te permettre de rater. Les vérifications pilotées par la machine font le travail ingrat. Un réviseur séparé te donne un second avis que les propres hooks du constructeur ne pouvaient pas donner.
Commence le niveau micro sur l'agent que tu utilises le plus. Au moment où un agent te rend un travail à moitié fini, ajoute un hook Stop. Amène le réviseur une fois que tu t'assures que le livrable entier tient la route, pas seulement que chaque fichier parse. Les configs d'agent peuvent rester dans ton CLAUDE.md, ou ils peuvent être leurs propres fichiers sous .claude/agents/, ce qui convient au projet.
Au-Delà des Agents Uniques
Pense aux vérifications propres et aux vérifications d'équipe comme une pile, pas des alternatives. Environ 90% des bugs de qualité sont gérés par les hooks PostToolUse intégrés plus le script Stop avant que le réviseur n'ouvre jamais un fichier. Ce qui reste pour le réviseur, c'est l'intégration et l'architecture, pas les erreurs de lint que les hooks ont déjà avalées.
Arrêtez de configurer. Commencez à construire.
Templates SaaS avec orchestration IA.