{"id":1334,"date":"2026-10-16T04:01:26","date_gmt":"2026-10-16T07:01:26","guid":{"rendered":"https:\/\/adrianosantostreina.com.br\/blog\/documentacao-automatica-ia-pipeline-sem-mentir\/"},"modified":"2026-10-16T04:01:34","modified_gmt":"2026-10-16T07:01:34","slug":"documentacao-automatica-ia-pipeline-sem-mentir","status":"publish","type":"post","link":"https:\/\/adrianosantostreina.com.br\/blog\/documentacao-automatica-ia-pipeline-sem-mentir\/","title":{"rendered":"Documenta\u00e7\u00e3o Como Proje\u00e7\u00e3o, N\u00e3o Transcri\u00e7\u00e3o: Arquitetando Pipelines de IA que Documentam o C\u00f3digo Sem Mentir Sobre Ele"},"content":{"rendered":"<p>Voc\u00ea j\u00e1 deve ter vivido essa cena: um colega abre um m\u00f3dulo de pagamentos escrito h\u00e1 tr\u00eas anos, encontra um docstring detalhado explicando que a fun\u00e7\u00e3o <code>calculateDiscount()<\/code> &#8220;aplica desconto progressivo baseado no hist\u00f3rico do cliente&#8221;, roda o c\u00f3digo e descobre que a fun\u00e7\u00e3o, na verdade, aplica um desconto fixo de 10% porque algu\u00e9m simplificou a regra numa sprint de emerg\u00eancia e esqueceu de atualizar o coment\u00e1rio. O docstring n\u00e3o \u00e9 s\u00f3 in\u00fatil \u2014 \u00e9 ativamente perigoso, porque carrega autoridade de documenta\u00e7\u00e3o oficial enquanto mente sobre o comportamento real do sistema. Agora troque &#8220;colega&#8221; por &#8220;agente de IA&#8221; e &#8220;docstring&#8221; por &#8220;contexto que o modelo vai usar para gerar o pr\u00f3ximo trecho de c\u00f3digo&#8221;, e voc\u00ea tem o problema central deste artigo.<\/p>\n<p>Documenta\u00e7\u00e3o gerada por IA promete resolver um dos problemas mais cr\u00f4nicos da engenharia de software: a assimetria entre o esfor\u00e7o de escrever c\u00f3digo e o esfor\u00e7o de document\u00e1-lo. Mas a forma como a maioria das equipes adota essa automa\u00e7\u00e3o \u2014 pedir para um LLM &#8220;explicar essa fun\u00e7\u00e3o&#8221; e colar o resultado \u2014 produz exatamente o tipo de artefato que descrevi acima: prosa fluente, plaus\u00edvel, e desconectada da verdade operacional do sistema. Neste artigo vou detalhar como projetar um pipeline de documenta\u00e7\u00e3o autom\u00e1tica que trata a IA n\u00e3o como autora, mas como tradutora de fatos extra\u00eddos mecanicamente do c\u00f3digo, dos testes e do hist\u00f3rico de execu\u00e7\u00e3o \u2014 e por que essa distin\u00e7\u00e3o arquitetural \u00e9 o que separa documenta\u00e7\u00e3o confi\u00e1vel de ru\u00eddo bem formatado.<\/p>\n<h2>O problema de origem: LLMs documentam inten\u00e7\u00e3o, n\u00e3o comportamento<\/h2>\n<p>Um modelo de linguagem, quando recebe o corpo de uma fun\u00e7\u00e3o e o prompt &#8220;documente isso&#8221;, n\u00e3o l\u00ea a fun\u00e7\u00e3o como um int\u00e9rprete executa um bytecode. Ele reconhece padr\u00f5es: nomes de vari\u00e1veis, estrutura sint\u00e1tica, conven\u00e7\u00f5es de nomenclatura que sugerem inten\u00e7\u00e3o. Se a fun\u00e7\u00e3o se chama <code>validateEmail<\/code> e tem um regex no meio, o modelo vai assumir \u2014 com razo\u00e1vel confian\u00e7a estat\u00edstica \u2014 que ela valida e-mails, mesmo que o regex esteja quebrado para dom\u00ednios com mais de dois pontos ou que a fun\u00e7\u00e3o, por um bug hist\u00f3rico, sempre retorne <code>true<\/code> para strings vazias.<\/p>\n<p>Isso n\u00e3o \u00e9 uma falha pontual de um modelo espec\u00edfico. \u00c9 uma consequ\u00eancia estrutural de como LLMs operam: eles modelam a distribui\u00e7\u00e3o estat\u00edstica de texto, e c\u00f3digo bem escrito tende a ter nomes que descrevem corretamente o comportamento. Quando o c\u00f3digo diverge dessa conven\u00e7\u00e3o \u2014 por d\u00edvida t\u00e9cnica, por refatora\u00e7\u00e3o parcial, por pressa \u2014 o modelo continua gerando a documenta\u00e7\u00e3o que o c\u00f3digo <em>deveria<\/em> ter, n\u00e3o a que ele <em>tem<\/em>. O resultado \u00e9 uma forma nova e mais sofisticada do mesmo problema que j\u00e1 existia com documenta\u00e7\u00e3o manual desatualizada, s\u00f3 que agora com verniz de autoridade computacional.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> vale a pena acompanhar discuss\u00f5es pr\u00e1ticas sobre gera\u00e7\u00e3o autom\u00e1tica de documenta\u00e7\u00e3o, como a thread em <a href=\"https:\/\/www.reddit.com\/r\/Python\/comments\/1gx2515\/project_guide_aipowered_documentation_generator\/?tl=pt-br\" target=\"_blank\" rel=\"noopener\">um projeto de gerador de documenta\u00e7\u00e3o com IA discutido na comunidade Python no Reddit<\/a>, que exp\u00f5e exatamente essa tens\u00e3o entre gera\u00e7\u00e3o autom\u00e1tica e fidelidade ao comportamento real do c\u00f3digo.<\/p><\/blockquote>\n<h2>Projetando o pipeline: tr\u00eas camadas de verdade antes da prosa<\/h2>\n<p>A solu\u00e7\u00e3o arquitetural n\u00e3o \u00e9 desistir de usar IA para documentar \u2014 \u00e9 inverter a ordem das opera\u00e7\u00f5es. Em vez de pedir ao modelo &#8220;explique esse c\u00f3digo&#8221;, voc\u00ea constr\u00f3i um pipeline que primeiro extrai fatos verific\u00e1veis por ferramentas determin\u00edsticas, e s\u00f3 ent\u00e3o entrega esses fatos ao LLM para serem transformados em prosa leg\u00edvel. O modelo deixa de ser o analista e passa a ser o redator t\u00e9cnico que trabalha a partir de um briefing factual.<\/p>\n<h3>Camada 1 \u2014 Extra\u00e7\u00e3o est\u00e1tica: o que o c\u00f3digo realmente declara<\/h3>\n<p>Antes de qualquer chamada a um modelo, rode ferramentas de an\u00e1lise est\u00e1tica que extraem assinaturas, tipos, exce\u00e7\u00f5es declaradas e grafos de chamada. Essa camada n\u00e3o interpreta inten\u00e7\u00e3o \u2014 ela apenas relata estrutura.<\/p>\n<pre><code class=\"language-python\">import ast\nimport json\n\ndef extract_function_facts(source_code: str) -&gt; list[dict]:\n    \"\"\"Extrai fatos estruturais de fun\u00e7\u00f5es via AST, sem interpreta\u00e7\u00e3o sem\u00e2ntica.\"\"\"\n    tree = ast.parse(source_code)\n    facts = []\n\n    for node in ast.walk(tree):\n        if isinstance(node, ast.FunctionDef):\n            raises = [\n                n.exc.func.id if isinstance(n.exc, ast.Call) else None\n                for n in ast.walk(node)\n                if isinstance(n, ast.Raise) and n.exc\n            ]\n            calls = [\n                n.func.id for n in ast.walk(node)\n                if isinstance(n, ast.Call) and isinstance(n.func, ast.Name)\n            ]\n\n            facts.append({\n                \"name\": node.name,\n                \"args\": [a.arg for a in node.args.args],\n                \"returns\": ast.unparse(node.returns) if node.returns else None,\n                \"raises\": [r for r in raises if r],\n                \"calls_internally\": list(set(calls)),\n                \"line_count\": node.end_lineno - node.lineno,\n                \"has_docstring\": ast.get_docstring(node) is not None,\n            })\n\n    return facts\n\n# Exemplo de uso\nwith open(\"billing\/discount.py\") as f:\n    facts = extract_function_facts(f.read())\n\nprint(json.dumps(facts, indent=2))\n<\/code><\/pre>\n<p>Esse JSON de fatos \u00e9 o que vai para o prompt \u2014 n\u00e3o o c\u00f3digo bruto. Isso reduz drasticamente a superf\u00edcie de alucina\u00e7\u00e3o, porque o modelo n\u00e3o precisa mais &#8220;adivinhar&#8221; que exce\u00e7\u00f5es existem: elas j\u00e1 v\u00eam listadas, extra\u00eddas mecanicamente da \u00e1rvore sint\u00e1tica.<\/p>\n<h3>Camada 2 \u2014 Evid\u00eancia de execu\u00e7\u00e3o: o que os testes provam<\/h3>\n<p>A segunda camada \u00e9 a mais negligenciada e a mais valiosa: extrair comportamento observado a partir da su\u00edte de testes. Se existe um teste que chama <code>calculateDiscount(customer_with_no_history)<\/code> e afirma que o retorno \u00e9 <code>0.10<\/code>, isso \u00e9 um fato muito mais confi\u00e1vel do que qualquer infer\u00eancia sobre o nome da fun\u00e7\u00e3o.<\/p>\n<pre><code class=\"language-python\">import subprocess\nimport json\n\ndef extract_test_evidence(test_file: str, target_function: str) -&gt; list[dict]:\n    \"\"\"Roda os testes com cobertura e captura quais cen\u00e1rios tocam a fun\u00e7\u00e3o alvo.\"\"\"\n    result = subprocess.run(\n        [\"pytest\", test_file, \"--json-report\", \"--json-report-file=report.json\", \"-v\"],\n        capture_output=True, text=True\n    )\n\n    with open(\"report.json\") as f:\n        report = json.load(f)\n\n    evidence = []\n    for test in report.get(\"tests\", []):\n        if target_function in test.get(\"nodeid\", \"\"):\n            evidence.append({\n                \"test_name\": test[\"nodeid\"],\n                \"outcome\": test[\"outcome\"],\n                \"duration\": test.get(\"duration\"),\n            })\n\n    return evidence\n\nevidence = extract_test_evidence(\"tests\/test_discount.py\", \"calculateDiscount\")\n<\/code><\/pre>\n<p>Para ir al\u00e9m dos metadados de execu\u00e7\u00e3o e capturar valores reais de entrada e sa\u00edda, instrumentar os testes com um decorador de captura \u2014 ou usar ferramentas de tracing como as listadas em comparativos de <a href=\"https:\/\/xygeni.io\/pt\/blog\/top-ai-coding-tools-for-secure-code\/\" target=\"_blank\" rel=\"noopener\">ferramentas de IA voltadas para an\u00e1lise e seguran\u00e7a de c\u00f3digo<\/a> \u2014 fecha ainda mais o gap entre o que a documenta\u00e7\u00e3o afirma e o que o sistema de fato faz sob teste.<\/p>\n<h3>Camada 3 \u2014 S\u00edntese via LLM: prosa a partir de fatos, n\u00e3o de suposi\u00e7\u00f5es<\/h3>\n<p>S\u00f3 agora, com fatos estruturais e evid\u00eancia de execu\u00e7\u00e3o em m\u00e3os, o LLM entra em cena \u2014 e seu papel \u00e9 estritamente de reda\u00e7\u00e3o, n\u00e3o de investiga\u00e7\u00e3o.<\/p>\n<pre><code class=\"language-python\">import anthropic\n\nclient = anthropic.Anthropic()\n\ndef generate_documentation(function_facts: dict, test_evidence: list[dict]) -&gt; str:\n    prompt = f\"\"\"Voc\u00ea \u00e9 um redator t\u00e9cnico. Gere um docstring em formato Google Style\nusando EXCLUSIVAMENTE os fatos abaixo. N\u00e3o infira comportamento que n\u00e3o esteja\nexplicitamente suportado pelos dados. Se um campo estiver ausente ou amb\u00edguo,\nmarque com [VERIFICAR MANUALMENTE] em vez de supor.\n\nFATOS ESTRUTURAIS:\n{json.dumps(function_facts, indent=2, ensure_ascii=False)}\n\nEVID\u00caNCIA DE TESTES:\n{json.dumps(test_evidence, indent=2, ensure_ascii=False)}\n\"\"\"\n\n    response = client.messages.create(\n        model=\"claude-sonnet-4-5\",\n        max_tokens=600,\n        messages=[{\"role\": \"user\", \"content\": prompt}]\n    )\n    return response.content[0].text\n\ndoc = generate_documentation(facts[0], evidence)\nprint(doc)\n<\/code><\/pre>\n<p>A instru\u00e7\u00e3o expl\u00edcita de marcar lacunas com <code>[VERIFICAR MANUALMENTE]<\/code> em vez de preencher com suposi\u00e7\u00e3o plaus\u00edvel \u00e9 o detalhe que faz a diferen\u00e7a entre um pipeline confi\u00e1vel e um gerador de prosa bonita. Voc\u00ea est\u00e1 pedindo ao modelo para admitir ignor\u00e2ncia textual sempre que a camada de fatos n\u00e3o cobrir o caso \u2014 o equivalente a instruir um estagi\u00e1rio a escrever &#8220;n\u00e3o sei&#8221; em vez de inventar uma resposta convincente numa entrevista t\u00e9cnica.<\/p>\n<h2>Onde isso se encaixa no fluxo de desenvolvimento<\/h2>\n<p>Documenta\u00e7\u00e3o autom\u00e1tica s\u00f3 tem valor sustent\u00e1vel se for parte do pipeline de integra\u00e7\u00e3o cont\u00ednua, n\u00e3o um comando manual executado esporadicamente. A arquitetura recomendada trata o docstring gerado como um artefato derivado \u2014 similar a um bin\u00e1rio compilado \u2014 que \u00e9 regenerado a cada merge e comparado contra a vers\u00e3o anterior.<\/p>\n<pre><code class=\"language-yaml\"># .github\/workflows\/doc-sync.yml\nname: Doc Sync Check\n\non:\n  pull_request:\n    paths:\n      - \"src\/**\/*.py\"\n\njobs:\n  check-doc-drift:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v4\n      - name: Install deps\n        run: pip install -r requirements.txt\n      - name: Extract facts and regenerate docs\n        run: python scripts\/generate_docs.py --diff-only\n      - name: Fail if docstrings diverge from generated facts\n        run: python scripts\/check_doc_drift.py --threshold 0.15\n<\/code><\/pre>\n<p>O script <code>check_doc_drift.py<\/code> compara, via similaridade sem\u00e2ntica, o docstring existente no c\u00f3digo contra o docstring regenerado a partir dos fatos atuais. Diverg\u00eancia acima de um limiar configur\u00e1vel bloqueia o merge \u2014 for\u00e7ando o desenvolvedor a decidir se o docstring estava errado ou se a regenera\u00e7\u00e3o autom\u00e1tica precisa de ajuste de prompt. Essa fric\u00e7\u00e3o deliberada \u00e9 o que impede a documenta\u00e7\u00e3o de apodrecer silenciosamente, o mesmo apodrecimento que motivou o <a href=\"https:\/\/coddy.tech\/blog\/pt\/desenvolvimento-de-software\/ia-na-programa%C3%A7%C3%A3o-programar-vai-virar-escrever-prompts-at%C3%A9-2030\" target=\"_blank\" rel=\"noopener\">debate sobre at\u00e9 que ponto programar vai se tornar escrever instru\u00e7\u00f5es em linguagem natural<\/a> \u2014 porque instru\u00e7\u00f5es em linguagem natural s\u00f3 t\u00eam valor se refletirem a realidade execut\u00e1vel do sistema.<\/p>\n<h2>Casos dif\u00edceis que a documenta\u00e7\u00e3o oficial das ferramentas n\u00e3o cobre<\/h2>\n<h3>C\u00f3digo ass\u00edncrono e efeitos colaterais distribu\u00eddos<\/h3>\n<p>Fun\u00e7\u00f5es que disparam eventos, publicam em filas ou atualizam estado em sistemas externos s\u00e3o o pesadelo da documenta\u00e7\u00e3o autom\u00e1tica baseada em AST. A assinatura da fun\u00e7\u00e3o n\u00e3o revela que ela publica uma mensagem no Kafka que ser\u00e1 consumida tr\u00eas servi\u00e7os depois. Para esses casos, a camada de extra\u00e7\u00e3o est\u00e1tica precisa ser estendida com reconhecimento de padr\u00f5es espec\u00edficos do seu stack \u2014 por exemplo, identificar chamadas a clientes de mensageria conhecidos e anot\u00e1-las explicitamente como &#8220;efeito colateral ass\u00edncrono, consumidor n\u00e3o rastre\u00e1vel estaticamente&#8221;.<\/p>\n<pre><code class=\"language-python\">SIDE_EFFECT_PATTERNS = {\n    \"kafka_producer.send\": \"Publica evento ass\u00edncrono \u2014 consumidor externo ao m\u00f3dulo\",\n    \"redis_client.set\": \"Escreve em cache compartilhado\",\n    \"requests.post\": \"Chamada HTTP de sa\u00edda \u2014 efeito observ\u00e1vel fora do processo\",\n}\n\ndef flag_side_effects(calls: list[str]) -&gt; list[str]:\n    return [\n        SIDE_EFFECT_PATTERNS[call]\n        for call in calls\n        if call in SIDE_EFFECT_PATTERNS\n    ]\n<\/code><\/pre>\n<p>Sem esse tipo de anota\u00e7\u00e3o expl\u00edcita, o LLM vai documentar a fun\u00e7\u00e3o como se ela fosse pura, porque sintaticamente ela parece ser \u2014 e essa \u00e9 exatamente a classe de erro que mais custa caro em produ\u00e7\u00e3o, porque engana quem l\u00ea a documenta\u00e7\u00e3o a respeito de depend\u00eancias ocultas entre servi\u00e7os.<\/p>\n<h3>C\u00f3digo legado sem testes: quando a camada 2 simplesmente n\u00e3o existe<\/h3>\n<p>Em bases de c\u00f3digo legadas, \u00e9 comum ter fun\u00e7\u00f5es cr\u00edticas sem nenhuma cobertura de teste. Nesse cen\u00e1rio, a tenta\u00e7\u00e3o \u00e9 deixar o LLM inferir comportamento s\u00f3 a partir do c\u00f3digo-fonte \u2014 voltando ao problema original. A alternativa mais honesta \u00e9 gerar testes de caracteriza\u00e7\u00e3o antes de documentar: rodar a fun\u00e7\u00e3o com entradas representativas, capturar as sa\u00eddas reais, e usar essas capturas como a evid\u00eancia de execu\u00e7\u00e3o que faltava.<\/p>\n<pre><code class=\"language-python\">def characterize(func, sample_inputs: list[tuple]) -&gt; list[dict]:\n    \"\"\"Gera evid\u00eancia de comportamento real executando a fun\u00e7\u00e3o com amostras.\"\"\"\n    observations = []\n    for args in sample_inputs:\n        try:\n            result = func(*args)\n            observations.append({\"input\": args, \"output\": result, \"error\": None})\n        except Exception as e:\n            observations.append({\"input\": args, \"output\": None, \"error\": str(e)})\n    return observations\n<\/code><\/pre>\n<p>Essas observa\u00e7\u00f5es viram a &#8220;evid\u00eancia de teste&#8221; da camada 2, mesmo sem um framework de testes formal por tr\u00e1s. \u00c9 uma solu\u00e7\u00e3o de transi\u00e7\u00e3o \u2014 o ideal continua sendo escrever testes de verdade \u2014 mas evita que a documenta\u00e7\u00e3o de c\u00f3digo legado seja pura fic\u00e7\u00e3o estat\u00edstica do modelo.<\/p>\n<h3>Custo de manuten\u00e7\u00e3o: quando o pipeline vira outro sistema para manter<\/h3>\n<p>\u00c9 preciso ser honesto sobre o trade-off: este pipeline de tr\u00eas camadas \u00e9, ele mesmo, um sistema de software com custo de manuten\u00e7\u00e3o. Scripts de extra\u00e7\u00e3o de AST quebram quando a linguagem evolui sintaxe nova. Thresholds de similaridade sem\u00e2ntica no check de drift precisam de calibra\u00e7\u00e3o cont\u00ednua \u2014 limiares muito r\u00edgidos geram falsos positivos que travam PRs leg\u00edtimos; limiares muito frouxos deixam a documenta\u00e7\u00e3o divergir sem ningu\u00e9m notar. Equipes pequenas, com baixa frequ\u00eancia de mudan\u00e7a em m\u00f3dulos cr\u00edticos, podem concluir racionalmente que o custo de operar esse pipeline supera o custo de revisar manualmente a documenta\u00e7\u00e3o a cada poucos meses. A decis\u00e3o de investir nessa automa\u00e7\u00e3o deve ser proporcional ao tamanho da base de c\u00f3digo, \u00e0 frequ\u00eancia de rotatividade de desenvolvedores e ao custo real de um engenheiro gastar meio dia reconstruindo contexto perdido \u2014 n\u00e3o uma ado\u00e7\u00e3o autom\u00e1tica porque &#8220;IA documenta c\u00f3digo&#8221; virou chav\u00e3o de 2026.<\/p>\n<blockquote><p><strong>\ud83d\udca1 Dica do Mestre:<\/strong> antes de investir em um pipeline completo, vale assistir \u00e0 discuss\u00e3o em <a href=\"https:\/\/www.youtube.com\/watch?v=m_tZrds9OaA\" target=\"_blank\" rel=\"noopener\">um v\u00eddeo sobre como usar IA para programar sem atrofiar seu crescimento como desenvolvedor<\/a>, que trata diretamente da armadilha de terceirizar compreens\u00e3o \u2014 inclusive a compreens\u00e3o necess\u00e1ria para validar se a documenta\u00e7\u00e3o gerada est\u00e1 correta.<\/p><\/blockquote>\n<h2>Integrando ao fluxo de trabalho com agentes e editores<\/h2>\n<p>Ferramentas como Claude Code e extens\u00f5es de IA em editores modernos j\u00e1 oferecem gera\u00e7\u00e3o de documenta\u00e7\u00e3o sob demanda, mas a diferen\u00e7a entre us\u00e1-las bem e mal est\u00e1 exatamente na disciplina de contexto descrita acima. Ao inv\u00e9s de pedir &#8220;documente esse arquivo&#8221; direto no editor, configure um comando customizado que primeiro executa a extra\u00e7\u00e3o de fatos e evid\u00eancia, e s\u00f3 ent\u00e3o invoca o agente com esse contexto estruturado \u2014 replicando o mesmo pipeline em modo interativo.<\/p>\n<pre><code class=\"language-bash\"># comando customizado em .claude\/commands\/document.md\n# Uso: \/document src\/billing\/discount.py\n\npython scripts\/extract_facts.py $ARGUMENTS &gt; \/tmp\/facts.json\npython scripts\/extract_evidence.py $ARGUMENTS &gt; \/tmp\/evidence.json\necho \"Gere documenta\u00e7\u00e3o usando APENAS os fatos em \/tmp\/facts.json e \/tmp\/evidence.json.\"\n<\/code><\/pre>\n<p>Esse tipo de integra\u00e7\u00e3o \u00e9 o que diferencia editores de IA gen\u00e9ricos de um ambiente de desenvolvimento que respeita a arquitetura de confian\u00e7a que voc\u00ea construiu. Vale comparar como diferentes ferramentas lidam com contexto estruturado em <a href=\"https:\/\/www.kimi.ai\/pt-br\/resources\/ai-code-editors\" target=\"_blank\" rel=\"noopener\">comparativos de editores de c\u00f3digo com IA<\/a> antes de decidir onde embutir esse fluxo \u2014 porque nem toda ferramenta permite injetar contexto pr\u00e9-processado da forma como o pipeline exige.<\/p>\n<h2>Participe da Comunidade Dev&#8217;s AI<\/h2>\n<p>Se voc\u00ea est\u00e1 implementando pipelines de documenta\u00e7\u00e3o, revis\u00e3o ou automa\u00e7\u00e3o com IA no seu dia a dia de desenvolvimento e quer trocar experi\u00eancias reais \u2014 com gente que tamb\u00e9m lida com os detalhes inc\u00f4modos de produ\u00e7\u00e3o, n\u00e3o s\u00f3 com demos bonitas \u2014 venha para a <a href=\"https:\/\/adrianosantos.link\/ComunidadeDevAI\" target=\"_blank\" rel=\"noopener\">Comunidade Dev&#8217;s AI<\/a>. \u00c9 o espa\u00e7o onde essas discuss\u00f5es t\u00e9cnicas avan\u00e7adas acontecem com profundidade, sem o ru\u00eddo do hype.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>A promessa de &#8220;documenta\u00e7\u00e3o autom\u00e1tica com IA&#8221; s\u00f3 se sustenta quando voc\u00ea reconhece que o modelo de linguagem \u00e9 a pior ferramenta poss\u00edvel para investigar comportamento de c\u00f3digo e a melhor ferramenta poss\u00edvel para transformar fatos verificados em prosa clara. Inverter essa ordem \u2014 extrair primeiro, sintetizar depois \u2014 \u00e9 o que separa um pipeline de documenta\u00e7\u00e3o que sua equipe vai confiar daqui a dois anos de mais uma camada de ru\u00eddo plaus\u00edvel que ningu\u00e9m vai ousar deletar, porque parece completa demais para estar errada. O trabalho de engenharia real n\u00e3o est\u00e1 no prompt final que gera o texto bonito; est\u00e1 nas tr\u00eas camadas de extra\u00e7\u00e3o que garantem que esse texto tenha algum compromisso com a realidade do sistema que ele descreve.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Voc\u00ea j\u00e1 deve ter vivido essa cena: um colega abre um m\u00f3dulo de pagamentos escrito h\u00e1 tr\u00eas anos, encontra um docstring detalhado explicando que a fun\u00e7\u00e3o calculateDiscount() &#8220;aplica desconto progressivo baseado no hist\u00f3rico do cliente&#8221;, roda o c\u00f3digo e descobre que a fun\u00e7\u00e3o, na verdade, aplica um desconto fixo de 10% porque algu\u00e9m simplificou a [&hellip;]<\/p>\n","protected":false},"author":127,"featured_media":1335,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1334","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/users\/127"}],"replies":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/comments?post=1334"}],"version-history":[{"count":1,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1334\/revisions"}],"predecessor-version":[{"id":1336,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/posts\/1334\/revisions\/1336"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media\/1335"}],"wp:attachment":[{"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adrianosantostreina.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}