- Este texto é a segunda parte sobre como adaptar a experiência tradicional de programação ao mundo dos computadores conversacionais (LLMs, agentes)
- Na primeira parte, "Como programar com LLMs", foi explicado como integrar LLMs às ferramentas existentes para usá-los como autocomplete ou substituto de busca
- Desta vez, o foco é compartilhar experiências práticas e insights sobre uma abordagem mais difícil, porém mais recompensadora: programação baseada em agentes
Definição e realidade dos agentes
- No contexto de LLMs (grandes modelos de linguagem), faz sentido definir o termo "agente"
- Embora venha sendo usado há muito tempo como um bordão da indústria de IA, só recentemente passou a se consolidar como uma estrutura realmente útil
- Nesse processo, muita retórica de marketing e um certo misticismo foram adicionados ao termo
- Do ponto de vista de um engenheiro, agora dá para definir isso de forma clara e simples: um agente são 9 linhas de código, ou seja, um loop
for com uma chamada de LLM
- Dentro desse loop, o LLM executa instruções, verifica diretamente os resultados e repete o processo sem intervenção humana
- Pode parecer simples, mas, na prática, essa estrutura aumenta drasticamente a capacidade de programação em comparação com o uso de um LLM puro
A diferença entre programação de quadro branco e agentes
- Imagine ficar diante de um quadro branco, com um marcador na mão, escrevendo em C uma função para validar uma string UTF-8
- (Foi de fato uma situação de entrevista vivida pelo autor, e também um desafio comum em entrevistas)
- O sucesso dessa tarefa depende da experiência do programador e da sua capacidade de disfarçar as limitações de não poder consultar materiais externos
- É preciso lembrar as regras de codificação UTF-8 e tomar cuidado para não confundir a sintaxe de C com a de outras linguagens da família C (ordem nome-tipo, tipo-nome etc.)
- No trabalho do dia a dia, normalmente é possível validar o código e encontrar erros com ajuda do compilador, busca em documentação,
printfs e vários outros recursos
- Pedir para um LLM escrever código sem um agente é parecido com programar num quadro branco sem ajuda externa
- É preciso puxar lembranças vagas da memória, tentar acertar a sintaxe de forma ineficiente e evitar erros como imaginar interfaces inexistentes
- É impressionante, tecnicamente, que um LLM consiga criar um programa completamente novo, mas um quadro branco virtual ligado a uma GPU, por si só, não aumenta muito a produtividade real em programação
- Mas e se dermos ao LLM mais do que um quadro branco virtual?
- Por exemplo, permitir que ele invoque o compilador, veja os erros de compilação e os corrija sozinho?
- E se ele puder ler arquivos existentes com
grep e cat, aplicar patches em vários arquivos (incluindo testes unitários) e executar testes repetidamente?
- Um agente é justamente um LLM com esse tipo de feedback.
Agente = LLM operando em um ambiente de feedback
- Assim como pessoas, LLMs que funcionam bem em um ambiente de feedback conseguem programar de forma prática com apenas algumas ferramentas familiares
bash(cmd): executa comandos de terminal (find, cat, grep etc.)
patch(hunks): aplica patches em arquivos, fazendo alterações no código
todo(tasks): gerencia uma lista de tarefas
web_nav(url), web_eval(script), web_logs(), web_screenshot() etc.: navegação na web, execução, logs, screenshots e afins
keyword_search(keywords): busca por palavras-chave
codereview(): revisão de código
- Usando a ferramenta de bash, eles exploram codebases de forma eficiente, automatizando até operações de controle de versão como
git add e git commit
- Ao contrário de um LLM que só gera código sem essas ferramentas, um agente traz vantagens bem distintas
- A precisão no uso de APIs melhora muito (busca documentação e a incorpora diretamente ao contexto)
- O feedback do compilador reduz erros de sintaxe e enganos com interfaces
- A capacidade de gerenciar dependências e versões fica mais forte (é possível entender características de versões específicas)
- A detecção de erros via falhas em testes e o hábito de escrever testes se fortalecem
- O processamento de codebases além da janela de contexto se torna viável (lendo apenas as partes necessárias)
- É possível experimentar diretamente os resultados da execução: rodar código, receber feedback por screenshot de páginas no navegador, ajustar CSS automaticamente, rastrear erros via logs do servidor e adicionar testes
- Também há desvantagens
- Um pedido de uma única frase pode gerar dezenas de milhares de tokens intermediários (chamadas de ferramentas, buscas na web, repetição de testes etc.), fazendo com que uma tarefa leve vários minutos ou mais
- Há também custo de chamadas de API, embora isso tenda a diminuir com a evolução do hardware
- Em última análise, o trabalho intermediário passa a ser feito por CPU/GPU, economizando tempo do desenvolvedor e permitindo concluir mais programas que ele gostaria de escrever
- Na prática, é fácil introduzir agentes em um projeto e dar pequenas tarefas para eles, verificando os resultados
Exemplo: desenvolvimento de autenticação para Github App
- Este é um caso real de uso de agentes para implementar o fluxo de autenticação de Github App do sketch.dev
- Com apenas 3 ou 4 ciclos de feedback, foi possível concluir rapidamente todo o fluxo de autenticação
- Quando surgiam erros ou novos requisitos, bastava descrevê-los em uma frase simples e o agente melhorava imediatamente o código e o comportamento
- Ao reduzir o trabalho repetitivo e tedioso de integração com APIs, sistemas de build, gerenciamento de pacotes e configuração de bibliotecas, isso ajudou muito a manter o momentum de produtividade
- No requisito inicial, foi incluída a condição de "usar apenas as credenciais globais de autenticação do app, sem armazenar tokens por usuário", e o agente implementou isso
- Mas o resultado foi uma vulnerabilidade de segurança grave (qualquer pessoa podia ver todos os repositórios)
- Ao explicar o problema em uma única frase, o agente introduziu imediatamente checagens de permissão por usuário e gerou um commit corrigido
- Em seguida, surgiu um problema de desempenho
- Na prática, o número de palavras usadas para explicar esse processo neste texto foi maior do que o total de palavras digitadas no Sketch para obter o código de autenticação
- Em resumo, os agentes ainda não estão no nível de substituir desenvolvedores hoje, mas ajudam a concluir em um dia tarefas repetitivas que tradicionalmente levariam vários dias
- A automação já chega ao ponto de permitir que o trabalho continue até mesmo enquanto o desenvolvedor está "arrumando o quarto da criança"
Exemplo: aplicação de regras SQL baseadas em JSON
- Uma das tarefas que o agente costumava executar era aplicar um estilo peculiar de SQL aprendido na Tailscale
- Em todas as tabelas, só há uma coluna real (os dados em JSON), e as demais são tratadas como generated columns derivadas desse JSON
- Exemplo de estrutura de tabela:
CREATE TABLE IF NOT EXISTS Cookie (
Cookie TEXT NOT NULL AS (Data->>'cookie') STORED UNIQUE, -- PK
UserID INTEGER NOT NULL AS (Data->>'user_id') STORED REFERENCES User (UserID),
Created INTEGER NOT NULL AS (unixepoch(Data->>'created')) STORED,
LastUsed INTEGER AS (unixepoch(Data->>'last_used')) CHECK (LastUsed>0),
Data JSONB NOT NULL
);
- Esse estilo funciona como uma espécie de poor man’s ORM, facilita a expansão do schema e ajuda a validar a qualidade dos dados JSON com constraints de SQL
- A desvantagem é o aumento do volume de dados armazenados por linha, além de exigir que todo
INSERT/UPDATE seja feito em unidade de JSON
- Porém, o agente nem sempre seguia esse estilo de forma consistente
- Ao criar novas tabelas, em geral seguia bem a regra, mas quando havia exceções às vezes se confundia ou mudava o estilo arbitrariamente
- Solução simples: adicionar uma explicação de 3 frases no topo do arquivo de schema SQL
- Incluir uma frase-chave dizendo que "cada tabela tem apenas uma coluna real
Data em JSON, e todas as outras colunas são derivadas dela"
- Nas tabelas que não seguem a regra, marcar explicitamente em comentários que são exceções
- Depois disso, o comportamento do agente melhorou visivelmente
- O ponto interessante é que esse tipo de explicação e comentário costuma ser ignorado ou subestimado por engenheiros humanos,
- mas agentes baseados em LLM usam ativamente comentários e explicações para escrever código
- Só de documentar bem, a qualidade da geração de código melhora claramente
O modelo de código como “ativo” e “passivo”
- Uma crítica comum às ferramentas de geração de código com LLM é que gerar código em si representa apenas uma fração minúscula do custo total de software
- Na prática, a maior parte do tempo vai para gerenciar dependências, acoplamentos e interfaces complexas do código existente
- Em produtos grandes, antigos e com muitos usuários, o custo de manutenção é esmagador
- Nesse contexto, pedir a um LLM algo como "escreva bubble sort em Fortran" pode parecer um brinquedo ou uma distração incômoda
- Há também discussões comparando isso com os conceitos financeiros de "ativo/passivo", embora essa analogia também não encaixe perfeitamente
- Mas nem toda engenharia de software se resume a projetos grandes e de longo prazo
- A maioria dos programas tem poucos usuários ou vida curta
- Não se deve generalizar a experiência de manutenção em grande escala como se fosse a essência de toda a indústria
- O valor dos agentes não se limita à geração de código
- Eles combinam várias ferramentas com LLMs para automatizar leitura de código, edição de arquivos, exclusão/modificação de código e a própria mudança
- Assim como adicionam código, também apagam código e fazem refatorações de forma natural
- No fim, o objetivo do engenheiro é produzir mudanças (
change)
- O processo de mudança ainda traz trabalho extra para que a pessoa responsável entenda as alterações, mas os agentes já mostram capacidade de promover mudanças graduais até mesmo em projetos de porte médio
- Mesmo que ainda não seja suficiente, eles estão evoluindo rapidamente na direção certa
- Há também a visão de que linguagens complexas e sistemas de build servem como barreira de entrada para projetos
- Existe o argumento de que ferramentas que facilitam escrever código (LMM, type safety, garbage collection, gerenciamento de pacotes, agentes etc.) podem reduzir a barreira de entrada às custas da qualidade
- Se o objetivo for desacelerar mudanças ou manter controle rígido, então ferramentas de automação como agentes realmente não combinam com isso
Por que agentes agora?
- Ao contrário de princípios complexos de IA, como transformers, colocar um loop de feedback em um LLM é uma abordagem intuitivamente clara
- Para quem pensa em ferramentas de desenvolvimento, isso parece uma direção natural de evolução
- De fato, há um ano a primeira versão do sketch.dev ainda era basicamente um LLM conectado apenas a ferramentas de Go, mas há uma grande diferença de praticidade em relação aos agentes usados hoje
- Na área de ML, reinforcement learning (aprendizado por feedback) já é um princípio básico há mais de 50 anos
- O surgimento prático dos agentes está diretamente ligado à evolução dos LLMs
- Em 2023, os LLMs ainda tinham pouca habilidade para chamar ferramentas, o que limitava seu papel como agentes
- Em 2025, os LLMs estão otimizados para chamadas de ferramentas e trabalho iterativo, o que torna o uso prático de agentes finalmente viável
- Modelos frontier (comerciais de ponta) estão muito à frente dos modelos abertos na capacidade de usar ferramentas
- Espera-se que os modelos abertos alcancem esse nível nos próximos 6 meses
- A capacidade de fazer chamadas úteis e repetitivas de ferramentas é a maior mudança dos LLMs mais recentes
Próximos passos: containers e execução paralela
- A área de agentes com LLM ainda está em uma fase inicial e de mudanças rápidas, que a maioria dos engenheiros ainda não adotou na prática
- Neste momento, agentes são usados principalmente em IDEs ou repositórios locais
- É fácil começar com um fork do VSCode ou instalando uma ferramenta de linha de comando
- Mas há duas limitações importantes
- A primeira é a falta de proteções de segurança: existe risco de exposição de dados sensíveis, como credenciais de produção armazenadas no computador real
- Se o agente executar comandos inesperados, como scripts de deploy, pode causar um incidente grave de segurança
- Mesmo exigindo confirmação manual a cada comando, o risco de vazamento de informações sensíveis por engano continua existindo
- A segunda é a limitação de paralelismo e automação: como cada desenvolvedor precisa rodar um agente por vez no próprio ambiente,
- cada execução pode levar vários minutos, tornando difícil tocar várias tarefas em paralelo e reduzindo a eficiência
- No sketch.dev, essas limitações estão sendo enfrentadas com um ambiente baseado em containers
- Para cada tarefa, é criado um container de desenvolvimento isolado, o código-fonte é clonado e apenas artefatos como commits de git são extraídos para fora
- Isso permite executar vários agentes ao mesmo tempo, e outros sistemas de agentes também vêm explorando esse caminho
- Caso real: enquanto o agente cuidava da autenticação do Github, outro agente em uma sessão separada melhorava a UI de um formulário
- Sem abrir um item separado em issue tracker, bastava fornecer um screenshot e um pedido curto de uma linha para receber melhorias no design do formulário
- Com apenas 30 segundos de investimento, já era possível obter um resultado minimamente bom
- Resultado de 6 meses de experimentos de UX:
- a conclusão foi que containers (ambientes isolados de execução) são a opção mais prática para desenvolvimento baseado em agentes
O que será da IDE?
- Em um ambiente de desenvolvimento baseado em agentes, qual será o papel da IDE (ambiente de desenvolvimento integrado)? Essa ainda é uma pergunta em aberto
- O fluxo real de trabalho pode vir a ser: escrever instruções para o agente, iniciar a tarefa, executá-la em um ambiente de container, revisar as mudanças via diff e fazer push em branch/PR
- Na prática, a maioria dos commits gerados por agentes ainda precisa de algum nível de acabamento humano
- No começo, quase todo commit exige correções manuais; mas, conforme a pessoa fica melhor em escrever prompts, a quantidade de ajustes vai diminuindo
- As correções vão desde coisas simples, como editar comentários e mudar nomes de variáveis, até refatorações mais complexas
- A questão central é como fazer esse tipo de ajuste de maneira eficiente dentro de um ambiente em container
- Alguns fluxos experimentados em sketch.dev e afins
- Uma interface em que a própria visualização de diff pode ser editada
- Na tela de diff do Sketch, é possível editar diretamente o código do lado direito, e isso já é refletido no commit e enviado em seguida
- É muito eficiente para ajustes pequenos de uma linha
- Acesso por SSH ao container, permitindo
- entrar direto no shell ou manipular o código em um terminal web
- abrir via URL
vscode:// e trabalhar em uma IDE tradicional
- Comentários em estilo code review deixados diretamente sobre o diff para enviar feedback ao agente
- Aproveitando a experiência de revisão de código, dá para comunicar explicações e requisitos com o mínimo de digitação
- Resumo geral
- O ambiente em container integra geração, modificação, validação e revisão de código,
tornando possível uma verdadeira experiência de desenvolvimento baseada em agentes, muito além de apenas escrever código
- Antes, o autor não queria desenvolver em containers,
mas a experiência de organizar e corrigir dentro do container os diffs produzidos por agentes tem se mostrado muito interessante e produtiva
Conclusão
- O processo de aprender e experimentar tecnologias baseadas em LLM foi uma lição de humildade
- No passado, mudanças como a adoção de multicore, SSDs e expansão de rede já traziam alegria por alterarem a natureza da programação,
mas LLMs, especialmente agentes, estão reinventando completamente o próprio processo de codar
- Diferentemente de mudanças que influenciavam algoritmos, linguagens ou escolha de bibliotecas,
os agentes fazem repensar de forma radical todas as premissas do próprio jeito de trabalhar
- Às vezes, a mudança é tão grande que dá a sensação de que "talvez fosse melhor reaprender tudo do zero como alguém que nunca programou"
- E essa transformação ainda está em andamento
- O que estamos vivendo agora já é completamente diferente de 6 meses atrás e ainda nem se estabilizou
- Padrões de cultura de desenvolvimento, como colaboração em equipe e revisão, provavelmente vão mudar bastante em breve
- Por exemplo, code reviews que eram feitas apenas por formalidade já não conseguem mais resolver problemas reais
- Já passou da hora de reinventar o próprio processo de revisão de código
- O próprio IDE, apesar de toda a ênfase histórica em integração, também está chegando ao momento de ser completamente repensado
- A indústria já percebe essa mudança, mas a abordagem centrada em agentes ainda está só no começo
- Mais transformações grandes estão por vir, e
curiosidade e humildade são provavelmente a melhor forma de atravessá-las
- Talvez, neste momento, seja até melhor se afastar dos fóruns de tecnologia na internet e
deixar esse tipo de discussão e resumo para os próprios agentes
1 comentários
Comentários do Hacker News
Como eu programo principalmente só para as minhas próprias ferramentas, tendo a achar que não há muito mérito em outra pessoa ou alguma coisa escrever o código no meu lugar e depois eu ter que ler, entender e corrigir aquilo; claro, pedir para um LLM encontrar na documentação da API a parte que eu quero é bastante útil e economiza tempo, então, independentemente de o desempenho futuro dos LLMs melhorar ou não, eu simplesmente não gosto muito de ler código dos outros
Concordo totalmente com a parte em que o autor diz que code review é fraco e quase nunca funciona direito; na era em que agentes escrevem código, o gargalo real não é escrever, e sim ler código; se as pessoas fizerem review de qualquer jeito ou usarem isso apenas para expressar preferências pessoais, agentes podem inserir facilmente problemas graves de segurança ou desempenho; sinceramente, o problema real é que essas coisas muitas vezes não aparecem só lendo o código: é preciso debugar de fato ou validar hipóteses manualmente
Minha impressão foi a de finalmente ver um texto com uma análise realista sobre LLMs; o termo “agente” me irrita um pouco porque, na prática, é basicamente dar um nome a um
forloop que chama LLM recursivamente, mas a indústria nunca teve grande talento para naming, então aceiteiSobre a parte “concordamos que contêineres são úteis e necessários na programação”, isso ajuda a explicar por que Solomon Hykes, criador do Docker, abriu recentemente o projeto Container Use como open source: para permitir que agentes rodem em paralelo com segurança; algumas plataformas, como a Sketch, já embutem ambientes locais de desenvolvimento isolados, mas outros agentes de programação não; como informação extra, também recomendo este vídeo no YouTube
Loops agênticos, um cérebro na máquina, parecem ser na prática um substituto para mecanismos de regras; ainda têm desvantagens próprias, mas acho que várias pessoas importantes identificaram bem a essência: “ligar ferramentas agênticas, gerar prompts a partir da solicitação do usuário, simplesmente executar em loop, e o próprio prompt muda dinamicamente conforme a situação”; sem precisar imitar à força interação humana ou um jeito humano de resolver problemas, isso já é bastante útil para orquestração, múltiplas etapas e para substituir ou automatizar tarefas ambíguas; antes era preciso implementar a ambiguidade diretamente em código, e isso pode desaparecer; em produção ainda há preocupação com executar sem dry run, mas acredito que as ferramentas e os serviços vão evoluir; se mais de 100 serviços parecidos se conectarem ao mundo externo com interfaces consistentes — por exemplo SMS, e-mail, clima, redes sociais etc. — imagino assistentes muito mais poderosos do que os de hoje, ou até algo além disso
Ler código sempre foi tão importante quanto escrevê-lo, mas agora está ficando ainda mais importante; é meu pesadelo; escrever código às vezes é divertido, mas ler código é sempre trabalho
Fico curioso sobre quantas pessoas que usam agentes realmente gostam de “programar” — isto é, de pensar na forma de resolver um problema e no prazer de expressá-lo em código; muito do trabalho com agentes hoje parece apagar esse processo e substituí-lo por descrever requisitos em linguagem natural e torcer para que o LLM não introduza bugs
Há algumas áreas em que gosto bastante de usar IA ao programar (é algo que eu realmente escrevi!):
divespecífica em um WordPress complexo depois de algumas tentativas ela chega lá rápidoA parte sobre “ativos” e “passivos” foi interessante, mas eu não concordo; muitos programas começam para um pequeno número de usuários e acabam virando grandes projetos; no passado, vi vezes demais código científico escrito de forma improvisada para uso pontual acabar se expandindo, sem querer, por muito tempo e em escopo muito maior; por isso, escrevo meu código pensando que ele será usado por mais tempo e em alcance maior, por consideração comigo mesmo e com os outros; quem já viu um side project pessoal de um colega ser promovido pelo gerente a projeto oficial do departamento vai entender bem esse problema
Acho que usar LLM não para escrever/projetar código, mas para fazer code review, pode ser a verdadeira funcionalidade matadora; hoje o code review está quebrado em muitos aspectos, e espero que no futuro o uso de LLM cresça em segurança, comportamento indefinido, mau uso de funcionalidades e dupla checagem de problemas de warnings do compilador; pessoalmente, uso mais LLM no estilo mecanismo de busca para diagnosticar erros ou debugar, e a taxa de acerto de uns 50% já me satisfaz bastante