7 pontos por GN⁺ 2026-01-09 | 1 comentários | Compartilhar no WhatsApp
  • A estrutura central de um assistente de programação com IA não é uma mágica complexa, mas cerca de 200 linhas de código Python simples
  • O sistema é baseado em um loop de conversa com o LLM; quando o LLM solicita uma chamada de ferramenta, o código local a executa e devolve o resultado
  • As três ferramentas básicas necessárias são leitura de arquivo (read), listagem de arquivos (list) e edição de arquivo (edit), o que permite explorar o projeto e modificar código
  • Com base na assinatura e na descrição (docstring) das ferramentas, o LLM decide por conta própria qual ferramenta chamar e quando
  • Essa estrutura é a mesma essência de produtos comerciais como o Claude Code, e mesmo uma estrutura simples pode implementar um agente de programação poderoso

Conceito básico de agente de programação

  • Um agente de programação é um sistema baseado em conversa com um LLM que recebe comandos do usuário e realiza operações reais em arquivos por meio de chamadas de ferramentas
    • O usuário digita uma solicitação como “crie um novo arquivo com uma função hello world”
    • O LLM responde com as chamadas de ferramenta necessárias em formato JSON
    • O programa executa a ferramenta e envia o resultado de volta ao LLM
  • O LLM não acessa diretamente o sistema de arquivos; ele apenas faz solicitações, e o trabalho real é tratado pelo código local

As três ferramentas necessárias

  • read_file: lê e retorna todo o conteúdo do arquivo especificado
  • list_files: retorna a lista de arquivos e pastas em um diretório
  • edit_file: substitui uma string existente por uma nova string ou, se old_str estiver vazio, cria um novo arquivo
    • Se a string a ser substituída não existir, retorna “old_str not found”
  • Mesmo só com essas três ferramentas, já é possível criar, modificar e explorar arquivos

Registro das ferramentas e integração com o LLM

  • Todas as ferramentas são registradas no TOOL_REGISTRY com nome e função, para que o LLM possa chamá-las
  • A docstring e a assinatura de cada ferramenta são extraídas e enviadas ao LLM
  • O prompt de sistema informa claramente ao LLM a “lista de ferramentas disponíveis” e o “formato de chamada”
    • As chamadas de ferramenta ficam restritas ao formato 'tool: TOOL_NAME({JSON_ARGS})'
    • Os resultados da execução das ferramentas são enviados ao LLM no formato tool_result(...)

Parsing das chamadas de ferramenta e tratamento das respostas do LLM

  • Nas respostas do LLM, procura-se por linhas que comecem com tool: para extrair o nome da ferramenta e os argumentos (JSON)
  • Após executar cada ferramenta, o resultado é serializado em JSON e adicionado ao histórico da conversa
  • A função execute_llm_call chama a API do LLM e retorna o texto da resposta
  • run_coding_agent_loop recebe a entrada do usuário e mantém o loop de conversa com o LLM
    • O loop interno se repete até que o LLM não solicite mais chamadas de ferramenta

Exemplos de execução e possibilidades de expansão

  • Exemplo de conversa:
    • “Crie o arquivo hello.py e implemente hello world” → cria um novo arquivo com uma chamada a edit_file
    • “Adicione uma função que multiplica dois números em hello.py” → chama read_file e depois edit_file
  • É possível implementar um assistente de programação completo com cerca de 200 linhas de código
  • Produtos comerciais acrescentam a isso tratamento de erros, respostas em streaming, gerenciamento de contexto, ferramentas adicionais e fluxo de aprovação
  • A estrutura central continua a mesma: um loop simples em que o LLM decide e o código executa

Prática e expansão

  • O código-fonte completo tem cerca de 200 linhas e pode ser expandido com troca por outro provedor de LLM ou adição de ferramentas
  • Mesmo com uma estrutura simples, é possível implementar diretamente um protótipo poderoso de agente de programação com IA

