Facebook
17 de outubro de 2026 | adrianosantostreina.com.br/blog Sobre o Autor

Documentação Como Projeção, Não Transcrição: Arquitetando Pipelines de IA que Documentam o Código Sem Mentir Sobre Ele

Você já deve ter vivido essa cena: um colega abre um módulo de pagamentos escrito há três anos, encontra um docstring detalhado explicando que a função calculateDiscount() “aplica desconto progressivo baseado no histórico do cliente”, roda o código e descobre que a função, na verdade, aplica um desconto fixo de 10% porque alguém simplificou a regra numa sprint de emergência e esqueceu de atualizar o comentário. O docstring não é só inútil — é ativamente perigoso, porque carrega autoridade de documentação oficial enquanto mente sobre o comportamento real do sistema. Agora troque “colega” por “agente de IA” e “docstring” por “contexto que o modelo vai usar para gerar o próximo trecho de código”, e você tem o problema central deste artigo.

Documentação gerada por IA promete resolver um dos problemas mais crônicos da engenharia de software: a assimetria entre o esforço de escrever código e o esforço de documentá-lo. Mas a forma como a maioria das equipes adota essa automação — pedir para um LLM “explicar essa função” e colar o resultado — produz exatamente o tipo de artefato que descrevi acima: prosa fluente, plausível, e desconectada da verdade operacional do sistema. Neste artigo vou detalhar como projetar um pipeline de documentação automática que trata a IA não como autora, mas como tradutora de fatos extraídos mecanicamente do código, dos testes e do histórico de execução — e por que essa distinção arquitetural é o que separa documentação confiável de ruído bem formatado.

O problema de origem: LLMs documentam intenção, não comportamento

Um modelo de linguagem, quando recebe o corpo de uma função e o prompt “documente isso”, não lê a função como um intérprete executa um bytecode. Ele reconhece padrões: nomes de variáveis, estrutura sintática, convenções de nomenclatura que sugerem intenção. Se a função se chama validateEmail e tem um regex no meio, o modelo vai assumir — com razoável confiança estatística — que ela valida e-mails, mesmo que o regex esteja quebrado para domínios com mais de dois pontos ou que a função, por um bug histórico, sempre retorne true para strings vazias.

Isso não é uma falha pontual de um modelo específico. É uma consequência estrutural de como LLMs operam: eles modelam a distribuição estatística de texto, e código bem escrito tende a ter nomes que descrevem corretamente o comportamento. Quando o código diverge dessa convenção — por dívida técnica, por refatoração parcial, por pressa — o modelo continua gerando a documentação que o código deveria ter, não a que ele tem. O resultado é uma forma nova e mais sofisticada do mesmo problema que já existia com documentação manual desatualizada, só que agora com verniz de autoridade computacional.

💡 Dica do Mestre: vale a pena acompanhar discussões práticas sobre geração automática de documentação, como a thread em um projeto de gerador de documentação com IA discutido na comunidade Python no Reddit, que expõe exatamente essa tensão entre geração automática e fidelidade ao comportamento real do código.

Projetando o pipeline: três camadas de verdade antes da prosa

A solução arquitetural não é desistir de usar IA para documentar — é inverter a ordem das operações. Em vez de pedir ao modelo “explique esse código”, você constrói um pipeline que primeiro extrai fatos verificáveis por ferramentas determinísticas, e só então entrega esses fatos ao LLM para serem transformados em prosa legível. O modelo deixa de ser o analista e passa a ser o redator técnico que trabalha a partir de um briefing factual.

Camada 1 — Extração estática: o que o código realmente declara

Antes de qualquer chamada a um modelo, rode ferramentas de análise estática que extraem assinaturas, tipos, exceções declaradas e grafos de chamada. Essa camada não interpreta intenção — ela apenas relata estrutura.

Esse JSON de fatos é o que vai para o prompt — não o código bruto. Isso reduz drasticamente a superfície de alucinação, porque o modelo não precisa mais “adivinhar” que exceções existem: elas já vêm listadas, extraídas mecanicamente da árvore sintática.

Camada 2 — Evidência de execução: o que os testes provam

A segunda camada é a mais negligenciada e a mais valiosa: extrair comportamento observado a partir da suíte de testes. Se existe um teste que chama calculateDiscount(customer_with_no_history) e afirma que o retorno é 0.10, isso é um fato muito mais confiável do que qualquer inferência sobre o nome da função.

Para ir além dos metadados de execução e capturar valores reais de entrada e saída, instrumentar os testes com um decorador de captura — ou usar ferramentas de tracing como as listadas em comparativos de ferramentas de IA voltadas para análise e segurança de código — fecha ainda mais o gap entre o que a documentação afirma e o que o sistema de fato faz sob teste.

Camada 3 — Síntese via LLM: prosa a partir de fatos, não de suposições

Só agora, com fatos estruturais e evidência de execução em mãos, o LLM entra em cena — e seu papel é estritamente de redação, não de investigação.

A instrução explícita de marcar lacunas com [VERIFICAR MANUALMENTE] em vez de preencher com suposição plausível é o detalhe que faz a diferença entre um pipeline confiável e um gerador de prosa bonita. Você está pedindo ao modelo para admitir ignorância textual sempre que a camada de fatos não cobrir o caso — o equivalente a instruir um estagiário a escrever “não sei” em vez de inventar uma resposta convincente numa entrevista técnica.

Onde isso se encaixa no fluxo de desenvolvimento

