El Bucle Ralph: Cómo ejecuto agentes de IA autónomos durante la noche
Construí un sistema de agentes autónomos que utiliza stop hooks para interceptar intentos de finalización, memoria en el sistema de archivos para persistir estado entre ventanas de contexto, y presupuestos de generación para prevenir recursión descontrolada. El sistema implementó mi infraestructura de deliberación de 9 PRD (3.455 líneas de Python, 141 pruebas) a lo largo de múltiples sesiones nocturnas.1
TL;DR
La arquitectura Ralph permite el desarrollo autónomo de IA de larga duración al resolver tres problemas simultáneamente: agotamiento de la ventana de contexto (resuelto mediante contexto fresco por iteración), persistencia de estado (resuelto mediante el sistema de archivos como memoria) y continuidad de tareas (resuelto mediante bucles de stop-hook que evitan que el agente termine antes de completarse). Implementé este patrón en mi sistema de hooks de Claude Code y lo utilicé para construir mi infraestructura de deliberación multiagente. El sistema funciona, pero me enseñó lecciones difíciles sobre presupuestos de generación, calidad de criterios y contaminación del sistema de archivos.
El problema de la ventana de contexto
Cada conversación de IA opera dentro de una ventana de contexto: un búfer de tamaño fijo que contiene el historial de conversación, los prompts del sistema, las salidas de herramientas y la memoria de trabajo. La ventana de contexto de Claude contiene aproximadamente 200.000 tokens. Una sesión de desarrollo compleja puede agotar esto en 30-60 minutos de trabajo intensivo.2
Medí esto directamente durante la construcción del sistema de deliberación. Las sesiones que comenzaban con ediciones precisas de múltiples archivos en 8 módulos de Python se degradaban a visión de túnel de un solo archivo alrededor de los 90 minutos. El agente dejaba de hacer referencia a la arquitectura que había leído anteriormente porque ese contexto había sido comprimido.3
La degradación sigue una curva predecible:
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 con una sesión larga continua:
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
El agente con contexto fresco por iteración supera al agente continuo porque cada iteración asigna recursos cognitivos completos al estado actual en lugar de cargar con el peso del razonamiento previo.
Mi implementación
El Stop Hook
Mi sistema de guardia de recursión intercepta los intentos de detención del agente y verifica los criterios de finalización:
#!/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
}
El hook lee un archivo de criterios que define las condiciones de éxito. Las condiciones deben ser verificables por máquina: resultados de pruebas (aprobado/fallido), salida del linter, códigos de estado HTTP, verificaciones de existencia de archivos.4
El sistema de archivos como memoria persistente
La idea clave: los archivos persisten entre ventanas de contexto. Mi directorio .claude/ sirve como la memoria persistente del agente:
| Directorio | Contenido | Rol en el bucle Ralph |
|---|---|---|
state/ |
recursion-depth.json, agent-lineage.json |
Rastrea el conteo de iteraciones, relaciones padre-hijo |
configs/ |
14 archivos JSON | Codifican umbrales, presupuestos, reglas (no hardcoded) |
handoffs/ |
49 documentos de contexto | Preservan decisiones arquitectónicas entre sesiones |
hooks/ |
95 manejadores de ciclo de vida | Aplican puertas de calidad entre iteraciones |
Cada nueva iteración lee el estado actual del disco y continúa desde donde la iteración anterior se detuvo. El hook de inicio de sesión inicializa un estado limpio:
# 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"
}
Si el estado se corrompe (lo cual sucedió dos veces durante el desarrollo), el patrón de recuperación recrea desde valores predeterminados seguros en lugar de fallar:
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 especificación de tareas
Las tareas efectivas del bucle Ralph incluyen tres elementos: objetivo, criterios de finalización y punteros 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
Lo que construí con este patrón
La infraestructura de deliberación (9 PRD)
El proyecto más grande del bucle Ralph: 9 Documentos de Requisitos de Producto implementados a lo largo de múltiples sesiones.
| PRD | Entregable | Pruebas |
|---|---|---|
| PRDs 1-4 | Hooks, configuración, extensiones de recursion-guard | Commit 3cad08c |
| PRD-5 | 48 pruebas de integración en bash (7 suites) | Commit 10df724 |
| PRDs 7-8 | Conexión de hooks + 81 pruebas unitarias en Python | Commit fbf1a0d |
| PRD-9 | 12 pruebas E2E de simulación de pipeline | Commit 32bd711 |
Producción total: 3.455 líneas de Python en 8 módulos, 141 pruebas, 4 commits. Cada sesión retomó desde el estado del sistema de archivos de la sesión anterior. El contexto fresco significó que cada PRD recibió la atención completa del agente sin cargar el historial de conversación de PRDs anteriores.5
Sistema de calidad del blog (12 módulos)
El linter del blog comenzó como un script de 3 módulos y creció a 12 módulos a través de bucles Ralph iterativos. Cada iteración agregaba un módulo, ejecutaba la suite completa de pruebas y verificaba cero regresiones. Los criterios de finalización evolucionaron:
- Iteración 1: “Las 77 pruebas pasan”
- Iteración 5: “Las 77 pruebas pasan Y el linter reporta 0 errores en los 33 posts”
- Iteración 8: “Todas las pruebas pasan Y 0 errores Y 0 advertencias Y puntuación de profundidad ≥2 en todos los posts”
Los fracasos y lecciones
Fracaso 1: El desastre del presupuesto de generación
Al inicio de la construcción del sistema de deliberación, ejecuté una sesión sin límites de presupuesto de generación. El agente generó 3 subagentes de exploración. Cada subagente generó sus propios subagentes. En minutos, el hook de recursion-guard estaba interceptando docenas de intentos de generación. La sesión consumió tokens de API a 10 veces la tasa normal antes de que la detuviera manualmente.6
La solución: Agregué un modelo de presupuesto de generación a recursion-limits.json. Los agentes heredan un presupuesto de su padre en lugar de incrementar la profundidad. Un agente raíz con budget=12 puede generar hasta 12 agentes en total a través de todos los niveles de recursión. Esta fue una decisión arquitectónica clave: la herencia de presupuesto previene el crecimiento exponencial mientras permite cadenas profundas de agentes.
Fracaso 2: Criterios que se cumplen trivialmente
Una tarea temprana le pedía al agente “escribir pruebas que pasen”. El agente escribió pruebas mínimas: assert True, assert 1 == 1. Técnicamente, los criterios se cumplieron. La salida era inútil.
La solución: Los criterios deben especificar tanto cantidad como calidad:
| Calidad del criterio | Ejemplo | Resultado |
|---|---|---|
| Vago | “Las pruebas pasan” | El agente escribe pruebas triviales |
| Medible pero incompleto | “Las pruebas pasan Y cobertura >80%” | El agente escribe pruebas que cubren líneas pero no prueban nada significativo |
| Completo | “Todas las pruebas pasan Y cobertura >80% Y sin errores de tipos Y linter limpio Y cada clase de prueba evalúa un módulo distinto” | Salida con calidad de producción |
Fracaso 3: Contaminación del sistema de archivos
Las iteraciones que exploraron enfoques sin salida dejaron artefactos: funciones parcialmente implementadas, archivos obsoletos, configuraciones en conflicto. La iteración 5 podría construir sobre un enfoque a medio terminar de la iteración 3 que fue abandonado en la iteración 4.
La solución: Agregué un paso de limpieza a los criterios del stop hook: “No existen archivos que no estén referenciados por imports o pruebas”. Esto obliga al agente a limpiar los callejones sin salida antes de que la iteración pueda completarse.
Fracaso 4: El incidente de ((VAR++))
Durante las pruebas de integración en bash, el hook de recursion-guard falló silenciosamente en la primera iteración. El error: ((VAR++)) retorna el código de salida 1 cuando VAR es 0 (porque 0++ evalúa a 0, que bash trata como falso). Con set -e habilitado, esto mataba el script.
La solución fue VAR=$((VAR + 1)) en lugar de ((VAR++)). Esta trampa de bash, documentada en mi MEMORY.md, ha prevenido el mismo error en 6 scripts de hooks subsiguientes.7
Cuándo funciona Ralph y cuándo no
Buen ajuste
- Implementación desde cero con especificaciones claras (nueva API, nuevo módulo, nueva suite de pruebas)
- Verificación automatizada disponible (pruebas, verificadores de tipos, linters, compilación)
- Alcance delimitado que puede describirse en un solo archivo de tareas
Mal ajuste
- Calidad subjetiva (“hacer que la UI se vea bien”) no tiene criterios verificables por máquina
- Trabajo exploratorio donde la dirección depende de descubrimientos intermedios
- Refactorización a gran escala que requiere comprender relaciones globales del código a través de docenas de archivos
Conclusiones clave
Para desarrolladores que construyen sistemas de agentes autónomos: - Invierta en criterios de finalización verificables por máquina antes de iniciar bucles autónomos; mi sistema de deliberación tuvo éxito porque cada PRD tenía criterios de éxito comprobables (141 pruebas en total) - Implemente presupuestos de generación desde el primer día; el modelo de herencia de presupuesto (no incremento de profundidad) previene la generación exponencial de agentes mientras permite cadenas profundas - Agregue limpieza del sistema de archivos a los criterios de finalización; los artefactos de iteraciones abandonadas contaminarán las iteraciones subsiguientes
Para equipos de ingeniería que evalúan el desarrollo autónomo con IA: - La arquitectura Ralph intercambia tiempo de implementación humana por tiempo de especificación humana; el retorno de inversión depende de si su cuello de botella es la capacidad de implementación o la claridad de especificación - Audite la salida autónoma con el mismo rigor que se aplica al código de contratistas externos; mis 141 pruebas existen porque aprendí que cumplir los criterios de finalización no garantiza estar listo para producción
Referencias
-
Implementación del autor del patrón del Bucle Ralph utilizando hooks de Claude Code. Infraestructura de deliberación: 3.455 líneas de Python, 8 módulos, 141 pruebas en 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. Eventos del ciclo de vida de hooks. ↩
-
Registro git del autor. Commits
3cad08c,10df724,fbf1a0d,32bd711abarcando la construcción completa de la infraestructura de deliberación. ↩ -
Experiencia del autor con generación de agentes sin presupuesto. Documentado en entradas de error de
~/.claude/projects/*/memory/MEMORY.md. ↩ -
Depuración de bash del autor. El comportamiento del código de salida de
((VAR++))conset -edocumentado como aprendizaje entre sesiones en MEMORY.md. ↩