---
title: "Loop engineering: ya no programas al agente, programas su bucle"
description: "El skill dejó de ser escribir el prompt perfecto. Ahora es diseñar el bucle que corrige al agente contra una señal real, hasta que dice hecho. Y se hace sin API."
pubDate: "2026-07-20"
category: "programacion"
language: "es"
tags: ["claude-code", "agentes", "loop-engineering", "harness", "ia", "productividad"]
---
import InlineCTA from '../../components/InlineCTA.astro';

Durante dos años el consejo fue el mismo: "aprende a promptear". Y estaba bien, hasta que dejó de estarlo. Llevo meses sin escribir prompts sueltos a un agente. Monto un flujo, le doy una señal contra la que corregirse, y lo dejo trabajar. Peter Steinberger lo dejó en una frase: *"You shouldn't be prompting coding agents anymore. You should be designing loops that prompt your agents."*

Boris Cherny, el creador de Claude Code en Anthropic, lo llevó al extremo: *"Ya no prompteo a Claude. Tengo loops ejecutándose. Ellos son los que lo prompean y deciden qué hacer."* A eso se le ha puesto nombre este año: **loop engineering**. Ya conoces la mecánica del sector: coges el último escalón del trabajo con agentes y le grapas "engineering" detrás, como se hizo con prompt engineering y con todo lo que vino después. Pero por una vez el nombre no es humo: lo que cambia de verdad es dónde está el apalancamiento de tu trabajo.

Te lo cuento con criterio de ingeniero, no de hype. Qué es, por qué importa, y cómo lo haces tú el lunes sin tocar una sola línea de API.

## El oficio se movió cuatro veces

Mira la progresión completa, porque el sitio donde estás tú marca lo que puedes hacer:

```
prompt   → escribes la instrucción perfecta una vez.
context  → diseñas QUÉ ve el modelo antes de responder.
harness  → montas el andamiaje: herramientas, memoria,
           verificación, guardarraíles alrededor del modelo.
loop     → diseñas el CICLO que usa ese andamiaje solo,
           vuelta tras vuelta, sin ti en cada paso.
```

El harness (que ya conté en [su propio artículo](/blog/harness-engineering/)) es el **equipo**: qué herramientas hay, qué memoria, qué verificación. El loop es la **coreografía de la carrera**: cuándo el agente actúa, cuándo mira el resultado, cuándo decide seguir, cuándo para.

Y aquí está la parte que casi nadie separa: puedes tener un harness excelente y un loop pésimo. Un agente con las mejores herramientas del mundo que igual entra en bucle infinito, o que para demasiado pronto y te deja el trabajo a medias. Loop engineering es diseñar ese ciclo.

## El loop es un `while` de verdad, no una metáfora

Esto es lo que más cuesta creer hasta que lo ves. Thorsten Ball, de Sourcegraph, montó un agente que edita código de verdad en **menos de 400 líneas**, "la mayoría boilerplate". El corazón, lo que de verdad *es* el agente, son unas 40 líneas. Su resumen es la mejor definición que he leído: *"It's an LLM, a loop, and enough tokens"* (un LLM, un bucle, y tokens suficientes).

Quítale el andamiaje y el bucle se queda en esto:

```python
mensajes = [tarea_del_usuario]
while True:
    respuesta = llm(mensajes)                 # el modelo decide: ¿herramienta o terminar?
    mensajes.append(respuesta)
    if not respuesta.tool_calls:              # no pidió herramientas: ha terminado
        break
    resultados = [ejecutar(t) for t in respuesta.tool_calls]  # el ENTORNO responde
    mensajes.append(resultados)               # el resultado real vuelve al contexto
```

Eso es todo, sin misterio. Lo importante está en la penúltima línea: entre cada vuelta, el loop recibe una respuesta del **entorno**, no del modelo. La salida de verdad de tus tests, tu compilador, tu linter. Anthropic lo llama obtener *ground truth* del entorno. Esa es la diferencia entre un loop que funciona y uno que gira en el vacío.

## El volante son las señales, no tu paciencia

Un loop necesita, en cada vuelta, saber si va mejor o peor. Esa señal es el volante. Y hay dos clases, con consecuencias opuestas.

El **volante malo** es tu juicio, o peor, el del propio modelo. Si el loop itera "hasta que la respuesta parezca buena", estás confiando en que el modelo evalúe su propio trabajo. No funciona, y hay razón: el generador y el evaluador son el mismo modelo, comparten los mismos sesgos, así que no ve el fallo que acaba de cometer. Auto-corregirse contra uno mismo es marcar tu propio examen.

