Como montar um agente de código do zero com llm-coding-agent
Tutorial prático: use a lib llm como framework de agente, escreva um spec.md e gere um agente de coding funcional com dois prompts simples.

A biblioteca llm do Simon Willison deixou de ser só um client de linha de comando para modelos e virou, aos poucos, um framework de agente. O projeto llm-coding-agent é a prova disso: um agente de coding simples, construído em cima do llm, escrito quase inteiro a partir de dois prompts e um arquivo de especificação. Neste tutorial você vai reproduzir esse processo do zero, entendendo cada etapa.
Por que isso importa
Montar um agente de coding do zero costuma parecer trabalho de várias semanas: gerenciar contexto, decidir quando rodar comandos, formatar chamadas de ferramenta, tratar erros do modelo. Usando a lib llm como base e um bom spec.md como ponto de partida, boa parte desse trabalho vira responsabilidade do próprio modelo durante a implementação. Você escreve a especificação, o agente escreve o código. O ganho prático é dobrado: você aprende como um agente de coding funciona por dentro e sai com uma ferramenta real, customizável, para o seu fluxo.
Passo 1: prepare o ambiente
Comece criando um repositório novo a partir de um template de projeto Python. Se você não tem um, pode usar qualquer template com pyproject.toml, estrutura de testes e CI básica já configurados. O importante é começar de uma base limpa, sem código de aplicação ainda.
gh repo create meu-coding-agent --template seu-usuario/python-lib-template --clone
cd meu-coding-agent
python -m venv .venv
source .venv/bin/activate
pip install llm
Instale também o llm-coding-agent se quiser comparar sua implementação com a original:
pip install llm-coding-agent
Passo 2: escreva o spec.md com um prompt
O pulo do gato aqui é não escrever a especificação manualmente do zero. Você pede para um modelo de coding (Claude Fable 5, GPT-5.6 ou equivalente) gerar o spec.md a partir de uma descrição curta do que você quer construir. Use um prompt direto, sem microgerenciar detalhes de implementação:
Write a spec.md for this project: a simple coding agent
built on top of the llm Python library. The agent should:
- accept a task description from the user
- use an LLM to plan and execute file edits and shell commands
- run in a loop until the task is done or a max number of
iterations is reached
- log every tool call and model response to a local file
Keep the spec concise and focused on behavior, not code.
Revise o resultado. Um spec.md bom descreve comportamento esperado, não implementação. Ele deve responder três perguntas: o que o agente recebe como entrada, o que ele faz em cada iteração do loop e quando ele para.
Passo 3: gere o agente com o segundo prompt
Com o spec.md pronto e commitado no repositório, o segundo prompt pede para o modelo implementar o projeto inteiro a partir dessa especificação:
Read spec.md and implement this project. Use the llm library
as the underlying agent framework. Write tests for the core
loop logic. Make sure the CLI entry point works with:
python -m meu_coding_agent "task description here"
Esse é o momento em que o “framework de agente” da lib llm entra em ação de verdade: ela já resolve chamadas de ferramenta, histórico de conversa e integração com múltiplos provedores de modelo. O trabalho do agente gerado é sobretudo orquestrar esse loop: enviar a tarefa, receber a resposta do modelo, executar as ações pedidas (editar arquivo, rodar comando) e alimentar o resultado de volta no contexto.
Passo 4: entenda o loop gerado
Depois que o código é gerado, vale a pena ler o loop principal antes de rodar qualquer coisa. Ele normalmente segue esse formato:
def run(task: str, max_iterations: int = 10):
conversation = llm.get_model("seu-modelo").conversation()
for i in range(max_iterations):
response = conversation.prompt(task if i == 0 else "continue")
tool_calls = parse_tool_calls(response)
if not tool_calls:
break
for call in tool_calls:
result = execute(call)
log(call, result)
return conversation
Não pule essa leitura. Segundo o princípio “entenda para participar” discutido recentemente em círculos de agentes de coding, deixar de entender como o agente decide parar ou continuar cria uma dívida cognitiva: você perde a capacidade de colaborar de verdade com o código conforme ele cresce.
Passo 5: rode o agente numa tarefa real
Teste com uma tarefa pequena e verificável, tipo adicionar uma função com teste:
python -m meu_coding_agent "Add a function `slugify(text: str) -> str`
in utils.py that converts a string to a lowercase, hyphenated slug.
Include a test in tests/test_utils.py."
Acompanhe o log gerado a cada iteração. Se o agente girar em loop sem progresso, geralmente é sinal de que o spec.md não deixou claro o critério de parada, ou que o prompt de tarefa está vago demais.
Passo 6: ajuste o critério de autonomia
Um erro comum é microgerenciar demais o agente, dizendo exatamente quando rodar testes ou qual comando shell usar em cada passo. Prefira dar critério e deixar o modelo decidir a execução. No spec.md, troque instruções rígidas por regras de julgamento:
Instead of: "run pytest after every file edit"
Prefer: "run tests when a change affects public behavior;
skip tests for internal refactors or comment-only changes"
Isso reduz o número de chamadas desnecessárias e deixa o agente mais rápido em tarefas pequenas, sem perder qualidade nas grandes.
Dicas finais
- Mantenha o
spec.mdversionado e atualize ele antes de pedir mudanças grandes no agente, não depois. - Rode o agente com um
max_iterationsbaixo (3 a 5) nos primeiros testes para não gastar tokens em loops que não convergem. - Leia o código gerado no primeiro dia inteiro. Depois disso, você já vai conseguir revisar apenas o diff.
- Se quiser comparar abordagens, instale o
llm-coding-agentoriginal e leia o própriospec.mddele como referência de estilo.
— Lucas