Nos últimos anos, o software deixou de ser caro e lento de construir para se tornar quase uma commodity, graças à IA generativa. Hoje vemos aplicativos que levariam meses para construir ficando prontos em semanas. Leigos, muitas vezes rotulados de "vibe coders", agora conseguem, na base do prompt, chegar a uma aplicação que de fato mais ou menos funciona. Isso deve significar que não vamos mais precisar de engenheiros de software, certo?
Eu não acho. Na verdade, talvez a gente precise de engenheiros competentes ainda mais agora. Claro, o papel mudou, e de certa forma eu sinto essa perda. Escrever o código inteiro do começo ao fim, depurá-lo e ver o ótimo resultado que semanas de trabalho alcançaram era muito divertido para mim, e é um tipo de alegria difícil de encontrar. Mas a IA ainda é só a última revolução que vimos nesta área -- uma que é impressionante, claro, mas não a primeira -- e precisamos nos adaptar a ela, aceitá-la e seguir em frente. Nunca mais vai ser como nos velhos tempos, e de certas formas para melhor. Vamos comparar com revoluções anteriores que tivemos.
No começo da computação, os pesquisadores escreviam o código de máquina no papel. Sem editor de texto, sem linguagem de programação, sem retorno visual imediato. Um grupo de assistentes traduzia manualmente cada linha do assembly para código binário. Esse longo fluxo de uns e zeros era inserido manualmente na máquina. Um processo longo e penoso, que tinha muitos gargalos.
Então, em 1952, Grace Hopper inventou o primeiro compilador, cunhando o termo para sempre. Foi um marco importante para a ciência da computação. Logo depois, em 1957, veio o FORTRAN, o primeiro compilador disponível comercialmente. Agora muitas instruções e abstrações comuns (funções, gerenciamento de memória, controle de fluxo e matemática) podiam ser condensadas em uma única instrução na linguagem de programação de mais alto nível. Mas o processo principal ainda era parecido com o antigo: o código era escrito em folhas de papel e transcrito manualmente para máquinas chamadas perfuradoras de cartões, que perfuravam o código nos cartões. Só depois disso ele era compilado.

Um cartão perfurado FORTRAN. Foto: Arnold Reinhold, CC BY-SA 2.5.
A passagem desse fluxo de trabalho para de fato editar o código em um sistema
digital foi lenta, levando décadas. Só virou rotina para todos os programadores
depois do desenvolvimento do Unix, em 1969, no Bell Labs. Eles usavam editores de
texto de linha de comando, como o ed, diretamente em terminais de vídeo (VDUs)
ou teleimpressoras.
Depois vieram os editores com interface de usuário no terminal (TUI), como o
antigo vi. O passo óbvio seguinte foram os editores com interface gráfica (GUI)
e os ambientes de desenvolvimento integrado (IDEs). Poderíamos falar deles o dia
inteiro, mas talvez o maior recurso a acelerar o desenvolvimento tenha sido o
autocompletar de código. Um dos sistemas mais populares surgiu nos anos 2000: a
análise de Árvore de Sintaxe Abstrata (AST) presente no IntelliJ IDEA.
Então, só em 2016, a Microsoft lançou o Language Server Protocol (LSP): um protocolo aberto que padronizou a maior parte dos recursos proprietários dos sistemas de autocompletar anteriores. Ele também permitiu muitos outros recursos de edição de código em massa e análise estática em uma única ferramenta, integrando diretamente os compiladores aos IDEs. Foi um dos recursos que popularizaram o Visual Studio Code entre os desenvolvedores.
Em paralelo a essas evoluções na edição de código, as linguagens de programação também evoluíram. Linguagens mais antigas, como FORTRAN e C, ganharam muitas melhorias, enquanto linguagens de mais alto nível, como Python e Java, começaram a surgir. Sua maior desvantagem era (e ainda é) que muitas vezes têm menos desempenho em comparação com as linguagens de mais baixo nível, mas isso melhorou bastante ao longo dos anos.
Vemos quantas vezes a indústria de engenharia de software mudou significativamente. Na revolução atual, as linguagens de programação são o baixo nível. Dizemos à máquina o que queremos em linguagem humana, e ela "compila" para a linguagem de programação, o meio-termo entre as linguagens humana e de máquina -- embora, claro, não seja um processo determinístico. O Large Language Model (LLM) se mostrou fantástico para prever código com base na entrada. Mas nem uma vez o conhecimento deixou de ser necessário na construção de aplicações em produção, e não acho que seja diferente agora.
Agora, voltando ao meu ponto principal: os LLMs têm várias limitações que tornam um operador humano fundamentalmente necessário. A mais óbvia: os próprios requisitos dependem do humano. Claro, o dono do produto poderia se comunicar diretamente com a máquina, sem o programador "traduzir" seus desejos. Mas o engenheiro sempre foi responsável por traduzir esses requisitos, e não acho que agora seja diferente. Ainda temos que tomar decisões técnicas e de arquitetura considerando escalabilidade, conformidade legal, privacidade, segurança e muito mais. Pela minha experiência, até os melhores modelos, como o Fable, da Anthropic, são muito ruins nesse tipo de decisão. Quando experimentei fazer "vibe coding" de um aplicativo complexo não faz muito tempo, esbarrei com frequência em erros que ele simplesmente não conseguia corrigir. O código era uma bagunça total e faltava completamente segurança e escalabilidade no design.
Código gerado por IA sem revisão é perigoso. E, por favor, não me diga que a IA pode revisar a si mesma, porque não pode. Falta a ela a janela de contexto, dentro e fora do código da aplicação, para entender plenamente os riscos. Acho que a maior preocupação dos programadores na era da IA generativa não é se ainda haverá vagas para eles, mas quantas vagas haverá, considerando o aumento da produção de um único desenvolvedor. Os engenheiros que entenderem isso serão recompensados, enquanto os demais estão sendo punidos. Agora, mais do que nunca, precisamos aprender os princípios de arquitetura de uma aplicação e infraestrutura robustas.