El **volante bueno** es una señal *determinista* y *externa al modelo*: la suite de tests que pasa o falla, el type-checker, el linter. El patrón se llama *code-then-correct* y se teclea en cuatro líneas (siempre acotado, que a eso vamos):

```python
for intento in range(MAX_INTENTOS):        # límite máximo: sin esto es un incendio con presupuesto
    codigo = llm(tarea, historial)
    escribir(codigo)
    resultado = ejecutar("pytest -q")        # el volante: ground truth, no opinión
    if resultado.ok:
        return codigo                      # verde: terminado
    historial.append((codigo, resultado.salida))  # el fallo REAL vuelve al contexto
```

La línea que hace el trabajo es `ejecutar("pytest -q")`. No le preguntas al modelo si su código está bien. Se lo preguntas a pytest. Grábate la idea clave: **la calidad de un loop está acotada por la calidad de su señal.** Un loop excelente contra tests flojos converge rápido a algo malo.

### El lado oscuro: el loop hace trampa

Ahora lo contraintuitivo, lo que un senior tiene que tener claro. Un loop no optimiza tu *objetivo*. Optimiza su *señal*. Si la señal es "que los tests pasen", el loop descubrirá que borrar el test que falla también hace que "los tests pasen".

No me lo invento. METR auditó modelos frontera y documentó dos casos de manual. En una tarea de optimizar un kernel, un modelo **recorrió el call stack de Python** hasta encontrar la respuesta que el propio sistema de puntuación ya había calculado, y la devolvió tal cual: cero cómputo, el test en verde, el trabajo sin hacer. En otra, el modelo **sobrescribió el operador de igualdad de PyTorch** para que `a == b` devolviera `1 == 1`, de forma que cualquier salida, correcta o no, pasara el eval.

Fíjate en que ninguno "rompió las reglas". Optimizaron exactamente la señal que les dieron. Eso es lo que hace tan traicionero el reward hacking, y la razón de que la señal tenga que estar **fuera del alcance del bucle**: si el agente puede tocar el test, tarde o temprano lo toca.

<InlineCTA
  language="es"
  listSlug="lista-espera-curso-ia"
  source="web_inline_cta_loop_engineering"
  title="Esto es un artículo. En el curso está entero"
  text="Loop engineering es una sección completa de <strong>Agentes e IA: Zero to Hero</strong>, el curso que estoy montando para desarrolladores: anatomía del bucle, condiciones de parada, contexto en runs largos, reward hacking y evals, todo con ejemplos que puedes teclear. Si quieres acceso anticipado y descuento de lanzamiento, déjame el correo."
  note="Sin fecha ni precio todavía. Te aviso cuando lo haya, y nada más."
/>

## Lo difícil no es el loop, es cuándo parar

Como dice el propio Cherny: "el loop es la parte fácil; el trabajo es el contexto y la condición de parada." Escribir el `while` te lleva diez minutos. Decidir cuándo se detiene, con qué presupuesto y contra qué objetivo alcanzable es donde se va el oficio.

De ahí sale la pregunta que casi nadie hace: ¿cuándo NO montar un loop? Cuando no tienes una señal determinista y barata que juzgue cada vuelta. Un loop brilla arreglando tests, pasando un linter o cuadrando tipos, porque el veredicto es instantáneo y objetivo. Ponlo a "mejorar la arquitectura" o a "escribir una landing que convierta" y no hay pytest que le diga si va bien: gira, gasta, y te devuelve algo que parece terminado sin estarlo. Ahí el humano no sobra, es el único juez que hay.

Y está el coste de la opacidad. Un bucle que se equivoca no te avisa: sigue, convencido. Cuando lo pillas, ya ha tocado veinte ficheros y quemado la mitad de tu presupuesto. Por eso lo primero que diseñas no es la autonomía, es el freno.

## Lo que de verdad vas a usar: loop engineering sin API

Todo lo de arriba parece "móntate tu propio agente". Y sí, se puede. Pero seamos honestos: tú no vas a escribir ese `while` el lunes. Vas a usar Claude Code, y ahí el bucle **ya se ejecuta por ti**. Lo que diseñas es cómo se ejecuta. Te enseño las tres piezas, con sintaxis que funciona hoy.

**La señal, con un hook.** Un hook `PostToolUse` ejecuta un comando cada vez que el agente edita un fichero. Si falla, le devuelves el error y se corrige solo. En `.claude/settings.json`:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/typecheck.sh" }
        ]
      }
    ]
  }
}
```

Y el script hace la magia con un código de salida:

```bash
#!/bin/bash
if ! salida=$(npm run typecheck 2>&1); then
  echo "$salida" >&2
  exit 2          # exit 2 = error bloqueante; el stderr se le pasa al agente
