9 pontos por GN⁺ 2025-12-24 | 1 comentários | Compartilhar no WhatsApp
  • Para usar LLMs de forma eficaz em grandes bases de código, o ponto central é investir em ‘guia’ (guide) e ‘supervisão’ (oversight)
  • O guia fornece contexto e ambiente para ajudar o LLM a tomar decisões melhores, enquanto a supervisão valida os resultados e orienta a direção
  • É importante construir uma biblioteca de prompts para que o LLM entenda as regras, a documentação e as boas práticas da base de código
  • Gestão de dívida técnica, simplicidade da estrutura do código, modularização e consistência estão diretamente ligadas ao aumento da capacidade de compreensão e da produtividade do LLM
  • Sistemas automatizados de supervisão e verificação são a chave da escalabilidade de longo prazo para ajudar o LLM a gerar código seguro e consistente

Conceitos centrais para escalar LLMs

  • Ainda não existe uma forma consolidada de aplicar LLMs a grandes bases de código, mas investir em guia e supervisão é apresentado como a abordagem mais eficaz
  • Guia (Guidance) significa o contexto e o ambiente que ajudam o LLM a fazer escolhas corretas, enquanto Supervisão (Oversight) é responsável por validar o resultado gerado e ajustar a direção

Investimento em guia

  • Para que o LLM consiga gerar código de alta qualidade em uma única tentativa, alcançando o ‘one-shotting’, é necessário um guia claro
    • Em contraste, quando o resultado é inadequado e exige correção manual, isso vira retrabalho (rework) e é ineficiente
  • Como o LLM gera todas as escolhas dentro do código — nomes de variáveis, estrutura de funções, stack tecnológica etc. — o ideal é que o prompt contenha apenas os requisitos de negócio, e todo o restante possa ser inferido ou esteja codificado

Construção de uma biblioteca de prompts

  • A biblioteca de prompts é um conjunto de contexto para o LLM que inclui documentação da base de código, boas práticas e mapas estruturais
    • Sempre que a saída do LLM se desviar, deve-se revisar “o que precisava ter sido esclarecido” e adicionar isso à biblioteca
    • É importante equilibrar abrangência e concisão
  • No exemplo, documentos como @prompts/How_To_Write_Views.md e @prompts/The_API_File.md são fornecidos ao LLM para orientar o desenvolvimento de funcionalidades
  • O prompt precisa ser suficientemente específico, mas ainda assim é preciso revisar todas as linhas do código gerado

Ambiente e qualidade do código

  • Uma base de código com muita dívida técnica (technical debt) reduz a eficiência do uso de LLMs
    • No caso da Meta, menciona-se que a dívida técnica dificultou atingir metas de automação
  • Código limpo, modularização, nomenclatura clara e estrutura simples aumentam a compreensão e a precisão do LLM
  • No exemplo com Django, o ponto de entrada de cada app fica em um arquivo _api.py, estruturado para que o LLM encontre rapidamente a funcionalidade necessária
    • Ex.: visit_api.handoff_to_doctor(user) unifica o acesso externo em um único ponto
    • O padrão _api é explicitado na biblioteca de prompts para induzir o LLM a consultar o local correto

Investimento em supervisão

  • A automação com LLMs deve ser tratada não como substituição de engenheiros, mas como uma forma de fortalecer a equipe
  • A supervisão leva a investimentos em equipe, alinhamento (alignment) e fluxo de trabalho
    • No nível da equipe, é importante elevar a capacidade de design, o que se conecta diretamente à qualidade da arquitetura
  • Como formas de fortalecer a capacidade de design, são sugeridas leitura de livros, blogs e código, reprodução de trabalhos exemplares e prática de implementação direta
    • Ex.: ampliar a sensibilidade de design analisando códigos como TLDraw e SerenityOS Jakt

Supervisão automatizada

  • Parte da validação de design pode ser automatizada programaticamente
    • Ex.: fornecer feedback imediato no ambiente para erros de tipo ou violações de regras
  • ‘Segurança’ (safety) significa proteger abstrações
    • Segundo a definição de Pierce, uma linguagem segura garante que o programador não quebre abstrações sem querer
  • Exemplo: automatizar com um script de verificação baseado em AST a regra que proíbe acesso direto a arquivos internos entre apps Django
    • Detectando acessos ilegais no formato from visit import logic.internal_file

Verificação (Verification)

  • Além de design e implementação, a etapa de verificação (code review, QA) é essencial para garantir a qualidade
  • À medida que o volume de trabalho cresce, a velocidade de revisão vira gargalo, então são propostas as seguintes melhorias
    • Reduzir a barreira de entrada para que seja possível fazer QA mesmo sem ambiente de desenvolvimento
    • Criar um ambiente em que escrever testes seja simples, incluindo geração de dados de teste
    • Documentar feedbacks recorrentes em PRs para que o LLM possa executar automaticamente parte da revisão
    • Incorporar regras de segurança como padrões do framework

