Como conferir que um agente de IA fez o que disse que fez?
A resposta: confira a afirmação numa fonte que o agente não controla e, antes disso, pergunte se a ação que ele diz ter feito deixa registro durável ou apenas um último estado. Em 15 de agosto de 2026 auditamos as 15 afirmações mais recentes do nosso próprio agente sobre agir fora do servidor dele. Dez se sustentam quando conferidas na fonte. Cinco não podem ser verificadas por nós nem por ninguém, porque a fonte guarda só o evento mais recente e sobrescreve o resto. Nenhuma das 15 foi mostrada falsa, e cinco delas nunca poderiam ser, que não é o mesmo resultado.
Essa distinção é a que mudou o nosso jeito de trabalhar. Entramos esperando pegar uma mentira e saímos com algo mais útil: uma classe inteira de afirmação de agente que é inauditável por construção, e que se parece exatamente com uma afirmação que daria para conferir.
O que significa conferir o relato de um agente de IA de programação?
Conferir o relato de um agente de IA de programação significa confirmar, num sistema em que o agente não tem permissão de escrita, que o efeito descrito por ele realmente aconteceu. É uma atividade diferente de ler o código dele. Quando um agente como o Claude Code, o Codex ou o Cursor termina uma tarefa, a saída costuma conter dois tipos de afirmação, e só um deles é um diff. "Refatorei o parser" aponta para código que você pode ler. "Rodei a suíte de testes", "subi a branch", "reiniciei o servidor de desenvolvimento", "abri o pull request" e "mandei a notificação" apontam para eventos no mundo, e o diff não diz nada sobre eles.
O segundo tipo é onde a confiança se acumula em silêncio. Revisar diff é um hábito que a indústria já tem, com ferramenta e cultura em volta. Auditar uma afirmação sobre ação executada não tem nem uma coisa nem outra, então a frase do agente costuma ser o único artefato que alguém olha. Um comentarista do Hacker News, escrevendo em 15 de agosto de 2026, resumiu a falha assim: sem saber escrever o software você não julga o resultado, e o sistema então alega que as metas foram cumpridas e que os testes passam enquanto o humano que o conduz apenas empurra mais um pull request. No original:
You have to be able to write the software yourself in order to judge the results and get good software out. Otherwise the system claims the goals are met, the tests pass, and the human driving the system puts up a new PR.
Então a pergunta prática não é se o agente é sincero. É quais frases dele estão presas a uma fonte que você pode consultar, e do que aquela fonte é capaz de se lembrar.
Por que o registro do próprio agente não é evidência
O registro do próprio agente é o relato do que ele acreditou ter feito, produzido pelo mesmo processo que fez, o que o torna descrição e não confirmação. Se a ação falhou em silêncio, o registro vai continuar dizendo que deu certo, porque ele é escrito a partir da intenção e de uma resposta que o agente pode ter lido errado.
Aprendemos isso na direção menos confortável. A nossa pipeline de conteúdo mantém um diário e, em 15 de agosto de 2026, uma execução leu o registro de uma execução anterior que afirmava um cross post para o dev.to, foi conferir se aquele post existia, concluiu que não, e registrou que a entrada anterior era falsa. A acusação estava errada. O post estava no ar desde as 11:04:24 UTC daquela manhã. O que tinha falhado era o método de conferência, não o diário, e o custo foi real: agindo sobre a conclusão errada, aquela execução publicou um segundo cross post e estourou a cota do dia.
A lição passa longe do nosso caso particular. Quando o relato do agente e a sua conferência discordam, há três candidatos ao erro e a maioria das pessoas considera só um. O agente pode estar errado, a fonte pode estar mentindo por omissão, ou a sua consulta pode estar fazendo a pergunta errada. Nós assumimos o primeiro e era o terceiro. Antes de tratar a afirmação de um agente como falsa, reproduza a conferência com outra consulta contra a mesma fonte, porque um método de verificação não tem mais autoridade do que o agente que ele audita.
Quais afirmações de um agente dá para verificar?
A afirmação de um agente pode ser verificada quando o efeito que ela descreve deixa registro durável, e não pode ser verificada quando o efeito só atualiza um último estado. Essa distinção decide tudo o que vem depois, e vale separar as afirmações antes de escrever qualquer ferramenta.
Registro durável quer dizer que a ação cria um objeto que persiste e carrega identificador próprio: uma página publicada que continua devolvendo 200, um post com slug permanente, um commit alcançável pelo SHA, uma execução de CI com identificador, um artefato lançado com checksum. Você pode pedir por ele pelo nome daqui a anos. Último estado quer dizer que o sistema guarda apenas a ocorrência mais recente: uma submissão de sitemap, uma invalidação de cache, o reinício de um serviço, um webhook disparado contra um endpoint que não mantém caixa de entrada. A ação deixa marca, mas a marca é sobrescrita pela seguinte, então ela responde "quando isso aconteceu pela última vez" e nunca responde "aconteceu na terça".
Aplicada a um agente de IA de programação, essa separação classifica uma sessão comum em segundos. "Subi o código" é durável, porque o remoto tem o SHA. "Abri o pull request" é durável, porque o pull request tem número. "Rodei os testes" só é durável se a execução aconteceu em algum lugar que guarda registro de execução, e fora disso é puro último estado, e é por isso que ela é a frase inverificável mais repetida da categoria. "Reiniciei o serviço" é último estado em quase todo lugar. Afirmação da segunda coluna não é mentira. É uma frase que nenhuma diligência posterior consegue promover a evidência, e a única correção é fazer a ação deixar registro antes de rodar.
O que a auditoria do nosso próprio agente devolveu?
A nossa auditoria devolveu 10 verificadas de 15, e as cinco que ficaram de fora falharam todas pelo mesmo motivo estrutural. O objeto foi o diário da nossa pipeline de conteúdo: das 100 entradas mais recentes, 15 afirmam efeito fora do servidor que as guarda, registradas entre 14 de agosto de 2026 às 00h14 UTC e 15 de agosto de 2026 às 17h11 UTC. Escrevemos o que esperávamos encontrar antes de consultar qualquer coisa, que é o único jeito de uma auditoria conseguir discordar de quem a conduz.
As seis afirmações de publicação verificaram 6 de 6. Cada uma nomeia um slug, e cada slug existe em três idiomas, então a conferência foram 18 requisições contra o site no ar, todas devolvendo 200:
curl -s -o /dev/null -w '%{http_code}\n' "https://canvascode.app/pt-br/news/undo-ai-coding-agent-changes"
As três afirmações de cross post verificaram 3 de 3, cada uma presente com a URL canônica correta apontando de volta para o nosso site. Usamos o endpoint de conta /api/articles/me/all, que devolveu 401 sem chave de API e 200 com ela, em vez da listagem pública, por motivos que a próxima seção explica.
As seis afirmações de aviso de sitemap verificaram 1 de 6. A resposta do Search Console para o nosso sitemap trouxe uma única submissão registrada, lastSubmitted em 2026-08-15T17:08:02.065Z, sem nenhuma anterior ao lado. Isso confirma o aviso mais recente e deixa os outros cinco indistinguíveis de avisos que nunca aconteceram. A mesma resposta trouxe lastDownloaded em 2026-08-15T17:08:04.364Z, e esse campo é a metade mais interessante: dois segundos depois da nossa submissão, o Google baixou o arquivo. Essa é a diferença entre evidência de que você falou e evidência de que o outro lado agiu, e é a confirmação mais forte desta lista.
Por que uma resposta vazia da API não prova que o agente não fez nada?
Uma resposta vazia de API não prova ausência porque um endpoint de listagem responde à pergunta que você digitou, não à que você quis fazer, e ele responde a uma pergunta malformada com um nada confiante e bem formado. Reproduzimos três jeitos distintos de ser enganado pela mesma API do dev.to em 15 de agosto de 2026, e cada um devolveu HTTP 200.
O primeiro é identidade. Consultar a listagem pública com um nome de usuário que não existe devolve [] e status 200. O nome da nossa marca não é o nosso identificador lá, e pedir pela marca produziu uma lista vazia e limpa, que se parece exatamente com um agente que não publicou nada.
O segundo é cache por URL. Com o identificador correto, o mesmo endpoint devolveu totais diferentes conforme um parâmetro que deveria apenas alargar a janela:
curl -s "https://dev.to/api/articles?username=hassekf&per_page=30"
Isso devolveu 8 artigos, enquanto per_page=10, per_page=20 e per_page=50 devolveram 10 cada. Rodamos os quatro valores três vezes e o padrão foi idêntico todas as vezes, então isso não é instabilidade, é cache com chave na URL inteira. Uma listagem que encolhe quando você pede mais não serve de censo.
O terceiro é a correção dos dois. Pedir o item pelo identificador dele, /api/articles/hassekf/<slug>, devolveu 200 para o post cuja existência tínhamos negado por engano naquele mesmo dia. Esse endpoint não precisa de chave; ele simplesmente responde sobre uma coisa nomeada em vez de enumerar. Quando você quer saber se uma coisa específica existe, peça aquela coisa pelo nome, e enumere só quando precisar de contagem.
Um contador que marca zero enquanto a mesma fonte relata 39 impressões
A mesma resposta do Search Console que verificou o nosso aviso de sitemap trouxe também um número que quase publicamos como crise. Ao lado dos carimbos de submissão, o bloco de conteúdo relatava 579 URLs submetidas e 0 indexadas. Lido sozinho, isso diz que o Google não indexou nada do que já escrevemos.
Ele é contradito pelo mesmo produto. Puxar a análise de busca dos 28 dias anteriores daquela propriedade idêntica devolveu 23 consultas distintas e 39 impressões, com 0 cliques. Uma página não pode ser mostrada 39 vezes em resultado de busca estando ausente do índice, então os dois números não podem descrever a realidade ao mesmo tempo, e o que merece desconfiança é o contador, não o relatório. O nosso registro de visitantes concorda com o relatório: ele guarda chegadas referidas pelo google.com na mesma janela.
Estamos dizendo o que medimos e não por que o contador se comporta assim, porque não temos fonte do Google explicando isso, e inventar uma seria exatamente a falha de que este artigo trata. A regra operacional que tiramos daqui é mais estreita e não precisa da explicação: um campo isolado não é medição enquanto um segundo campo da mesma fonte não concordar com ele. Contador que contradiz o relatório do próprio produto é motivo para procurar o segundo campo, não para abrir alarme. Nós teríamos aberto.
A conferência que rodamos em nós mesmos, e perdemos
Auditando o nosso agente, pegamos uma crença nossa que nunca tinha sido verificada, e vale contar porque é a mesma falha em miniatura. As nossas anotações internas dizem que buscar páginas do canvascode.app com script pelado é recusado pela defesa contra sondagem que guarda o site, então toda conferência desta auditoria foi escrita com User-Agent completo de navegador, por hábito e não por medição.
Durante esta auditoria finalmente testamos o hábito, pedindo a mesma página de três jeitos: sem nenhum cabeçalho de User-Agent, com curl/8.7.1, e com uma string de navegador. Os três devolveram 200. A precaução era desnecessária para este tipo de requisição, e a anotação que a justificava não sobreviveu ao contato com um comando, e é por isso que agora conferimos o canvascode.app com curl puro, sem opção de User-Agent, e não mais com a string de navegador que usávamos por hábito.
A crença não foi inventada. Ela veio de uma observação real anterior, e a leitura que fazemos é que generalizamos um caso específico em regra e paramos de testá-la. É exatamente o que um agente faz quando escreve "pronto" no registro dele: converte uma observação em fato permanente. A diferença entre nós e o agente, naquele dia específico, foram três segundos de curl.
Como fazer o relato de um agente ser conferível antes de ele rodar?
Você torna o relato de um agente conferível exigindo que ele registre o identificador que a fonte devolveu, em vez do fato de ter agido. Isso é uma mudança nas instruções que você dá ao agente, e custa zero no momento da escrita, que é o único momento em que ainda é possível.
Três exigências cobrem a maior parte. Primeira, o relato precisa carregar um identificador que possa ser consultado de forma independente: um SHA de commit, um número de pull request, um identificador de execução de CI, uma URL publicada, um identificador de mensagem. "Subi a correção" é inverificável; "subi 4f2a91c para origin/main" pode ser conferido por qualquer um que tenha o repositório. Segunda, precisa carregar o carimbo de tempo da fonte, não o do agente, porque o relógio do agente só prova quando ele acreditou ter agido. Terceira, precisa incluir o comando ou a chamada exata que ele fez, para quem revisa poder repetir a conferência em vez de inventar uma, que foi justamente como a nossa conferência ruim aconteceu.
Para ações de último estado, a única opção honesta é criar o registro você mesmo. Se o agente reinicia um serviço, faça-o capturar o horário de início do novo processo logo em seguida e colocar isso no relato. Se ele roda testes localmente, faça-o escrever o resumo num arquivo com carimbo de tempo, ou rodá-los em algum lugar que guarde registro de execução. O CanvasCode, o nosso aplicativo de macOS para rodar vários agentes de IA de programação num canvas só, ajuda na parte disto que é enxergar muitos agentes ao mesmo tempo, e não resolve este problema: um agente cujo relato não tem identificador dentro é inverificável por melhor que seja a sua visão dele. A correção mora no que você exige que o agente anote, não na ferramenta pela qual você o observa.
O que esta auditoria não prova
Esta auditoria não prova que agentes de IA de programação relatam as ações deles com precisão, e a amostra é pequena o bastante para não defendermos taxa nenhuma a partir dela. Quinze afirmações de um agente ao longo de 41 horas é estudo de caso. Ela também não prova nada sobre as cinco afirmações não verificadas: elas não foram mostradas falsas, foram mostradas infalseáveis, que é um resultado diferente e, de certo modo, pior.
A maior limitação é o que o agente auditado é. A nossa pipeline escreve e publica conteúdo; ela não é um agente de programação e não encosta em repositório. O que transfere é a classificação das afirmações, não os números: publicar uma página e subir um commit são ações de registro durável, e avisar um sitemap e reiniciar um serviço são ações de último estado, mas o nosso 10 de 15 não diz nada sobre qual seria a proporção de um agente de programação no seu repositório. Gostaríamos de ver alguém rodar a mesma auditoria contra o log de sessão de um agente de programação, porque o método é barato e o resultado é conferível.
Mais um ponto sobre a contagem. Contamos uma afirmação como verificada quando uma fonte independente confirmou o efeito, mas para as seis páginas publicadas a fonte independente é o nosso próprio site, no qual a nossa própria pipeline escreveu. Uma auditoria mais rigorosa confirmaria em algum lugar que não é nosso, como um arquivo de terceiro. Todas as medições deste artigo foram feitas em 15 de agosto de 2026 com os comandos mostrados.