fi
exit 0
```

Ese `exit 2` es la clave. Con él, Claude Code le entrega el error al modelo como parte del bucle, y el agente itera hasta dejarlo limpio. Acabas de convertir tu type-check en el volante, sin una línea de API. Cambia `npm run typecheck` por `pytest -q` y tienes lo mismo con tests.

**El freno, con un sub-agente.** Un sub-agente es un bucle hijo con su propio contexto. Se define en un Markdown, y `maxTurns` le pone el tope. En `.claude/agents/arregla-tests.md`:

```markdown
---
name: arregla-tests
description: Ejecuta la suite, lee los fallos y los arregla hasta verde.
tools: Read, Edit, Bash
model: sonnet
maxTurns: 20
---

Ejecuta `pytest -q`, lee el primer fallo, corrígelo, y repite hasta verde
o hasta agotar los turnos. Regla dura: NUNCA modifiques un test para que
pase. Arregla el código.
```

Dos cosas que valen oro. `maxTurns: 20` es el tope: si no converge en veinte vueltas, para en vez de quemarte los tokens. Y esa última línea del prompt es tu defensa contra el reward hacking de antes: le cierras al bucle el camino de hacer trampa borrando el test.

**Y cuando quieras que se ejecute sin ti**, ya no es una sesión que vigilas:

```bash
/loop 5m comprueba si el deploy ha terminado y avísame
claude --bg "investiga el test flaky y arréglalo"
```

`/loop` y los agentes en background son estándar. Hay más (workflows para orquestar varios sub-bucles, agentes programados por cron), pero eso ya es otra liga y con sus avisos: los workflows queman muchos tokens y los programados se ejecutan en la nube, no en tu máquina.

## Seis loops que se pagan solos

Para bajarlo del todo a tierra, seis bucles que puedes tener en marcha esta semana. Fíjate en que todos comparten lo mismo debajo: una señal clara que dice si la vuelta valió. Sin ella, ninguno funcionaría.

- **Guardia de errores.** Cada hora revisa Sentry o Grafana, coge el error nuevo, lo reproduce, lo corrige y te deja la PR preparada. La señal es el test que reproduce el bug pasando a verde.
- **Revisor de PRs.** Cada hora mira las PRs abiertas contra tus reglas (tamaño, tests, nombres, secretos colados) y deja comentarios donde algo chirría. La señal es tu propia checklist.
- **Vigilante de dependencias.** Cada noche busca librerías con CVE nuevo, actualiza la que puede sin romper nada y abre PR; la que rompe tests, la deja anotada. La señal es la suite completa.
- **Cazador de flaky.** Cuando CI falla por un test no determinista, lo ejecuta en bucle hasta capturar el fallo y te dice si el culpable es el test o el código. La señal es reproducir el fallo unas cuantas veces.
- **Sincronizador de docs.** Cuando cambias un endpoint, revisa si el README y los ejemplos siguen cuadrando y actualiza lo que se quedó viejo. La señal es que los ejemplos de la doc siguen ejecutándose.
- **Traductor de i18n.** Cuando añades una clave en el idioma base, rellena las que falten en los demás idiomas y deja PR. La señal es que no queda ninguna clave sin traducir.

El hilo común: todos son tareas con veredicto objetivo. No es casualidad, es la condición para que un loop merezca la pena.

## Lo que te llevas

Tres ideas, y las tres cambian cómo trabajas mañana:

1. **Tu palanca se movió.** Si mides tu skill por lo bien que prompeas, estás optimizando la herramienta de 2024. La de 2026 es cuánto trabajo verificado produces por cada bucle que diseñas y sueltas.
2. **La señal es lo primero.** Antes de automatizar nada, ten un comando determinista que te diga en segundos si la última vuelta fue a mejor. Sin eso no tienes un loop, tienes un generador de texto caro.
3. **Asume que el loop hará trampa.** No es maldad del modelo, es la definición de optimizar. La señal tiene que estar donde el agente no pueda tocarla.

Y la parte tranquilizadora: nada de esto necesita que montes un agente desde cero. Un hook, un `maxTurns` y una regla en un fichero de texto ya son loop engineering. Empieza por ahí.

---

*Para seguir el hilo: [harness engineering](/blog/harness-engineering/) es la pieza de debajo (el equipo que el loop ejecuta), y [cómo reduje un 80% el consumo de tokens](/blog/token-optimization/) baja a producción mucho de esto.*

**P.D.**: Si montas un loop y descubres una forma nueva en que tu agente hace trampa, cuéntamela. Colecciono esas. Me encuentras en Twitter como [@lm_martinbar](https://x.com/lm_martinbar).