Projeto + Revisão de Loop
Premissa. Um LLM é um sistema feed-forward: prompt entra → tokens saem, sem um "direcionamento intrínseco para o objetivo" entre as iterações. Para fazê-lo comportar-se como um sistema orientado a objetivos, você envolve um loop de feedback. Esta skill ajuda você a escrever esse loop corretamente e revisá-lo para que ele não fuja do controle.
Quando usar / não usar
Use quando:
- Você quer entregar uma tarefa repetitiva a um agente que executa repetidamente (escreve→testa, testa→corrige, corrige→verifica…).
- Você já tem um loop e teme que ele gire, trapaceie ou execute uma resposta errada até o fim.
Não use para:
- Uma tarefa única → apenas execute-a; não envolva em um loop.
- Um timer / polling simples → use
/loop; nenhum projeto é necessário. - Como conectar a arquitetura do loop (pipelines → DAGs, recuperação de longa execução) → essa é a camada de mecanismo; veja
autonomous-loops/continuous-agent-loop. Esta skill cobre apenas "o objetivo está certo? e ele vai fugir?" — ela não reexplica o mecanismo.
Premissa da linha vermelha: dois níveis de feedback
| Nível | Quem controla | O que faz |
|---|---|---|
| Execução (baixo) | máquina / agente | Mede "quão longe do objetivo literal" e reduz a zero. A máquina é forte aqui. |
| Julgamento (alto) | humano | Decide "esse objetivo em si está certo? deve mudar? deve parar?" A máquina não pode sair do próprio loop para questionar o objetivo. |
Um termostato pode realimentar "quão longe de 26°C", mas quando você está com febre e quer 28°C, ele não consegue julgar se 26 é a meta certa — ele apenas reduz para 26. "O que ajustar hoje" é sempre a decisão do humano. Entregar o julgamento / aprovação / última chave para a máquina = remover o feedback de alto nível = ela corre, rápida e forte, em direção a um objetivo que ninguém questionou → saída errada.
Ação 1 — Escrever um loop (5 passos)
Passo 0 · Subtraia primeiro: você deveria mesmo construí-lo? (portão de 4 condições, qualquer falha = veto)
① a tarefa se repete semanalmente ou mais ② a verificação pode ser automatizada ③ o orçamento de tokens suporta ④ o agente tem ferramentas que realmente executam e veem o resultado
Qualquer falha → não construa um loop; faça manualmente ou de outra forma.
O que impede a maioria das pessoas não é "consigo escrever um loop", é "meu repositório merece um?" Um repositório que merece um loop tem uma linha de base de conciliação (amostra dourada / total upstream) + testes + um guardião de lint. Um repositório que não merece um loop só terá seus erros amplificados por ele.
Passo 1 · Defina uma meta decidível por máquina (a parte difícil — o loop vive ou morre aqui)
O loop inteiro depende do comparador "já terminou?" O comparador só funciona se sua condição de saída puder ser julgada sim/não por uma máquina.
- Ruim: Vaga ("tornar bom", "escrever mais afiado") → o comparador não consegue julgar → ou nunca passa (fica tentando) ou chuta (passa/bloqueia aleatoriamente).
- Bom: Decidível ("todos os 96 testes unitários verdes E uma lista de alterações é produzida", "campos do módulo-02 preenchidos, pytest passa, lógica de negócio intacta") → uma verificação resolve; o loop converge limpo.
Estrutura de objetivo em cinco pontos:
- Critério de conclusão é verificável por máquina.
- Condições de contorno definidas junto com o critério de conclusão ("o que NÃO deve fazer") — antídoto para Goodhart; limites ausentes = licença para trapacear.
- Possui um plano de fallback para falha — limite de tentativas N + escalar para humano quando excedido.
- O objetivo é em camadas.
- Prefira conciliação em vez de asserção para o critério de conclusão — ancore a um fato externo (amostra dourada / total upstream / conciliação financeira / números do back-office da plataforma) antes de suas próprias asserções. "Todos os testes passam" pode ser manipulado (afrouxar asserts, falsificar mocks, engolir exceções); "diferença vs. a referência < 0,01" não pode.
Auto-verificação: leia o objetivo para alguém que não conhece o domínio — essa pessoa consegue executar um comando e dizer se está pronto? Se não, não é decidível o suficiente. Volte.
Passo 2 · Escolha o tipo de loop
| Sua tarefa | Tipo de loop (cibernético) | Como para |
|---|---|---|
| Tem um teste "pronto" claro (escrever até concluir / processar um lote de imagens) | servo (loop fechado estilo /goal) | para ao atingir o objetivo |
| Sem ponto final, precisa manter um estado (alerta de inventário / verificação de saúde programada) | regulador (termostato estilo /loop) | nunca para; atua apenas na mudança (banda morta suprime ruído) |
| Amostragem periódica, para em uma condição (observar um PR até o CI ficar verde) | regulador com saída | para quando a condição de saída é verdadeira |
| Deve "garantir que algo aconteça no prazo" | envolva o acima com /schedule | cron o dispara |
Regra prática: teste "pronto" claro → servo; precisa manter, sem ponto final → regulador; precisa "acontecer no prazo" → envolva um regulador em schedule.
Passo 3 · Escolha um esqueleto
Tipo manutenção (cuidar de algo que existe) → despacho orientado por documento. O loop não é "executar uma verificação fixa em um timer", é "ler um documento em um timer, e despachar apenas quando o documento mudou". O documento é a fila de tarefas + máquina de estados + interface humana. Três disciplinas: ① a coluna de problema é apenas escrita por humano, a coluna de resultado é apenas escrita pelo loop, o estado avança em uma direção e nunca retrocede; ② o código de saída é final (se o script disser exit 1, o script vence); ③ o estado avança apenas até "aguardando verificação" — a célula "concluído" é virada apenas por um humano. O loop é o trabalhador, não o oficial de aceitação.
Tipo greenfield (construir do zero) → planejar / construir / julgar, três papéis.
| Papel | Faz | Chave |
|---|---|---|
| Planejar | decompor o objetivo em uma especificação + condições de aceitação decidíveis | aceitação deve ser julgável por script |
| Construir | escrever de acordo com a especificação | não deve alterar as condições de aceitação |
| Julgar | executar a aceitação de forma independente; passar → para, falhar → retornar com o motivo da falha para Construir | independente + determinístico |
Três regras de ferro (todas apostam no juiz): ① o juiz deve ser independente — não o mesmo agente que Construir (corrigir a própria lição de casa sempre infla); ② regras determinísticas — pytest / diff de conciliação / verificação de tipo / diff, nunca "parece certo"; ③ Construir não pode editar as condições de aceitação para passar. Três tentativas falhas → escalar para um humano.
Passo 4 · Adicione amortecimento (contra oscilação / fuga)
Limite de tentativas, parada brusca, humano vira a última chave = amortecimento. Feedback negativo sem amortecimento oscila (o loop Ralph-Wiggum: girando no lugar, queimando tokens).
Passo 5 · Implemente em três estágios (não vá totalmente automático no primeiro dia)
① Execute uma vez manualmente (força você a declarar exatamente "como o juiz decide") → ② endureça em uma skill / subagentes do Claude Code (um Claude principal faz o loop, despachando planejar/construir/julgar) → ③ coloque no cron para automação total.
Ação 2 — Revisar um loop (checklist = cinco modos de falha)
Execute o loop em cada linha. Acertar qualquer um = este loop vai falhar; mande de volta. Esses cinco são experiência negativa (armadilhas) — valem mais do que regras positivas.
| # | Modo de falha (como quebra) | Pergunta de revisão (acerto = vermelho) | Anticorpo |
|---|---|---|---|
| 1 | Objetivo é um lugar-comum correto → gira, queima dinheiro | A condição de saída pode ser julgada sim/não por máquina? Ou é "gerencie bem / torne bom"? | Substitua por uma condição de resultado decidível (Ação 1·Passo 1) |
| 2 | "Verificação" escrita como "verificar se parece certo" → agente diz confiantemente que está bom e para | O juiz é o próprio réu? A verificação depende de "parece certo" ou de regras determinísticas? | Reconcilie + regras de código de saída + juiz independente |
| 3 | (pior) Apenas verifica "todos os testes passam" → agente deleta os testes | Existe um limite ("o que NÃO deve fazer")? Ou apenas um critério de conclusão? | Critério de conclusão + limite juntos (o anticorpo Goodhart) |
| 4 | Conta com o agente perguntando no meio da execução → ele não pergunta; executa a resposta errada até o fim | Existe algum ponto "esclarecer apenas em tempo de execução"? | Esclareça tudo antes; resolva uma vez antes do lançamento |
| 5 | CLAUDE.md inchado + memória desatualizada → quanto mais rápido o loop, mais ele erra | Os documentos/memória dos quais depende estão atualizados? Quem os mantém? | Memória em camadas + lint periódico |
Mais três linhas vermelhas (violar qualquer uma = não permitido ir para automático):
- Mantenha o julgamento com o humano. A aceitação / célula "concluído" é virada por um humano; o loop não é o oficial de aceitação.
- A responsabilidade não se transfere. Qualquer coisa cuja falha você não pode arcar (fundir o PR errado / publicar a coisa errada / alocar dinheiro errado) → não entregue a autoridade automaticamente.
- Aviso contra-intuitivo. Quanto mais "auto-melhorável / reescreve suas próprias regras" for um loop, mais rigorosa precisa ser a revisão humana (para ver no que ele transformou as regras) — não menos. A máquina é rápida demais para interceptar depois do fato, então o julgamento humano deve estar antes da ação (um portão rígido), não como um patch posterior.
Exemplo prático — revisando um loop "guardião noturno"
Você quer um loop que execute todas as noites e corrija quaisquer testes que estejam falhando.
- Objetivo ingênuo: "fazer todos os testes passarem." → A auto-verificação do Passo 1 falha: esta é a isca para o modo de falha #3.
- Objetivo decidível (corrigido): "todos os testes verdes E nenhum arquivo de teste deletado ou enfraquecido E cobertura não reduzida E uma lista de alterações produzida." Limite agora definido junto com o critério de conclusão.
- Tipo: servo com limite de tentativas de 3 (Passo 2 + Passo 4).
- Esqueleto: planejar/construir/julgar — o juiz é a execução do CI de forma independente, nunca o agente corretor (Passo 3).
Agora execute a checklist de revisão, e ela pega o que a versão ingênua teria perdido:
- #3 acertado → o ingênuo "todos os testes passam" permite que o agente delete um teste falho para "vencer." Corrigido pelo limite "nenhum arquivo de teste deletado/enfraquecido."
- #2 acertado → se o agente corretor também julgasse sua própria correção, ele se aprovaria. Corrigido por "juiz = CI independente, determinístico."
- #4 acertado → se uma correção é ambígua, o agente não vai parar para perguntar às 2 da manhã; ele vai commit um palpite. Corrigido por esclarecimento prévio: correções ambíguas são deixadas para o humano, não adivinhadas.
- Linha vermelha → o loop abre um PR, mas não faz auto-merge; o humano vira a última chave (a responsabilidade não se transfere).
O loop ingênuo e o loop revisado diferem por quatro linhas de restrição — e essa é a diferença entre "acordar com uma suíte de testes deletada" e "acordar com um PR limpo."
Linha de fechamento
A parte difícil de escrever um loop não é "consigo escrever um loop", é definir um objetivo que uma máquina possa reconciliar — decidível, delimitado, baseado em conciliação. O controlador deve ser determinístico e externo; mantenha o julgamento e o padrão com o humano; o sistema tende à entropia, portanto mantenha-o. Um loop só recompensa alguém que já pensou sobre ele. Conte com ele para pensar por você, e ele pensará errado, com você, em escala.
Linhagem: feedback de dois níveis de Wiener (The Human Use of Human Beings, 1950) para a divisão julgamento/execução e linhas vermelhas; o padrão planejar/construir/julgar de Anatoli (Loops explained) e Addy (Loop Engineering). Camada de mecanismo (como conectar a arquitetura do loop): veja
autonomous-loops/continuous-agent-loop. Esta skill não reimplementa mecanismo; ela cobre apenas definição de objetivo e prevenção de fuga.