Agentes Claude Code Auto-Validantes
Agentes Claude Code auto-validantes: liga hooks PostToolUse de lint, hooks Stop e sub-agentes revisores em modo só-leitura às definições dos agentes para que output de má qualidade nunca seja entregue.
Pare de configurar. Comece a construir.
Templates SaaS com orquestração de IA.
Problema: Um agente entrega trabalho que parece bem à primeira vista. Depois o linter grita, falta um export, e um ficheiro inteiro foi ignorado. Só reparas durante a revisão, vinte minutos depois do run ter terminado.
Solução Rápida: Adiciona um hook PostToolUse diretamente na definição do agente. Cada ficheiro que este agente escreve passa pelo linter antes de o veres:
# .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.Código sem lint deixa de ser uma opção para este agente. A verificação faz parte de quem ele é, não é algo que acrescentas depois.
Existem três camadas num agente auto-validante. Cada uma apanha uma classe diferente de bugs, e encaixam-se bem umas com as outras.
Micro é por chamada de ferramenta. Um hook PostToolUse na definição do agente corre um linter, um formatter, ou um verificador de tipos logo após um ficheiro ser escrito. Qualquer coisa partida é apanhada segundos depois de acontecer.
Macro é para o trabalho todo. Quando o agente tenta terminar, um hook Stop faz as perguntas reais: os ficheiros necessários estão lá, os exports existem, o test suite fica verde. Se algum falha, o agente não tem permissão para declarar o trabalho concluído.
Equipa traz um segundo agente. Um revisor em modo só-leitura abre o trabalho do construtor com uma janela de contexto limpa. É o padrão construtor/revisor, um nível acima na pilha.
PostToolUse: Validação Micro em Cada Escrita
Os hooks declarados dentro do frontmatter do agente só disparam quando esse agente é o que está a correr. O âmbito é automático. ESLint pertence ao construtor frontend, Ruff pertence ao construtor Python, e nunca colidem.
Aqui está um agente Python ligado ao Black e 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.A vantagem é o âmbito. Estes hooks pertencem ao agente. Nada vaza para as settings a nível de projeto. Quando o orquestrador lança este agente através da ferramenta Task, a validação vai junto.
O nível micro apanha sintaxe e formatação. Não apanha um ficheiro que nunca foi escrito. Para isso, precisas de um hook Stop.
Hooks Stop: Validação Macro Antes da Conclusão
Os hooks Stop no frontmatter do agente tornam-se eventos SubagentStop. Este script confirma que todos os ficheiros de output necessários existem e têm o conteúdo que pediste:
#!/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 0Depois liga-o ao próprio agente:
---
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"
---Agora ambas as camadas estão ativas. Cada escrita é formatada. O output todo é avaliado antes de o agente ter permissão para parar. Se o hook Stop bloquear, o agente continua até as verificações passarem finalmente.
Agentes Validadores em Modo Só-Leitura
A terceira camada é um revisor que não pode tocar nos ficheiros. O disallowedTools aplica isso a nível da ferramenta:
# .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.Escrever ficheiros está fora da mesa para este agente. Ler e reportar é tudo o que pode fazer. Combina-o com um construtor via dependências de tarefas:
TaskCreate(subject="Build auth module", description="...")
TaskCreate(subject="Validate auth module", description="Run output-validator on src/auth/")
TaskUpdate(taskId="2", addBlockedBy=["1"])Quando Usar Cada Camada
Só micro (PostToolUse) é o encaixe certo para tarefas pequenas e focadas cujo critério de qualidade começa e acaba no linting. Overhead baixo. Feedback instantâneo.
Micro mais macro (PostToolUse + Stop) encaixa-se em agentes que entregam vários ficheiros com uma forma estrutural associada. O hook Stop apanha o que um linter nunca apanha: ficheiros que nunca foram escritos, lógica deixada a meio, uma suite de testes vermelhos.
As três camadas pertencem a caminhos de código que não podes dar ao luxo de errar. As verificações automáticas fazem o trabalho pesado. Um revisor separado dá-te uma segunda opinião que os próprios hooks do construtor não conseguiam.
Começa com a camada micro no agente que mais usas. No momento em que um agente te entrega trabalho a meio, adiciona um hook Stop. Traz o revisor quando te importas que o deliverable todo esteja coerente, não só que cada ficheiro faça parse. As configs dos agentes ficam bem no teu CLAUDE.md, ou podem estar como ficheiros próprios em .claude/agents/, o que encaixar melhor no projeto.
Para Além de Agentes Únicos
Pensa nas verificações do próprio agente e nas de equipa como uma pilha, não como alternativas. Cerca de 90% dos bugs de qualidade são tratados pelos hooks PostToolUse incorporados mais o script Stop antes de o revisor alguma vez abrir um ficheiro. O que sobra para o revisor é integração e arquitetura, não os erros de lint que os hooks já absorveram.
Pare de configurar. Comece a construir.
Templates SaaS com orquestração de IA.