Padrão outbox para agentes de IA: guia prático
Aprenda a usar o padrão outbox em agentes de IA para registrar estado e eventos juntos, evitar mensagens perdidas e publicar integrações com segurança.
O estado mudou, mas ninguém recebeu o evento
Um agente analisa uma solicitação, atualiza o banco local para aprovada e, em seguida, tenta publicar um evento para o CRM. A gravação funciona. A fila fica indisponível antes da publicação.
O painel do agente mostra a tarefa como concluída. O CRM continua sem atualização, o responsável não recebe a próxima ação e nenhuma retentativa acontece porque o estado local já encerrou o fluxo.
Também existe o caminho inverso. O agente publica o evento, a integração cria a tarefa no CRM e o processo falha antes de registrar a conclusão no banco. Quando o worker volta, ele repete a publicação e pode produzir outro efeito.
O padrão outbox reduz essa lacuna. A aplicação grava a mudança de estado e uma mensagem pendente na mesma transação do banco. Um processo separado lê a outbox, publica o evento e registra a confirmação. A tarefa pode ser retomada sem depender de uma sequência frágil entre dois sistemas.
Qual problema o padrão outbox resolve
Uma operação distribuída costuma precisar de duas escritas:
- atualizar o estado interno da unidade de trabalho;
- informar a mudança a outra aplicação, fila ou processo.
Essas escritas pertencem a componentes diferentes. O banco pode confirmar enquanto o broker falha. O broker pode aceitar enquanto a resposta se perde. Uma transação local não consegue garantir, sozinha, o compromisso dos dois destinos.
A outbox transforma a publicação em dado persistido dentro da mesma transação que altera o estado do negócio. Se a transação confirmar, existe uma mensagem pendente. Se ela falhar, nem o novo estado nem a mensagem aparecem.
O resultado esperado é uma relação verificável entre estado e evento. Cada mudança que exige propagação deixa uma unidade publicável, com identidade, destino, versão e histórico de tentativas.
Outbox, webhook e idempotência cumprem funções diferentes
Esses mecanismos se encontram no mesmo fluxo, mas protegem fronteiras distintas.
Outbox protege a saída
Ela garante que uma mudança local destinada a outros componentes deixe um registro durável para publicação. O problema central é evitar estado confirmado sem evento correspondente.
Webhook protege a entrada
O guia de webhooks para agentes de IA cobre autenticação, persistência, duplicidade, ordem e replay de eventos recebidos de terceiros. Webhook trata o aviso que entra. Outbox organiza o aviso que sai.
Idempotência protege o efeito repetido
A outbox normalmente trabalha com entrega pelo menos uma vez. O relay pode publicar novamente depois de timeout ou reinício. O consumidor precisa reconhecer o evento e impedir outra consequência para a mesma unidade.
A idempotência em agentes de IA define a chave estável, a reserva e a confirmação no destino. Outbox evita perda entre estado e publicação. Idempotência evita que a recuperação gere duplicidade.
Reconciliação resolve a incerteza restante
Mesmo com outbox e idempotência, pode existir publicação sem confirmação local ou efeito externo com estado ambíguo. A reconciliação em agentes de IA compara registros e devolve cada unidade ao fluxo correto.
O desenho básico da outbox
Considere um agente que prepara uma próxima ação comercial. Depois da validação, a aplicação precisa marcar a recomendação como aprovada e avisar uma integração que criará a tarefa no CRM.
A transação local executa duas gravações:
BEGIN
atualizar work_item para "aprovado"
inserir evento na outbox como "pendente"
COMMIT
A linha da outbox pode conter:
event_idúnico;event_typeconhecido;aggregate_type, como oportunidade ou chamado;aggregate_iddo objeto empresarial;aggregate_versionesperada;work_item_idda unidade de trabalho;- cliente, conta e ambiente;
- payload ou referência protegida;
- destino ou tópico;
- data de criação;
- estado de publicação;
- quantidade de tentativas;
- próxima tentativa permitida;
- prazo de validade;
- identificador de correlação;
- versão do contrato do evento.
Um relay busca linhas pendentes, publica no destino e atualiza o registro com confirmação, horário e identificador retornado quando houver.
Defina o evento a partir de um fato confirmado
A outbox deve registrar algo que aconteceu dentro da autoridade da aplicação.
Exemplos:
- recomendação comercial aprovada;
- documento validado para conferência;
- solicitação encaminhada para uma fila;
- pedido preparado para atualização;
- exceção aberta para revisão;
- etapa de onboarding concluída;
- tarefa cancelada por perda de validade.
Evite eventos com nomes vagos, como agente_finalizou ou processamento_ok. Eles descrevem atividade técnica e dizem pouco sobre o fato que outro sistema pode consumir.
O nome precisa indicar o objeto, a transição e a versão relevante. Um consumidor consegue decidir se o evento ainda se aplica e qual contrato deve validar.
Também separe proposta de compromisso. O modelo pode sugerir uma ação. A outbox só registra o evento que passou pelas regras e aprovações exigidas. Publicar uma sugestão como decisão confirmada transfere ambiguidade para todos os consumidores.
Mantenha a transação curta
A principal garantia da outbox vem da transação local. Ela deve envolver somente o estado que a aplicação controla e a linha correspondente na outbox.
Não coloque dentro dessa transação:
- chamada ao modelo;
- consulta remota ao CRM;
- envio de mensagem;
- upload para fornecedor externo;
- aprovação humana;
- publicação no broker;
- espera por outro agente.
Essas etapas possuem latência e falhas próprias. Mantê-las dentro de uma transação longa aumenta bloqueio, contenção e chance de rollback local sem controle do efeito externo.
Prepare contexto e decisão antes. Ao chegar ao ponto de compromisso, valide versão, autorização e contrato. A transação grava o novo estado e o evento pendente. A publicação acontece depois.
Escolha como o relay encontra eventos pendentes
Existem dois caminhos comuns.
Consulta periódica
Um worker consulta a tabela por estado, horário e prioridade. É simples de operar e funciona em muitos bancos.
O worker precisa evitar que várias instâncias publiquem a mesma linha ao mesmo tempo. Pode usar seleção com bloqueio adequado, reserva com prazo ou atualização atômica de estado.
Captura do log de mudanças
Uma ferramenta de change data capture observa o log transacional e encaminha inserções da outbox. Esse caminho reduz polling e pode suportar grande volume, mas adiciona componentes, contratos e operação próprios.
A escolha depende de volume, prazo, tecnologia disponível e maturidade da equipe. Um relay simples, observável e testado costuma ser melhor que uma arquitetura sofisticada sem dono.
Em ambos os casos, a confirmação da publicação precisa retornar ao controle operacional. Um evento que saiu do banco e desapareceu da visibilidade apenas mudou de ponto cego.
Trate a entrega como repetível
O relay pode publicar e perder a confirmação. Também pode reiniciar depois da publicação e antes de marcar a linha como enviada. O consumidor deve assumir reentrega.
Use o mesmo event_id em todas as tentativas. Não crie um ID novo para cada publicação. O consumidor registra o identificador recebido e aplica a consequência uma única vez.
A chave da consequência pode combinar:
- objeto empresarial;
- tipo de ação;
- versão relevante;
- janela ou competência;
- identificador da unidade.
O ID do evento deduplica a mesma mensagem. A chave de idempotência protege efeitos equivalentes que podem nascer de eventos diferentes.
Exemplo: duas mudanças legítimas na oportunidade podem pedir a mesma tarefa de follow-up. Os eventos têm IDs diferentes. A tarefa continua sendo uma só para aquele compromisso.
Controle ordem e versão
A outbox preserva a ordem de criação dentro da transação, mas publicação paralela, filas e consumidores podem alterar a ordem de chegada.
Inclua a versão do objeto e defina a política por tipo de evento.
Possíveis tratamentos:
- consumidor aceita apenas versão posterior à última aplicada;
- eventos independentes podem ser processados em paralelo;
- transições sensíveis seguem uma partição por objeto;
- evento antigo vira evidência, sem reverter o estado atual;
- lacuna de versão pausa o objeto e solicita recuperação;
- consumidor consulta a fonte oficial antes de uma consequência relevante.
Uma oportunidade pode gerar followup_preparado e, logo depois, oportunidade_encerrada. Se o primeiro evento chegar por último, o CRM não deveria recriar uma ação vencida.
O contrato de dados para agentes de IA ajuda a definir versão, semântica, validade e tratamento de quebra entre produtor e consumidor.
Preserve isolamento entre clientes e ambientes
A tabela da outbox participa da fronteira de dados. Cada linha precisa carregar a identidade necessária para resolver destino, credencial e permissão sem inferência por nome ou conteúdo.
Registre:
- tenant ou conta;
- ambiente;
- aplicação produtora;
- destino autorizado;
- classificação do payload;
- finalidade;
- política de retenção;
- identificador da credencial, sem guardar o segredo.
O relay deve selecionar a credencial depois de validar essa identidade. Um payload com cliente_nome não oferece isolamento suficiente.
Se uma linha não puder ser associada a uma fronteira conhecida, bloqueie a publicação e envie a pendência ao responsável. Mistura de clientes transforma um problema de integração em incidente.
Reduza o payload e preserve a fonte
Copiar o objeto inteiro para a outbox simplifica o primeiro protótipo e amplia exposição, retenção e risco de dado vencido.
Escolha entre dois formatos.
Evento com dados mínimos
Carrega os campos necessários para o consumidor concluir uma ação estável. Funciona quando o fato deve permanecer reproduzível mesmo que a origem mude.
Evento de referência
Carrega identidade, versão e uma referência para consulta autorizada. Reduz cópia, mas depende da disponibilidade e do contrato da fonte no momento do consumo.
Muitos processos usam um envelope híbrido: identidade, tipo, versão, tempos e poucos campos invariantes seguem no evento; conteúdo sensível ou mutável permanece na fonte oficial.
A política deve indicar o que o consumidor pode considerar histórico e o que precisa revalidar antes de agir. O artigo sobre freshness de dados para agentes de IA detalha janelas de validade e confirmação antes da consequência.
Defina estados operacionais da outbox
Um booleano published esconde diferenças importantes. Use estados que orientem recuperação.
Exemplo:
pendente;reservado;publicando;publicado;confirmacao_incerta;retry_agendado;bloqueado_contrato;bloqueado_permissao;expirado;enviado_dlq;cancelado.
Cada transição exige evidência. publicando → publicado pode pedir confirmação do broker ou protocolo do destino. confirmacao_incerta → retry_agendado exige política que preserve o mesmo ID. pendente → expirado exige prazo vencido e decisão sobre a unidade de negócio.
O estado da outbox não substitui o estado do processo. Ele descreve a publicação. Uma recomendação pode continuar aprovada enquanto seu evento permanece bloqueado. O painel precisa mostrar ambos para que a equipe entenda o impacto.
Coordene retentativas e fila de erros
Classifique falhas antes de repetir.
Falhas temporárias incluem indisponibilidade curta, limite de taxa e timeout antes de qualquer confirmação. Use teto, backoff e jitter.
Falhas permanentes incluem contrato desconhecido, destino inexistente, tenant sem configuração e payload inválido. Repetir não corrige a causa.
Estados incertos aparecem quando o destino pode ter aceitado a publicação. Consulte por event_id, aguarde a janela de consistência ou envie para reconciliação antes de publicar novamente.
Quando uma linha esgota tentativas seguras, preserve-a em uma rota com causa, contexto, dono e critério de reprocessamento. A fila de erros para agentes de IA organiza esse tratamento sem contaminar o fluxo saudável.
Monitore o tempo entre estado e propagação
Uma outbox pode evitar perda e ainda criar atraso operacional. A equipe precisa saber quanto tempo um fato confirmado espera para alcançar seus consumidores.
Acompanhe:
- eventos criados por tipo e processo;
- linhas pendentes;
- idade da linha mais antiga;
- tempo entre commit e primeira tentativa;
- tempo entre commit e confirmação;
- tentativas por evento;
- falhas por destino e contrato;
- confirmações incertas;
- eventos expirados antes da publicação;
- duplicidades bloqueadas no consumidor;
- versões fora de ordem;
- backlog por cliente e prioridade;
- tempo estimado de drenagem;
- unidades de negócio afetadas;
- eventos sem dono ou destino válido.
Um alerta útil informa o processo, o fato represado, a idade, a consequência, a contenção aplicada e quem decide o próximo passo.
“Outbox com 430 linhas” é telemetria. “Eventos de aprovação comercial estão há vinte minutos sem chegar ao CRM; criação automática de tarefas foi pausada; operação comercial precisa revisar oito casos próximos do prazo” é um alerta operacional.
Teste as falhas entre o commit e o consumidor
Inclua cenários como:
- banco falha antes do commit;
- estado e outbox tentam gravar com versão vencida;
- relay reinicia antes da publicação;
- relay publica e cai antes da confirmação local;
- broker entrega o mesmo evento duas vezes;
- dois relays reservam trabalho ao mesmo tempo;
- lock ou reserva expira durante o envio;
- consumidor recebe versões fora de ordem;
- contrato do evento muda durante backlog;
- credencial do destino expira;
- tenant ou ambiente não pode ser resolvido;
- payload ultrapassa o limite;
- evento vence antes da publicação;
- consumidor conclui manualmente durante a pausa;
- backlog retorna depois de indisponibilidade prolongada.
Para cada caso, verifique o estado local, a linha da outbox, a quantidade de publicações, o efeito no destino e a evidência entregue ao responsável.
A engenharia do caos para agentes de IA pode exercitar falhas controladas depois que o fluxo básico estiver coberto em ambiente de teste.
Checklist do padrão outbox
- [ ] A mudança local e a mensagem pendente entram na mesma transação?
- [ ] O evento descreve um fato empresarial confirmado?
- [ ] Cada evento possui ID, objeto, versão, cliente e ambiente?
- [ ] O relay preserva o mesmo ID entre tentativas?
- [ ] Consumidores tratam reentrega e efeitos equivalentes?
- [ ] Ordem e lacunas de versão possuem política?
- [ ] Payload e referência seguem finalidade e sensibilidade?
- [ ] Estados de publicação diferenciam falha, incerteza e expiração?
- [ ] Retentativas param diante de erro permanente?
- [ ] Confirmação incerta segue para consulta ou reconciliação?
- [ ] Backlog possui idade, prioridade, prazo e responsável?
- [ ] Eventos vencidos deixam de produzir ações antigas?
- [ ] Métricas ligam publicação ao resultado do processo?
- [ ] Testes cobrem reinício, duplicidade, concorrência e mudança de contrato?
A publicação precisa fazer parte do estado
Agentes empresariais combinam decisões, filas e sistemas que falham de forma independente. Gravar a conclusão local e depois tentar avisar os demais cria uma janela em que o processo parece fechado enquanto a operação continua incompleta.
O padrão outbox coloca a intenção de publicação dentro do mesmo compromisso do estado. O relay assume o trabalho externo, consumidores tratam repetição e a reconciliação resolve incertezas que atravessam a fronteira.
Essa arquitetura permite retomar o fluxo com evidência. A empresa consegue localizar fatos represados, medir atraso, corrigir a causa e confirmar o efeito no destino sem depender da memória do worker ou de uma sequência perfeita entre componentes.