Ralph Wiggum Loop

1. El problema de fondo

Durante veinte años, el cuello de botella del desarrollo de software fue escribir código. Contratabas más desarrolladores, pagabas horas extras, subcontratabas. Ese paradigma se invirtió. Hoy, generar 1.000 líneas de código con una IA cuesta menos que una hora de un desarrollador senior en la mayoría de los mercados. El código dejó de ser el recurso escaso.

El recurso escaso ahora es la especificación: la capacidad de diseñar qué construir, en qué orden, y cómo orquestar la máquina que construye. El ingeniero ya no escribe código línea por línea; programa bucles que escriben código por él.

El Ralph Wiggum Loop es la cristalización más radical de este cambio. En su forma más pura, es un bucle while de Bash que ejecuta un agente de IA iterativamente. Cada iteración arranca con un contexto limpio, lee un archivo de especificaciones, ejecuta una tarea atómica, y se detiene al completarla. Pero entender por qué esto funciona —y por qué es revolucionario— requiere entender cómo se degradan los LLMs bajo carga.

Cada LLM opera con una ventana de contexto finita (~200K tokens), pero la calidad de las respuestas no es uniforme en todo ese rango. La relación entre tokens escala cuadráticamente: cuanto más contexto usás, más caro (en degradación) es cada token adicional. La zona útil —la “smart zone”— ocupa aproximadamente el primer 40% del contexto. El resto es la “dumb zone”, donde el modelo comienza a confundirse y a tomar decisiones erráticas.

El Ralph Loop explota exactamente este límite: cada iteración destruye el proceso del agente y lo recrea desde cero. La ventana de contexto nunca se llena con basura de iteraciones anteriores. El LLM trabaja siempre en smart zone.

2. Geoffrey Huntley

Geoffrey Huntley es un ingeniero DevOps, ex-Canva, que en julio de 2025 publicó un post que sacudió la comunidad de IA aplicada al desarrollo. Su experimento fue tan simple como extremo: dejar a Claude Code corriendo de forma autónoma durante meses, en un bucle, para construir un compilador completo para un lenguaje de programación nuevo llamado CURSED. Sin supervisión humana. Mientras dormía.

La técnica la llamó “persistencia ingenua”: no construir arquitecturas elaboradas para guiar a la IA, sino simplemente forzarla a chocar una y otra vez contra sus propios errores y stack traces hasta que el código compilara. El nombre “Ralph Wiggum” viene del personaje de Los Simpson, y es además un juego de palabras: “ralph” como el acto de vomitar ante la velocidad de la automatización.

La implementación canónica es una línea de Bash:

while :; do cat PROMPT.md | claude-code ; done

La advertencia de Huntley es explícita: Ralph no está diseñado para bases de código existentes. Funciona mejor en proyectos Greenfield donde puedas aceptar el caos controlado. “No hay forma de que use Ralph en una base de código existente”, dijo textualmente.

2.1. Fase 1: generar — especificaciones, plan y una sola tarea por iteración

La mecánica interna de cada iteración comienza con una premisa contraintuitiva: una sola tarea por iteración. Huntley insiste en esto como regla de oro. El LLM recibe dos cosas que se asignan de forma determinista en cada ciclo: el plan (fix_plan.md) y las especificaciones (specs/). El prompt le pide que estudie el código fuente, compare contra las especificaciones, elija la tarea más importante, y la implemente.

La gestión del contexto es quirúrgica. Huntley descubrió que el contexto real útil de Claude 3.7 se recorta en el rango 147K-152K tokens, no los 200K anunciados. Por eso el stack debe asignarse igual en cada ciclo: no hay margen para desperdicio.

Para maximizar el throughput, el prompt de planificación usa hasta 500 subagentes paralelos para escanear el código fuente y generar el plan de tareas pendientes. Pero solo un subagente para builds y tests, para evitar el “back pressure” por fan-out excesivo.

Huntley descubrió que la ventana de contexto real útil de Claude 3.7 es aproximadamente 25% menor que la anunciada. Esto obliga a optimizar cada iteración al extremo.

2.2. Fase 2: contrapresión

Una vez que el LLM genera código, el sistema necesita validarlo. Acá entra el concepto de contrapresión: el build system y los tests actúan como un filtro que rechaza código inválido. La velocidad de la rueda (el tiempo de cada ciclo) depende críticamente de qué tipo de contrapresión usés.

