← Artigos · · 5 min de leitura

Orquestrando agentes com GitHub Actions

Movi todo meu pipeline autônomo de coding para o GitHub Actions em dois dias, porque a Anthropic fechou a porta da configuração anterior de uma noite para outra. Notas sobre o que mudou e o que eu faria diferente.

  • agentes
  • github-actions

Fazer um agente de IA escrever código é a parte fácil. O problema difícil, o que a maioria dos times encontra depois que a novidade passa, é tudo em volta. Como agendar agente de forma confiável e saber quando ele falhou em silêncio? Como replicar o setup para um projeto novo sem reconstruir do zero? A camada de orquestração é onde os pipelines de código autônomo realmente quebram.

Aprendi isso rodando uma fábrica de agentes na IGNIO. O post anterior fala dos princípios que fizeram funcionar. Este aqui é sobre o que aconteceu quando tive que mover tudo para o GitHub Actions em dois dias, e o que aprendi no caminho.

A migração forçada

A fábrica rodava pelo OpenClaw na minha máquina de CI local, gerando sessões do Claude Code com tokens de assinatura. O OpenClaw era a camada de orquestração e era o ponto fraco. Se o processo crashava, o pipeline ficava em silêncio. A trilha de auditoria era o que eu conseguia tirar de logs de sessão depois do fato. Replicar para outro repo era copiar scripts na mão torcendo para não esquecer nada.

Eu já sabia que a arquitetura estava errada. Aí, em 4 de abril, a Anthropic deixou isso urgente. Bloquearam tokens de assinatura de ferramentas third-party como o OpenClaw. Tinha desenvolvedor roteando frontier AI por assinatura flat enquanto consumia compute que devia estar sendo cobrado por token. A Anthropic fechou a arbitragem.

Engoli seco. Mudei tudo para API keys pay-per-token, dropei as sessões geradas por assinatura e escolhi o GitHub Actions como o novo runtime de orquestração. Sem área cinzenta, sem workaround.

Por que GitHub Actions e não a action oficial

A Anthropic tem uma GitHub Action first-party, e ela é excelente para os casos interativos: PR review, menção @claude, e triggers conversacionais em geral. Não combina com agente autônomo de execução longa. A action é otimizada para interação curta, e o modelo de permissão dela exige enumerar cada tool permitida explicitamente. Para sessão de noventa minutos com quinhentos turnos máximo fazendo implementação completa de issue, chamar a CLI do Claude Code direto é mais simples e dá controle total. A complexidade real do pipeline é a lógica de shell que roda em volta do passo do Claude (varrer board, ranqueamento de prioridade, detecção de dependência, mutation de GraphQL), e a action não ajuda em nada disso.

A migração levou uns dois dias. A máquina que roda os agentes não mudou; o runner self-hosted é o mesmo ambiente de dev que sempre uso. O que mudou foi tudo o resto: a orquestração agora vive em workflow files versionados dentro de .github/workflows/, toda execução é auditável pela UI do Actions, e falha aparece como notificação em vez de silêncio. Copiar o diretório para um repo novo replica o pipeline inteiro.

A arquitetura, em um parágrafo

Seis workflows formam o sistema. O Implementer roda toda hora, pega a issue de maior prioridade no board e entrega para CLI do Claude Code numa sessão completa. O Fixer roda a cada trinta minutos, varre as PRs do autoagent por falha de CI ou feedback de review, e pede um patch para o Claude. O Merger roda a cada duas horas, processa as PRs verdes em sequência e usa o Claude para verificar se o feedback de review foi de fato endereçado antes de dar merge. Dois workflows de apoio cuidam do resto: o Board Sync move os cards do projeto quando eventos de PR acontecem, e o Week Rollover cria o milestone da semana seguinte e leva o trabalho inacabado adiante toda segunda. O todo é shell, GraphQL e Telegram. Sem framework, sem SDK, sem dependência além de gh, jq e curl. A arquitetura completa está na página do projeto.

Conduzindo o trabalho com seis labels

