Projetos / Three-Body Agent github.com/a7t-ai/three-body-agent
Three-Body Agent
Pipeline de desenvolvimento autônomo no GitHub Actions + Claude Code.
Cinco workflows num cron. O implementer pega a próxima issue p0 do board do projeto e abre um PR. O fixer persegue o CI até ficar verde. O merger entrega quando os reviews chegam. Board-sync e rollover mantêm a fila limpa. Nenhum humano no loop até a reunião da manhã.
O pitch é curto. Você abre um GitHub Project, coloca issues nele ranqueadas de p0 a p5, vai embora e volta na manhã seguinte para uma pilha de PRs mergeados, com uma thread no Telegram mostrando o que foi entregue.
Esse é o loop inteiro. A parte interessante é o que está embaixo.
Os três corpos
O sistema é shell script e GraphQL. Três workflows rodam em schedule, cada um na própria órbita.
O Implementer roda a cada hora. Escaneia o milestone da semana, pega a issue Todo de maior prioridade, entrega ao Claude Code e abre um PR.
O Fixer roda a cada trinta minutos. Observa PRs marcados para revisão, lê o feedback, pede um patch ao Claude Code e faz push de novo.
O Merger roda a cada duas horas. Promove PRs verdes que ficaram estáveis o suficiente para serem confiáveis.
Mais dois workflows seguram o loop. O Board Sync escuta eventos de PR e move os cards pelas colunas. O Rollover roda semanalmente e varre o trabalho não terminado para o milestone seguinte.
A piada do “três corpos” é que eles orbitam um ao outro, cada um puxando o trabalho do outro, e o arranjo é estável enquanto nada cair num estado degenerado. (Spoiler: coisas caem em estados degenerados. É para isso que servem os labels de prioridade e a coluna paused.)
O que conta como “marcado para revisão” depende do seu setup. No meu, pode ser qualquer um de três sinais: a CI falhou, um humano deixou um comentário de review, ou um LLM separado agindo como crítico postou o veredito no PR.
O LLM como crítico é o caso mais interessante. Com uma rubrica clara do que conta como issue crítico versus médio, ele diz ao Fixer o que priorizar. E é deliberadamente sem viés: processo novo a cada chamada, sem memória dos fixes anteriores, sem contexto do que já foi feito. Cada passada lê o diff como código novo. Um crítico com memória vai derivando para “tá ok, você consertou da última vez” em vez de pegar o novo modo de falha que o último fix introduziu.
Abaixo você pode ver o caminho de um ticket pelos três workflows. A primeira tentativa volta marcada para revisão (CI vermelha, nesse run), o Fixer roteia o feedback para o Implementer, a segunda passa, e o Merger leva para a main. Arraste a barra ou clique em play.
Sobre o que ele roda
Nada exótico.
O GitHub Actions roda o cron e o runner. O GitHub Projects V2 é o estado compartilhado, com colunas como status, milestones como semanas e labels como prioridade. A CLI do Claude Code é o worker; o Implementer entrega um prompt com o body da issue, a árvore de arquivos e o diff atual, enquanto o Fixer entrega o feedback do revisor e pede um patch.
O Claude Code é o que eu uso, mas o loop não se importa com qual modelo está atrás da CLI; qualquer LLM frontier com uma CLI de coding encaixa. Modelos locais também funcionam, com a ressalva de que precisam de uma infraestrutura séria por trás: um servidor que aguente contextos longos e tool calls confiáveis. Um modelo local que perde metade das tool calls ou trava num prompt de 60k tokens custa mais em debug do que economiza em inference.
O Telegram é o que eu uso para visibilidade, mas qualquer canal de mensagem com API de bot encaixa: Slack, Discord, um webhook para qualquer coisa que você já acompanha. Ele posta uma mensagem em cada transição para eu assistir do celular.
Sem framework, sem SDK, sem dependências além de gh, jq e curl. Tudo é auditável nos logs do Actions e versionado junto do código que opera.
O que surpreende
O Implementer ordena por prioridade e depois por tamanho do body. Descrições mais longas tendem a produzir PRs mais limpos, porque o Claude tem mais constraint para trabalhar. Issues vazias falham mais, então o bot se autoseleciona para as issues nas quais você realmente pensou.
O Fixer é o workflow mais usado, com folga. Eu esperava que o Implementer fizesse o trabalho pesado, mas na prática a primeira tentativa quase nunca passa verde: testes flakey, dependência faltando, problema de type narrowing. O Fixer é o que transforma tentativas em merges, e vale a pena mais do que eu esperava.
O Telegram é load-bearing. As notificações são o único lugar onde dá para mandar o sistema parar antes que ele empurre outro PR ruim.
O que está deliberadamente fora de escopo
Sem auto-deploy. O Three-Body mergeia na main; quem pega main para deploy é problema seu.
Sem seleção de modelo. A CLI usa o que você configurou; o Three-Body só entrega o trabalho.
Sem “supervisor de agente”. O Three-Body é o supervisor. Botar outra camada acima é onde esses sistemas começam a perder o pragmatismo.
O que eu faria diferente
O polling por cron é desperdício. Três workflows acordam a cada hora, a cada trinta minutos, a cada duas horas, tendo trabalho ou não. A maioria dos runs é no-op. O GitHub tem webhooks para isso: tanto webhooks HTTP externos quanto triggers internos de workflow do tipo on: pull_request. O Fixer e o Merger deveriam estar ligados a eventos de PR em vez do relógio. Os dois reagem a mudanças de estado de PR, então um filtro de evento acordaria os dois no momento certo e deixaria quietos no resto do tempo. Só o Implementer realmente precisa de relógio, porque ele consulta o board atrás de tickets novos e não existe evento do GitHub para “o board tem trabalho esperando”.
O Fixer não tem regra de desistência. Ele fica em loop no mesmo PR para sempre, o que é tranquilo até deixar de ser. Depois de três tentativas no mesmo erro, eu quero que ele marque o PR como paused, mande uma mensagem no Telegram e pare de queimar crédito.
Os runs de sub-agente caem nos mesmos logs do thread principal, e isso embaralha o diagnóstico quando o Fixer está tentando entender por que algo falhou. Um transcript separado por tentativa deixaria o post-mortem bem mais limpo.
Como rodar
Repo: https://github.com/a7t-ai/three-body-agent. O README te leva por:
- Forkar para o repo alvo.
- Criar um GitHub Project com as colunas
Todo · In Progress · Ready for QA · Done. - Adicionar as labels
p0ap5. - Configurar o milestone dessa semana.
- Adicionar os secrets que os workflows pedem (
CLAUDE_CODE_API_KEY,TELEGRAM_BOT_TOKEN, etc.). - Colocar uma issue no board e ver o Implementer pegá-la na próxima hora.
a7t.ai · LIVRO
A arquitetura completa em PDF. Quatorze capítulos: os três papéis, as duas revisões, o quadro e os gatilhos, o catálogo de falhas, os painéis de custo. Reembolsável por catorze dias. Edição em inglês.
Ver detalhes →O que eu faria por você
Esse padrão se transfere para times que querem um “júnior que nunca dorme” rodando no backlog. O formato certo depende de três coisas: como sua main é (protegida? CODEOWNERS? reviews obrigatórios?), quanto custa rodar a sua suite de testes, e quem revisa antes do merge. Me conta essas três e a gente especifica a adaptação certa em 45 minutos.