1 comentários

 
GN⁺ 2026-01-09
Comentários do Hacker News
  • O que eu acrescentaria é planning
    A chave para usar ferramentas de forma eficaz é perceber que elas operam sobre uma lista de TODOs dinâmica
    O modo Plan serve para inicializar como essa lista é semeada e quando cada item é executado
    A interação do usuário funciona como uma forma de reordenar essa lista
    No mês passado, experimentei o quão bem o Claude Code resolve problemas de CTF, e quando desliguei a ferramenta TodoList e o planning, o desempenho caiu de 1 a 2 níveis
    Para um vídeo relacionado, veja Breaking Bots: Cheating at Blue Team CTFs with AI Speed Runs
    O interessante é que muita gente se concentra apenas em “usar ou não o modo plan”, mas a lista de TODOs está sempre ativa
    Também acho engraçado ver textos que tratam “gerenciamento inteligente de contexto” como se fosse apenas um item de TODO
    Muita gente acaba tentando implementar isso por conta própria e perde um ano por causa de resultados de avaliação que quebram em produção

    • No gist com o prompt de sistema extraído do Claude Code, há muitos detalhes sobre a iteração de TODOs
      Dá para adicionar isso simplesmente como tokens de reasoning, mas na prática é muito mais previsível e eficaz implementar como uma ferramenta explícita de armazenamento de chave única
      Parece que essa abordagem simples também pode funcionar para outras ideias de ferramentas que armazenam estrutura de linguagem
    • Para agentes de CLI, manter um arquivo de “working memory” funcionou muito bem
      Ao testar o Codex, eu passava uns 10 minutos organizando a especificação, dividindo em uma lista de mudanças, mandando salvar isso em um arquivo e depois instruindo a revisar e ajustar o plano após cada mudança
      Isso permite que o LLM se concentre em tarefas curtas e orientadas a objetivos sem precisar de entrada contínua de prompt
      Na prática, produz um efeito parecido com ter subagentes
    • Eu também costumo acrescentar no fim do prompt algo como “use uma lista de todo extremamente detalhada para esta tarefa”
      Às vezes também coloco como último TODO: “revise todo o trabalho novamente e verifique a qualidade com linter etc.”
    • A lista de TODOs muitas vezes é reinserida no HEAD do contexto para que o LLM reconheça o passado e os próximos passos
      Durante a compressão de contexto, ela também é usada como uma representação concisa da sessão
    • Talvez no fim do ano apareça alguma piada do tipo “How to Code Claude Code in 200 Million Lines of Code”
  • O núcleo de um agente de código é, na verdade, uma simples estrutura de loop e chamadas de ferramentas
    Mas se você vai escrever algo como “The Emperor Has No Clothes: How to Code Claude Code in 200 Lines of Code”, precisa mesmo consultar How to Build an Agent do Thorsten Ball
    Foi esse texto que apresentou primeiro a ideia de que “a essência do agente é simples”
    Claro que, na prática, são necessários TODOs e vários tipos de scaffolding, e o próprio Claude Code também tem configurações complexas, plugins e muitos recursos de UI
    Ainda assim, só com o loop mínimo já dá para inicializar um processo que expanda as próprias funcionalidades
    Se quiser ver o funcionamento interno, dá para usar claude-trace para rastrear a interação entre o LLM e as chamadas de ferramenta

    • Eu analisei as transcrições locais do Claude Code e do Codex para observar a estrutura interna
      Além do loop simples, há muitos elementos complexos, como encadeamento de UUID, processamento de fila de mensagens, snapshots de mudanças em arquivos e sidechains de subagentes
      Então, “200 linhas” faz sentido conceitualmente, mas em nível real de produção é muito mais complexo
      O Codex ainda não tem recurso de enfileiramento, mas continua poderoso
      Eu criei um app para macOS chamado Contextify para monitorar em tempo real as transcrições de CLI do Claude Code e do Codex, e permitir consultar o histórico da conversa com o recurso Total Recall
    • A edição de código é a parte mais importante
      Os modelos Claude são treinados com seu próprio schema de ferramenta str replace
      Reescrever o arquivo inteiro é ineficiente, então o essencial é fazer edições parciais
    • Também houve reação do tipo “achei que era um repost do mesmo texto”
    • E também pediram: “você pode mostrar diretamente esse loop central simples?”
  • Na prática, há mais elementos
    Por exemplo, às vezes o agente entra em early stopping e encerra a tarefa antes da hora
    Isso não se resolve nem com os modelos de reasoning mais recentes
    O Claude Code contorna isso injetando TODOs em cada prompt para relembrar o trabalho restante
    O repositório público do HolmesGPT tem vários benchmarks experimentais

    • Também surgiu a pergunta: “por que acontece early stop?”
  • No começo, foi chocante para mim a ideia de que “basta informar ao LLM a lista de ferramentas e o formato de chamada”
    Eu pensava: como um LLM, que só gera texto, poderia chamar ferramentas? Mas quando percebi que era só isso, pareceu magia

  • Durante o feriado, tentei criar com o Opus um agente de código baseado em DSL de Prolog (passou de 200 linhas)
    E, surpreendentemente, funcionou bem quase de imediato
    Parece que os modelos da geração mais recente chegaram a um ponto em que a importância do harness do agente diminuiu
    Para um experimento relacionado, veja este post

  • Há um ano, este texto era bem preciso, mas agora os harnesses evoluíram muito, então o modelo de loop simples já não explica bem o funcionamento real do Claude Code

    • Claro que os harnesses modernos têm mais funcionalidades, mas o conceito básico continua válido
      Mesmo agentes simples, usando o mesmo modelo, não ficam tão atrás em desempenho
      É parecido com um tutorial de “crie seu próprio banco de dados” mostrando o B-tree básico
    • Segundo o leaderboard do tbench.ai, a complexidade até melhora um pouco o desempenho, mas abordagens baseadas em loop simples como “Terminus” continuam suficientemente poderosas
    • Também houve a observação de que “este texto foi publicado em janeiro de 2025”
    • Na prática, os avanços do último ano se concentraram em simplificar prompts e design de ferramentas
      Subagent, MCP e Skills ficam em um nível intermediário, e otimização de contexto só é realmente significativa em execuções longas
    • Também dá para fazer uma análise melhor do modelo aproveitando o repositório codex-cli
  • Eu mesmo construo diretamente loops de agentes para uso corporativo e processo mais de 1 bilhão de tokens por mês
    O loop simples é o núcleo, mas em ambiente real inúmeros detalhes fazem a complexidade explodir
    Por exemplo, como tratar o loop quando o usuário manda uma mensagem no meio, como sincronizar entradas por webhook de algo como Slack,
    além de aprovação, guardrails, tratamento assíncrono de tasks etc.
    Estou pensando em organizar essa experiência em um post de blog

  • Como leitura útil, há You Should Write An Agent e How To Build An Agent

  • Nossa equipe do SWE-bench publicou um agente open source de 100 linhas
    É o mini-swe-agent, e ele é popular tanto na academia quanto na indústria
    É um bom ponto de partida para aprender sobre o mundo dos agentes

  • Em 2023, houve um texto chamado “Reimplementando o LangChain em 100 linhas”
    Vi esse texto, implementei de fato e usei em vários projetos

    • Também houve a reação: “não acredito que isso já faz 3 anos”