A lógica de seleção do orquestrador do Implementer é a parte menor do sistema e também a que mais tem me dado valor.

O board usa seis labels de prioridade, p0 a p5. O orquestrador ordena os candidatos por prioridade primeiro, e por tamanho do body da issue como desempate. Descrição mais longa tende a produzir PR mais limpa, porque o agente tem mais constraint para trabalhar. Issue vaga falha mais, então o bot se auto-seleciona para as issues nas quais você de fato pensou. Sem grafo de dependência, sem ordenação topológica, sem fila de prioridade com score ponderado. Só labels.

Repriorizar é trivial. Muda a label, o orquestrador pega na próxima execução horária. Quando taggei um pré-requisito não-construído como p0 e o resto da fase como p1, o agente parou de se confundir com a cadeia de dependência e começou a trabalhar na ordem certa.

O que é auditável, o que é conversacional

O OpenClaw ficou na história como o canal conversacional, agora rodando em API keys. A divisão acabou sendo mais do que workaround. Ela mapeia uma distinção real em como o trabalho de agente se separa.

Tem trabalho que é inerentemente conversacional. Uma noite pedi para o meu agente desabilitar todos os workflows agênticos num repo, comentar os triggers de cron, dar push direto na main, e depois criar um novo workflow de rollover de semana. Isso exigiu ler cada arquivo, decidir o que comentar versus deletar, e fazer múltiplos commits. Algumas edge cases pediram julgamento, como o fato de o workflow do Copilot não poder ser desabilitado por API. Dez minutos de vai-e-volta com uma decisão a cada passo. Você não bota isso num workflow file. Precisa de contexto e julgamento, incluindo a capacidade de perguntar “espera, eu também devo desabilitar os crons do lado do OpenClaw?”

Então rodo dois sistemas: GitHub Actions para o trabalho autônomo e repetível (implementação de issue, conserto de CI, gestão de board e sprint) e Telegram para o trabalho interativo e contextual (elaboração de issue, reação rápida, coordenação entre projetos). É a divisão certa. Tem trabalho que precisa de autonomia, tem trabalho que precisa de conversa, e forçar os dois num sistema só faz os dois piorarem.

Os números

Depois de algumas semanas rodando a versão GitHub Actions: 240 issues implementadas, 232 PRs abertas, 95% de taxa de sucesso, onde “sucesso” é PR mergeada sem intervenção manual significativa. Os 5% que precisaram de ajuda eram issues com requisito ambíguo ou edge case que exigia conhecimento de domínio que o agente não tinha. Escrever descrição melhor de issue eleva a taxa de sucesso direto.

O que eu faria diferente

Três coisas se destacam de rodar isso em escala.

Escreve descrição de issue melhor desde o começo. O preditor número um de sucesso de implementação autônoma é a qualidade da issue. Issue vaga produz PR vaga. Issue com critério de aceite claro e referência ao código existente produz implementação limpa. Cada hora gasta na descrição da issue economiza três no review da PR.

Começa pelo Fixer, não pelo Implementer. O Fixer entrega valor imediato em qualquer projeto com CI; ele só fica de olho em falha e empurra patch. O Implementer precisa de project board, label de prioridade e orquestrador antes de fazer qualquer coisa. Se eu fosse começar de novo, eu colocava o Fixer no ar primeiro e ia adicionando o resto aos poucos.

Fica de olho no consumo de token. Rodar Opus com quinhentos turnos máximo é caro. Acompanha o custo de API por execução de workflow. Sonnet dá conta de issue simples e custa uma fração do Opus. Um dropdown de modelo no workflow input permite escolher por run, e essa troca sozinha mudou o custo mensal mais que qualquer outra otimização no pipeline.

Para levar

Você não precisa de framework complexo. GitHub Actions e Claude Code com um prompt bem estruturado já são o bastante para construir um pipeline autônomo completo. A orquestração é shell e GraphQL. A inteligência vem do modelo, não do framework.

Quando a plataforma que você estava usando muda as regras de uma noite para outra, ter sua infraestrutura de agente nos trilhos do próprio GitHub significa pisar em chão firme.