A geração de código por LLM pode levar ao enfraquecimento da confiança
(jaysthoughts.com)- Recentemente, a geração de código baseada em LLM vem sendo cada vez mais usada entre desenvolvedores
- O código gerado automaticamente tem ampliado as preocupações com a qualidade e a confiabilidade do código
- Desenvolvedores relatam maior dificuldade de manutenção de projetos devido à falta de compreensão do código e à validação insuficiente
- A disseminação do uso de código não confiável afeta todo o ecossistema de software
- Com o avanço da tecnologia, destaca-se a necessidade de criar formas de garantir a confiabilidade
Visão geral
Em seu blog, Jay aborda o impacto recente das tecnologias de geração de código baseadas em LLM (modelos de linguagem de grande porte) no desenvolvimento de software. Embora a evolução dessas ferramentas esteja aumentando a eficiência no desenvolvimento, também traz à tona questões de confiabilidade e qualidade do código.
A ascensão da geração de código com LLM
- Ferramentas de geração automática de código com uso de LLM estão se espalhando rapidamente no ambiente de desenvolvimento
- Elas oferecem alta produtividade na implementação de funcionalidades complexas ou em tarefas repetitivas de programação
- Têm como vantagens a prototipagem rápida e a redução da carga de aprender novas linguagens
Problemas de confiabilidade
- O código gerado por LLM nem sempre funciona como pretendido
- Como a intenção e a lógica de projeto dentro do código nem sempre ficam claras, os processos de compreensão e validação se tornam difíceis
- Se os processos de revisão e teste forem insuficientes, podem surgir bugs ou vulnerabilidades inesperadas
Manutenção de projetos e impacto no ecossistema
- Surgem problemas de falta de documentação e explicações insuficientes sobre o código gerado automaticamente
- Como os desenvolvedores têm dificuldade para entender como o código funciona, a complexidade da manutenção aumenta
- Existe o risco de deterioração da cultura de desenvolvimento de software confiável
Conclusão e sugestões
- A geração de código baseada em LLM é inovadora, mas garantir a confiabilidade é um desafio essencial
- Ao adotar código gerado automaticamente, destaca-se a necessidade de reforçar a validação e realizar revisões de código sistemáticas
- No longo prazo, é importante estabelecer critérios para proteger a confiança no ecossistema computacional
1 comentários
Opiniões no Hacker News
https://archive.is/5I9sB
Funciona até em navegadores antigos e não precisa de JavaScript, exceto ao passar pelo CloudSnare
Um amigo sempre diz que “a inovação acontece na velocidade da confiança”, e desde o GPT-3 essa frase não sai da minha cabeça
Verificar é caro, e o principal meio de reduzir esse custo é a confiança. Não sei como fazer para confiar em LLMs. Eles são muito fluentes tanto em código quanto em linguagem natural, mas, ao mesmo tempo, entram de bom grado em tocas de coelho que se aprofundam infinitamente como fractais e também exibem comportamentos que, em uma pessoa, seriam vistos como maliciosos
Este novo mundo em que tudo precisa ser sempre verificado é bem cansativo e, francamente, muito lento
É útil demais para ignorar, e confiança sempre é construída tijolo por tijolo. Não podemos esquecer que humanos, para começo de conversa, também não são tão confiáveis assim. Como dirigir um carro, a capacidade de produzir código com menos bugs em vias previamente definidas parece que em breve vai superar a dos humanos; depois disso, será apenas uma disputa de fundamentos para melhorar a complexidade
Na ciência, vamos construindo confiança ao longo do caminho
Passei por isso no trabalho de uma forma diferente do que eu esperava. Um colega e eu estávamos sob pressão para mostrar progresso, e decidi apressar o merge de uma refatoração bem grande em que eu estava trabalhando. Era um PR em rascunho, mas fizemos o merge por causa do impulso, e na semana seguinte apareceram alguns bugs em áreas de código não testadas
Durante a depuração, meu colega revelou que tinha presumido que eu teria escrito aquilo com IA e disse que era frustrante tentar entender um artefato gerado por IA depois do fato. Mas esse código não foi feito com IA. Claro que uso IA para escrever código, mas esse código foi escrito à mão, pensando cuidadosamente no design geral. Os bugs não eram falhas fundamentais da refatoração, e sim pequenas omissões surgidas ao ajustar o código existente à API alterada
No fim, acabou sendo uma experiência de construção de confiança, porque conseguimos falar explicitamente sobre a tensão com o colega. Foi uma forma relativamente suave de encarar a força do que está acontecendo agora. Olhando para trás, fico feliz que tenha se resolvido assim, e imagino que em outro ambiente de trabalho poderia ter ficado muito mais complicado. É preciso tomar cuidado
Cerca de 4 anos atrás, cometi uma grande estupidez. Um jornal local publicou uma matéria com uma alegação absurda sobre uma pessoa, usando uma foto como principal prova, e eu mandei um e-mail diretamente ao editor explicando por que tinha certeza de que a imagem havia sido manipulada. Minha lógica se apoiava em um mal-entendido meu: interpretei errado o fato de que a pessoa em questão havia posado com várias pessoas em um meet-and-greet, quase sem mudar de posição e postura. O editor ficou ofendido e respondeu em tom de deboche; quando não recuei, ele percebeu que eu não era um agitador, só burro mesmo, e compartilhou comigo o vídeo completo inédito de onde a foto tinha sido tirada. Na época, pedi desculpas profundamente e também fiz uma doação; depois disso, meu ego ficou devidamente menor por um ano
Antes de mandar o e-mail, eu não queria fazer uma acusação falsa, então compartilhei a foto com amigos ponderados e pedi a opinião deles; como eles também concluíram que havia grande chance de a imagem ter sido manipulada, eu estava bastante confiante. Hoje confio implicitamente naquele jornal e nas pessoas envolvidas, mas deu muito trabalho convencer uma única pessoa
É difícil entender a premissa. Se você confia que alguém escreve bom código, essa confiança foi aprendida porque o código dessa pessoa funcionou bem, não porque exista, na mente dela, algum modelo mental a priori que “produz bom código”
Se alguém usar um LLM para criar código sem bugs, vou confiar. Se alguém usar um LLM para criar código cheio de bugs, não vou confiar. O que muda em relação à época em que essa pessoa fazia código usando apenas a própria cabeça?
Por causa dos LLMs, ficou muito difícil julgar imediatamente a qualidade do desenvolvedor que enviou um patch olhando apenas para o código submetido. Se não dá para estimar que tipo de pessoa é a outra parte, você volta ao “sem confiança” e precisa revisar tudo de forma muito minuciosa. Ou seja, não existem mais “atalhos de review” seguros, e isso pode ser doloroso em lugares que dependiam desses sinais para fazer o trabalho andar. Se a equipe já é competente e de alta confiança, esse problema não se aplica, e é bem provável que o próprio conceito pareça estranho
Se a pessoa contribuidora explica bem as mudanças, confio mais. Se fez um ótimo trabalho no passado, confio mais. Se gerencia bem o escopo das mudanças, como em commits razoáveis, confio mais. Se escolhe os problemas certos, como corrigir bugs antes de adicionar novos recursos, confio mais. Se mostra que consegue manter o código existente, em vez de simplesmente empilhar coisas por cima, confio mais. Se contribui regularmente, confio mais
O problema frequentemente é falha de comunicação. Para quem executa a tarefa, ela pode estar clara, mas, por causa das frequentes reinicializações de contexto, é difícil garantir que o LLM também conheça o quadro completo; quando há ambiguidade, ele tende a fazer suposições idiotas. Acho que a forma como o deep research do 4o pede informações adicionais antes de fazer algo deveria se tornar padrão também na geração de código. Isso poderia evitar uma montanha de problemas
Em alguns casos, é simples. É uma questão de esta rotina retornar ou não o valor desejado. Mas outras situações são muito mais complexas, porque exigem prever como ela vai interagir com outras partes do sistema e quais casos de borda pouco visíveis podem existir. Numa situação dessas, para escrever código “sem bugs”, o autor precisa entender as implicações do código; se o desenvolvedor não entende exatamente o que o código escrito pelo LLM faz, também não consegue entender essas implicações. Então esse ônus passa para o reviewer, aumentando a carga de trabalho dele. Essa era a premissa
Uma boa regra prática é simplesmente rejeitar trabalhos que tenham envolvimento de LLM e ignorar comunicações escritas por LLM. Mesmo para alguém que usa inglês como língua estrangeira, acho que o inglês “imperfeito” da própria pessoa é muito melhor do que o ChatGPT falando por ela. À medida que os problemas graves dos LLMs ficarem mais claros, acho que esse tipo de política vai se tornar o padrão geral, e espero que isso aconteça
O LLM faz qualquer tipo de trabalho ruim parecer um trabalho plausivelmente bom. Por isso, é razoável descontar automaticamente o valor do resultado de alguém que usou IA
Há algum tempo, um dos meus parentes acabou se revelando um golpista. Depois que foi descoberto, cortei contato dizendo que não o conhecia, e ele disse: “Eu sou a mesma pessoa que você conheceu por 10 anos”. Respondi: “Talvez. Mas só agora percebi que eu não fazia a menor ideia de quem essa pessoa era, e que nunca poderei saber”
Todos nós presumimos que as pessoas em nossas vidas não estão ativamente tentando nos prejudicar. Quando essa confiança se quebra, ela se quebra de forma muito forte. Quem usa IA não pode afirmar “este é meu trabalho”. Porque não dá para saber se é seu trabalho. Quem usou IA também não pode afirmar que é um bom trabalho a menos que o entenda profundamente, e provavelmente não vai entendê-lo profundamente. Muitos dos meus alunos afirmaram ter lido e entendido textos que escrevi, mas descobri que, na prática, não tinham entendido. E se eu fosse uma IA, e eles tivessem pegado meu trabalho e colocado o próprio nome como autores? Eles não conseguiriam explicar nada, defender nada nem dar continuidade ao trabalho. Esse problema já existia antes da IA, mas agora ficou dez vezes pior
Sou alguém que dedicou “mais de 10 mil horas” à programação de aplicações complexas antes do surgimento de LLMs úteis. Durante anos, todas as noites eu mergulhava em documentação e no código-fonte de outras pessoas, totalmente imerso em dominar full-stack. No fim, essa imersão levou a um burnout grave, minha saúde piorou e meu casamento ficou abalado. Logo depois de lançar uma aplicação, precisei me afastar completamente por 3 anos para me recuperar, e tinha certeza de que nunca mais conseguiria voltar a isso
Depois de ouvir muitas histórias de que os LLMs tinham ficado bastante bons em código, voltei com cautela ao computador, e foi nesse ponto que minha experiência se afastou bastante dessas preocupações. Não consigo concordar com a frase “quem usa IA não pode afirmar ‘este é meu trabalho’”. Quando uso um LLM, sou o arquiteto e o revisor final. Direciono a visão, projeto o sistema e reviso, com ferramentas de diff, cada linha gerada pelo LLM. Recentemente, criei com um LLM um modelo de otimização complexo para o mecanismo de cotação do meu negócio. Usar um modelo de otimização de verdade sempre foi o modo “correto”, mas antes isso teria exigido meses de trabalho árduo para aprender todos os detalhes da biblioteca e ler código de outras pessoas. Desta vez, terminei em uma semana. Isso parece meu trabalho? Completamente. Eu só tinha um assistente incansável e excelente, embora às vezes falho
Minha experiência também contraria a ideia de que o usuário “provavelmente não vai entender profundamente”. Para usar um LLM de forma eficaz em algo não trivial, é preciso ter uma compreensão mais profunda dos fundamentos para guiar o LLM e detectar os erros sutis que acontecem com frequência. Sem meus anos de experiência, eu não teria conseguido conduzir um desenvolvimento complexo em múltiplos módulos, depurar a saída, nem perceber que um trabalho que parecia plausivelmente bom estava, na verdade, errado de maneiras como um problema N+1
Tenho empatia pela experiência como professor. O problema de alunos fingirem ter entendido com essas ferramentas é real e difícil. Na academia, o objetivo é o processo de aprendizagem, ou seja, obter alguma parte substancial daquelas 10 mil horas. Mas no mundo profissional, o objetivo são os resultados, e isto é uma ferramenta nova e poderosa para obter resultados melhores. Não sei como os professores deveriam ensinar alunos nesta nova realidade, mas demonizar o uso de LLMs provavelmente não é o melhor caminho
Para mim, isto não fez um trabalho ruim parecer bom. Tornou possível fazer um ótimo trabalho de novo e, ao mesmo tempo, me devolveu a minha vida. Trouxe de volta o prazer do craft de desenvolver software sem destruir a mim e à minha família, e hoje minha vida está muito mais equilibrada, pelo que sou grato
Para mim, já é assim. Já li “desculpe por não ter percebido, você está totalmente certo” um número enorme de vezes. Algo como 8 ou 9 em cada 10
Por outro lado, continuo vendo pessoas copiarem sem pensar código gerado por LLM pago e ficarem furiosas quando ele não funciona como esperavam. Aliás, essa é a melhor alternativa. Porque algo claramente quebrado é preferível a algo que, por fora, parece funcionar
Mesmo assim, mecanismos de previsão ainda não conseguem fazer engenharia de verdade. Se você não instruir especificamente para usar algo como um generator em Python, é bem provável que o resultado seja um código que consome memória demais. Infelizmente, isso não é muito diferente de muitos programadores Python que conheço, mas também é um exemplo de como o LLM é exatamente ruim do jeito descrito. O lado positivo é que ele faz as pessoas realmente escreverem especificações mais detalhadas do que uma linha dizendo “adicionar funcionalidade”
O lugar em que agentes de IA são mais úteis para nós é em código legado que ninguém prioriza. Temos um extrator de dados escrito no milênio passado, que usa cerca de 200 coordenadas hardcoded para extrair dados de um tipo específico de documento recebido por fax. O documento não mudou por uns 30 anos e funcionava bem, mas mudou recentemente, e o Copilot levou cerca de 30 segundos para corrigir as coordenadas. Para uma pessoa, provavelmente teria sido um dia inteiro de trabalho extremamente tedioso. Mas não faço a menor ideia de como nosso setor pretende formar especialistas na era do vibe coding
Lutar contra os LLMs é como mijar contra o vento
Os LLMs do jeito que existem hoje parecem tornar os desenvolvedores mais produtivos. É possível que tragam ganhos maiores para desenvolvedores menos experientes do que para desenvolvedores experientes. Ganhos de produtividade, talvez ganhos de produtividade por multiplicadores muito grandes, não serão abandonados por causa de obstáculos criados por pessoas que se opõem à tecnologia por qualquer motivo
Mesmo que surja um exemplo de uma nova ferramenta de produtividade causando um dano enorme, como um bug que deixe um grande serviço fora do ar por um tempo considerável, se a tecnologia oferecer produtividade significativa, ela não será interrompida. O único caminho razoável é trabalhar com a tecnologia e mitigar seus pontos fracos. E essas mitigações não devem ser um conjunto de regras que elimine completamente os ganhos de produtividade da nova tecnologia. As mitigações precisam funcionar junto com a tecnologia, no sentido de ampliar sua adoção; caso contrário, serão contornadas
Pela minha experiência, quem afirma com convicção que ficou 10 vezes mais produtivo graças aos LLMs geralmente é um desenvolvedor frontend relativamente júnior, ou desenvolvedores de startups em série que ficam criando novos apps do zero. Claro que é um caso de uso totalmente válido, mas é por isso que um desenvolvedor frontend júnior e um desenvolvedor C embarcado sênior tendem a falar de coisas diferentes ao discutir ganhos de produtividade com IA
Em vez de dizer que a única coisa razoável é trabalhar com a tecnologia e mitigar seus pontos fracos, basta usá-la com mais discernimento. Por exemplo, a própria ideia de um “agente” de IA é boa? O recente caso do Copilot[0] fez a MS e a IA parecerem motivo de piada. É bem possível que a tentativa de fazer a IA trabalhar de forma autônoma em si não seja muito sensata
Uma analogia recente é blockchain e criptomoedas. Gostando ou não, pelo sucesso da Coinbase e de outras, está claro que blockchain encontrou um caso de uso real, mas estreito. Mas, no auge da febre das criptomoedas, havia gente dizendo coisas como “vamos rastrear a cadeia de suprimentos dos grãos de café com blockchain”. Em 2025 isso soa como uma piada exagerada do Twitter, mas em 2020 a IBM estava de fato tentando vender algo assim[1]. Talvez, um dia, olhando para trás, vejamos que agentes de IA ou algumas das aplicações atuais de IA generativa foram o blockchain do café dessa bolha
[0] https://www.reddit.com/r/ExperiencedDevs/comments/1krttqo/my...
[1] https://www.forbes.com/sites/robertanzalone/2020/07/15/big-c...
Mas isso não significa que a combinação modelo/humano atenda às necessidades do usuário de forma mais eficaz. Significa produzir “mais código”. Não existe LLM que entregue um conjunto de mudanças que remove 2.000 linhas de código. É por isso que dá para saber que, quando dizem “torna os engenheiros mais produtivos”, estão falando da quantidade de código gerada
Você argumenta como se fosse uma dicotomia entre usar ou não usar LLMs, mas o autor está falando principalmente de mitigação de riscos. Fazendo uma analogia: é como se o autor tivesse apontado que alguns carros explodiram e dito que, como os cavalos antigos não explodiam, deveríamos tornar os carros menos propensos a explodir antes de ligar a fábrica de cola; mas você parece achar que o autor é fundamentalmente contra o desenvolvimento dos carros em si
Ainda hoje tenho resistência a usar GPT, mas recentemente meus colegas dizem coisas como “o ChatGPT disse que...” ou “este código foi feito pelo ChatGPT”. Sinto orgulho de escrever código diretamente e não usar GPT, mas ao mesmo tempo uso Google e Stack Overflow. Dá para dizer que isso também é uma versão mais lenta do GPT
Parece que o autor deixou passar que atores imperfeitos e probabilísticos também podem criar sistemas determinísticos confiáveis
Você provavelmente não confiaria em uma ferramenta de coleta de lixo pela confiabilidade do autor, e sim por ver, depois de testes extensivos, se ela comprovadamente faz o que se propõe a fazer. É perfeitamente possível imaginar a confiança se enfraquecendo daqui para frente, e acho que, como resultado, o desenvolvimento orientado a testes vai ganhar mais força. Não confie; verifique
A pergunta mais importante é: quem testa os próprios testes? No desenvolvimento tradicional, toda lógica é implementada duas vezes: uma no código e outra nos testes. Os testes verificam o código e, inversamente, o código verifica implicitamente os testes. É bastante comum o bug estar nos testes, não no código da aplicação. Não dá para confiar cegamente nos testes e esperar até que um agente encontre uma forma de replicar o bug dos testes no código
Pegando o exemplo da coleta de lixo: claro, talvez um dia um sistema agentivo consiga subir alguma coisa e ajustá-la na marra com um test harness, correções de bugs etc. Mas imagine usar o modelo como o próprio coletor de lixo/ferramenta. Por exemplo, a cada sweep, você joga a memória do programa no modelo e o instrui a liberar os blocos desnecessários. Você jamais poderia confiar que o modelo identificaria exatamente os blocos de memória corretos, e nenhuma “correção” ou “ajuste fino” levaria você até lá
Em abstrações do passado, como a JVM, se a saída determinística — neste caso, o assembly emitido pelo JIT — estivesse errada, esse bug era corrigido e aquela abstração nunca mais teria a mesma falha. LLMs não são assim. Quando falamos de ferramentas de desenvolvimento do passado que mudaram toda a natureza da indústria, essa diferença é muito importante para mim. Não estou dizendo que LLMs não terão um impacto profundo na forma como as coisas vão funcionar no futuro. Só acho que entramos em um território totalmente desconhecido, quase sem precedentes históricos
Também não entendo por que o desenvolvimento orientado a testes sempre é apresentado como uma bala de prata que resolve todos os problemas de construção de software. A quantidade de vezes em que vi TDD partir de testes errados e produzir software errado é, francamente, constrangedora
É preciso especificar os resultados, não o processo. Esperar que um colaborador entenda o patch é uma boa ideia
Mas recomendar ou exigir que um júnior evite ferramentas assistidas por LLM por um tempo durante o onboarding é uma ideia terrível. Onboarding tem muitos problemas aleatórios de configuração de ambiente, e LLMs muitas vezes são bem fortes nisso. Também envolve se atualizar sobre o código e a documentação, e há ótimas ferramentas de busca/sumarização de texto que eu gostaria de compartilhar
Parece bem óbvio que, se você remove suavemente todas as dificuldades e complexidades da vida, em pouco tempo, quando se deparar com dificuldade ou complexidade, não fará a menor ideia do que fazer. Só eu penso assim?
É a primeira vez que ouço falar do fenômeno que o autor chama de penhasco da IA, em que LLMs “aproximam algo próximo da resposta correta por algum tempo e, depois de um tempo, a precisão despenca”. Outras pessoas já passaram por isso?
Os geradores atuais tendem a deixar as coisas mais complexas com o tempo, em vez de mais simples. Sou sempre eu que faço prompts para o LLM refatorar para algo mais simples, ou que refatoro manualmente quando fica complexo demais para o LLM lidar. Então, pelo menos com a geração atual de LLMs, parece bastante inevitável que, se você simplesmente “soltar as rédeas do LLM” e deixá-lo fazer o que quiser, ele acabe criando uma enorme bagunça à la Rube Goldberg, e você depois tente limpar aquilo
Ligando isso ao ponto do texto: alguém experiente consegue perceber cedo quando o LLM começa a levá-lo para alto-mar e, mesmo que vá um pouco longe, encontra o caminho de volta para águas rasas. Um iniciante fica fora de sua profundidade e perdido no mar antes mesmo de entender o que aconteceu
Imagine que você tenha 10 mil tokens no contexto, 99% corretos. Cada vez que o LLM responde, ele acrescenta 1000 tokens 90% corretos. Depois de algumas idas e vindas corrigindo o LLM, a janela de contexto passa a ficar majoritariamente preenchida com a própria saída residual do LLM. Pior: os erros se acumulam. Mesmo os 90% corretos são apenas uma extrapolação correta sobre código incorreto, e o LLM dá mais peso aos tokens mais recentes. O mesmo problema aparece em prosa
Em modelos de raciocínio, esse problema pode ficar ainda pior. O processo de pensamento inteiro fica dentro do contexto e, se o raciocínio realmente toma um desvio, ele planta sementes venenosas que alimentam a degradação. Seria bom implementar alguma forma de poda de contexto para cortar contexto irrelevante quando ele surgisse. Hoje, quando sinto a degradação aparecendo, faço um resumo e passo para uma nova instância
Em ferramentas agentivas como claude code, codex e gemini cli, isso é um problema muito menor. Elas gerenciam a própria janela de contexto e conseguem executar ferramentas de desenvolvimento para fazer sanity checks por conta própria
Esse processo treina o hábito de documentar o estado atual do trabalho para que um novo agente consiga se atualizar