- 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
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
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
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
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
Adicionei comandos personalizados como
/research_codebase,/create_plane/implement_planao Claude CodeFunciona muito bem com revisão e ajustes cuidadosos, mas não conseguiu se espalhar pelo time inteiro
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
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
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
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
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
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
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
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
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