← Volver al Blog

Un modelo del mundo puede pasar todos los tests y aun así perder

Un modelo del mundo puede pasar todos los tests y aun así perder

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 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.

0%50%100% Juego aleatorio 2.5% Juego competente ~50%
Con qué frecuencia la regla de material-al-tope decide realmente la partida. El gate muestrea juego aleatorio (2.5%); la partida se decide bajo juego competente (~50%). El gate mira donde la regla casi nunca importa.

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.

0.350.450.55 tasa de victoria vs el juego real Baseline justo 0.495 CWM ciego a la regla 0.404 brecha 0.091
El modelo ciego a la regla (rosa), que pasa el gate y es ≥98% preciso, pierde contra el baseline justo (índigo). Los intervalos al 95% no se solapan — el coste de juego de 0.091 no es un artefacto de muestreo.

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

dan˜o=play_cost×(1rareza)N\text{daño} = \text{play\_cost} \times (1 - \text{rareza})^N

donde rareza es cada cuánto una partida aleatoria dispara la regla omitida y NN cuántas partidas muestrea el gate. El factor (1rareza)N(1 - \text{rareza})^N es exacto — es simplemente la probabilidad de que NN 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.

0 5% 10% 15% rareza de la regla (fracción de partidas aleatorias que la disparan) 0.5 0 daño esperado nuestra regla (2.5%) daño ≈ coste de juego completo mientras la regla es demasiado rara para un gate de N
daño = play_cost × (1 − rareza)N, aquí con N = 40 muestras del gate. El daño se mantiene cerca del coste de juego completo mientras la regla es lo bastante rara para colarse por el gate, y luego se desploma cuando es lo bastante común para cazarla. Nuestra regla diseñada (rosa) cae de lleno en la zona peligrosa.

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.

región profunda — decide partidas competentes, nunca muestreada inicio
Lo que ve un gate de muestreo: las partidas aleatorias (índigo) acaban superficiales, por error. La región profunda donde vive el juego competente — y donde la regla rara decide la partida — casi nunca se alcanza, así que el gate nunca la prueba.

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.

✕ fin✕ fin ✕ fin✕ fin s0 s1 s2 s3 s4 s5 s6 ? decisión con info oculta El juego aleatorio se sale del camino en uno o dos pasos… …así que el gate nunca prueba s5–s6, donde se decide la partida.
Beacon: un testigo construido a mano donde la habilidad significa sobrevivir más profundo, no explorar más ancho. Un movimiento continúa; el equivocado acaba la partida. La decisión final depende de un dato oculto — así que una función de creencias equivocada solo en s6 pasa un gate de juego aleatorio y aun así pierde todas las partidas.

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.