Hooks, enforcement programático e handoffs
Objetivos de aprendizagem
- Distinguir enforcement programático (hooks, gates de pré-requisito) de orientação por prompt — e saber quando cada um é aceitável.
- Implementar hooks PreToolUse para bloquear ações que violam política (ex.: reembolso acima de $500) e redirecionar para escalação.
- Implementar hooks PostToolUse para normalizar formatos heterogêneos de dados antes de o modelo processá-los.
- Implementar gates de pré-requisito que bloqueiam ferramentas downstream até a etapa anterior completar (ex.:
process_refundsó apósget_customer). - Compilar handoffs estruturados para escalação a humanos: customer ID, causa raiz, valores e ação recomendada.
Prompt orienta; hook garante
Instruções no prompt são probabilísticas: mesmo bem escritas, têm taxa de falha diferente de zero — o modelo pode pular a verificação de identidade em 1 caso a cada 20, e em operação financeira isso é inaceitável. Hooks e gates programáticos são determinísticos: código que roda fora do modelo e não pode ser "convencido" a abrir exceção.
| Mecanismo | Natureza | Use quando |
|---|---|---|
| Instrução no system prompt / few-shot | Probabilística | Preferências de estilo, priorização, heurísticas de decisão em que erro ocasional é tolerável. |
| Hook / gate programático | Determinística | Compliance obrigatória: verificação de identidade antes de operação financeira, tetos de valor, políticas regulatórias. |
Heurística de prova: se o enunciado fala em "garantir", "nunca permitir", "compliance", valor financeiro ou consequência regulatória — a resposta correta envolve enforcement programático (hook/gate). Alternativas que "reforçam o prompt" ou "adicionam few-shot" são distratores quando a exigência é determinística.
Os dois hooks que a prova cobra
- PreToolUse — intercepta a chamada de ferramenta antes de ela executar. Usos: bloquear ações que violam política (reembolso > $500 → negar e redirecionar para escalação humana) e gates de pré-requisito (bloquear
process_refundelookup_orderenquantoget_customernão retornou um customer ID verificado). - PostToolUse — intercepta o resultado da ferramenta antes de o modelo processá-lo. Uso clássico do exam guide: normalizar formatos heterogêneos vindos de MCP tools diferentes — timestamps Unix vs. ISO 8601, status numéricos vs. strings — para o agente raciocinar sobre dados consistentes.
flowchart LR
M[Modelo pede tool_use
process_refund $750] --> H{Hook PreToolUse}
H -- viola política --> B[Bloqueia + motivo:
reembolso acima de $500
exige aprovação humana]
B --> E[Fluxo de escalação
handoff estruturado]
H -- ok --> X[Executa a ferramenta]
X --> P[Hook PostToolUse
normaliza timestamps/status]
P --> M2[Resultado normalizado
volta ao modelo]
Hooks no Claude Agent SDK
No Agent SDK, hooks são callbacks Python registrados por evento, opcionalmente filtrados por ferramenta via HookMatcher. Um PreToolUse pode negar a chamada com permissionDecision: "deny" e um motivo — que o modelo lê e usa para se redirecionar (ex.: escalar):
import datetime
from claude_agent_sdk import ClaudeAgentOptions, HookMatcher
REFUND_LIMIT = 500
async def block_large_refunds(input_data, tool_use_id, context):
"""PreToolUse: garantia deterministica da politica de reembolso."""
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
if tool_name.endswith("process_refund"):
amount = float(tool_input.get("amount", 0))
if amount > REFUND_LIMIT:
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": (
"Reembolsos acima de $%d exigem aprovacao humana. "
"Use escalate_to_human com o handoff estruturado."
% REFUND_LIMIT
),
}
}
return {}
async def normalize_timestamps(input_data, tool_use_id, context):
"""PostToolUse: normaliza formatos heterogeneos antes de o modelo ler."""
response = input_data.get("tool_response", {})
raw = response.get("created_at")
if isinstance(raw, (int, float)):
iso = datetime.datetime.fromtimestamp(
raw, tz=datetime.timezone.utc
).isoformat()
# Anexa contexto adicional normalizado para o modelo
return {
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "created_at normalizado (ISO 8601): " + iso,
}
}
return {}
options = ClaudeAgentOptions(
allowed_tools=["mcp__support__get_customer",
"mcp__support__process_refund",
"mcp__support__escalate_to_human"],
hooks={
"PreToolUse": [
HookMatcher(matcher="mcp__support__process_refund",
hooks=[block_large_refunds]),
],
"PostToolUse": [
HookMatcher(hooks=[normalize_timestamps]), # todas as ferramentas
],
},
)
O motivo da negação (permissionDecisionReason) não é burocracia: é o texto que o modelo recebe no lugar do resultado. Um motivo acionável ("use escalate_to_human") redireciona o agente para o fluxo alternativo correto; um "denied" seco deixa o agente sem saída.
Gate de pré-requisito
Variante do PreToolUse cobrada na sample question oficial: manter estado no harness (ex.: "customer verificado?") e bloquear ferramentas downstream até o pré-requisito completar. Um PostToolUse em get_customer marca verified = True; um PreToolUse em lookup_order/process_refund nega enquanto verified for False. Nenhum prompt, por melhor que seja, dá essa garantia — em produção o agente pulava get_customer em 12% dos casos mesmo com instrução "obrigatória" no prompt.
Handoff estruturado para escalação humana
Quando o agente escala no meio do processo, o humano que assume não tem acesso ao transcript da conversa. O task statement 1.4 exige um protocolo de handoff estruturado, tipicamente os campos:
- customer_id (e identificação verificada);
- root_cause — análise do problema feita até aqui (ex.: "pedido extraviado pela transportadora; segunda ocorrência");
- valores envolvidos — ex.: refund_amount solicitado;
- recommended_action — o que o agente faria se pudesse (ex.: "aprovar reembolso de $750 e cupom de 10%");
- itens já resolvidos vs. pendentes, quando a solicitação tinha múltiplas questões.
Além do handoff, o task statement 1.4 cobra a decomposição de solicitações multi-questão: separar as questões distintas do cliente, investigar cada uma (em paralelo, compartilhando contexto) e sintetizar uma resolução unificada — em vez de responder só à primeira questão.
Pegadinhas da prova
- Distrator típico: "reforce no system prompt que a verificação é obrigatória" quando o cenário exige compliance determinística. Prompt tem taxa de falha não nula; a resposta certa é hook/gate programático.
- Distrator típico: few-shot examples para forçar ordem de ferramentas em operação financeira. Mesmo problema: probabilístico.
- Distrator típico: usar PostToolUse para bloquear uma ação — tarde demais, a ferramenta já executou. Bloqueio de política é PreToolUse; PostToolUse transforma/normaliza resultados.
- Distrator típico: pedir ao modelo que normalize os formatos heterogêneos "quando notar inconsistência". A normalização determinística em PostToolUse remove a chance de o modelo interpretar errado um timestamp Unix como número mágico.
- Distrator típico: escalar para humano encaminhando o transcript bruto da conversa (ou nada). O humano precisa do handoff estruturado: customer ID, causa raiz, valores e ação recomendada.
- Distrator típico: classificador/roteador de intenções para resolver um problema de ordem de ferramentas. Routing decide quais ferramentas ficam disponíveis, não a sequência entre elas.
Resumo em 5 linhas
- Prompt = orientação probabilística; hook/gate = garantia determinística. Compliance obrigatória (identidade antes de operação financeira, tetos de valor) exige hooks.
- PreToolUse intercepta antes de executar: bloqueia violações de política (reembolso > $500) com motivo acionável que redireciona o agente (ex.: escalação).
- PostToolUse intercepta o resultado: normaliza formatos heterogêneos (Unix vs. ISO 8601, códigos numéricos) antes de o modelo raciocinar sobre eles.
- Gate de pré-requisito: estado no harness + PreToolUse bloqueando ferramentas downstream até o pré-requisito (customer ID verificado) completar.
- Escalação a humano sem acesso ao transcript pede handoff estruturado: customer ID, causa raiz, valores e ação recomendada.
Documentação oficial
Questões de fixação
1. A política da empresa proíbe reembolsos acima de $500 sem aprovação humana — sem exceções. Como garantir isso no agente de suporte?
Gabarito: B. "Sem exceções" = garantia determinística = interceptação antes da execução. A e C são enforcement por prompt, com taxa de falha não nula — inaceitável em operação financeira. D age tarde demais: o reembolso já saiu; estornar depois não é garantia, é remediação.
2. Três MCP tools retornam datas em formatos diferentes (Unix timestamp, ISO 8601 e string local), e o agente ocasionalmente compara datas de forma errada. Qual é a solução recomendada?
Gabarito: C. Normalização determinística do resultado é exatamente o caso de uso de PostToolUse do exam guide. A delega ao modelo uma conversão que deveria ser garantida por código. B bloqueia ferramentas funcionais — o problema é o formato do resultado, não a chamada. D pode nem ser viável (servidores de terceiros) e é a opção de maior esforço quando um hook resolve.
3. Ao escalar um caso no meio do atendimento para um humano que não tem acesso ao transcript, o que o agente deve enviar?
Gabarito: A. O protocolo do task statement 1.4: dados estruturados e acionáveis que aproveitam a investigação já feita. B joga fora o trabalho do agente e aumenta o tempo de resolução. C não está disponível no cenário (sem acesso ao transcript) e seria ruim mesmo se estivesse — humano teria que reler tudo. D perde detalhes críticos (valores, causa raiz).
4. (escolha duas) Em quais situações o enforcement por prompt é insuficiente e um hook/gate programático é exigido?
Gabarito: B e E. Ambas exigem compliance determinística (identidade antes de operação financeira; teto regulatório) — instrução no prompt tem taxa de falha não nula, o que é inaceitável aí. A, C e D são preferências/heurísticas em que erro ocasional é tolerável: exatamente o território onde prompt é o mecanismo adequado e um hook seria over-engineering.