NoticiasMacroExperimento de ingeniería de bucles revela que los ciclos de retroalimentación y verificadores pueden fallar silenciosamente

Experimento de ingeniería de bucles revela que los ciclos de retroalimentación y verificadores pueden fallar silenciosamente

Autor: Towards AI·

Puntos clave

  • El experimento evaluó dos componentes de ingeniería de bucles: un ciclo de retroalimentación que usa fallas reales de pruebas y una configuración maker/checker que separa la generación de código del juicio final.
  • Una primera ejecución de pruebas no mostró beneficio de la retroalimentación real porque el arnés de pruebas ocultas devolvía errores de aserción escuetos sin detalles útiles sobre la falla.
  • Después de agregar al arnés las entradas fallidas, salidas esperadas y resultados reales, la retroalimentación real resolvió un problema que un bucle de reintento genérico no pudo resolver.
  • El verificador que ejecutaba pruebas aceptó falsamente 3 de 8 candidatos incorrectos, una tasa más alta que dos verificadores basados en opinión en la comparación medida.
  • El sistema combinado final mejoró los resultados principalmente gracias al bucle de retroalimentación, mientras que el verificador produjo una falsa aceptación que solo fue detectada por la calificación con pruebas ocultas.
Experimento de ingeniería de bucles revela que los ciclos de retroalimentación y verificadores pueden fallar silenciosamente

Actualizado por última vez el 27 de julio de 2026 por el equipo editorial. Publicado originalmente en Towards AI.

“Mi trabajo es escribir bucles”.

Esa declaración provino de Boris Cherny, quien lidera Claude Code en Anthropic. Cherny ha dicho que dejó de dar instrucciones directamente a Claude y que ahora dedica su tiempo a diseñar los bucles que lo instruyen por él [1]. El comentario, junto con varios similares, ayudó a desencadenar una ola de explicadores sobre ingeniería de bucles este año [1][2]. Después de leer seis de ellos, construí uno.

Más precisamente, construí los dos componentes que casi todos los explicadores describen, pero que pocos parecen ejecutar de punta a punta. El primero fue un bucle de ejecución hasta completar: en lugar de pedirle al modelo que vuelva a adivinar después de una falla, le proporciona al modelo sus propias fallas reales de pruebas. El segundo fue una configuración maker/checker: el modelo que escribe el código no puede ser el juez final de si el código es correcto.

Esa distinción importa porque los flujos de trabajo de agentes de programación suelen depender de la misma separación: un sistema propone un cambio, mientras que otra herramienta, conjunto de pruebas o modelo decide si el cambio es aceptable. Si el canal de retroalimentación o el verificador es débil, el bucle puede parecer automatizado sin volverse significativamente más seguro.

Implementé ambos desde cero en unas 600 líneas de Python, los conecté a claude-opus-4-8 y los evalué contra MBPP+ [3]. MBPP+ es un benchmark de EvalPlus con pequeñas tareas de programación en Python, lo que lo hizo útil para aislar el comportamiento del bucle sin incorporar complicaciones a escala de repositorio. El costo total de todos los experimentos analizados aquí fue inferior a dos dólares. El segundo componente —el que a menudo se trata como la mitad más segura porque “realmente ejecuta pruebas” en lugar de confiar en la palabra del modelo— produjo en mis mediciones resultados sobre los que esos explicadores no habían advertido.

La versión corta: las dos piezas centrales de la ingeniería de bucles son simples de conectar y fáciles de hacer mal de forma silenciosa. Mi bucle de “retroalimentación real” inicialmente parecía indistinguible de reintentos aleatorios hasta que encontré un error en mi propio arnés de pruebas. Mi verificador “seguro” que ejecutaba pruebas tuvo una tasa de falsas aceptaciones más alta que un verificador que simplemente le preguntaba al modelo qué tan seguro se sentía. Construir el bucle es el 20% fácil.

Conectar un bucle a la nada

Gran parte de lo que se escribe sobre ingeniería de bucles se queda en el diagrama de cableado. Presenta un disparador, un objetivo verificable, herramientas, estado y reglas de parada: cinco cajas con flechas entre ellas. El mensaje implícito es que, una vez conectadas las cajas, el bucle funciona.

Eso es como instalar un detector de humo y declarar segura la casa porque el detector está montado en el techo y conectado, sin comprobar si tiene una batería funcionando.

