
Como colocar uma etapa de aprovação humana entre seu agente de IA e qualquer ação no mundo real
Eu tenho construído agentes de IA há um tempo. Claude Code, alguns scripts agendados de agente, esse tipo de coisa. Ao longo de alguns meses, continuei montando a mesma peça de infraestrutura do zero, e cada vez era a mesma forma com substantivos diferentes.
Em algum momento, o agente quer fazer algo de verdade. Enviar um e-mail. Postar uma resposta. Executar um comando que é irritante de desfazer. E toda vez, eu queria ser aquele que dizia sim antes que isso acontecesse. Não uma vez eu quis que o agente simplesmente agisse.
Então, cada projeto cresceu o mesmo apêndice: um pequeno passo de aprovação. Um trabalho cron que produzia um rascunho, um seen.json para evitar duplicatas, e uma interface pequena para que eu pudesse tocar em sim ou não do meu telefone antes que qualquer coisa fosse enviada. Três projetos separados, mesma estrutura. Então eu extraí isso para algo reutilizável. Este post é sobre o padrão, não o produto, porque o padrão é a parte útil, mesmo que você construa o seu próprio.
Um prompt não é um portão
A primeira tentativa óbvia é escrever "sempre pergunte ao usuário antes de enviar" no prompt do sistema. Isso não funciona como um controle. Um modelo capaz, mais cedo ou mais tarde, encontrará uma maneira de contornar uma instrução em linguagem natural: ele decide que o caso atual é obviamente aceitável, ou esquece, ou um caso extremo escapa. Você está confiando no mesmo componente que está tentando proteger.
O que você realmente quer é que a verificação "um humano aprovou isso?" seja uma dependência de dados, não uma instrução. O agente não deve ser capaz de alcançar o ramo de execução sem um valor real retornando que diga aprovado.
A forma
O agente submete uma ação proposta. Isso retorna imediatamente como pending. Um humano vê, aprova, rejeita ou edita o rascunho primeiro. O agente faz polling e só prossegue quando vê approved. O ramo que realmente faz a coisa está atrás de um valor retornado, então não há palavras que um caso extremo possa usar para se passar.
Aqui está todo o loop em três chamadas REST:
# 1. Propor a ação
ACTION=$(curl -s -X POST https://api.impri.dev/v1/actions \
-H "Authorization: Bearer $IMPRI_API_KEY" \
-d '{"kind":"email.send","title":"Outreach: Acme","preview":{"format":"markdown","body":"Oi Sarah, ..."}}')
ID=$(echo "$ACTION" | jq -r .action_id)
# 2. Poll até que um humano decida
while true; do
DECISION=$(curl -s "https://api.impri.dev/v1/actions/$ID" \
-H "Authorization: Bearer $IMPRI_API_KEY")
STATUS=$(echo "$DECISION" | jq -r .status)
[ "$STATUS" != "pending" ] && break
sleep 5
done
# 3. Somente agora, e somente se aprovado, execute
if [ "$STATUS" = "approved" ]; then
send_email "$(echo "$DECISION" | jq -r .preview.body)" # use a versão editada pelo humano
fi
Se o seu agente fala MCP, a mesma coisa são três chamadas de ferramenta (impri_push_action, impri_await_decision, impri_report_result) e o modelo não precisa de nenhum código SDK. As ferramentas aparecem no Claude Code, Cursor, Claude Desktop ou qualquer cliente MCP.
A parte que as pessoas erram (incluindo minha própria primeira proposta)
Quando escrevi sobre isso pela primeira vez, disse que o portão é "estrutural" e que o agente "literalmente não pode alcançar o código de execução." Alguém no r/mcp corretamente contestou, e eles estavam certos, então deixe-me ser preciso aqui.
O portão é real apenas enquanto o caminho aprovado é o único caminho do agente para o efeito colateral.
Existem duas maneiras de conectá-lo:
Cooperativo. O agente chama a ferramenta de aprovação, espera, então o próprio agente executa. Isso é melhor do que um prompt porque a verificação é uma dependência de dados no fluxo de controle. Mas se o agente já possui a credencial de e-mail bruta, um agente com bugs ou desalinhado poderia simplesmente chamar o envio diretamente e pular tudo.
Intercepção. Você envolve a ferramenta alvo para que o uso proposto de
tool_useseja interceptado antes da execução, e o executor não é chamado até que a decisão retorne aprovada. Agora seu portão é literalmente o único caminho para a função real. A definição da ferramenta que o modelo vê permanece inalterada; apenas o caminho de execução passa pelo portão.
Mesmo o segundo é apenas um verdadeiro portão se esse wrapper for o único ponto de estrangulamento. Entregar ao agente chaves brutas ou uma segunda ferramenta que alcance o mesmo serviço e ele contorna você. Portanto, a formulação honesta é: este é um ponto de estrangulamento que você confina o agente, não um interceptor mágico em nível de rede de toda saída. Construa de acordo, e não dê ao agente uma segunda porta.
Tirando o passo humano da sua mesa
A aprovação em si não precisa viver em um painel que você verifica. O pedido pode chegar no Slack, Discord ou Telegram como uma mensagem com botões de Aprovar e Rejeitar, e você toca em um do seu telefone. Cada decisão vai para um log de auditoria: quem aprovou o que, quando, e se editaram primeiro. Para agentes que precisam, também há edição antes da aprovação, para que o humano possa corrigir a redação e o agente receba essa versão para agir.
Se você quiser experimentar em vez de construir
A coisa que eu extraí se chama Impri. O núcleo completo (caixa de entrada, aprovações de chat, servidor MCP, log de auditoria) é MIT e auto-hospedável com Docker Compose em um comando. Há uma versão hospedada também, mas está em beta inicial, então a auto-hospedagem é o caminho que eu apontaria para você.
- Repo (MIT): https://github.com/sekera-radim/impri
- Docs: https://impri.dev
Está genuinamente no início. Um punhado de usuários reais e algumas dezenas de aprovações através dele até agora. Se você está construindo agentes que tomam ações reais e montou sua própria versão desse portão, eu adoraria
Empresas brasileiras que utilizam agentes de IA podem se beneficiar ao implementar uma etapa de aprovação humana, aumentando a segurança e a confiabilidade das ações automatizadas. Isso ajuda a evitar erros e garante que as decisões sejam revisadas antes da execução, promovendo uma melhor governança de IA.