Rust da la máxima corrección —su tipo de sistema es extremadamente restrictivo— pero la compilación es lenta. Los lenguajes dinámicos compilan rápido pero requieren analizadores estáticos externos como Dialyzer (Erlang) o Pyrefly (Python). El trade-off es inevitable: velocidad del ciclo contra precisión de la validación.

Para el proyecto CURSED, Huntley eligió Rust por la necesidad de corrección absoluta (es un compilador), aceptando ciclos más lentos. Su recomendación: si usás un lenguaje dinámico, tenés que conectar sí o sí un analizador estático. Sin eso, “vas a terminar en una hoguera de resultados”.

Si usás un lenguaje de tipado dinámico con Ralph, la documentación oficial de herramientas como Dialyzer (Erlang) o Pyrefly (Python) no es opcional. Sin analizador estático, el modelo va a generar código que corre pero está mal.

2.3. Fase 3: loop-back

El output de cada iteración se realimenta al LLM como entrada de la siguiente. Pero Huntley fue más lejos: Ralph puede auto-mejorar su propio AGENT.md. Cuando el agente descubre algo nuevo sobre cómo compilar o ejecutar el proyecto, actualiza ese archivo. Cada bug detectado se documenta en fix_plan.md. Cuando los tests pasan, Ralph hace commit y push, y crea un tag de versión automáticamente.

Este mecanismo de “eventual consistency” es central a la filosofía: Ralph va a cometer errores, pero cada error es una oportunidad de calibrar. “Ralph te va a poner a prueba”, dice Huntley. “Cada vez que Ralph hace algo mal, lo afinás, como una guitarra.”

# Cuando los tests pasan, el prompt instruye:
# git add -A
# git commit -m "descripción de cambios"
# git push
# git tag 0.0.N (incrementando patch)

El LLM tiene una tendencia inherente a implementaciones placeholder o mínimas. Los modelos han sido entrenados para maximizar su función de recompensa, y esa función privilegia código que compila sobre código completo. Para combatirlo, Huntley usa prompts explícitos: “DO NOT IMPLEMENT PLACEHOLDER OR SIMPLE IMPLEMENTATIONS. WE WANT FULL IMPLEMENTATIONS.”

3. Matt Pocock

Matt Pocock es educador de TypeScript, ex-Vercel, creador de Total TypeScript y AI Hero. Cuando se encontró con el Ralph Loop de Huntley, identificó dos problemas fatales para usar la técnica en producción:

  1. Bucles infinitos: el enfoque libre no tiene cortocircuitos. Si el LLM no produce nunca la señal de completitud, el bucle corre hasta consumir tu presupuesto de API.
  2. Alucinación arquitectónica: sin un artefacto de requerimientos bien definido, el agente inventa features, cambia de dirección, o implementa cosas que no pediste.

La solución de Pocock es desacoplar la memoria del agente del contexto del LLM usando archivos en disco:

  • PRD.md: documento de requerimientos con tareas atómicas priorizadas y criterios de completitud explícitos.
  • progress.txt: archivo de tracking con dos secciones: (1) “RALPH PERSISTENT INSTRUCTIONS” — directrices que el agente lee al inicio de cada iteración— y (2) “Progress Log” — registro de tareas completadas.

Su flujo completo es: idea → write-a-prd → PRD → prd-to-issues → Kanban → ralph.sh → bucle Ralph → QA manual.

Aspecto Enfoque Huntley Enfoque Pocock
Memoria del agente Contexto del LLM Archivos en disco (PRD.md + progress.txt)
Cortocircuito Ninguno <promise>COMPLETE</promise> + MAX_ITERATIONS
Tracking de progreso Git history progress.txt + git commits
Idoneidad Experimentación Producción

progress.txt funciona como memoria exosomática: desacopla el estado del agente del contexto del LLM. Cada iteración lee el estado actual del disco, ejecuta, escribe el nuevo estado, y termina. La siguiente iteración lee el estado actualizado. Esto es análogo a un sistema de archivos de transacciones atómicas.

3.1. Bash script vs plugin oficial de Anthropic

Cuando Anthropic lanzó su plugin oficial de Ralph Loop para Claude Code, la comunidad esperaba una solución integrada. El plugin se ejecuta dentro de una sola sesión de Claude Code usando un stop hook que intercepta las salidas del agente y realimenta el prompt automáticamente:

/ralph-loop "Build a REST API..." --completion-promise "COMPLETE" --max-iterations 50

