Todo piloto de agente passa. O que trava a escala é a pergunta que vem depois, feita pelo jurídico, pelo auditor ou pelo cliente grande: quem autorizou essa ação, com qual dado, quanto custou e como reverter? Sem uma resposta em vinte segundos, o projeto volta para o começo. A trilha de auditoria é o que transforma essa conversa de um mês de trabalho em uma consulta. Este artigo traz o esquema que usamos em Postgres, campo a campo, com o que ele resolve e o que ele deliberadamente não guarda.
O essencial
- Trilha de agente não é log de aplicação. Log serve para depurar. Trilha serve para responder quem autorizou, com que dado e com qual efeito, meses depois.
- Uma linha por ação, não por mensagem. A unidade é a ação com efeito no mundo: gravou, enviou, cobrou, agendou.
- O custo entra na trilha. Tokens e valor por execução na mesma linha da ação, senão a conta do mês vira mistério em vez de relatório.
- Dado pessoal não vira histórico eterno. A trilha guarda referência e resumo, não a conversa inteira, e tem prazo de descarte definido.
- Sem particionamento, a tabela vira problema em um ano. Partição por mês e política de retenção desde o primeiro dia custam quase nada.
Neste artigo
- Log e trilha não são a mesma coisa
- As perguntas que a trilha precisa responder
- O esquema
- Campo a campo, por que cada um existe
- O que nunca gravar
- Volume, partição e retenção
- As consultas que valem estar prontas
- O que a trilha resolve na LGPD
- Aprovação humana e limite de custo
- A tabela de aprovações
- Avaliação contínua sobre a mesma trilha
- Erros comuns
- Implantação em seis passos
- Perguntas frequentes
Log e trilha não são a mesma coisa
Log de aplicação é escrito para quem está depurando: verboso, descartável, organizado por tempo, apagado em duas semanas. Trilha de auditoria é escrita para quem vai perguntar meses depois: enxuta, imutável, organizada por entidade, guardada por anos. Usar o log como trilha é o atalho que parece funcionar até a primeira auditoria de verdade.
A distinção fica clara na pergunta de teste. “Por que o serviço caiu ontem às 3h” é log. “Quais decisões automáticas afetaram este cliente nos últimos seis meses, e quem as autorizou” é trilha. A segunda pergunta não é respondível varrendo arquivo de texto, e é justamente a que aparece quando o projeto cresce.
Agentes acrescentam uma terceira exigência que nem sistema tradicional tem: a decisão foi tomada por um modelo, e o modelo não é determinístico. Precisa ficar registrado qual modelo, qual versão da instrução, o que ele consultou e o que ele concluiu. Sem isso, não dá para explicar por que a mesma entrada produziu saídas diferentes em dois dias.
As perguntas que a trilha precisa responder
Um esquema de auditoria se projeta de trás para frente, a partir das perguntas que ele terá de responder. Estas são as sete que aparecem em todo projeto, e cada campo do esquema existe para atender pelo menos uma delas.
- O que o agente fez, em termos de efeito no mundo, não em termos de chamada de função.
- Sobre qual entidade, para que a busca por cliente, pedido ou contrato seja direta.
- Com qual autorização, se foi regra automática, permissão prévia ou aprovação de uma pessoa nomeada.
- Com base em quê, quais fontes foram consultadas antes de decidir.
- Com qual modelo e qual instrução, incluindo a versão, porque as duas coisas mudam.
- Quanto custou, em tokens e em dinheiro, por ação.
- Como reverter, ou ao menos o que precisaria ser feito para desfazer.
O esquema
Uma tabela principal de ações, particionada por mês, e uma tabela auxiliar de aprovações. O desenho abaixo roda igual em Postgres puro e em Supabase, e cabe em uma migração.
create table agente_acao (
id bigserial,
ocorrido_em timestamptz not null default now(),
correlacao_id uuid not null,
agente text not null,
agente_versao text not null,
modelo text not null,
instrucao_hash text not null,
acao text not null,
entidade_tipo text,
entidade_id text,
resultado text not null,
autorizacao text not null,
aprovado_por text,
fontes jsonb not null default '[]',
entrada_resumo text,
saida_resumo text,
tokens_entrada integer not null default 0,
tokens_saida integer not null default 0,
custo_centavos integer not null default 0,
duracao_ms integer,
reversivel boolean not null default false,
reversao_ref text,
erro text,
primary key (id, ocorrido_em)
) partition by range (ocorrido_em);
create index on agente_acao (entidade_tipo, entidade_id, ocorrido_em desc);
create index on agente_acao (correlacao_id);
create index on agente_acao (agente, ocorrido_em desc);
create index on agente_acao (resultado) where resultado <> 'ok';
Os quatro índices não são decoração. O primeiro atende a pergunta do titular de dado e a do auditor, que sempre chegam por entidade. O segundo reconstrói uma execução inteira. O terceiro alimenta relatório por agente. O quarto é parcial e cobre a consulta de incidente sem pagar o custo de indexar as linhas normais, que são a maioria.
Campo a campo, por que cada um existe
Cada coluna corresponde a uma pergunta real que alguém já fez em uma reunião. A tabela abaixo explica a intenção de cada uma, que é a parte que costuma se perder quando outra pessoa herda o projeto.
| Campo | Para que existe | Exemplo |
|---|---|---|
correlacao_id | Amarra todas as ações de uma mesma execução | Uma conversa que gerou consulta, decisão e escrita |
agente_versao | Saber qual versão do fluxo produziu aquilo | atendimento@2026.08.14 |
instrucao_hash | Provar qual instrução estava valendo, sem guardá-la inteira | Resumo criptográfico do texto da instrução |
acao | O efeito no mundo, em vocabulário do negócio | ordem_servico.criada |
autorizacao | Distinguir regra automática de aprovação humana | regra, previa, humana |
fontes | O que foi consultado antes de decidir | Documento, consulta ao ERP, histórico |
custo_centavos | Fechar a conta do mês por ação, não por fatura | 4 |
reversivel | Responder na hora se dá para desfazer | Verdadeiro para agendamento, falso para envio |
reversao_ref | O identificador que permite desfazer | Número do lançamento a estornar |
Uma decisão de desenho que costuma gerar discussão: acao usa vocabulário de negócio, não nome de função interna. ordem_servico.criada continua legível daqui a três anos, quando a função que a implementava já terá sido renomeada duas vezes. A trilha precisa sobreviver ao código.
O que nunca gravar
Uma trilha de auditoria mal desenhada vira o maior repositório de dado sensível da empresa, com retenção longa e acesso amplo. É o oposto do objetivo. Existem cinco coisas que não entram, e a disciplina precisa estar no código, não na intenção.
- A conversa inteira. Guarde referência ao registro original e um resumo curto. O histórico completo tem outro dono, outro prazo e outro nível de acesso.
- Credencial, token ou chave. Nem no campo de entrada, nem no de erro, que é por onde eles costumam vazar sem que ninguém perceba.
- Dado sensível por reflexo. Saúde, biometria, origem racial e opinião política têm tratamento próprio na lei e não devem ser copiados para uma tabela de auditoria.
- O texto completo da instrução. Um resumo criptográfico prova qual versão estava valendo e ocupa 64 caracteres.
- Documento de identificação por extenso, quando não for necessário. Um identificador interno resolve a maior parte dos casos de rastreio.
Erro comum
Gravar a resposta bruta do modelo no campo de erro “para investigar depois”. É por aí que entram nome, telefone e conteúdo de conversa numa tabela que ninguém revisou sob a ótica de proteção de dados, e que tem retenção de cinco anos.
Volume, partição e retenção
Trilha cresce rápido e cresce sempre. Um agente de atendimento com volume moderado gera de três a seis linhas por conversa, entre consulta, decisão e ação. Vinte mil conversas por mês viram algo entre 60 mil e 120 mil linhas mensais, e o problema não é o espaço em disco: é a consulta que fica lenta e a exclusão que trava a tabela.
3 a 6
linhas de trilha por conversa atendida
1 mês
tamanho de partição que usamos por padrão
< 1 s
alvo para a consulta por entidade
Particionar por mês resolve os três problemas de uma vez. A consulta recente toca uma partição pequena. O descarte de um período vira remoção de partição, que é instantânea, em vez de exclusão linha a linha, que gera bloqueio e inchaço. E a manutenção de índice fica confinada ao período ativo.
Sobre retenção: o prazo é decisão jurídica, não técnica, e precisa estar escrito. O que a engenharia entrega é o mecanismo que cumpre o prazo automaticamente. Uma rotina mensal que cria a partição do mês seguinte e remove a que passou do prazo cabe em vinte linhas e evita que a decisão vire uma tarefa manual esquecida.
Vale antecipar uma dúvida frequente sobre imutabilidade. Não basta prometer que ninguém altera a tabela: a garantia precisa vir do banco. O caminho que usamos é um papel de aplicação com permissão apenas de inserção e de leitura na tabela de ações, sem alteração nem remoção, e a remoção por prazo executada por uma rotina de manutenção separada, que só sabe apagar partição inteira. Com isso, uma linha alterada indevidamente deixa de ser possível por descuido e passa a exigir intervenção deliberada de quem administra o banco, o que já é um evento auditável em outro lugar.
As consultas que valem estar prontas
Trilha que só existe como tabela não é usada. O que a torna útil é ter três ou quatro consultas prontas, com nome, que qualquer pessoa do time consegue rodar sem escrever SQL na hora da urgência.
- Histórico de uma entidade. Tudo o que o agente fez sobre um cliente, pedido ou contrato, em ordem. É a consulta que responde ao titular de dado e ao auditor.
- Reconstrução de uma execução. Todas as linhas de um mesmo
correlacao_id, do gatilho ao efeito. É a consulta de incidente. - Custo por agente e por dia. Soma de
custo_centavosagrupada, para que a fatura do mês nunca seja surpresa. - Ações não reversíveis do período. Filtro por
reversivelfalso, para revisão periódica do que passou sem poder voltar atrás. - Taxa de repasse humano. Proporção entre
autorizacaohumana e automática, que é o melhor indicador de se a regra de repasse está calibrada.
O que a trilha resolve na LGPD
A Lei Geral de Proteção de Dados dá ao titular o direito de saber com quem seus dados são compartilhados e de pedir revisão de decisões automatizadas que afetem seus interesses. A trilha é o mecanismo que torna essas duas obrigações operáveis, em vez de declarações num documento de política.
| Obrigação | O que a trilha entrega | O que ainda falta |
|---|---|---|
| Informar tratamento ao titular | Histórico por entidade, em uma consulta | Processo de atendimento ao pedido |
| Revisão de decisão automatizada | Qual decisão, com base em quê, por qual versão | Fluxo de contestação com pessoa responsável |
| Registro de operações | Quem fez o quê, quando, com qual autorização | Inventário e mapeamento de dados |
| Resposta a incidente | Escopo do que foi acessado, por correlação | Plano de comunicação e prazo de notificação |
| Descarte após a finalidade | Remoção de partição por prazo | Definição jurídica do prazo |
A pergunta do auditor não é se você tem política de governança. É se você consegue mostrar, em vinte segundos, o que o agente fez com o dado daquele cliente.
Aprovação humana e limite de custo
A trilha registra o passado. Duas peças vizinhas controlam o presente, e as três juntas formam a governança que um comitê de risco costuma pedir. A primeira é a aprovação humana em operação sensível. A segunda é o teto de custo.
Aprovação humana funciona melhor como fila do que como bloqueio. O agente prepara a ação inteira, grava a linha com autorizacao pendente, e uma pessoa confirma ou recusa. Preparar antes reduz o tempo da pessoa a um clique informado, o que faz a diferença entre um controle que é usado e um que todo mundo contorna.
Teto de custo precisa existir em dois níveis: por execução e por período. O primeiro impede que um caso patológico consuma o orçamento inteiro numa tarde. O segundo protege o mês. Como custo_centavos já está na trilha, o cálculo do consumido é uma soma, e o corte pode ser automático.
A tabela de aprovações
A segunda tabela guarda o pedido de aprovação e o que aconteceu com ele. Ela existe separada porque tem ciclo de vida próprio: nasce pendente, muda de estado, expira. A tabela de ações é imutável por natureza, e misturar um registro que muda com um que não muda estraga as duas garantias.
create table agente_aprovacao (
id bigserial primary key,
criada_em timestamptz not null default now(),
correlacao_id uuid not null,
acao text not null,
entidade_tipo text,
entidade_id text,
proposta jsonb not null,
risco text not null,
estado text not null default 'pendente',
decidida_em timestamptz,
decidida_por text,
motivo text,
expira_em timestamptz not null
);
create index on agente_aprovacao (estado, expira_em)
where estado = 'pendente';
Três campos merecem explicação. proposta guarda a ação já montada, pronta para executar, e não a intenção genérica: é isso que reduz a decisão humana a ler e confirmar. risco classifica em baixo, médio ou alto, e é o que permite rotear aprovação para papéis diferentes. expira_em existe porque pedido pendente sem prazo vira fila abandonada, e fila abandonada é o começo de todo controle que ninguém respeita.
Quando a decisão sai, a ação correspondente é gravada na tabela principal com autorizacao igual a humana e aprovado_por preenchido. As duas tabelas se encontram pelo correlacao_id, e a reconstrução da execução mostra a proposta, a decisão e o efeito na mesma linha do tempo.
Regra prática
Se a taxa de aprovação de um tipo de ação passa de 95 por cento durante um mês, aquele controle virou carimbo. Ou a regra de risco está calibrada errada, ou a ação pode ser automática com auditoria posterior. Nos dois casos, a decisão é de quem responde pelo processo, e a trilha entrega o número que sustenta a conversa.
Avaliação contínua sobre a mesma trilha
A trilha responde o que aconteceu. A avaliação contínua responde se o que aconteceu estava certo. As duas usam a mesma base, e é essa reutilização que torna a avaliação barata o suficiente para acontecer toda semana em vez de uma vez por trimestre.
O mecanismo é simples. Uma rotina sorteia uma amostra de execuções do período, agrupadas por correlacao_id, e submete cada uma a dois julgamentos: um automático, feito por um modelo com critério escrito, e um humano, sobre uma fatia menor. A concordância entre os dois é o que diz se o julgamento automático pode ser usado sozinho na semana seguinte.
Três indicadores costumam bastar no começo, e todos saem de campos que já existem. A taxa de repasse humano, que indica calibragem da regra de segurança. A taxa de erro por tipo de ação, que localiza onde o fluxo está frágil. E o custo médio por resultado útil, que é o único número que responde se o agente está ficando mais eficiente ou apenas mais falante.
Uma observação de método: avaliação feita apenas sobre os casos que deram errado engana. A amostra precisa incluir execuções normais, senão o time otimiza para o incidente do mês e degrada o comportamento comum sem perceber.
Erros comuns
- Deixar a trilha para a fase dois. Ela é barata no desenho e cara no retrofit, porque exige reprocessar histórico que não existe.
- Gravar por mensagem, não por ação. Gera volume enorme e não responde nenhuma das sete perguntas.
- Permitir alteração e exclusão. Trilha alterável não é prova de nada. Permissão de escrita apenas para inserir, e leitura restrita.
- Esquecer o custo. Sem valor por ação, a única visão de gasto é a fatura, e a fatura chega tarde demais para corrigir.
- Não versionar a instrução. Sem saber qual texto estava valendo, o comportamento passado fica inexplicável.
- Guardar tudo para sempre. Retenção infinita é passivo, não segurança.
Implantação em seis passos
- Liste as ações com efeito no mundo. Antes de criar tabela. Se a lista tem mais de vinte itens no primeiro agente, ela está descrevendo funções, não ações.
- Crie a tabela particionada e os índices. Com a partição do mês corrente e a do seguinte já criadas.
- Instrumente um fluxo só. O de maior volume. Rode uma semana e confira se as sete perguntas são respondíveis.
- Revise sob a ótica de dado pessoal. Leia cem linhas reais procurando o que não deveria estar ali. Sempre tem algo.
- Escreva as consultas nomeadas. E deixe acessíveis a quem vai precisar delas sob pressão.
- Automatize partição e descarte. Rotina mensal que cria a próxima e remove a vencida, com o prazo definido pelo jurídico.
Perguntas frequentes
Preciso de Postgres ou dá para usar outro banco?
O desenho funciona em qualquer banco relacional. Postgres é a escolha por três recursos que facilitam a vida: particionamento por intervalo nativo, coluna JSON com índice e índice parcial. Em SQL Server ou MySQL o mesmo esquema roda com ajustes de sintaxe.
Quanto tempo devo guardar a trilha?
É definição jurídica, não técnica, e varia com o setor e o tipo de dado. O papel da engenharia é entregar o mecanismo que cumpre o prazo escolhido automaticamente. O que não funciona é deixar sem prazo, porque retenção indefinida é passivo de proteção de dados.
A trilha não deixa o sistema lento?
Uma inserção por ação é irrelevante diante do tempo de uma chamada de modelo, que é ordens de grandeza maior. O que fica lento é consulta sobre tabela grande sem partição e sem índice, e é exatamente isso que o desenho deste artigo evita.
Devo guardar o prompt completo?
Não na trilha. Guarde o resumo criptográfico da instrução na linha da ação e mantenha as versões do texto em um repositório versionado. Assim você prova qual instrução estava valendo sem transformar a tabela de auditoria em cópia do seu próprio conteúdo.
Como registrar quando o agente decide não agir?
Com uma linha de ação própria, algo como repasse.humano ou acao.recusada, e o motivo no resumo de saída. A não ação é uma decisão, e é frequentemente a mais importante de auditar, porque é onde a regra de segurança aparece funcionando.
Isso serve para atender um pedido de titular de dado?
Serve como fonte da resposta, não como o processo inteiro. A consulta por entidade devolve o que o agente fez com o dado daquela pessoa. O atendimento ao pedido ainda exige um fluxo definido, com prazo, responsável e formato de resposta ao titular.
Vale usar uma ferramenta pronta de observabilidade de IA?
Vale, para depuração e avaliação de qualidade, que é o papel delas. Para auditoria, o registro precisa estar no seu banco, sob seu controle de retenção e acesso. As duas coisas convivem, e confundir uma com a outra é o que gera surpresa na primeira auditoria.
Próximo passo
Se você já tem um agente rodando, faça o teste mais rápido que existe: escolha um cliente atendido na semana passada e tente listar tudo o que o sistema decidiu sobre ele. Se levar mais de um minuto, a trilha ainda não existe, e ela é o que vai destravar a próxima fase do projeto.
Continuando pelo blog: O handoff é o produto trata da regra de repasse que a trilha registra, e Legado sem API mostra como chegar ao dado que o agente vai consultar.
Fontes e leitura
- Brasil, Lei 13.709 de 2018, em especial os artigos sobre direitos do titular e decisões automatizadas.
- PostgreSQL, documentação de particionamento de tabelas.
- OWASP, Top 10 para aplicações com modelos de linguagem.
- NIST, AI Risk Management Framework.