A Inteligência Artificial está nos tornando programadores piores?
Perspectivas sobre a adoção da IA no dia-a-dia dos programadores e seu efeito na produtividade.
Eles estão em toda parte – do Copilot ao Cursor, do Zed ao Aider – assistentes de IA permearam as IDEs e ferramentas de programação. Construídos a partir de modelos cada vez mais avançados, muitos deles ajustados para se destacar em tarefas de programação, é seguro dizer que é preciso tomar uma decisão consciente para evitar usar IA durante um dia típico de trabalho como programador.
Posso dizer por experiência: testei quase todos e os integrei de alguma forma ao meu workflow. Também tenho mais de 10 anos de experiência em programação, então sei bem como é não usar tais assistentes (o efeito que eles podem causar em uma geração mais jovem me intriga, mas não vou explorar neste artigo.)
Decidi refletir sobre fenômeno tentando responder à pergunta: o uso de Inteligência Artificial está me tornando um programador pior?
Claro que muito do que tenho a dizer é inteiramente pessoal, mas espero poder extrair princípios fundamentais que se vão além da programação, e portanto você possa se identificar com base em sua própria experiência.
O mundo agora requer menos habilidades que no passado?
Tendo nascido nos anos 90, você pode imaginar como estava fresca na mente de todo adulto a figura de Ayrton Senna. Um dos pilotos de corrida mais talentosos até hoje, obcecado com performance, Senna tragica – mas de certa forma poeticamente – morreu em um acidente no circuito de San Marino em 1994.
Senna foi imortalizado como um dos maiores de todos os tempos, e um tema recorrente em debates geracionais sobre quem foi melhor (tipicamente com um adendo que torna o exercício ainda mais impossível de resolver) no auge.
Para aqueles que escolheriam os old schools, um argumento comum é: "hoje em dia os pilotos têm tudo automatizado, antigamente eles tinham que saber tudo". Quantas vezes não ouvi meu pai dizer que eles costumavam “controlar o carro no braço”. Não pretendo me enfiar nessa seara, mas acho que esse argumento carrega um ponto que vale a pena discutir.
Na programação, linguagens de alto nível muitas vezes abstraem a complexidade do programador – quem trabalha com JavaScript, Python, Java, etc., sabe bem. Parece evidente que a IA introduz uma nova interface: linguagem natural. Isso é ruim?
Separando core skills do conhecimento de ferramentas específicas
Existe um debate acalorado sobre se ir para a faculdade estudar Engenharia de Computação ou Ciência da Computação é relevante em um mundo onde você tem acesso a incontáveis cursos, gratuitamente ou por um preço muito baixo. No Brasil há a particularidade das faculdades públicas, mas ainda assim, existe no mínimo uma economia de tempo.
Eu tenho um diploma em Engenharia de Computação e não tenho uma opinião final. Por quê? Pois na faculdade aprendi a entender computadores. Estudei os fundamentos, e eles ficaram. Em contraste, 99% das ferramentas que tive que aprender ou estão desatualizadas ou simplesmente não são mais utilizadas.
No entanto, aqueles anos aprimoraram minhas core skills, conhecimento que é exterior às ferramentas específicas que você tem à disposição, princípios que governam a atividade de ser um engenheiro de software. E isso é difícil de conseguir em crash courses e bootcamps.
Note que não estou dizendo que esses cursos são inúteis, apenas que por sua própria natureza não há tempo hábil para desenvolver as core skills, em troca do domínio do uso de ferramentas em nível profissional (muitos alarmistas que juram que as AIs vão dominar o mundo vem justamente daí.)
Assim como Senna sabia coisas sobre carros de corrida que talvez a nova geração não precise, devemos nos perguntar: realmente precisamos dos detalhes específicos que costumávamos conhecer no passado? Especialmente em um mundo de tecnologias tão transitórias?
Vou dar outro exemplo. Comecei a trabalhar com Gatsby por volta de 2018. Na época, parecia um framework legal para construir sites estáticos, com um apelo interessante para apps dinâmicos. Desenvolvi diversas aplicações usando esse framework, participei de competições públicas e posso dizer com segurança que havia dominado a ferramenta.
Até que... ele acabou. Next.js e outros frameworks como Astro assumiram a posição que outrora fora do Gatsby, que num piscar de olhos já estava unmaintained. Todos os detalhes específicos que tive que aprender para operar essa ferramenta não servem mais para meus projetos atuais, e o esforço hercúleo que tive que fazer para migrar todos os meus apps foi extremamente doloroso.
O que eu realmente tirei deste episódio? Aprendi sobre Server-Side Rendering e Static Site Generation – então quando o React 18 adotou server components como padrão, eu já tinha um modelo mental para isso. Mudar para o app router do Next.js também foi fácil, já que eu podia entender o raciocínio por trás. Mas meu conhecimento de plugins do Gatsby, gatsby-node, gatsby-config, e até GraphQL está agora devidamente enterrado.
O que os difere? Server-Side Rendering é uma core skill, está fundamentalmente ligada ao desenvolvimento web e a como a internet funciona. Devo construir esta página estaticamente ou dinamicamente? Esta é uma decisão que eu – um humano – preciso tomar com base em meu conhecimento. Uma vez que esta decisão é tomada, a IA pode seguramente me ajudar com os detalhes de implementação – eles não importarão na maior parte.
O caso a favor das IA
Até agora minha postura foi defensiva, então gostaria de oferecer uma visão mais positiva.
Uma coisa que sempre gostei de fazer é destrinchar um requisito de negócio em uma tarefa concreta para um desenvolvedor. Portanto, preciso trabalhar minhas capacidades de abstração sempre que sou apresentado com um problema (é por isso que gosto do termo engenheiro de software, alguém que usa software para modelar e resolver problemas do mundo real.)
Desse modo, é natural para mim dividir um problema em etapas menores, enfrentá-los na ordem certa e avaliar o resultado no final. Acontece que este é um framework bastante decente para empregar com as IA.
Qualquer um que tenha utilizado uma IA como parceira de programação reconhecerá que sua capacidade se deteriora exponencialmente à medida que se adiciona mais informação no context, mesmo que o context window seja grande. Portanto, ser capaz de alimentá-los com informação precisa, de modo que lhes reste apenas determinar os detalhes de implementação, é crucial (diga-se de passagem, na minha opinião o Zed é quem melhor resolve esse problema.)
Acontece que essa tarefa de raciocínio e organização é exatamente o que diferencia os humanos. Claro, modelos como o1 da OpenAI são impressionantes nesse aspecto, mas ainda estão longe de serem autossuficientes no processo end-to-end: raciocinar, implementar, avaliar.
Além disso, todo programador reconhece que a constante mudança de contexto é um destruidor de produtividade. Independentemente de quão pequena a interrupção, ela afetará sua capacidade de concentração. Em Deep Work, Cal Newport apresenta teorias que propõe termos uma quantidade limitada de força de vontade (willpower) disponível a cada dia. Outro conceito explorado pelo autor é o de resíduo de atenção (attention residue), o fato de que mudar de atividades com muita frequência reterá parte de seu contexto em nossa mente, efetivamente reduzindo nossa capacidade cognitiva para as tarefas seguintes.
IA são grandes aliadas nesse aspecto, especialmente quando integrados na IDE. Não lembra uma sintaxe específica do TypeScript? Highlight a variável e peça ao modelo para tipá-la para você. Quer subdividir um componente em outros menores? Solicite um refatoramento do arquivo e economize energia cognitiva. Você realmente lembra de cor como fazer mock de uma chamada de API em um teste unitário? Faço isso há anos e nunca lembro a sintaxe. A IA se destaca em tais tarefas, ajudando-o a se manter no flow.
Suponha que você tenha que implementar uma certa animação na interface de um app. É realmente importante dominar a API do framer-motion ou react-spring? Desde que você possa conscientemente empregar animações na medida certa, sem sobrecarregar a interface, tudo certo. E cabe a você – não à máquina – encontrar o equilíbrio.
Ao migrar do Gatsby, decidi mover todos os arquivos de JSX para TSX. A quantidade de tempo que economizei solicitando que a IA reescrevesse os componentes adicionando types é incrível. Houve, porém, uma troca entre velocidade e o aprimoramento de minhas habilidades em TypeScript. Isso importa? Acho que não. Nesse caso, TypeScript é um meio para um fim. Quem sabe se não teremos StaticScript ou UberScript em breve? Já vi o suficiente.
Quando pode dar errado
Certamente a esta altura você acredita que embarquei no hype train, empolgado com minhas ações de NVDA (disclaimer: infelizmente não tenho) e, portanto, pronto para defender o uso de IA em todos os casos. Não exatamente: definitivamente existem problemas que podem surgir do abuso de IA em seu workflow.
O maior deles, de longe, é a over-reliance trap, ou em bom português, um excesso de confiança em suas habilidades. Isso acontece quando você delega cegamente o trabalho para a IA, e ela falha em resolver o problema (ironicamente, isso geralmente é fácil de perceber logo de cara.) Então você tenta novamente. E novamente. O context window começa a explodir, você perde a paciência... as desculpas são irritantes, você xinga o computador: "não era você a máquina idiota que supostamente iria dominar o mundo?"
Quando isso acontece, você perde muito mais do que apenas seu tempo (e sanidade). Você corre o risco de esgotar seu estoque de willpower (no jargão de Newport) e agora precisa consertar um código que não escreveu. O trabalho que poderia ter começado como uma tela em branco agora se tornou uma sessão de pair programming com um desenvolvedor júnior que escreveu um código ruim.
Já caí diversas vezes nessa armadilha, que geralmente termina em frustração quando percebo que gastei mais tempo do que teria gasto se não tivesse usado a IA.
Como evitar esse problema? Sendo mais humano. Fazendo melhores julgamentos sobre quando é o momento certo de delegar para a IA; garantindo que você foi capaz de dividir os requisitos em tarefas menores e gerenciáveis, do tipo que um assistente poderia resolver sozinho. Este é o prompt engineering em que acredito. Se a IA é uma nova interface, você prosperará se aprender a interagir com ela.
Sabendo quando o problema está resolvido
Eu tinha um professor de matemática que, ao explicar um problema complicado, chamava nossa atenção quando a parte mais difícil tinha sido resolvida. O problema ainda precisava ser finalizado, mas em suas palavras, a única coisa que restava era burocracia.
Este é também o caso com a engenharia de software. A maior parte do meu trabalho não é particularmente difícil – apenas requerem abstração, paciência, ordem e conhecimento das ferramentas necessárias para completar a tarefa. É importante saber quando um problema está resolvido, delegando à IA o trabalho burocrático. Isso nos libera para implantar nossa melhor arma – o intelecto humano – para resolver a parte mais difícil do quebra-cabeça.
Por exemplo, suponha que você seja encarregado de adicionar um dropdown que permita ao usuário ordenar uma tabela. Não há nada desafiador aqui: o algoritmo de ordenação é básico, a UI é padrão, se você tiver sorte há até um componente comum para reutilizar... Tudo que você precisa fazer é juntar as coisas, visualizando como elas irão interagir entre si, mesmo que a implementação real varie dependendo do framework. Em outras palavras, é um problema resolvido. Em tais casos – que são muito mais comuns do que muitos gostam de admitir – a ajuda de um modelo de IA não é apenas útil, mas provavelmente o melhor curso de ação.
Conclusão
Existe um argumento a ser feito de que o uso excessivo de IA termina por enferrujar as suas habilidades como programador. Também é verdade que, se usada da maneira errada, a IA também pode fazer você gastar mais tempo do que deveria, além de diminuir seu estoque limitado de willpower. E francamente, não vai substituir humanos nem tão cedo.
No entanto, é uma ferramenta incrível – e como todas as ferramentas, é um meio para um fim. O objetivo final de um desenvolvedor é traduzir para uma linguagem que o computador possa entender as instruções para ações que terão impacto no mundo real. E essa habilidade requer fomento constante, o que lhe dá uma vantagem sobre a máquina.
A Inteligência Artificial é extremamente útil no que diz respeito a detalhes de implementação, do tipo que não afeta suas core skills, mas são apenas requisitos de tecnologias transitórias. Deixar que ela adicione o tipo correto de uma variável para você, ou crie do zero uma pure function cujas entradas e saídas são conhecidas, não vai fazer de você um desenvolvedor ruim – pelo contrário, preservará sua mente para enfrentar os problemas mais difíceis, permitindo que você se concentre nas coisas certas, projete soluções abrangentes e, em última análise, se torne um desenvolvedor mais produtivo.
Artigo original: Are AI Assistants Making Us Worse Programmers?