Tem uma coisa que venho observando na forma como desenvolvedores falam sobre agentes de código.

Eles revisam código gerado por agente com lupa. Apontam pra um nome de variável que não gostaram, uma função um pouco verbosa, uma abstração que fariam diferente, e descartam tudo. “Tá vendo? IA não sabe programar.”

Enquanto isso, esses mesmos desenvolvedores passam as segundas-feiras revisando pull requests de colegas que não têm testes, com nomes confusos e lógica que precisa de três leituras pra entender. E aprovam. Talvez com um comentário. Talvez nem isso.

A gente tolera código ruim de pessoas mas se recusa a aceitar código bom o suficiente de máquinas.

Isso não é julgamento técnico. Isso é dois pesos e duas medidas.

O dois pesos e duas medidas do code review

Pensa no último codebase em que você trabalhou. Pensa de verdade.

Quantas funções eram longas demais? Quantos módulos tinham responsabilidades confusas? Quantos workarounds “temporários” viraram permanentes? Quantas vezes alguém falou “a gente refatora depois” e nunca refatorou?

Eu já trabalhei em codebases onde features inteiras se sustentavam com fita adesiva e boas intenções. Todo mundo já. E a gente fez deploy. Usuários pagaram. Empresas rodaram em cima daquilo.

Ninguém exigiu perfeição desses codebases. A gente exigiu que funcionassem.

Mas quando um agente de IA produz código funcional, testado e razoavelmente estruturado, só que não é exatamente como você teria escrito, aí o padrão vira perfeição.

Eu construí o Kanario, um gerador de thumbnails pro blog da Codeminer, inteiramente com agentes de IA. 83 commits, 209 testes, 5.7k linhas de TypeScript, deploy em produção no Cloud Run com CI/CD completo. O código não era perfeito. Algumas abstrações poderiam ser melhores. Alguns nomes poderiam ser mais claros. Mas funciona, tá testado e foi entregue. Já vi coisa muito pior escrita por humano rodando em produção por anos.

“Linux wins heavily on points of being available now”

Em 1992, Andrew Tanenbaum, professor e criador do MINIX, postou uma mensagem no USENET com o assunto “LINUX is obsolete”.

O argumento dele era claro e, do ponto de vista acadêmico, correto: Linux usava um kernel monolítico, que era um design ultrapassado. Microkernels eram o futuro. Entre projetistas de sistemas operacionais, o debate estava “essencialmente encerrado”. Ele chegou a dizer pro Linus:

“Agradeça por não ser meu aluno. Você não tiraria uma nota alta por esse design.”

Tanenbaum estava certo no papel. Microkernels são teoricamente superiores: mais modulares, mais confiáveis, mais fáceis de entender.

Linus Torvalds respondeu no dia seguinte:

“É verdade, linux é monolítico, e eu concordo que microkernels são mais elegantes. Do ponto de vista teórico (e estético), linux perde. […] Linux ganha muito por estar disponível agora.”

Lê de novo. Linux ganha muito por estar disponível agora.

Linus concedeu o argumento teórico inteiro. Concordou que microkernels eram mais elegantes. Mas o kernel dele existia, funcionava e as pessoas podiam usar naquele momento. O GNU Hurd — o kernel “correto” baseado em microkernel — não estava pronto. E ainda não está pronto, mais de 30 anos depois.

Linux hoje roda a maioria dos servidores do mundo, todos os smartphones Android, a maioria dos supercomputadores e a maior parte da nuvem. O kernel “imperfeito” ganhou porque foi entregue, revisado, melhorado e continuou sendo entregue.

O debate completo vale a leitura.

Worse is better

Essa não é uma ideia nova. Richard Gabriel escreveu sobre isso em 1989 no ensaio “Worse is Better”.

Ele comparou duas filosofias de design: a “abordagem MIT” (a coisa certa) e a “abordagem New Jersey” (pior é melhor). A abordagem MIT prioriza corretude e completude. A interface tem que ser consistente, o design tem que ser elegante. A abordagem New Jersey prioriza simplicidade e entrega. A implementação deve ser simples, mesmo que a interface sofra um pouco.

A conclusão do Gabriel? A abordagem “pior” ganha. Não porque é melhor isoladamente, mas porque entrega, se espalha e vai sendo melhorada com o tempo.

Unix ganhou das Lisp Machines. C ganhou de linguagens mais “corretas”. Linux ganhou do Hurd. JavaScript ganhou de tudo que supostamente ia substituí-lo.

O padrão é sempre o mesmo: a coisa imperfeita que existe bate a coisa perfeita que não existe.

O que isso significa pra agentes

Quando as pessoas reclamam que código de agente não é perfeito, estão fazendo o argumento do Tanenbaum em 1992. Estão levantando o ideal teórico e descartando a realidade prática.

Sim, um agente de IA pode produzir código que não é exatamente como um engenheiro sênior escreveria. Mas olha o que esse código de fato é:

  • Compila e roda
  • Geralmente vem com testes
  • Segue os padrões que você definiu (se você definiu)
  • Foi produzido em minutos, não dias
  • Pode ser revisado e melhorado

Isso é pior do que o código sem testes, sem documentação, “vou limpar depois” que humanos escrevem todo dia?

A pergunta que importa é: é bom o suficiente pra entregar, revisar e melhorar?

Porque esse é o padrão que a gente sempre aplicou pra código humano. E esse é o padrão que construiu Linux, Unix, JavaScript e a maioria do software de que a gente depende.

Fred Brooks escreveu em The Mythical Man-Month que a parte mais difícil do software é a estrutura conceitual, não o código em si. A complexidade essencial. Se sua arquitetura e suas decisões são sólidas, o código é a parte fácil. Código “imperfeito” na superfície importa muito menos do que a arquitetura por trás dele.

Pare de exigir de máquinas o que você não exige de si mesmo

Não estou dizendo que a gente deve aceitar código lixo de agentes. Revise. Melhore. Cobre o mesmo padrão que cobra de código humano. O mesmo padrão, não um padrão mais alto.

Se um colega seu escreveu uma função que funciona corretamente, tem testes, mas usa um pattern levemente diferente do que você prefere, você aprovaria o PR. Aplique o mesmo julgamento pra código de agente.

Perfeição nunca foi o ponto. Entregar de forma sustentável foi. Entrega, revisa, melhora, entrega de novo. Linus sabia disso em 1992. Richard Gabriel sabia disso em 1989. Fred Brooks sabia disso em 1975.

Pare de esperar que agentes produzam código perfeito. Trate o output do agente como você sempre tratou código: um ponto de partida que funciona, que você revisa e que você melhora.

Por hoje é só.

Referências