Conteúdo da trilha
RefatoraçãoSegurança e confiabilidade

Pedir Aprovação Antes do Efeito

Add Approval Before Side Effect

Pedir Aprovação Antes do Efeito (Add Approval Before Side Effect) é uma refatoração de IA para sistemas com LLM, do grupo Segurança e confiabilidade. Pausar a execução e mostrar a ação para um humano antes de pagar, enviar ou apagar.

Elemento
25/35
Nível
Intermediário
Leitura
4 min
Atualizado
Nesta página 9
  1. 01Problema
  2. 02Solução
  3. 03Antes e depois
  4. 04Por que funciona
  5. 05Passo a passo seguro
  6. 06Riscos
  7. 07Desafio
  8. 08Relacionados
  9. 09Teste seu entendimento
  10. ··Perguntas rápidas

Problema

O assistente de cobrança agenda um Pix de R$ 1.890 para “pagar a conta de luz”. A chave veio de um PDF anexado. Ninguém confirmou. O dinheiro saiu para um nome que o cliente não reconhece. O agente enviou, pagou ou apagou sem nenhuma confirmação. É o smell Efeito Sem Portão.

Solução

Antes de executar uma ação com efeito, pause a execução, mostre a uma pessoa exatamente o que vai acontecer e só siga com um “sim” explícito registrado pelo sistema. A checagem fica no código da ferramenta, não no prompt.

Antes e depois

 def schedule_pix(key: str, amount_cents: int, date: str) -> dict:
-    return bank.schedule_pix(key, amount_cents, date)
+    preview = {
+        "acao": "Agendar Pix",
+        "destinatario": bank.lookup_key_owner(key),   # nome real do dono da chave
+        "valor": format_brl(amount_cents),
+        "data": date,
+    }
+    approval = approvals.request(user_id, preview, expires_in="15m")
+    if not approval.wait():                           # pausa até a resposta
+        return {"status": "recusado", "motivo": approval.reason}
+    return bank.schedule_pix(key, amount_cents, date,
+                             idempotency_key=approval.id)

Antes: o modelo chama e o dinheiro sai.

flowchart LR
  M(["1. Modelo decide pagar"]):::llm --> T["2. schedule_pix"]:::tool
  T --> B[("3. Banco")]:::store

Depois: o modelo propõe, a pessoa decide, o código executa.

flowchart LR
  M(["1. Modelo propõe pagar"]):::llm --> P["2. Montar prévia com dados reais"]:::tool
  P --> H((("3. Pessoa aprova ou recusa"))):::human
  H -->|sim| T["4. Executar com chave de idempotência"]:::tool
  T --> B[("5. Banco")]:::store
  H -->|não| R(["6. Resultado recusado volta ao modelo"]):::io
  1. O modelo continua decidindo que há algo a fazer.
  2. O código monta a prévia com dados vindos do sistema, não do texto do modelo: o nome real do dono da chave, o valor formatado.
  3. A pessoa vê a prévia num canal confiável (app, push, tela) e decide.
  4. Com o “sim”, o código executa, com uma chave que impede execução duplicada.
  5. O efeito acontece uma vez.
  6. Com o “não”, a ferramenta devolve a recusa, e o modelo segue a conversa sabendo disso.

Por que funciona

Uma regra no prompt depende do modelo lembrar e obedecer. O portão no código não depende de nada: a ferramenta simplesmente não executa sem uma aprovação registrada. Mesmo que o modelo seja enganado por um email malicioso, o pior que ele consegue é pedir. Quem decide é uma pessoa olhando dados reais. O modelo propõe; nunca executa.

A prévia precisa vir do sistema, não do modelo. Se o modelo escrevesse “pagar a conta de luz da Enel”, um atacante poderia fazê-lo escrever isso sobre uma chave Pix qualquer. Buscar o nome do dono da chave no banco mostra a verdade: “Pagar R$ 1.890,00 para Fulano da Silva”.

Isso já saiu do hipotético. Em 2023, o chatbot de uma concessionária Chevrolet em Watsonville “aceitou” vender um Tahoe por 1 dólar. Não havia um humano no circuito olhando o valor real. Em 2024, no caso Moffatt v. Air Canada, um chatbot inventou uma política de reembolso e a empresa foi condenada a cumprir o que a máquina prometeu. Aprovação não apaga responsabilidade jurídica, mas impede o efeito irreversível antes de alguém ver o número.

A chave de idempotência fecha o último buraco: um retry de rede ou um segundo clique não pagam duas vezes. Veja também Classificar Erro Antes de Tentar de Novo.

Checagem +20 XP de primeiraA ferramenta schedule_pix devolve {status: 'precisa_confirmar', preview: 'pagar luz'} e aceita um parâmetro confirmed: bool que o modelo preenche na chamada seguinte. Por que isso não é aprovação?

