- Mesmo que um LLM continue escrevendo código no seu lugar, se você mesclar condições duplicadas e implementações temporárias do jeito que estão, o código gerado depois pode passar a seguir essa prática como se fosse uma regra do projeto
- Se a lógica de verificação de permissões de acesso for repetida em route handlers, background jobs, endpoints de API e webhooks, os testes podem até passar, mas a carga de manutenção continua a mesma
- Como o modelo gera o próximo código olhando os arquivos abertos, os padrões existentes e as mudanças recentes, 4 condicionais copiadas viram um sinal para criar uma quinta cópia
- Mesmo que você peça um refactor depois, é difícil garantir que o LLM vai organizar corretamente todas as cópias existentes, e um padrão ruim fica mais próximo de um estilo do codebase do que de um erro pontual
- Quando condicionais duplicadas, funções “god” e merges de “arrumar depois” se acumulam, fica difícil reverter isso só com prompts e, no fim, uma pessoa precisa corrigir manualmente
O que o LLM usa como referência é o codebase atual
- O LLM não escreve código “no vácuo”; ele lê o seu codebase
- arquivos abertos
- padrões que já existem
- mudanças recentes
- Atalhos que foram mesclados no codebase viram um sinal de aprendizado de que “é assim que se faz aqui”
- A mesma condição de controle de acesso pode acabar repetida em vários lugares
if (user.isActive && user.hasPermission('read') &&
!user.isSuspended && account.status === 'open') {
// do a thing
}
- Essa condicional poderia ser extraída para um helper compartilhado, mas pode acabar sendo mesclada como está porque o código gerado pelo LLM funciona e os testes passam
- Se você pedir um quinto endpoint com a mesma regra, aumenta a chance de o modelo seguir as cópias existentes no repositório em vez de projetar isso do zero
A ilusão de deixar a manutenção para o LLM
- A ideia de que “depois o LLM resolve quando eu precisar mudar” faz com que duplicação e code smells sejam deixados de lado
- Algumas condicionais duplicadas podem não ser fatais, mas esse tipo de code smell continua se acumulando
- condicionais duplicadas
- funções “god”
- merges feitos com a ideia de “arrumar depois”
- À medida que os padrões ruins aumentam, eles também afetam o resultado dos próximos prompts, e fica difícil acreditar que depois o LLM vai corrigir todas as instâncias sem deixar nenhuma para trás
- Mesmo pensando na manutenção como algo terceirizado para o LLM, na prática isso pode virar uma situação em que você só reforça hábitos que vão piorando com o tempo
- É preciso escrever código como se uma pessoa fosse fazer a manutenção, e manter em bom estado os padrões de código que o LLM vai absorver e devolver
1 comentários
Comentários do Hacker News
É útil criar um comando /review como um arquivo Markdown vazio em
.claude/commands/review.mde colocar lá um checklist que o agente deve verificarQuando preciso de revisão de código, digito
/review, ele consulta esse checklist, planeja o que pode precisar ser corrigido e depois perguntaMeu arquivo começa com “entre no modo de planejamento. Observe a diferença entre esta branch e a main. Considere: ...”, e fui adicionando continuamente itens que encontrei durante revisões de código para o agente corrigir; agora já deve ter uns 200
O agente não se incomoda em receber um paredão de feedback genérico e vai passando item por item; quando adicionei “verifique se o que foi criado não duplica código existente”, fiquei surpreso ao ver que ele realmente começou a planejar trabalho de limpeza
Ainda estamos só arranhando a superfície, e é preciso dar ferramentas para as ferramentas para que a ferramenta se torne melhor
Mesmo agora eu uso instruções bem simples, mas o Claude frequentemente desobedece as primeiras, como “não faça commit no git sem permissão” e “não assine a mensagem de commit”
Se eu pergunto, ele responde “é verdade, havia essa instrução, mas eu a ignorei”; se eu corrijo isso educadamente na sessão, ele entende, mas depois às vezes entra num estado em que não consegue mais fazer commit algum
Se você mandar revisar um checklist de 200 itens, há uma boa chance de ele deixar passar silenciosamente uma parte considerável deles
Um engenheiro humano, vendo que há uma biblioteca de asserções usada por 200 testes existentes, não escreveria um teste novo usando uma biblioteca totalmente diferente, mas o Claude já fez isso várias vezes
Por isso acabo acrescentando itens como “antes de escrever, observe as convenções de teste”
Por outro lado, coisas básicas como o que é uma função, ou que o teste deve lidar com o diff alterado, teoricamente eu não precisaria dizer; mas como não existe uma lista clara do que precisa ser dito e do que pode ficar implícito, parece que estamos chegando a um método utilizável por tentativa e erro
No meu caso, muitas vezes vou refinando na ida e volta com o agente “até parecer aceitável aos meus olhos e ao meu gosto”, mas ainda não cheguei a montar uma lista assim
Dependendo do projeto, tolero probleminhas ou números mágicos; em outros, imponho constantes com nomes significativos, como
SECONDS_IN_A_DAY = 24 * 60 * 60, então isso é dependente do contextohttps://github.com/alibaba/open-code-review
https://layandreas.github.io/personal-blog/posts/beyond-vide...
Por exemplo, fazer com que ele escolha os N papéis mais adequados para a mudança a partir de uma lista longa de funções, como Senior Engineer, Security Engineer e especialista em WCAG
O Claude executa essas revisões em paralelo e depois consolida o feedback
Como faço desenvolvimento orientado por especificação, acrescento os problemas encontrados à especificação para deixar um rastro das questões e decisões
É quase estranho quantos engenheiros estão colocando mais um prompt por cima disso
Pela minha experiência, quanto mais fazem isso, pior fica: abstraem, mas criam abstrações erradas, e enchem de comentários a ponto de confundir até chamadas futuras de LLM
Em codebases boas isso até funciona mais ou menos, mas vai deixando o código cada vez pior, e se você continuar usando assim, quando um dia parar de funcionar vai ter que pagar o preço e consertar algo que não construiu com as próprias mãos
Quando se coloca um agente numa codebase nova, em geral ainda existe um modelo mental do código e o código é relativamente conciso, mas conforme as iterações se acumulam os dois desaparecem, e o desempenho do LLM também cai
Por isso uso LLMs para exploração e revisão, e escrevo o código eu mesmo
Programar nem toma tanto tempo assim e é a parte mais divertida, então é difícil entender por que tentam evitar isso; às vezes faço uma corrida de depuração com a AI usando o prompt
/bug, e a AI nem sempre é mais rápidaNos últimos anos, o trabalho em software deixou de ser um dos refúgios práticos de engenharia para curiosos fuçadores e viciados em quebra-cabeças, e virou uma trilha de carreira para gente inteligente atrás de dinheiro, como finanças, direito ou medicina
Muitas pessoas que hoje têm o título de “engenheiro de software” nunca chegaram a gostar do trabalho em si; só eram inteligentes e responsáveis o bastante para atingir metas razoáveis dadas pelo empregador
São justamente essas pessoas que mais querem que agentes de AI bloqueiem o trabalho rigoroso de projeto e de resolução de quebra-cabeças, permitindo usar sua inteligência inata de forma mais preguiçosa
Como não internalizaram programação e princípios de engenharia, quando ficam cercadas de colegas com a mesma mentalidade é difícil prever que resultado isso vai produzir no futuro
Se programar em si sempre foi, desde o começo, uma experiência muito frustrante e cheia de atrito, é fácil sentir que a AI é mais rápida
Não basta só ler código; é preciso passar pelo sofrimento para internalizá-lo
Agentes frequentemente envolvem código antigo de forma defensiva, em vez de perguntar se aquele caminho existente ainda deveria existir, o que gera uma enorme quantidade de código defensivo com efeito de bonecas russas empilhadas em camadas
https://softwaredoug.com/blog/2026/07/09/write-code
O Opus 4.8 foi o ponto de virada, e agora, especialmente em problemas complexos, eu já não ganho tantas vezes dele
Se todo mundo usasse Opus 4.8 ou superior para todo tipo de tarefa e pergunta, o clima geral seria bem diferente, e acho que não sobrariam tantos céticos de AI
Ainda escrevo o código manualmente, e o Opus gera uma parte, embora não tudo
Pode ser um pensamento fora de propósito, mas dá para simplesmente escrever o código você mesmo
Na era da AI isso parece um conceito difícil de acreditar, mas se é um código que pessoas vão ler e manter, é melhor escrevê-lo pensando nelas
Ler código excessivamente verboso e copiado-e-colado vai irritar você, e os outros também
Se você escreve diretamente, acaba corrigindo por conta própria e escrevendo de um jeito que faz sentido para outra pessoa manter
Ou então pode tentar apaziguar isso criando uma teia complexa de arquivos Markdown para fazer o agente e o loop entenderem qual formato de código o futuro mantenedor vai esperar
Não sei qual dos caminhos será mais fácil no longo prazo, e fico curioso se alguém já herdou uma codebase guiada por agentes baseados em loop e conseguiu entendê-la
Não sei o quanto é verdade a frase “na próxima vez que você pedir ao LLM um endpoint com as mesmas regras de acesso, o modelo não vai pensar do zero e vai começar a partir das quatro cópias que já existem no repositório”
Na prática, parece haver um viés embutido para repetir a estrutura básica e reutilizar ou abstrair menos
Se o padrão existente for esse, parece que ele está apenas seguindo esse padrão, mas na prática é bem provável que teria feito isso de qualquer jeito
Mesmo quando eu primeiro estabeleci abstrações rígidas e exemplos de uso, e instruí explicitamente a usar apenas a API de abstração específica e até copiar o estilo que eu escrevi, muitas vezes os LLMs mais recentes não fizeram nenhuma das duas coisas e reimplementaram a estrutura básica de baixo para cima, ignorando parcial ou totalmente a abstração
Não sei exatamente por quê, mas imagino se não é porque há código demais assim nos dados de treinamento, e os pesos “sabem” melhor produzir resultados desse jeito
Ainda assim, acho ok usar LLM como um motor de implementação rápido
O desafio é fazer com que essas decisões de implementação apareçam antes de o modelo sair correndo na direção errada
Depois de mudanças grandes, tive bons resultados com o seguinte prompt
“Agora faça uma revisão final do código. Está tudo organizado e os componentes seguem o princípio de separação de responsabilidades? Está compreensível e manutenível? Não está fazendo suposições que talvez já não sejam verdadeiras? Não ficou nenhum código de edições anteriores ou experimentos dentro da codebase? A documentação ainda reflete o estado atual do código?”
Aí ele geralmente infere a maior parte do que foi dito acima e até mais
Mas uma coisa que ainda preciso apontar explicitamente o tempo todo é para apagar todos os comentários de “rastreamento de progresso” e deixar apenas comentários adequados para manutenção de longo prazo
O Claude deixa comentários como “o clique no botão agora dispara o salvamento e não usa mais onBlur”, quando na prática o código nunca usou onBlur e isso é só um vestígio do que o Claude tinha tentado fazer antes, no mesmo trabalho/branch, e que eu reverti
O modelo vai interpretar à sua maneira, mas ainda assim muitas vezes é melhor do que não fazer nada
É uma forma de ensinar tudo à AI e depois perguntar se ela aprendeu direito, e os resultados são surpreendentemente bons
Estou seguindo etapas parecidas com as deste texto
https://www.lucasfcosta.com/blog/backpressure-is-all-you-nee...
Existe um velho ditado
“comente o código assumindo que a próxima pessoa a fazer a manutenção é um maníaco homicida que sabe onde você mora”
Encontrei esse tipo de coisa pela enésima vez numa revisão de PR recente, fiquei irritado e deixei um comentário
Até eu mesmo me surpreendi
Não sabia que eu podia reagir assim
Ou seja, significaria que o comentário existe porque o código em si não está claro, e isso às vezes acontece, mas no geral acho melhor ter mais comentários do que menos
Especialmente se eles explicarem como o código se conecta aos requisitos reais de negócio ou de funcionalidade, em vez de apenas repetir o que o código faz
Alguns anos atrás, eu costumava escrever os comentários primeiro
Explicava o objetivo geral, dividia em rotinas e em ordem de tarefas e, quando ficava satisfeito, preenchia os blocos de código entre os comentários
Era quase uma espécie de programação literária, mas eu já fazia isso antes de conhecer o termo, e era mais como dar prompts a mim mesmo em direção ao objetivo
A desvantagem é que os comentários acabam facilmente virando apenas uma explicação em inglês do que o código faz, o que pode não ser tão útil para quem for mantê-lo no futuro
O código deve se explicar sozinho, e comentários são para onde há dragões
Nessa mesma linha, um prompt de que gosto é: “revise o teste que você escreveu. Esse teste realmente testa o que pretendia testar? Se o código quebrar, o teste também falha?”
É impressionante a frequência com que LLMs escrevem testes vazios que não validam nada
Ainda precisamos discutir isso seriamente?
Depois de tanta “experimentação” com LLM, parece que isso já deveria ser aceito como óbvio
Fico me perguntando quando vamos poder voltar a falar de programar à mão sem tratar isso como um tabu
LLMs são úteis de várias formas, mas ver gente delegando a um agente a digitação de todo o código-fonte
me passa uma sensação parecida com ouvir que a web é boa, então deveríamos estar felizes com isso
Tenho passado codebases por vários modelos para continuar procurando maus cheiros como código duplicado
Isso tem sido bem eficaz, e parece que, com o tempo, se você não continuar gerenciando, tudo vira um amontoado bagunçado e isso vai se acumulando
Dá até para colocá-los no pipeline de build, e eles não usam tokens nenhum
Ou será que o mais importante é o processo de revisão e a reinicialização de contexto?
Vi muito esse tipo de duplicação e coisas piores em código mantido por pessoas durante 20 anos
Sinceramente, na maioria das vezes o código escrito e mantido por humanos era pior do que o que os LLMs produzem agora
Às vezes por falta de experiência, às vezes por negligência deliberada, mas no geral por causa de cronogramas apertados e da pressão para entregar logo
As pessoas sabem como fazer melhor, mas não têm tempo nem orçamento para realmente fazer assim
Os LLMs aprenderam isso também