Documentação automática só tem valor sustentável se for parte do pipeline de integração contínua, não um comando manual executado esporadicamente. A arquitetura recomendada trata o docstring gerado como um artefato derivado — similar a um binário compilado — que é regenerado a cada merge e comparado contra a versão anterior.

O script check_doc_drift.py compara, via similaridade semântica, o docstring existente no código contra o docstring regenerado a partir dos fatos atuais. Divergência acima de um limiar configurável bloqueia o merge — forçando o desenvolvedor a decidir se o docstring estava errado ou se a regeneração automática precisa de ajuste de prompt. Essa fricção deliberada é o que impede a documentação de apodrecer silenciosamente, o mesmo apodrecimento que motivou o debate sobre até que ponto programar vai se tornar escrever instruções em linguagem natural — porque instruções em linguagem natural só têm valor se refletirem a realidade executável do sistema.

Casos difíceis que a documentação oficial das ferramentas não cobre

Código assíncrono e efeitos colaterais distribuídos

Funções que disparam eventos, publicam em filas ou atualizam estado em sistemas externos são o pesadelo da documentação automática baseada em AST. A assinatura da função não revela que ela publica uma mensagem no Kafka que será consumida três serviços depois. Para esses casos, a camada de extração estática precisa ser estendida com reconhecimento de padrões específicos do seu stack — por exemplo, identificar chamadas a clientes de mensageria conhecidos e anotá-las explicitamente como “efeito colateral assíncrono, consumidor não rastreável estaticamente”.

Sem esse tipo de anotação explícita, o LLM vai documentar a função como se ela fosse pura, porque sintaticamente ela parece ser — e essa é exatamente a classe de erro que mais custa caro em produção, porque engana quem lê a documentação a respeito de dependências ocultas entre serviços.

Código legado sem testes: quando a camada 2 simplesmente não existe

Em bases de código legadas, é comum ter funções críticas sem nenhuma cobertura de teste. Nesse cenário, a tentação é deixar o LLM inferir comportamento só a partir do código-fonte — voltando ao problema original. A alternativa mais honesta é gerar testes de caracterização antes de documentar: rodar a função com entradas representativas, capturar as saídas reais, e usar essas capturas como a evidência de execução que faltava.

Essas observações viram a “evidência de teste” da camada 2, mesmo sem um framework de testes formal por trás. É uma solução de transição — o ideal continua sendo escrever testes de verdade — mas evita que a documentação de código legado seja pura ficção estatística do modelo.

Custo de manutenção: quando o pipeline vira outro sistema para manter

É preciso ser honesto sobre o trade-off: este pipeline de três camadas é, ele mesmo, um sistema de software com custo de manutenção. Scripts de extração de AST quebram quando a linguagem evolui sintaxe nova. Thresholds de similaridade semântica no check de drift precisam de calibração contínua — limiares muito rígidos geram falsos positivos que travam PRs legítimos; limiares muito frouxos deixam a documentação divergir sem ninguém notar. Equipes pequenas, com baixa frequência de mudança em módulos críticos, podem concluir racionalmente que o custo de operar esse pipeline supera o custo de revisar manualmente a documentação a cada poucos meses. A decisão de investir nessa automação deve ser proporcional ao tamanho da base de código, à frequência de rotatividade de desenvolvedores e ao custo real de um engenheiro gastar meio dia reconstruindo contexto perdido — não uma adoção automática porque “IA documenta código” virou chavão de 2026.

💡 Dica do Mestre: antes de investir em um pipeline completo, vale assistir à discussão em um vídeo sobre como usar IA para programar sem atrofiar seu crescimento como desenvolvedor, que trata diretamente da armadilha de terceirizar compreensão — inclusive a compreensão necessária para validar se a documentação gerada está correta.

Integrando ao fluxo de trabalho com agentes e editores

Ferramentas como Claude Code e extensões de IA em editores modernos já oferecem geração de documentação sob demanda, mas a diferença entre usá-las bem e mal está exatamente na disciplina de contexto descrita acima. Ao invés de pedir “documente esse arquivo” direto no editor, configure um comando customizado que primeiro executa a extração de fatos e evidência, e só então invoca o agente com esse contexto estruturado — replicando o mesmo pipeline em modo interativo.

Esse tipo de integração é o que diferencia editores de IA genéricos de um ambiente de desenvolvimento que respeita a arquitetura de confiança que você construiu. Vale comparar como diferentes ferramentas lidam com contexto estruturado em comparativos de editores de código com IA antes de decidir onde embutir esse fluxo — porque nem toda ferramenta permite injetar contexto pré-processado da forma como o pipeline exige.

Participe da Comunidade Dev’s AI

Se você está implementando pipelines de documentação, revisão ou automação com IA no seu dia a dia de desenvolvimento e quer trocar experiências reais — com gente que também lida com os detalhes incômodos de produção, não só com demos bonitas — venha para a Comunidade Dev’s AI. É o espaço onde essas discussões técnicas avançadas acontecem com profundidade, sem o ruído do hype.

Conclusão

A promessa de “documentação automática com IA” só se sustenta quando você reconhece que o modelo de linguagem é a pior ferramenta possível para investigar comportamento de código e a melhor ferramenta possível para transformar fatos verificados em prosa clara. Inverter essa ordem — extrair primeiro, sintetizar depois — é o que separa um pipeline de documentação que sua equipe vai confiar daqui a dois anos de mais uma camada de ruído plausível que ninguém vai ousar deletar, porque parece completa demais para estar errada. O trabalho de engenharia real não está no prompt final que gera o texto bonito; está nas três camadas de extração que garantem que esse texto tenha algum compromisso com a realidade do sistema que ele descreve.

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *