Um Ralph loop é três coisas: uma tarefa, um verificador e um orçamento. Esse é o padrão inteiro. Geoffrey Huntley nomeou assim em homenagem ao personagem dos Simpsons que continua avançando independentemente de algo estar funcionando, e a analogia se mantém. O risco não é que Claude pare cedo demais. O risco é que ele declare sucesso em um estado quebrado, queime seu orçamento de tokens ou ambos. Este artigo cobre como definir cada um dos três elementos com precisão, escolher a implementação correta para sua situação e parar o loop com segurança quando ele realmente terminou. O fluxo de trabalho de desenvolvimento agentic é uma preocupação separada; este artigo é restrito estritamente à iteração até que uma condição seja atendida.
Defina o Objetivo, o Verificador e o Orçamento
Antes de escrever um único comando, escreva três frases. Como se parece "feito"? Como você checará isso mecanicamente? E quantas iterações você está disposto a pagar?
O objetivo precisa ser verificável por máquina. "O código é bom" não é um objetivo. "Todos os testes em npm test passam e git status está limpo" é um objetivo. A diferença importa porque um verificador só pode avaliar o que consegue observar. Se sua condição de conclusão depender de um humano olhar para algo, você não tem um verificador; você tem uma etapa de revisão, e essas duas coisas não deveriam estar dentro do mesmo loop.
O verificador não é a própria opinião do Claude. Esta é a parte que a maioria das pessoas erra. Como um comentarista do Hacker News colocou, "se a IA acha que as coisas funcionam, ela dirá COMPLETE mesmo que você não achasse que está completo." DONE gerado pelo modelo é um sinal, não um verificador. Um verificador real é um processo externo: seu test runner, seu linter, um curl contra um endpoint ativo retornando o código de status esperado. Ele é executado após cada iteração e produz um resultado determinístico verdadeiro/falso. Construa isso primeiro.
O orçamento é sua válvula de segurança. Escolha um número que você realmente esteja confortável em queimar. A implementação da comunidade frankbria/ralph-claude-code requer tanto indicadores de conclusão heurística (dois ou mais) quanto um EXIT_SIGNAL: true explícito no bloco RALPH_STATUS do modelo antes de sair. Esse design de dupla condição existe precisamente porque sinais únicos são pouco confiáveis. Seu --max-iterations deve ser conservador na primeira execução. Você pode aumentá-lo depois de ver até onde o loop realmente chega.
Para ser claro, sua configuração antes de executar qualquer coisa deve responder:
- Qual comando shell retorna código de saída 0 apenas quando a tarefa está genuinamente completa?
- Qual é o número máximo de iterações que vou permitir?
- Qual arquivo ou log registrará os resultados das iterações para que eu possa inspecioná-los depois?
Escolha a Implementação do Loop
Claude Code 2.1 inclui três primitivos integrados que cobrem a maioria dos casos de uso de Ralph sem nenhum plugin. O guia Awesome Claude documenta todos os três:

