- A solução de que bastaria uma pessoa revisar todos os erros frequentes das ferramentas de codificação com LLMs dificilmente consegue garantir qualidade e produtividade ao mesmo tempo, por causa dos limites de processamento da revisão de código
- Segundo estudos empíricos, uma revisão eficaz tem como limite cerca de 1 hora e 400 LOC por vez; acima disso, a eficácia na detecção de defeitos cai rapidamente por fadiga e perda de concentração
- Aplicando esse critério, a cada 400 LOC escritos por um LLM seria necessária 1 hora de revisão concentrada por um desenvolvedor experiente, de modo que o volume diário realista pode ser inferior a 1.000 LOC
- Há evidências iniciais de que humanos encontram menos defeitos em código gerado por LLMs, mas demonstram mais confiança, o que torna difícil acreditar que apenas a revisão consiga filtrar erros de forma suficiente
- São necessários estudos empíricos que meçam e reproduzam diretamente a taxa de detecção de defeitos, a velocidade de revisão e o volume diário sustentável de código de LLMs, para julgar a eficácia das ferramentas com base em evidências, não em anedotas
Por que vejo ferramentas de codificação com LLMs com ceticismo
- O foco do problema não está em propriedade intelectual, custos ecológicos, consumo de recursos nem na avaliação de que todos os resultados de LLMs são ruins
- Com as evidências científicas atuais, é difícil confirmar de que maneira ferramentas de codificação com LLMs ajudam desenvolvedores a escrever código melhor ou mais rapidamente
- A defesa dessas ferramentas não trata diretamente dos problemas e evidências relevantes, e as refutações ao ceticismo às vezes acabam reforçando o problema
- Como o texto foi escrito há cerca de um ano, usa a expressão Coding Assistants, que hoje já foi quase substituída, mas ela foi mantida por falta de outro termo que cubra todos os vários usos de IA generativa em codificação
A analogia do “estagiário” e a solução da revisão completa
- Ferramentas de codificação com LLMs apresentam um risco relativamente alto de erro por motivos como sua estrutura de funcionamento e interface de interação
- Podem produzir alucinações ou erros de digitação
- Podem gerar resultados não relacionados ao pedido ou executar a tarefa por outro caminho
- Usuários frequentemente comparam essas ferramentas a estagiários
- Deve-se esperar que o resultado esteja, em alguma medida, incorreto
- Deve-se presumir que elas trabalham sem entender direito o que estão fazendo
- A resposta amplamente usada é fazer uma pessoa experiente revisar tudo, como faria com o código de um estagiário ou desenvolvedor júnior
- Baseia-se na premissa de que o humano sabe mais e também assume a responsabilidade final
- Também vem acompanhada da lógica de que todo código que entra na base já deveria ser revisado de qualquer forma
O nível de revisão necessário para supervisionar LLMs
- Na indústria e na literatura de pesquisa, revisão abrange várias práticas diferentes
- Revisões leves e distribuídas entre várias pessoas são úteis para compartilhar conhecimento sobre mudanças e aplicar regras superficiais, mas são insuficientes como padrão para supervisionar código de LLMs
- Não é preciso chegar ao ponto das antigas revisões em comitê, em que todas as linhas eram verificadas dolorosamente por horas, mas é necessária uma revisão de código bastante profunda e completa
- Como LLMs podem escrever código complexo e defeitos podem ficar escondidos nos detalhes do software, uma checagem superficial não basta
Os limites empíricos enfrentados pela revisão de código
- Os principais limites da revisão eficaz identificados em estudos empíricos são os seguintes
- Uma sessão de revisão passa a ser longa demais quando excede 1 hora
- A quantidade que pode ser revisada de forma eficaz nesse período é de no máximo cerca de 400 LOC
- Revisões que passam de 1 hora perdem eficácia rapidamente, independentemente do tamanho do código
- Não apenas porque a maior parte já foi revisada
- Manter alta concentração por 1 hora causa fadiga e tédio, exigindo descanso
- Não encontrei estudos sobre o tempo de recuperação necessário entre sessões de 1 hora
- Como limite extremo, pode-se supor algumas vezes por dia
- Cerca de 2 vezes por dia é sugerido como número médio possível, mas não é um valor estabelecido
- O número de linhas de código que podem ser revisadas por hora varia muito conforme o contexto e o tipo de código, bem como a experiência e o conhecimento do revisor
- Não é uma regra absoluta, mas quase não há dados empíricos mostrando revisões mais rápidas que 400 LOC/h encontrando e marcando defeitos de forma eficaz, então isso pode ser visto como uma velocidade máxima efetiva
Cálculo de throughput aplicado ao código de LLMs
- Para resolver os problemas do código de LLMs por meio de revisão, mesmo no melhor caso seriam necessários 1 hora de um desenvolvedor experiente para cada 400 LOC geradas
- Um desenvolvedor pode realizar cerca de 10 a 40 sessões de revisão por semana, e entre cada sessão é necessário um tempo de recuperação de duração desconhecida
- Esse tempo de recuperação pode ser de pelo menos 1 a 2 horas, mas não há pesquisa direta que sustente isso
- Esse tempo de concentração também precisa ser usado em reuniões, design, resposta a incidentes e reflexão sobre o código que a própria pessoa precisa escrever
- No melhor dos casos, um desenvolvedor que usa LLM pode escrever, revisar e fazer commit de alguns milhares de LOC por dia
- Em um cenário realista, o throughput diário pode ser inferior a 1.000 LOC
- Isso inclui boilerplate, testes, migrações e arquivos de configuração
- Um único arquivo de teste também pode ultrapassar 400 LOC
- Mesmo nas melhores condições, em que a maior parte do código é simples e fácil de revisar, a revisão atua como um limite superior para ganhos de produtividade
Diferenças entre a revisão de código humano e de código de LLMs
- As evidências existentes vêm de situações em que revisores humanos encontram defeitos em código escrito por humanos, e não há evidência de que a mesma eficiência se aplique a código de LLMs
- Evidências iniciais mostram uma tendência de pessoas que revisam código gerado por LLMs encontrarem menos defeitos, mas terem mais confiança de que encontraram todos
- A combinação de uma ferramenta de codificação com LLM e um revisor humano pode produzir resultados de qualidade inferior à combinação de autor humano e revisor humano, enquanto o revisor do primeiro caso avalia seu próprio desempenho como melhor
- A revisão completa não apenas limita a vantagem de produtividade dos LLMs, como também carece de evidências sólidas de que de fato resolva seus erros frequentes
Custos que surgem antes mesmo da correção de defeitos
- Esse cálculo não inclui o custo de corrigir os defeitos encontrados
- Ele trata apenas da capacidade e do custo de desenvolvedores profissionais revisarem código e marcarem problemas em um ambiente de trabalho
- Independentemente da quantidade ou gravidade dos defeitos criados pelo LLM, o custo de revisar o código gerado existe
- Mesmo que uma ferramenta de codificação com LLM produza código de altíssima qualidade, se todo resultado precisar ser revisado, o mesmo custo e os mesmos limites de produtividade permanecem
A contradição de delegar código difícil de revisar
- Defensores de LLMs apresentam como vantagem o fato de a ferramenta poder produzir código que seria penoso para humanos escreverem
- Um exemplo sugere deixar que LLMs escrevam 100% do código Bash necessário daqui em diante
- Scripts shell têm parsing frouxo e significados excessivamente sobrepostos, de modo que um único erro de pontuação pode ser inofensivo ou levar à exclusão de todo o computador
- Esse tipo de código é propenso a erros, difícil de entender e revisar, e também dificulta perceber falhas catastróficas
- Entregar a uma ferramenta que erra aleatoriamente o código mais difícil de revisar e depois dizer que um humano pode conferir não demonstra antes que a saída do LLM seja de fato um bom objeto de revisão
- O problema é usar o código mais difícil de revisar como caso de uso representativo sem responder se a revisão resolve os erros e se resta ganho de produtividade suficiente
Tarefas empíricas que precisam ser verificadas
- A primeira tarefa é medir quão bem revisores humanos encontram defeitos em código gerado por LLMs
- Capacidade de detecção de defeitos
- Velocidade de revisão
- Volume de revisão sustentável ao longo de um dia
- Assim como nos estudos sobre código escrito por humanos, são necessários dados sobre humanos revisando código de LLMs
- Experimentos e dados empíricos existentes são limitados em escala e contexto, portanto são necessários mais estudos de reprodução
- Os dados científicos atuais apontam para a possibilidade de humanos não revisarem bem resultados de LLMs ou terem dificuldade para detectar seus problemas
- Isso pode ser compatível com a característica de LLMs serem treinados para evitar detecção
- Também é preciso verificar a possibilidade de os resultados existentes terem sido acidentais
- A segunda tarefa é verificar se a revisão de artefatos gerados por LLMs é um problema qualitativamente diferente da revisão de artefatos escritos por humanos
- Se a diferença for grande a ponto de tornar inaplicáveis os estudos existentes sobre revisão de código, a lógica crítica atual pode ruir
- No entanto, as evidências iniciais indicam que revisar código gerado por LLMs pode ser mais difícil, não mais fácil; nesse caso, a crítica é reforçada
Avaliação empírica de ferramentas profissionais, não anedotas
- Considerando o que se sabe sobre revisão de código, é difícil confirmar que benefício ferramentas de LLM com as interfaces e procedimentos atuais trazem a desenvolvedores profissionais
- Mais do que fornecedores oferecerem repetidamente ferramentas e procedimentos que conflitam com as evidências, o que incomoda é a postura de tratar céticos como anormais sem enfrentar o problema
- Em TDD, sistemas de tipos, separação entre organizações de teste e desenvolvimento, CI/CD e DevOps, o predomínio de anedotas sobre evidências empíricas também já se repetiu
- Em vez de se apoiar em casos do tipo “desta vez funcionou para mim”, é preciso realizar pesquisa real, seguindo a forma como as evidências empíricas sobre revisão de código foram construídas
- Para tratar ferramentas de codificação com LLMs como ferramentas profissionais de desenvolvimento, é preciso verificar seus efeitos e limites com foco em ergonomia humana e evidências empíricas
1 comentários
Opiniões no Lobste.rs
Velocidade não precisa ser o único objetivo. Correções de bugs podem ser separadas em commits preparatórios independentes para revisão, corrigir estruturas de tipos que permitem representar estados inválidos e, se a confiabilidade dos testes for insuficiente, experimentar testes baseados em propriedades, fuzzing e métodos formais
Antes, esse tipo de trabalho era enfiado em um único commit ou deixado como TODO de dívida técnica, mas agora o custo marginal de implementar isso direito ficou surpreendentemente baixo. LLM é uma ferramenta aberta e devolve utilidade na medida dos valores que o usuário prioriza
Claro, também existe o risco de aumentar a quantidade de protótipos que nunca ficam prontos nem chegam à produção, mas, no geral, ajuda bastante em uma engenharia que valoriza o rigor
Pode ser um problema de cultura da empresa, mas é decepcionante, e espero que o setor acorde e passe a fazer software de qualidade mais alta
Se você coloca um agente em um projeto antigo com um único prompt, ele continua encontrando bugs reais sem muito esforço. Humanos também são descuidados, e eu mesmo erro, mas o LLM é rápido e, em vários aspectos, mais tolo, então esse problema só aparece mais cedo
Erros se acumulam, então, se você deixar o agente mudar código sem critério, tudo degrada rapidamente; mas concluir que a ferramenta em si é inútil só porque um uso ingênuo é instável também é um julgamento preguiçoso
Hoje, a cada mudança, faço automaticamente 5 revisões especializadas, incluindo arquitetura, manutenibilidade, confiabilidade e segurança, e organizo isso em um sistema de documentos de design para melhorar bastante a tomada de decisão do agente. Não é perfeito, mas é melhor do que a abordagem ingênua, e o fato de ainda haver espaço para melhorar também é parte da diversão de lidar com uma ferramenta nova
Mesmo gerando mais rápido com prompt, acaba levando mais tempo para verificar e entender, então fico pensando se não teria sido mais rápido escrever tudo eu mesmo desde o começo. Só decidir qual das duas opções é melhor já consome tempo e energia, e eu preferiria usar esse recurso em outra coisa
Ainda assim, se quem envia o PR assumir propriedade e responsabilidade, não importa se usou LLM ou não. Se atender aos critérios de qualidade, exatidão e consistência, pode escolher o jeito mais rápido, e a responsabilidade continua sendo do autor humano
Pessoalmente, a IA é boa para aprender e ampliar o entendimento em largura e profundidade, mas, considerando não só o tempo de entrada como o processo inteiro, ainda sou mais produtivo escrevendo código diretamente
O primeiro problema é que o texto foi escrito há quase 1 ano. Nos últimos 6 meses, especialmente nos últimos 3, a utilidade dos modelos de nuvem pagos de ponta aumentou bastante
Como no princípio MFIC desenvolvido em trabalho de auditoria, é preciso verificar se existem controles que bloqueiem toda a categoria de falhas: https://gist.github.com/pmarreck/b30aa3ca69cb70a5526f8a63ab8c8d7e
Também são necessárias ferramentas como https://github.com/pmarreck/dirtree e https://github.com/pmarreck/codescan, que mantêm no contexto o código existente e a estrutura do projeto; isso também é útil para desenvolvedores humanos que esqueceram a base de código ou não a conhecem bem
No fim, você pode usar isso direito e obter vantagens, ou continuar escrevendo código sob medida manualmente, criando bugs e vulnerabilidades de segurança, e ser ultrapassado por concorrentes mais rápidos. Tendo passado 2 pessoa-anos numa base descartada de um milhão de linhas em Ruby on Rails da Desk.com, código corporativo é temporário, então combina bem com código gerado por LLM
Se fosse implementação interna de Erlang, eu teria dificuldade de confiar, mas ainda daria para pedir geração no nível de função e revisar depois, e às vezes o resultado seria melhor do que o esperado. Em vez de escolher só entre agulhas de tricô e tear, o ideal é usar ambos conforme a situação
Pela minha experiência pessoal e pela de desenvolvedores experientes e confiáveis ao meu redor, os LLMs repetidamente tornaram possível programar melhor e mais rápido, então é difícil levar muito a sério um texto dizendo que, cientificamente, isso não pode estar ajudando
Mesmo sem artigo revisado por pares, eu já vi o bastante, e um único estudo da METR refutando estimativas de aumento de produtividade dos desenvolvedores não me faria mudar de ideia
Se você mostrar, de forma rigorosa e metodologicamente válida, em que isso difere da pesquisa empírica robusta que já existe, estou disposto a mudar de ideia. Mas experiência pessoal ou uma dúzia de anedotas sem explicação não bastam
Ciência e engenharia melhoraram a vida de bilhões de pessoas, e não dá para abandonar isso só porque alguém acredita que sabe mais
Não quero chamar ninguém de membro de seita, mas essa postura de levar um desafio à própria crença para o lado pessoal e, ao mesmo tempo, não saber como persuadir os outros lembra o modo de comunicação de grupos sectários
Mesmo que a maioria dos PRs seja feita com LLM, quem submete continua responsável e precisa dividir o conteúdo em contexto e tamanho fáceis para outras pessoas entenderem. O código continua sendo a especificação final do software, e o fato de que o desenvolvedor precisa possuí-lo e entendê-lo não mudou
A afirmação de que agentes de IA cometiam muitos erros há 1 ano é correta, mas não está claro se isso ainda vale hoje; por volta de novembro do ano passado senti um ponto de inflexão nos modelos de ponta
É verdade que LLMs aumentam o volume de código e criam uma nova pressão sobre a capacidade de revisão, mas os engenheiros precisam frear isso e garantir que o volume revisado corresponda à capacidade real de processamento
O pior é que esse código novo geralmente funciona, então há grande chance de ser mergeado sem a devida limpeza
Acho curioso que, mesmo com modelos de ponta escrevendo quantidades enormes de código, quase não se explore seriamente a contribuição negativa de sugerir remover código. Como em “The Best Code is No Code At All” - Jeff Atwood, seria algo novo se eles conseguissem desfazer a complexidade de bases infladas por camadas de abstração e sugerir deleções de linhas
Talvez isso já seja possível, mas eu ainda não vi pessoalmente
Corrigindo: a seção “The Limits Of Reviews” apresenta a velocidade máxima eficiente como 400 linhas por hora, e não 400 linhas por revisão, como pensei inicialmente
Ainda assim, continuo curioso sobre de qual artigo de revisão de código vieram exatamente os números de 1 hora e 400 linhas. Se você não guardou o nome do artigo, não precisa gastar muito tempo procurando de novo
Estou viajando agora, então me cobre de novo em alguns dias
Se, em uma semana de 40 horas, 25% forem de revisão, dá cerca de 540 linhas por hora; se forem 15%, 900; se forem 5%, 2.700. Estimo que minha vazão real seja de 500 a 1.000 linhas por hora, algo relativamente próximo do número sem fonte apresentada
Acho difícil entender a lógica de que código gerado por IA deva ser revisado mais ou menos do que código escrito por humanos. Como o critério de aprovação é o mesmo, ele deve ser revisado no mesmo nível