Pero el plugin tiene un problema arquitectónico fundamental. En lugar de destruir y recrear el proceso (como hace el Bash loop), mantiene todo dentro de la misma sesión. Esto produce una degradación predecible:

Iteración Bash Loop Plugin Anthropic
1 Contexto fresco ~5% lleno Contexto fresco ~20% lleno
2 Contexto fresco ~5% lleno Contexto ~35% lleno
3 Contexto fresco ~5% lleno Contexto ~50% lleno → dumb zone
4 Contexto fresco ~5% lleno Contexto ~65% lleno → degradación severa
N Siempre fresco Acumulación hasta colapso

El problema es que el plugin acumula historial de sesión, intentos fallidos, y decisiones pasadas que contaminan iteraciones futuras. Gordon Mickel lo resumió con precisión: “El plugin: sesión única, contexto acumulativo, sin re-anclaje. Esto derrota el propósito. La visión original de Huntley: contexto fresco por iteración, File I/O como estado (no transcripto), bucle Bash tonto y determinista.”

Matt Pocock fue más directo: “Dos modelos > uno”, refiriéndose a que el bucle Bash y el agente son dos sistemas separados que se acoplan débilmente, mientras el plugin acopla fuertemente el bucle y el agente en el mismo contexto. La guía oficial de contexto largo de Anthropic dice que “los agentes deben re-anclarse en fuentes de verdad para prevenir deriva”. El plugin de Anthropic no re-ancla en absoluto.

El plugin de Anthropic garantiza que después de 3-4 iteraciones vas a estar operando completamente en la dumb zone. Cada iteración adicional no solo es menos productiva —es contraproducente, porque el contexto contaminado empeora las decisiones del modelo.

4. Ejemplos

4.1. ralph.sh

El siguiente script es una versión simplificada de ralph.sh, la implementación de referencia basada en las enseñanzas de Matt Pocock. Ejecuta Claude Code en un bucle, leyendo PRD.md y progress.txt en cada iteración, y se detiene cuando el agente emite la señal de completitud.

#!/bin/bash
set -e

# ralph.sh - Bucle Ralph Wiggum simplificado
# Dependencias: jq, claude-code CLI

MAX_ITERATIONS=${1:-10}   # Por defecto: 10 iteraciones
MODO_AFK=false

if [ "$1" == "afk" ]; then
  MAX_ITERATIONS=9999     # Modo sin límite
  MODO_AFK=true
fi

# Validar archivos requeridos
if [ ! -f "PRD.md" ] || [ ! -f "progress.txt" ]; then
  echo "Error: PRD.md y progress.txt son obligatorios"
  exit 1
fi

for ((i=1; i<=MAX_ITERATIONS; i++)); do
  echo ""
  echo "=== RALPH ITERACION $i de $MAX_ITERATIONS ==="
  echo ""

  # Archivo temporal para capturar la salida
  tmpfile=$(mktemp)
  trap "rm -f $tmpfile" EXIT

  # Invocar Claude Code con el contexto actual
  claude \
    --print \
    --output-format stream-json \
    --dangerously-skip-permissions \
    "@progress.txt @PRD.md

Completá UNA tarea de PRD.md siguiendo las instrucciones persistentes
en progress.txt. Actualizá progress.txt después de cada cambio.
Si TODAS las tareas están completas, emítí exactamente:
<promise>COMPLETE</promise>" \
    | tee "$tmpfile"

  # Verificar si el agente marcó completitud
  if grep -q "<promise>COMPLETE</promise>" "$tmpfile"; then
    echo ""
    echo "=== PRD COMPLETO en $i iteraciones ==="
    rm -f "$tmpfile"
    exit 0
  fi

  rm -f "$tmpfile"
done

echo ""
echo "=== Completadas $MAX_ITERATIONS iteraciones (PRD incompleto) ==="

El script requiere jq instalado. En macOS: brew install jq. En Debian/Ubuntu: sudo apt install jq. En Arch: sudo pacman -S jq.

4.2. PRD.md

# PRD: API REST de Tareas

## Pendientes (priorizadas)

- [ ] **P1 - CRUD de tareas**: Endpoints GET, POST, PUT, DELETE para /tasks.
  - Criterio: `curl` a cada endpoint devuelve 200/201 con JSON válido.
- [ ] **P2 - Validación de entrada**: Rechazar payloads malformados con 422.
  - Criterio: `curl` con body inválido devuelve 422 + schema de error.