Passo a passo seguro

  1. Meça. Liste todas as ferramentas com efeito e conte, nos traces, quantas vezes cada uma foi chamada e quantas dessas chamadas o usuário pediu de forma explícita.
  2. Classifique os efeitos por risco: dinheiro, comunicação externa, dados de terceiros, dados do próprio usuário, reversíveis.
  3. Escolha o portão de cada nível: aprovação sempre, aprovação acima de um limite, aprovação pré-autorizada com teto, ou nenhuma para efeitos reversíveis (rascunho, lixeira).
  4. Monte a prévia a partir do sistema, com os dados que a pessoa precisa para decidir. Nome do destinatário, valor, data, o que não tem volta.
  5. Implemente a pausa: síncrona no chat (“confirma?”) ou assíncrona com estado salvo, se a resposta pode demorar minutos. A execução precisa sobreviver a um reload.
  6. Ponha a checagem dentro da ferramenta, para que nenhum caminho de código a pule.
  7. Use chave de idempotência na execução final.
  8. Registre aprovação e recusa com quem, quando e o que foi mostrado. Esse registro é o que você mostra num incidente.
  9. Meça de novo. Efeitos sem aprovação devem ser zero; acompanhe a taxa de recusa e o tempo até a resposta.

Armadilha: confirmar no mesmo chat

Pedir “responda SIM para confirmar” no mesmo fio onde entrou o PDF malicioso não é portão. O conteúdo injetado escreve SIM. Use um canal que só o usuário controla: botão no app, push, tela de revisão. O padrão Humano no Circuito descreve essa pausa.

Fadiga é o outro lado. Confirmar cada rascunho de email treina a pessoa a clicar sem ler. Separe o que é irreversível do que dá para desfazer. Reembolso via Pix e rascunho no Zendesk não compartilham o mesmo portão.

Checagem +20 XP de primeiraSeu time coloca aprovação em send_email, create_draft e search_orders. Depois de uma semana, a taxa de ‘sim’ passa de 99% e o tempo médio de confirmação cai para dois segundos. O que isso indica?

Riscos

  • Fadiga de aprovação. Peça só onde importa, e deixe a prévia curta e clara.
  • Prévia enganosa. Mostrar texto gerado pelo modelo em vez de dados do sistema anula o portão.
  • Canal inseguro. Pedir confirmação no mesmo chat onde um conteúdo malicioso pode escrever “sim” não é aprovação.
  • Execução que expira. A pessoa aprova horas depois e o contexto mudou (saldo, preço, chave Pix). Revalide antes de executar e ponha prazo na aprovação.

Desafio

Esta implementação tem um portão, mas ele pode ser burlado. Como?

def send_email(to, subject, body, confirmed: bool = False):
    if not confirmed:
        return {"status": "precisa_confirmar", "preview": f"Enviar para {to}"}
    return mailer.send(to, subject, body)
Ver solução

O parâmetro confirmed é preenchido pelo próprio modelo. Basta ele chamar de novo com confirmed=True, e um conteúdo malicioso pode instruí-lo a fazer isso. A confirmação precisa ser um registro do sistema, criado por uma ação da pessoa, que o modelo não consegue forjar.

def send_email(to, subject, body):
    preview = {"para": to, "assunto": subject, "corpo": body[:500]}
    approval = approvals.request(current_user, preview)   # canal do usuário
    if not approval.wait():
        return {"status": "recusado"}
    return mailer.send(to, subject, body, idempotency_key=approval.id)

Relacionados

Teste seu entendimento

Checagem +20 XP de primeiraA prévia do Pix mostra ‘Pagar conta de luz da Enel, R$ 1.890’, texto gerado pelo modelo a partir do PDF. O banco devolveria ‘Fulano da Silva’ se você consultasse a chave. A pessoa clica sim. O que falhou?

Checagem +20 XP de primeiraA pessoa aprova um Pix às 18h. A execução só roda às 21h, quando o saldo já não cobre o valor. Sem revalidação, o banco recusa. Qual é o conserto certo no portão?

Checagem +20 XP de primeiraUm rascunho de resposta no Zendesk é reversível. Um reembolso via Pix não é. Como você escolhe o portão dos dois?

Perguntas rápidas

O que é Pedir Aprovação Antes do Efeito?

Pedir Aprovação Antes do Efeito (Add Approval Before Side Effect) é uma refatoração de IA para sistemas com LLM, do grupo Segurança e confiabilidade. Pausar a execução e mostrar a ação para um humano antes de pagar, enviar ou apagar.

Que problema Pedir Aprovação Antes do Efeito resolve?

Trata Efeito Sem Portão.

Aonde Pedir Aprovação Antes do Efeito leva?

Ao padrão de projeto Humano no Circuito e Simulação Antes de Agir.

Para ir além

Relações

Smells que trata 1
Aparece nas trilhas 1
Buscar