Me encontré exactamente con esta falla en mi bucle de “retroalimentación real”. Estaba conectado a la salida real de las pruebas, no a una instrucción genérica de reintento. En teoría, debería haber superado claramente a un bucle que solo recibía el mensaje: “eso estuvo mal, inténtalo de nuevo”. Mi primera ejecución mostró lo contrario.

El evaluador que evalúa al evaluador

Antes de tocar el bucle en sí, construí el componente del que dependía todo lo demás: un evaluador que ejecuta código candidato en un subproceso aislado con un tiempo límite estricto y lo califica contra pruebas ocultas.

No confié en el evaluador hasta que se evaluó a sí mismo. Cuando recibía una solución conocida como correcta, tenía que aprobarla. Cuando recibía una solución conocida como incorrecta, tenía que fallar y adjuntar el error de aserción. Cuando recibía un bucle infinito, tenía que ser terminado por el tiempo límite en lugar de quedarse colgado para siempre.

Luego validé todo el pipeline contra 75 soluciones de referencia de MBPP+. Las 75 aprobaron. Solo después de eso confié en cualquier número producido por el bucle.

El bucle que parecía correcto, pero no lo era

El bucle en sí era muy simple. Generaba una solución, la evaluaba y, ante una falla, devolvía el stderr real —no un “inténtalo de nuevo” genérico, sino el error real— durante un máximo de tres intentos.

También construí un brazo de control porque no quería confiar en una cifra principal sin una línea base. El control usaba el bucle idéntico, pero reemplazaba el error real por una instrucción genérica: “eso estuvo mal, escribe una solución diferente”. Si la retroalimentación real no superaba claramente eso, entonces algo en el cableado estaba roto.

En la primera ejecución con 35 problemas, los tres brazos fueron idénticos. Eso no era evidencia de un bucle funcionando. Era una señal de alerta con forma de bucle.

En lugar de enfocarme en la métrica principal, examiné las fallas y encontré el problema: el arnés de pruebas ocultas de MBPP+ estaba fallando con un AssertionError escueto. No incluía la entrada que fallaba, el valor esperado ni el valor real. Como resultado, la “retroalimentación real” era informativamente idéntica a “inténtalo de nuevo”, porque el modelo no recibía nada sobre lo que pudiera actuar.

Instrumenté el arnés para que reportara la entrada fallida, la salida esperada y el valor real devuelto por el código. En los mismos 35 problemas, en una segunda ejecución, la retroalimentación real recuperó un problema que el brazo genérico no pudo resolver, con un costo de unos 2,500 tokens de entrada adicionales en toda la ejecución.

El bucle no estaba roto. La señal a la que estaba conectado estaba vacía. Solo el brazo de control expuso eso; la métrica principal por sí sola no lo habría hecho.

El verificador falló de una manera que la teoría no predijo

Un bucle necesita una regla de parada, y “el modelo dice que terminó” no es una regla de parada. Por eso construí un verificador que escribe sus propias pruebas a partir de la especificación. Nunca ve las pruebas ocultas y nunca ve el código de la solución que está evaluando. Luego ejecuta esas pruebas. La política era aceptar solo si todo pasaba y rechazar por defecto.

Comparé ese verificador con tres verificadores más débiles sobre 41 candidatos producidos por mi bucle: 33 correctos y 8 incorrectos. La medida fue la tasa de falsas aceptaciones, es decir, con qué frecuencia cada verificador dejaba pasar código aunque en realidad estuviera roto.

VerificadorFalsa aceptaciónFalso rechazo
Confiar en todo8/8 — 100%0/33 — 0%
Preguntar al modelo si está seguro2/8 — 25%4/33 — 12%
Un segundo modelo lee el código2/8 — 25%5/33 — 15%
Escribe pruebas y las ejecuta3/8 — 38%1/33 — 3%

Esperaba que el verificador que ejecutaba pruebas ganara claramente en falsas aceptaciones. No fue así. Dejó pasar una fracción más alta de código incorrecto que cualquiera de los verificadores basados en opinión.

La razón importaba más que el número. Los ocho candidatos incorrectos provenían de tres problemas con especificaciones genuinamente ambiguas. El verificador y el corrector eran el mismo modelo leyendo la misma oración ambigua. Por lo tanto, las pruebas autoescritas por el verificador codificaban la misma mala interpretación que ya contenía el código incorrecto, lo que permitía que ese código pasara esas pruebas sin problemas.