- [ ] **P3 - Tests de integración**: Suite que cubre los 4 endpoints.
  - Criterio: `pnpm test` pasa sin errores.

## Completadas

- (vacío al inicio)

4.3. progress.txt

# === RALPH PERSISTENT INSTRUCTIONS ===
# Estas instrucciones se leen al inicio de CADA iteración.
- Ejecutá `pnpm test` antes de cada commit
- Ejecutá `pnpm lint --fix` después de cambios de código
- Cada commit debe tener un mensaje descriptivo
- Si una tarea no se puede completar, marcá IN_PROGRESS con notas

# === PROGRESS LOG ===
# El agente actualiza esta sección automáticamente.

2026-06-09: Iniciado proyecto. PRD creado con 3 tareas.

5. Guía de uso

5.1. Estrategia TDD

La forma más efectiva de usar Ralph es escribir los tests primero, activar el bucle, y dejar que la IA resuelva la implementación basándose exclusivamente en los reportes de error del test runner. Cada fallo del test runner se realimenta como entrada del siguiente ciclo. Esto crea un loop de retroalimentación determinista: el agente no puede declarar una tarea completa hasta que los tests pasen.

Huntley recomienda capturar el significado de cada test en el momento: cuando Ralph escribe un test, el prompt debe pedirle que documente por qué ese test es importante. Esto deja “notas para futuras iteraciones del LLM”, que de otra forma no tendrían contexto.

5.2. Control de costos

El principal riesgo del Ralph Loop es el consumo desmedido de tokens. Las protecciones obligatorias son:

  • Límite estricto de iteraciones: MAX_ITERATIONS=10 es un valor de inicio sensato. Si en 10 intentos el agente no completa la tarea, probablemente está en un bucle lógico que requiere intervención humana.
  • Señal de completitud: el agente debe emitir una señal explícita como <promise>COMPLETE</promise> para romper el bucle temprano.
  • Modo AFK con cortocircuito: incluso en modo ilimitado, el for loop de Bash actúa como último cortocircuito (9999 iteraciones máximas).
Síntoma Corrección
Ralph implementa lo mismo repetidamente Reducí a una tarea por iteración
Ralph ignora instrucciones Agregá una “señal” más específica al prompt
Ralph hace implementaciones placeholder Agregá: “DO NOT IMPLEMENT PLACEHOLDER”
Ralph no completa nunca Reducí MAX_ITERATIONS e intervení manualmente

5.3. Calibración de prompts

Huntley describe el proceso de calibración como “afinar una guitarra”. Cuando ves que Ralph hace algo mal, no culpés a la herramienta: añadí una instrucción más precisa. Si Ralph genera código incorrecto, actualizá la biblioteca técnica estándar. Si construye la cosa equivocada, las especificaciones están mal.

El proceso es iterativo: cada comportamiento no deseado se corrige añadiendo una “señal” en el prompt. Eventualmente Ralph internaliza esas señales. “Al final todo en lo que Ralph piensa son las señales”, dice Huntley. “Entonces tenés un Ralph nuevo que ya no se siente defectuoso.”

El límite fundamental es que Ralph funciona mejor en proyectos Greenfield: aproximadamente el 90% del valor está ahí. Si necesitás operar sobre una base de código existente, el riesgo de efectos secundarios no anticipados es muy alto.

5.4. Hacia el software evolutivo

Huntley ha evolucionado el concepto de Ralph Loop hacia lo que llama “The Weaving Loom”, una infraestructura para software evolutivo. En la escala de Gas Town (que va del nivel 1 al 9), el nivel 8 es “spinning plates” —orquestación de múltiples servicios— y el nivel 9 es “evolutionary software”: bucles autónomos que evolucionan productos y optimizan automáticamente para generación de ingresos.

En enero de 2026 se documentó el primer caso de auto-healing evolutivo: un sistema que se ejecutaba bajo un Ralph Loop de verificación identificó un bug, estudió el código fuente, lo arregló, hizo deploy automático, verificó que funcionara, y documentó el cambio — todo sin intervención humana.

Enero 2026: Primer caso documentado de auto-healing evolutivo. Geoffrey Huntley tuiteó: “something incredible just happened here — perhaps first evolutionary software auto heal.” El sistema identificó un problema con una feature, estudió el codebase, lo fixeó, lo deployó automáticamente, y verificó que funcionara.