Hace un tiempo escribí que la programación se está desplazando de verificar cómo funciona el código a verificar qué produce — programación orientada a resultados. Este post es lo que pasó cuando me tomé esa idea lo bastante en serio como para romperla. Quise reproducir un resultado de DeepMind y acabé varias semanas con una pregunta pequeña y testaruda: si un chequeo de resultado pasa, ¿significa eso de verdad que el resultado es correcto? La respuesta resulta ser “no necesariamente” — y se puede decir exactamente cuándo falla, y demostrar parte del porqué.
Lo escribí todo como un preprint, When a Verified World Model Still Loses: Play-Adequacy vs Prediction-Accuracy in LLM-Synthesized Code World Models, ya en arXiv (arXiv:2607.14169). El código y el registro completo de reproducción son abiertos; el resto de este post es la historia en lenguaje llano.
El planteamiento: Code World Models
El paradigma que estaba hurgando viene del paper de DeepMind Code World Models for General Game Playing (Lehrach et al., 2025). En vez de pedirle a un modelo de lenguaje que juegue directamente, le pides que escriba las reglas del juego como un programa en Python — un “modelo del mundo” con funciones para movimientos legales, transiciones y resultados. Luego un planificador clásico (Monte Carlo Tree Search) juega contra ese programa sintetizado. La división del trabajo es elegante: el LLM hace traducción (reglas → código) y la búsqueda clásica hace la anticipación.
Funciona bien, y en juegos conocidos un modelo pequeño + MCTS le gana por mucho al mismo modelo usado como política directa. Eso lo reproduje. Pero un paso me incomodaba: el paso de verificación.
Antes de que el planificador confíe en el modelo del mundo sintetizado, el modelo se refina hasta alcanzar el 100% de precisión de transición sobre un lote de partidas aleatorias — siguiente estado, movimientos legales, resultado, todo coincidiendo con el juego real. Si lo pasas, “pasas el gate”. Parece un chequeo de corrección limpio y automático.
La pregunta que no me podía quitar de encima: pasar ese gate significa que el modelo coincide con la verdad en juego aleatorio. ¿Significa que el modelo es lo bastante bueno para planificar con él?
El nulo honesto
Lo primero, la parte aburrida e importante: en juegos pequeños y completamente especificados, el gate sí basta. Tres en raya, una variante de ajedrez generalizado (army5x5a, más abajo), Trike — siempre que un modelo sintetizado pasaba el gate, también era correcto en los estados que el planificador realmente visita. Sin brecha. Lo reporto como resultado nulo, porque marca la frontera: el gate es un filtro fuerte cuando las reglas están completas y el espacio de estados es pequeño.
Así que la pregunta interesante pasa a ser: ¿cuándo se puede engañar al gate? Y la condición es precisa: necesitas una regla que el juego aleatorio casi nunca dispara pero que el juego competente busca de forma fiable.
El instrumento: una regla rara que decide partidas
Para hacer real esa condición no inventé un juego desde cero — tomé un juego de ajedrez generalizado del propio paper de DeepMind (army5x5a, definido en su Apéndice H.5: un tablero 5×5 con piezas de general, infantería y caballería, se gana capturando al general rival) y le añadí una regla: si la partida llega a un tope alto de jugadas con ambos generales aún vivos, gana quien tenga más material en vez de empatar. Bajo juego aleatorio, esa regla decide la partida un 2.5% de las veces — las partidas aleatorias acaban pronto, por error. Bajo juego competente decide cerca de la mitad de las partidas, porque el buen juego sobrevive hasta el tope.
Ahora omite esa regla de la especificación y sintetiza un modelo del mundo. El resultado es un modelo que:
- pasa el gate al 100% de precisión de transición,
- es ≥98% preciso sobre la distribución exacta de estados que visita el planificador,
- y aun así pierde sistemáticamente al jugar (tasa de victoria 0.404 vs 0.495 de un baseline justo calibrado — un coste de juego de 0.091, con intervalos de confianza al 95% que no se solapan; IC 95% agrupado por semilla [0.065, 0.117] sobre 20 semillas).
En todo el texto, coste de juego es simplemente la tasa de victoria que sacrifica el fallo: la tasa del baseline justo menos la del modelo defectuoso, ambos jugando contra el juego real al mismo presupuesto. 0 significa “juega tan bien como la verdad”; cuanto mayor, más partidas te está costando el fallo.
El puñado de estados que falla son exactamente los que deciden partidas. Las medias lo esconden — el error queda diluido por todas las posiciones normales que acierta. Precisión de predicción y adecuación para jugar se separan, de forma limpia y reproducible.
Para asegurarme de que no era un artefacto de mi sustituto escrito a mano, también lo ejecuté de extremo a extremo a través del pipeline de síntesis real, al mismo presupuesto y con sus propios intervalos de confianza: el modelo sintetizado pasa el gate solo cuando la regla rara está ausente de su muestra, y cuando lo hace, pierde al jugar — con un coste al menos tan grande como el de arriba. El mismo efecto, sin un humano dibujando a mano el modelo defectuoso.
| Brazo (vs el juego real) | Tasa de victoria [IC 95%] | Coste de juego |
|---|---|---|
| ● Baseline justo (verdad vs verdad) | 0.495 [0.475, 0.515] | — |
| ● Instrumento ciego a la regla (Panel A) | 0.404 [0.384, 0.424] | 0.091 |
| ● Sintetizado, regla ausente (Panel B) | 0.345 [0.317, 0.374] | 0.154 |
El coste de juego se mide pareado por semilla contra el baseline justo de cada brazo; el coste mayor del brazo sintetizado refleja imperfecciones más allá de la regla omitida. Números completos e ICs en el preprint.
Una ley para cuándo la verificación se queda ciega
Lo bonito es que esto no es una anécdota aislada; tiene forma. El daño esperado sigue
donde rareza es cada cuánto una partida aleatoria dispara la regla omitida y cuántas partidas muestrea el gate. El factor es exacto — es simplemente la probabilidad de que partidas aleatorias independientes fallen todas la regla. Así que el daño es despreciable mientras la regla sea lo bastante común como para que la cacen, sube atravesando un umbral según se hace más rara, y se satura en el coste completo de la regla cuando casi siempre escapa al gate.
Hay una lectura más afilada de ese factor. Cuando la regla nunca aparece en la muestra, los datos son literalmente idénticos esté la regla en el modelo o no. Así que ningún aprendiz de ningún tipo — ni un LLM más grande, ni descenso por gradiente, ni búsqueda exhaustiva — puede recuperar la regla solo a partir de esa muestra. No es una debilidad del modelo; es información que falta. Cualquier recuperación tiene que venir de la especificación, no de los datos.
Traducción, no inferencia
Eso lleva al hallazgo que me parece más práctico. ¿Se puede reparar la brecha dándole al modelo ejemplos de la regla? Lo intenté — en serio: DAgger, estados cosechados on-manifold, decenas de ejemplos discriminantes, dos tamaños de modelo, bucles de refinamiento que sacan datos frescos en cada iteración.
(Para fans del imitation learning: el “DAgger propio” aquí es el bucle de Ross et al. (2011) — recoger estados del propio juego del modelo defectuoso y reetiquetarlos con el oráculo — no solo volcar trayectorias competentes.)
No funciona. En todos los casos, el modelo sintetizado sigue ciego a la regla incluso cuando la regla está presente en sus trayectorias casi con certeza (se puede ver: la precisión del gate se queda muy por debajo de 1.0, lo que significa que la regla está en los datos, y tras seis pasadas de refinamiento el modelo aún no la ha codificado). El comportamiento es traducción de reglas, no inferencia de reglas: el modelo codifica fielmente las reglas que se le dicen, y no infiere de forma fiable las reglas que solo se le muestran. La versión accionable: completa la especificación antes de sintetizar. Verificar sobre la distribución de juego detectará una especificación incompleta; no la reparará.
La misma división en el lado de las creencias
Los juegos con información oculta — póker y similares — añaden una segunda cosa que el modelo tiene que acertar: no solo la dinámica, sino una función de creencias, el código que reconstruye lo que un jugador no puede ver a partir de lo que sí ve. Esperaba que la brecha apareciera también aquí. La primera sorpresa fue que no — y la razón es casi graciosa.
En juegos pequeños de póker (Kuhn, Leduc) el gate muestreado es demostrablemente suficiente para certificar la función de creencias; puedo escribir la cota. Resulta que el juego aleatorio es un explorador más exhaustivo de un árbol de apuestas que el juego hábil, porque rapea y paga indiscriminadamente mientras que el buen juego se retira. Así que los estados de creencia raros nunca se esconden del gate — el juego competente solo visita un subconjunto de lo que el aleatorio ya cubrió. Sin brecha.
Pero eso te dice exactamente qué necesitaría una brecha: un juego donde la habilidad te lleve más profundo que el azar — donde la profundidad venga de sobrevivir, no de dar palos de ciego. Así que construí el juego más pequeño posible con esa forma. Lo llamo Beacon, y es básicamente el dibujo de servilleta: una caminata donde, en cada paso, eliges un movimiento — una opción te deja continuar, la equivocada acaba la partida en el acto. El juego aleatorio se sale del camino casi de inmediato; el juego hábil camina hasta el final. Y justo al final hay una única decisión que depende de un dato oculto sobre tu rival — un dato que podrías haber leído de los movimientos que hizo por el camino.
Ahora dale a un modelo una función de creencias correcta en todas partes excepto en ese tramo final — el extremo profundo de la caminata al que solo llega el juego hábil. Pasa el gate sin problema (el aleatorio nunca llega lo bastante lejos para probarlo) y luego pierde todas las partidas, porque el único sitio donde sus creencias están mal es el único sitio donde la partida se decide de verdad. La misma forma que la regla rara, ahora en el lado de las creencias: verificada, y aun así equivocada justo donde importa.
Seamos claros: Beacon es un testigo construido a propósito, no algo con lo que un modelo se tropezó — una prueba de existencia. Y el emplazamiento profundo no es una trampa, es justo el punto: es el único sitio que a la vez es inalcanzable para el gate (que muestrea juego aleatorio, superficial) y decisivo para el resultado (la partida se resuelve en la ronda final). Pon el error en cualquier sitio más superficial y el gate lo caza; ponlo en un sitio que no decida partidas y no cuesta nada. “Equivocada justo donde el gate no puede mirar y donde se gana la partida” es exactamente la esquina que la construcción tiene que acertar — y Beacon demuestra que esa esquina no está vacía.
Debajo hay un punto estructural limpio: un gate de precisión de transición es ciego por construcción a la función de creencias. Lo que un jugador puede y no puede ver nunca aparece en una transición “este estado pasó a ese estado” — así que ningún chequeo de transiciones puede cazar un modelo de creencias erróneo; necesitas un chequeo aparte sobre las creencias. (Estos resultados de información imperfecta usan juegos que instrumenté a mano para aislar el efecto, en vez de modelos totalmente sintetizados — una distinción que mantengo con cuidado en el paper.)
La mitad más esperanzadora de la historia es que ese chequeo aparte a menudo basta, y de forma demostrable. En el paper desarrollo una cota de cobertura: un inference gate aleatorio está garantizado que caza los errores de creencias en cuanto muestrea más de aproximadamente bᵈ partidas, donde b es cuántas opciones enfrenta un jugador en cada paso y d es cómo de profundo llegan las decisiones del juego. Los juegos superficiales superan ese listón con holgura — que es exactamente por qué el póker de Kuhn y Leduc no muestran brecha de creencias: su gate es demostrablemente suficiente. Para juegos demasiado grandes para enumerar, hay una cota compañera que limita el error no detectado que una función de creencias que pasa el gate puede esconder. Beacon es simplemente el caso diseñado para caer al lado malo de esa cota. Lo que sigue faltando — y lo que marcaría como trabajo futuro — es un chequeo de creencias adversarial que muestree deliberadamente la región profunda alcanzable por la habilidad, en vez de esperar a que el juego aleatorio se cuele ahí; ese es el chequeo que cerraría de verdad el hueco con forma de Beacon.
Lo que me llevo de esto
Una batería de tests que pasa — o un gate basado en muestreo — es un chequeo de resultado con un punto ciego de cobertura. Certifica el modelo justo donde caen tus muestras, y el comportamiento competente cae sistemáticamente en otra parte: las zonas raras, decisivas y profundas del espacio. Si verificas un modelo del mundo (o, francamente, cualquier modelo usado para planificar o decidir) por muestreo, mide la adecuación sobre la distribución en la que realmente se va a usar, no sobre una aleatoria cómoda. Y cuando la corrección depende de una regla, pon la regla en la especificación — no esperes que el sistema la infiera.
Si quieres la versión formal, con los teoremas y los números, está en el preprint. El código también es abierto.
Preprint: “When a Verified World Model Still Loses” (arXiv:2607.14169) · código. Lecturas relacionadas: Programación Orientada a Resultados y Software Disolviéndose en el Modelo.