O Ralph Loop: Como Executo Agentes de IA Autônomos Durante a Noite
Construí um sistema de agentes autônomos que usa stop hooks para interceptar tentativas de encerramento, memória em sistema de arquivos para persistir estado entre janelas de contexto e orçamentos de spawn para prevenir recursão descontrolada. O sistema entregou minha infraestrutura de deliberação de 9 PRDs (3.455 linhas de Python, 141 testes) ao longo de múltiplas sessões noturnas.1
TL;DR
A arquitetura Ralph possibilita desenvolvimento autônomo de IA de longa duração resolvendo três problemas simultaneamente: esgotamento da janela de contexto (resolvido por contexto limpo a cada iteração), persistência de estado (resolvida pelo sistema de arquivos como memória) e continuidade de tarefas (resolvida por loops de stop-hook que impedem o agente de encerrar antes da conclusão). Implementei esse padrão no meu sistema de hooks do Claude Code e o usei para construir minha infraestrutura de deliberação multi-agente. O sistema funciona, mas me ensinou lições duras sobre orçamentos de spawn, qualidade de critérios e poluição do sistema de arquivos.
O problema da janela de contexto
Toda conversa com IA opera dentro de uma janela de contexto: um buffer de tamanho fixo que contém o histórico da conversa, prompts de sistema, saídas de ferramentas e memória de trabalho. A janela de contexto do Claude comporta aproximadamente 200.000 tokens. Uma sessão complexa de desenvolvimento pode esgotar isso em 30 a 60 minutos de trabalho intensivo.2
Medi isso diretamente durante a construção do sistema de deliberação. Sessões que começavam com edições multi-arquivo precisas em 8 módulos Python degradavam para visão de túnel em arquivo único por volta da marca de 90 minutos. O agente parava de referenciar arquitetura que havia lido anteriormente porque esse contexto tinha sido comprimido.3
A degradação segue uma curva previsível:
Iteration 1: [200K tokens] → writes code, creates files
Iteration 2: [200K tokens] → reads files from disk, continues
Iteration 3: [200K tokens] → reads updated files, continues
...
Iteration N: [200K tokens] → reads final state, verifies criteria
Compare com uma única sessão longa:
Minute 0: [200K tokens available] → productive
Minute 30: [150K tokens available] → somewhat productive
Minute 60: [100K tokens available] → degraded
Minute 90: [50K tokens available] → significantly degraded
Minute 120: [compressed, lossy] → errors accumulate
O agente com contexto limpo por iteração supera o agente contínuo porque cada iteração aloca recursos cognitivos completos ao estado atual em vez de carregar o peso do raciocínio anterior.
Minha implementação
O Stop Hook
Meu sistema de recursion-guard intercepta tentativas de parada do agente e verifica critérios de conclusão:
#!/bin/bash
# From recursion-guard.sh - simplified
CONFIG_FILE="${HOME}/.claude/configs/recursion-limits.json"
STATE_FILE="${HOME}/.claude/state/recursion-depth.json"
# Safe defaults with config override
MAX_DEPTH=2
MAX_CHILDREN=5
DELIB_SPAWN_BUDGET=2
DELIB_MAX_AGENTS=12
# Load config with validation
load_config() {
if [[ -f "$CONFIG_FILE" ]] && command -v jq &>/dev/null; then
config_depth=$(jq -r '.max_depth // 2' "$CONFIG_FILE")
if [[ "$config_depth" =~ ^[0-9]+$ ]] && [[ "$config_depth" -gt 0 ]]; then
MAX_DEPTH="$config_depth"
fi
fi
}
O hook lê um arquivo de critérios que define condições de sucesso. As condições devem ser verificáveis por máquina: resultado de testes (passou/falhou), saída de linter, códigos de status HTTP, verificações de existência de arquivos.4
Sistema de arquivos como memória persistente
O insight fundamental: arquivos persistem entre janelas de contexto. Meu diretório .claude/ funciona como a memória persistente do agente:
| Diretório | Conteúdo | Papel no Ralph Loop |
|---|---|---|
state/ |
recursion-depth.json, agent-lineage.json |
Rastreia contagem de iterações, relações pai-filho |
configs/ |
14 arquivos JSON | Codificam limites, orçamentos, regras (não hardcoded) |
handoffs/ |
49 documentos de contexto | Preservam decisões arquiteturais entre sessões |
hooks/ |
95 handlers de ciclo de vida | Aplicam portões de qualidade entre iterações |
Cada nova iteração lê o estado atual do disco e continua de onde a iteração anterior parou. O hook de início de sessão inicializa um estado limpo:
# From session-start.sh - recursion state initialization
RECURSION_STATE_FILE="$RECURSION_STATE_DIR/recursion-depth.json"
# Initialize with safe defaults
{
"depth": 0,
"agent_id": "root",
"parent_id": null,
"initialized_by": "session-start"
}
Se o estado for corrompido (o que aconteceu duas vezes durante o desenvolvimento), o padrão de recuperação recria a partir de valores padrão seguros em vez de travar:
if ! jq -e '.depth' "$RECURSION_STATE_FILE" &>/dev/null; then
# Corrupted state file, recreate with safe defaults
echo "- Recursion state recovered (was corrupted)"
fi
Formato de especificação de tarefas
Tarefas Ralph eficazes incluem três elementos: objetivo, critérios de conclusão e ponteiros de contexto:
OBJECTIVE: Implement multi-agent deliberation with consensus validation.
COMPLETION CRITERIA:
- All tests in tests/test_deliberation_lib.py pass (81 tests)
- post-deliberation.sh validates consensus above 70% threshold
- recursion-guard.sh enforces spawn budget (max 12 agents)
- deliberation-pride-check.sh passes 5 quality checks
- No Python type errors (mypy clean)
CONTEXT:
- Follow patterns in lib/deliberation/state_machine.py
- Consensus thresholds in configs/deliberation-config.json
- Spawn budget model: agents inherit budget, not increment depth
O que construí com esse padrão
A infraestrutura de deliberação (9 PRDs)
O maior projeto Ralph loop: 9 Product Requirement Documents implementados ao longo de múltiplas sessões.
| PRD | Entrega | Testes |
|---|---|---|
| PRDs 1-4 | Hooks, config, extensões do recursion-guard | Commitado como 3cad08c |
| PRD-5 | 48 testes de integração bash (7 suítes) | Commitado como 10df724 |
| PRDs 7-8 | Wiring de hooks + 81 testes unitários Python | Commitado como fbf1a0d |
| PRD-9 | 12 testes E2E de simulação de pipeline | Commitado como 32bd711 |
Produção total: 3.455 linhas de Python em 8 módulos, 141 testes, 4 commits. Cada sessão retomava do estado no sistema de arquivos da sessão anterior. O contexto limpo significava que cada PRD recebia a atenção total do agente sem carregar o histórico de conversas de PRDs anteriores.5
Sistema de qualidade do blog (12 módulos)
O linter do blog começou como um script de 3 módulos e cresceu para 12 módulos através de Ralph loops iterativos. Cada iteração adicionava um módulo, executava a suíte completa de testes e verificava zero regressões. Os critérios de conclusão evoluíram:
- Iteração 1: “Todos os 77 testes passam”
- Iteração 5: “Todos os 77 testes passam E o linter reporta 0 erros em todos os 33 posts”
- Iteração 8: “Todos os testes passam E 0 erros E 0 warnings E score de profundidade ≥2 em todos os posts”
As falhas e lições
Falha 1: O desastre do orçamento de spawn
No início da construção da deliberação, executei uma sessão sem limites de orçamento de spawn. O agente criou 3 subagentes de exploração. Cada subagente criou seus próprios subagentes. Em minutos, o hook recursion-guard estava interceptando dezenas de tentativas de spawn. A sessão consumiu tokens de API a 10x a taxa normal antes que eu a encerrasse manualmente.6
A correção: Adicionei um modelo de orçamento de spawn ao recursion-limits.json. Agentes herdam um orçamento do seu pai em vez de incrementar profundidade. Um agente raiz com budget=12 pode criar até 12 agentes no total em todos os níveis de recursão. Este foi um insight arquitetural fundamental: herança de orçamento previne crescimento exponencial enquanto ainda permite cadeias profundas de agentes.
Falha 2: Critérios que passam trivialmente
Uma tarefa inicial pedia ao agente para “escrever testes que passem.” O agente escreveu testes mínimos: assert True, assert 1 == 1. Tecnicamente, os critérios foram atendidos. A saída era inútil.
A correção: Critérios devem especificar tanto quantidade quanto qualidade:
| Qualidade do critério | Exemplo | Resultado |
|---|---|---|
| Vago | “Testes passam” | Agente escreve testes triviais |
| Mensurável mas incompleto | “Testes passam E cobertura >80%” | Agente escreve testes que cobrem linhas mas não testam nada significativo |
| Abrangente | “Todos os testes passam E cobertura >80% E sem erros de tipo E linter limpo E cada classe de teste testa um módulo distinto” | Saída com qualidade de produção |
Falha 3: Poluição do sistema de arquivos
Iterações que exploraram caminhos sem saída deixavam artefatos: funcionalidades parcialmente implementadas, arquivos obsoletos, configurações conflitantes. A iteração 5 poderia construir sobre uma abordagem inacabada da iteração 3 que foi abandonada na iteração 4.
A correção: Adicionei uma etapa de limpeza aos critérios do stop hook: “Nenhum arquivo deve existir que não seja referenciado por imports ou testes.” Isso força o agente a limpar caminhos abandonados antes que a iteração possa ser concluída.
Falha 4: O incidente do ((VAR++))
Durante testes de integração bash, o hook recursion-guard travou silenciosamente na primeira iteração. O bug: ((VAR++)) retorna código de saída 1 quando VAR é 0 (porque 0++ avalia para 0, que o bash trata como falso). Com set -e habilitado, isso matava o script.
A correção foi VAR=$((VAR + 1)) em vez de ((VAR++)). Essa pegadinha do bash, documentada no meu MEMORY.md, preveniu o mesmo bug em 6 scripts de hook subsequentes.7
Quando o Ralph funciona e quando não funciona
Boa adequação
- Implementação greenfield com especificações claras (nova API, novo módulo, nova suíte de testes)
- Verificação automatizada existente (testes, verificadores de tipo, linters, compilação)
- Escopo delimitado que pode ser descrito em um único arquivo de tarefa
Má adequação
- Qualidade subjetiva (“deixe a UI bonita”) não tem critérios verificáveis por máquina
- Trabalho exploratório onde a direção depende de descobertas intermediárias
- Refatoração em larga escala que requer entendimento de relações globais de código em dezenas de arquivos
Principais conclusões
Para desenvolvedores construindo sistemas de agentes autônomos: - Invista em critérios de conclusão verificáveis por máquina antes de iniciar loops autônomos; meu sistema de deliberação teve sucesso porque cada PRD tinha critérios de sucesso testáveis (141 testes no total) - Implemente orçamentos de spawn desde o primeiro dia; o modelo de herança de orçamento (não incremento de profundidade) previne spawning exponencial de agentes enquanto permite cadeias profundas - Adicione limpeza do sistema de arquivos aos critérios de conclusão; artefatos de caminhos abandonados de iterações anteriores vão poluir iterações subsequentes
Para equipes de engenharia avaliando desenvolvimento autônomo com IA: - A arquitetura Ralph troca tempo de implementação humana por tempo de especificação humana; o ROI depende de se o seu gargalo é capacidade de implementação ou clareza de especificação - Audite a saída autônoma com o mesmo rigor aplicado a código de prestadores de serviço externos; meus 141 testes existem porque aprendi que atender critérios de conclusão não garante prontidão para produção
Referências
-
Author’s implementation of the Ralph Loop pattern using Claude Code hooks. Deliberation infrastructure: 3,455 lines of Python, 8 modules, 141 tests across 4 commits (2025-2026). ↩
-
Anthropic, “Claude Models,” 2025. ↩
-
Liu, Nelson F. et al., “Lost in the Middle: How Language Models Use Long Contexts,” TACL, 2024. ↩
-
Anthropic, “Claude Code Documentation,” 2025. Hook lifecycle events. ↩
-
Author’s git log. Commits
3cad08c,10df724,fbf1a0d,32bd711spanning the full deliberation infrastructure build. ↩ -
Author’s experience with unbudgeted agent spawning. Documented in
~/.claude/projects/*/memory/MEMORY.mderror entries. ↩ -
Author’s bash debugging.
((VAR++))exit code behavior withset -edocumented as a cross-session learning in MEMORY.md. ↩