/goal, continua trabalhando entre turnos até que uma condição seja verificada. Usa um modelo menor separado (Haiku por padrão, conforme descrito por Ranjan Kumar) para ler a transcrição da sessão após cada turno e responder uma pergunta: o objetivo foi alcançado? Se não, Claude faz outro turno. Se sim, o loop é encerrado./loop, executa novamente um prompt em intervalo fixo ou autoajustável. Esc para parar. Útil para tarefas de sondagem./batch, distribui uma grande mudança entre 5 a 30 agentes worktree paralelos. Uma coisa bem diferente; não é o que você quer para uma tarefa simples e delimitada.
Depois tem o caminho do plugin, e o bash loop raw. Aqui é onde eles diferem de uma forma que realmente importa para o seu trabalho.
O plugin (ralph-wiggum@claude-plugins-official ou o fork da comunidade) roda dentro de uma única sessão usando um stop hook. Quando Claude tenta sair, o hook intercepta e passa o prompt de volta. O contexto se acumula ao longo das iterações. É conveniente, mas significa que na iteração 15 a janela de contexto está carregando o resíduo de cada tentativa anterior, o que pode degradar a qualidade de cada novo turno.
A abordagem bash raw, canalizando PROMPT.md para claude -p dentro de um while loop, inicia um processo completamente novo toda vez. Como Steve Kinney observa, "Cada invocação de claude -p recebe uma janela de contexto completamente limpa. Este é o ponto inteiro da técnica, evitando degradação de contexto ao deliberadamente começar do zero." A compensação: você perde a memória implícita do que foi tentado, então seu PROMPT.md e arquivos de estado de tarefa têm que carregar todo o contexto explicitamente entre iterações.
Qual você deve escolher? Se sua tarefa é curta (menos de 10 iterações esperadas) e o contexto permanece gerenciável, /goal com limite de turnos é a opção de menor fricção. Se a tarefa é longa ou a qualidade do contexto é uma preocupação, o bash loop de contexto fresco é mais confiável. O post sobre testes e ferramentas de codificação IA cobre como estruturar sua suíte de testes para que o verificador possa realmente rodar limpo de qualquer forma.
Execute Uma Tarefa com Iterações Delimitadas
Aqui está uma configuração ilustrativa para uma tarefa delimitada usando o primitivo /goal:
/goal Todos os testes em npm test passam e git status está limpo, ou parar após 20 turnos
Essa única linha dá ao Claude uma condição de saída verificável e um limite máximo. O avaliador Haiku lê a transcrição após cada turno e verifica ambas as condições. A cláusula or stop after 20 turns é seu guardrail de orçamento.
Para uma abordagem bash-loop, a estrutura do time Geocodio é um bom modelo a seguir. Eles usam um arquivo JSON (um simples prd.json) onde cada tarefa tem um campo "passes": false. Cada iteração encontra a história de maior prioridade com passes: false, a implementa, roda o verificador e muda a flag para true no sucesso. O while loop sai quando toda história tem passes: true. O relatório deles vale a pena ler só pela estrutura de critérios de aceitação.
O fluxo numerado para um bash loop de contexto fresco se parece com isto:
- Escreva
PROMPT.mdcom a tarefa atual, o comando do verificador e o caminho do log de passa/falha. - Inicie o
whileloop, canalizandoPROMPT.mdparaclaude -p. - Claude lê instruções, faz uma unidade de trabalho, faz commit para git.
- O verificador roda. Código de saída 0 significa passar; qualquer outra coisa significa falhar.
- Registre o resultado (número da iteração, passa/falha, custo de token se disponível) em um arquivo.
- Se todas as tarefas passarem, escreva o sinal de parada e quebre. Caso contrário, volte ao passo 2.
Mantenha cada iteração como uma unidade de trabalho. Tentar fazer muito por loop é como você termina em um estado meio-terminado que o verificador não consegue avaliar limpo.
Detecte Falta de Progresso e Conclusão Falsa
Dois modos de falha são muito mais comuns que loops infinitos: o loop não faz progresso ao longo das iterações, e o modelo declara sucesso em um estado quebrado.
A detecção de falta de progresso requer comparar algo concreto entre a iteração N e a iteração N+1. Um git diff é o sinal mais simples. Se git diff HEAD~1 está vazio após uma iteração que não produziu um verificador aprovado, o loop está girando. Você deve sinalizar isso imediatamente em vez de desperdiçar três iterações a mais esperando que algo mude.
A conclusão falsa é mais complicada. O modelo vai produzir DONE, COMPLETE, ou EXIT_SIGNAL: true em circunstâncias onde seu verificador atual retornaria um código de saída diferente de zero. A verificação de dupla condição da implementação frankbria (dois ou mais indicadores heurísticos e o sinal explícito) é uma mitigação razoável. Mas a solução mais eficaz é: nunca deixe o loop sair baseado apenas na saída do modelo. O script verificador executa independentemente do que o modelo diz, e o loop continua se o verificador falhar, fim de história.
Cuidado com uma armadilha relacionada: o próprio verificador retornando um falso positivo. Se sua suite de testes tem testes instáveis que às vezes passam sem o bug subjacente ser corrigido, você vai obter uma conclusão falsa que o modelo nem mesmo causou. Essa é a próxima seção.
Lidar com Testes Instáveis e Verificadores com Falha
Testes instáveis são o inimigo de qualquer loop automatizado. Um teste que passa 80% das vezes eventualmente vai disparar uma saída do loop nos 20% em que não deveria. E como cada iteração custa tokens, uma saída falsa seguida por uma re-execução é cara.
A mitigação não é complicada, mas requer algum trabalho inicial:
- Execute seu comando verificador três vezes seguidas antes de confiar em um aprovação. Se falhar uma vez em três, trate como uma falha.
- Separe seus testes "o trabalho está feito" de seus testes "o ambiente funciona". Testes dependentes de rede, asserções sensíveis ao tempo, e qualquer coisa que exija estado externo não devem estar no verificador que controla a saída do loop.
- Registre cada execução do verificador com sua saída. Se o loop parar e algo parecer errado, você quer a saída completa do verificador da iteração final, não apenas o código de saída.
Se o próprio verificador falhar (travar, expirar timeout, ou retornar um código de erro inesperado que não seja uma falha de teste), trate como uma parada do loop, não uma continuação. Tentar iterar através de um verificador quebrado vai apenas produzir iterações que não podem ser avaliadas.
Os hooks Claude Code permitem anexar scripts em pontos específicos do ciclo de vida da sessão. O guia de hooks Claude Code cobre o mecanismo em detalhes. Para loops Ralph, o hook relevante é aquele que dispara quando Claude tenta sair: intercepte-o, execute seu verificador, e só permita a saída se o verificador passar. Se você está usando o caminho do plugin, isso já está conectado. Se você está no loop bash, a decisão de saída acontece em seu script shell em vez de um hook.
Registre Custo e Pare com Segurança
Você deve saber o que cada iteração custa antes do loop terminar. Você não precisa de números exatos em tempo real, mas precisa de um arquivo de log que registre número da iteração, resultado do verificador, e informação de token suficiente para estimar gastos depois.
O post da comunidade Alibaba Cloud sobre loops Ralph identifica três condições de parada que valem a pena construir em qualquer implementação:
- Sucesso: o verificador retorna 0 e todas as tarefas têm
passes: true. - Parada sem progresso: duas ou mais iterações consecutivas sem git diff e sem melhora no verificador.
- Esgotamento de orçamento: o contador de iteração atinge
--max-iterationsindependentemente do estado do verificador.
O esgotamento de orçamento não é um modo de falha, é uma parada projetada. Quando acionada, o loop deve escrever um resumo do que passou, do que não passou, e o que a última iteração tentou. Isso fornece um handoff limpo para uma revisão manual ou um novo loop com um prompt revisado.
Uma coisa a construir explicitamente: uma distinção entre "loop parou porque teve sucesso" e "loop parou porque atingiu o limite". Se você volta a um terminal e vê "loop parou na iteração 20," você precisa saber qual dos dois foi. Uma única flag no arquivo de log, STOP_REASON: BUDGET_EXHAUSTED versus STOP_REASON: SUCCESS, é tudo o que é necessário.
Se você está fazendo esse tipo de trabalho em escala ou quer uma configuração gerenciada em vez de scripts feitos à mão, o trabalho de engenharia agnóstica cobre como é uma configuração de loop de grau de produção com observabilidade adequada.
FAQ
É `/goal` realmente um loop Ralph, ou é algo diferente?
Eles compartilham o mesmo princípio (iterar até uma condição ser válida) mas diferem em arquitetura. /goal executa dentro de uma sessão única persistente; um loop bash Ralph clássico spawna um novo processo a cada iteração. Como Ranjan Kumar documenta, /goal usa um modelo Haiku separado para avaliar a transcrição depois de cada turno. O loop bash não avalia nada, seu script shell faz a verificação. Ambos são válidos; escolha baseado em se a acumulação de contexto é um problema para sua tarefa.
Posso usar a própria saída `DONE` do modelo como o verificador?
Não. A saída do modelo é um sinal que você pode usar como uma entrada, mas não pode ser a única condição de saída. Um modelo produzirá marcadores de conclusão quando acreditar que a tarefa está concluída, o que não é a mesma coisa que quando ela realmente está. Combine qualquer sinal gerado pelo modelo com um comando externo que verifique o estado real do sistema.
O que acontece com o loop se Claude Code compactar o contexto durante a execução?
Em um loop de sessão persistente (plugin ou /goal), a compactação acontece automaticamente quando o contexto fica longo, e a qualidade dessa compactação é inconsistente. Um comentarista do Hacker News observou que "as compactações do Claude Code são de tão baixa qualidade que é basicamente o mesmo que limpar o histórico a cada alguns turnos." O loop bash de contexto fresco contorna isso inteiramente porque cada iteração começa limpa. Se você estiver no caminho do plugin e executando jobs longos, fique atento à qualidade de saída degradada após pontos de compactação.
Quão pequena deve ser a unidade de trabalho de cada iteração?
Tão pequena quanto você conseguir fazer enquanto ainda for significativa. Uma tarefa por iteração é o modelo mental correto. A abordagem Geocodio (uma história de prd.json por loop) e a descrição do comentarista do Hacker News ("ele pega a tarefa mais importante, conclui e encerra seu loop") apontam para a mesma resposta: pequenos chunks verificáveis são muito mais confiáveis do que iterações grandes e ambiciosas.
Eu realmente preciso de um plugin?
Para a maioria das tarefas, não. O primitivo /goal integrado com um limite de turnos cobre o caso comum. Recorra ao plugin (ralph-wiggum@claude-plugins-official ou frankbria/ralph-claude-code) quando você especificamente quer o comportamento de interceptação stop-hook ou a lógica de dupla condição de saída que essas implementações fornecem. Não instale um plugin só porque viu em um tutorial.
A ressalva mais afiada em todo esse padrão: um sinal de conclusão gerado pelo modelo não é um verificador. Construa a verificação externa primeiro, antes de tudo mais, e deixe que toda outra decisão decorra disso.