Conclusão e observações adicionais

  • LLMs funcionam especialmente bem em projetos novos (greenfield)
    • Porque não há contexto pré-existente e a exigência de consistência é menor
  • À medida que o projeto cresce, consistência e modularização passam a determinar a produtividade
    • Uma estrutura modular que reutiliza componentes validados é o ponto central para um desenvolvimento eficiente

1 comentários

 
GN⁺ 2025-12-24
Comentários do Hacker News
  • À medida que os modelos melhoram, eles passaram a conseguir lidar com codebases complexos e arquivos longos
    Então eu criei um loop de framework simples que uso repetidamente

    1. Research: peço para descrever a funcionalidade atual e carregar os arquivos relevantes no contexto
    2. Plan: peço um brainstorming de boas práticas para implementar uma nova funcionalidade ou fazer refatoração. O resultado é escrito em um arquivo md
    3. Clear: limpo completamente o contexto. Funciona melhor do que uma compressão simples
    4. Execute plan: recarrego só o plano e mando executar. Se necessário, repito perguntas
    5. Review & test: limpo o contexto de novo e peço para revisar se o plano foi bem aplicado. Nessa etapa adiciono código de teste, lint, typecheck etc.
      Rodando esse loop por 20~30 minutos, sai um resultado bem utilizável. No fim, o ponto central é gerenciar o contexto e criar um loop de feedback com testes
    • Em dezembro de 2025, modelos como Sonnet/Opus e GPTCodex já têm capacidade de exploração com subagentes embutida
      Se você iniciar a exploração com a palavra-chave “explore”, eles conseguem fazer a fase de Research sem precisar escrever um plano separado ou limpar o contexto
      Ainda assim, tendem a assumir que a linguagem do código é C ou Python, então às vezes geram código desestruturado, como dividir algo em cinco funções em vez de encapsular o estado em um objeto
      Além disso, o claude às vezes ignora o CLAUDE.md, então é mais estável mandar ler esse arquivo primeiro e só depois pedir “explore”
      Os modelos mais novos descartam melhor o contexto inútil, mas nos antigos a abordagem baseada em documento de plano ainda costuma funcionar melhor
    • Se o modelo falha na capacidade básica de raciocínio, nenhum workflow resolve
      Muitas vezes ele executava o oposto exato do plano e das diretrizes, ou relia a mesma frase e chegava à conclusão contrária
      Por um tempo eu acreditei que dava para montar um processo centrado em LLM, mas hoje tenho menos certeza
      Quando o modelo está em “bom estado”, tudo bem, mas colocá-lo nesse estado ainda depende muito de sorte
    • Eu também uso uma abordagem parecida. Me inspirei nas diretrizes de Advanced Context Engineering da HumanLayer
      Adicionei comandos personalizados como /research_codebase, /create_plan e /implement_plan ao Claude Code
      Funciona muito bem com revisão e ajustes cuidadosos, mas não conseguiu se espalhar pelo time inteiro
    • Eu quase não uso esse tipo de procedimento. Com GitHub Copilot e Claude Sonnet 4.5, instruções claras já bastam para resolver bem
      Só limpo o contexto quando vou criar uma funcionalidade totalmente nova. No Codespaces funciona bem, mas o recurso Tasks é quase inútil
      Se eu passo uma tarefa grande, ele às vezes vai para uma direção aleatória, então é preciso ficar sempre de olho
    • Eu também uso quase o mesmo workflow. Deixo os arquivos md de planejamento no repositório para servirem de referência ao adicionar novas funcionalidades
      Também é útil para repriming de contexto, então uso bastante
  • Para tornar uma biblioteca de prompts útil, é preciso fazer melhoria iterativa
    Sempre que o LLM sai um pouco do trilho, eu me pergunto: “o que eu deveria ter deixado mais claro?” e adiciono essa resposta ao prompt
    Só apertar Enter ou aprovar automaticamente desperdiça tokens. Em vez disso, observo onde o LLM trava e registro isso brevemente no CLAUDE.md
    Quando o arquivo de contexto fica grande, separo por tipo de tarefa
    Meu principal caso de uso é explorar a codebase, rastrear caminhos de execução e fornecer resumos dos arquivos necessários. Se você especificar como o resultado deve ser entregue para cada tipo de pergunta, fica muito mais eficiente

    • Um método melhor do que perguntar “o que eu deveria ter deixado mais claro?” é fazer o próprio LLM se perguntar isso
      Eu chamo isso de “Student Pattern (Fresh Eyes)”. Um subagente lê a documentação ou o código com o olhar de um iniciante e encontra pontos de confusão, contradições e informações ausentes
      É excelente para capturar conhecimento implícito que o desenvolvedor deixa passar. É útil como etapa anterior à revisão de documentação nova ou à avaliação de prompts
    • Eu também faço isso, mas o Claude Code às vezes ignora prompts ou documentação demais
      Mesmo quando mando ler o CLAUDE.md várias vezes, ele frequentemente ignora, e isso também acontece de forma aleatória logo no começo da sessão
      Mesmo com documentos e comandos todos preparados, ainda há muitos casos em que ele simplesmente “esquece”
  • Estou experimentando estruturar codebases grandes de forma amigável para agentes
    Decompus o projeto em um grafo direcionado baseado em nix flakes, de modo que cada nó tenha um ambiente de desenvolvimento independente
    Ao executar o Claude Code no devshell do flake, ele enxerga só aquele escopo e evita sobrecarga de contexto
    Faço a colaboração acontecer por entradas e saídas entre flakes, e deixo que troquem pedidos de funcionalidades e testes entre si
    Acho que essa divisão de contexto é a chave para reduzir o problema da explosão de tokens

    • Essa abordagem é interessante. Eu também venho pensando na correlação entre estrutura e propriedades de software
      Em vez de apenas melhorar workflows existentes, precisamos projetar novas estruturas que o LLM consiga escalar com facilidade
      Estou explorando a relação entre propriedades como “testabilidade, escalabilidade e segurança” e a estrutura do código
    • Além da divisão de contexto, isso também é interessante pelo lado da reprodutibilidade e fixação de dependências
      Eu já fiz experimentos parecidos em projetos baseados em Docker e gostaria que existisse uma ferramenta que automatizasse isso
  • LLMs explicam muito bem assuntos que eu não conheço, mas na minha área de especialidade erram com confiança

    • Isso parece o efeito Gell-Mann Amnesia
    • Varia bastante conforme o tema. Para mim ele foi preciso em web, mas em linguagens raras como Hare foi um desastre
    • Talvez isso aconteça porque em áreas que não conhecemos fazemos perguntas simples, enquanto nas que conhecemos fazemos perguntas muito mais difíceis
    • Na verdade, também pode ser que em áreas que não conhecemos não consigamos distinguir besteira
  • Eu tenho uma visão diferente. A melhor forma de aumentar o desempenho do LLM é embutir significado na própria codebase
    Ou seja, código estruturado como em DDD (Domain-Driven Design) também é mais fácil para o LLM entender
    Tentar forçar ferramentas para lidar com código complexo é desperdício de dinheiro
    No fim, o que os LLMs provaram é que a filosofia do DDD, com ênfase em “linguagem e significado”, estava certa
    Texto relacionado: DDD & the Simplicity Gospel

    • Eu também gerencio duas codebases grandes, e a mais estruturada é muito mais fácil para o LLM entender
  • Sobre a pergunta “por que os LLMs funcionam bem em projetos greenfield?”, eu tive a experiência oposta
    Quando um padrão se repete 2 ou 3 vezes na codebase, o LLM aprende aquilo e reproduz com consistência
    Mas “consistência” não é o mesmo que “qualidade”. Se você buscar só consistência sem critérios, acaba com código impossível de manter

  • A frase “código que engenheiros não entendem, LLMs também não entendem” está certa, mas o inverso não vale
    Muitas vezes humanos entendem, mas agentes não
    Tornar uma codebase mais fácil para agentes entenderem do que para humanos é ainda mais difícil
    Também existe a afirmação de que “se você transferir o feedback para o computador, a taxa de sucesso em uma tentativa sobe”, mas isso é parecido com afirmar que P=NP
    O fato de verificar ser fácil não significa que encontrar a solução também seja
    Linguagens como ATS ou Idris permitem escrever provas de correção junto com o código
    Se essa afirmação estivesse certa, então LLMs deveriam mostrar o melhor desempenho nessas linguagens
    Mas não é o que acontece na prática. No fim, hoje acho que é melhor esperar pela melhora dos modelos

  • Por causa desses problemas, eu acho que frameworks opinionados vão aumentar a produtividade de programação com IA
    Como o LLM já conhece as regras do framework, não é preciso diretrizes separadas

    • Trabalho numa codebase com 1,6 milhão de linhas, e em lugares com muita inconsistência de padrões o LLM era quase inútil
    • Eu fiz o mesmo app em várias linguagens, e em Rails ele ficou praticamente pronto de imediato, e com Bun também foi ok
      Já em Go, Rust, Elixir e C# ele exigiu muito mais dependências e instruções
      Em Rust o resultado foi bom, mas trouxe mais de 200 pacotes, o que virou um peso grande
  • O princípio “Garbage in, garbage out” está certo, mas não se aplica totalmente a LLMs
    Eles foram treinados com os dados ruidosos da internet inteira e ainda assim funcionam muito bem
    Alucinação (hallucination) acontece com mais frequência por causa de contexto impreciso do que por ruído simples
    Mesmo uma codebase mal estruturada ainda pode fornecer contexto útil se tiver bastante informação

  • No fim, as pessoas estão reaprendendo princípios básicos
    Estão redescobrindo que documentação (= biblioteca de prompts) e estrutura de código organizada aumentam a velocidade de desenvolvimento

    • Ainda assim, se isso fizer mais gente começar a escrever testes, já não me parece nada ruim