Los verificadores basados en opinión “ganaron” esa comparación de falsas aceptaciones principalmente porque tendían a ser cautelosos. Esa misma cautela también explica por qué rechazaron falsamente de cuatro a cinco veces más código correcto.

Ejecutar pruebas no es una garantía automática contra falsas aceptaciones. Es un tipo distinto de evidencia: una que incluye una entrada específica, un valor esperado y un valor real, en lugar de una impresión general. Eso es lo que hace que su tasa de falsos rechazos de 3% sea utilizable como una compuerta real. Un verificador que rechaza 15% del buen trabajo puede enterrar un flujo de trabajo en reintentos antes de evitar una mala integración.

Combinar las dos piezas

La composición final ejecuta primero el bucle de retroalimentación. Si falla, toma muestras de candidatos nuevos y deja que el verificador —no la confianza del modelo— decida qué se envía. También incluye una ruta explícita de rendición si nada supera el umbral.

Evalué esta configuración en una porción reservada de MBPP+ que no había usado mientras construía ninguno de los componentes anteriores. La calificación se realizó contra las pruebas ocultas, independientemente de lo que decidiera el verificador.

El bucle hizo esencialmente todo el trabajo: añadió 14.2 puntos, recuperó cinco de seis fallas de intento único y requirió unas 10 llamadas adicionales a la API. La etapa del verificador se activó exactamente una vez, en el único problema que el bucle no pudo resolver. Su primer candidato muestreado pasó sus propias pruebas autoescritas y aun así falló las pruebas ocultas.

Eso fue una falsa aceptación en vivo, consistente con el modo de falla predicho por la tabla anterior. Solo se detectó porque el ejecutor calificó los envíos contra una fuente de verdad que el verificador nunca ve. Si el juicio del propio verificador hubiera sido definitivo, ese error habría llegado a producción.

El costo total de esta etapa fue de 45 llamadas, o aproximadamente trece centavos.

Dónde se rompe el enfoque

Este enfoque funciona cuando el objetivo es genuinamente comprobable: una función con casos de prueba ocultos, un esquema que valida o no valida, o un oráculo al que el bucle no puede convencer con palabras. No funciona cuando la especificación en sí es ambigua, porque un verificador basado en el mismo modelo puede heredar la misma mala interpretación que el generador. En ese caso, la solución no es necesariamente un verificador más ingenioso. Es una especificación más clara, o un oráculo independiente de una familia de modelos completamente distinta.

También probé esto solo en funciones pequeñas e independientes de MBPP+. El experimento no abordó una base de código grande con dependencias entre archivos. No construí ni probé aislamiento de worktrees para ejecutar múltiples bucles en paralelo. Ese es un problema real, pero no fue el problema que midió este experimento.

El bucle también se detiene en “verificado”. No decide si aplicar automáticamente un cambio o escalarlo a una persona. Eso se convierte en un problema separado y más difícil tan pronto como el sistema toca algo con acceso real de escritura.

Por dónde empezar

Empieza con el evaluador. Escribe la autoprueba —caso correcto conocido, caso incorrecto conocido y bucle infinito— antes de escribir cualquier lógica de bucle. Ese script de cinco minutos es la principal protección contra una cifra principal ficticia.

Para una base de código con incluso un conjunto pequeño de pruebas unitarias, conecta después el bucle de retroalimentación y construye junto con él, desde el primer día, el brazo de control de reintento genérico. No confíes en la mejora hasta que supere a “inténtalo de nuevo”.

Luego construye un segundo verificador y compáralo con el primero. Cuando la tabla de falsas aceptaciones contradiga lo que sugería la teoría —y puede que lo haga—, la razón mostrará por qué el bucle importa más que el modelo que hay debajo.

Referencias

[1] Rohan Mistry, “Prompt Engineering Is Dead. Loop Engineering Is Here.,” Towards AI, julio de 2026.

[2] Mehmet Özel, “Loop Engineering for AI Agents : Building Verifiable, Self-Correcting Coding Workflows,” Towards AI, junio de 2026.

[3] EvalPlus, “MBPP+ Dataset,” Hugging Face Datasets.