# No puedes hacer un test unitario a una tirada de dados

Los desarrolladores acoplan un LLM a un sistema, escriben un test normal de pasa/falla a su alrededor, lo ven fallar de forma intermitente, y entonces o borran el test o mockean el modelo hasta dejarlo sin sentido. Ambas cosas están mal. Un componente probabilístico no está roto cuando varía — pero 'varía' no es permiso para dejar de probarlo. Simplemente tienes que probar la distribución en lugar de la muestra: puntúa un conjunto dorado con tolerancia, condiciona el paso a una tasa de aciertos, afirma las invariantes que deben cumplirse siempre, y mantén una línea dura entre el núcleo estocástico y la cáscara determinista que lo rodea.

- **Author:** Fedor Chishchin
- **Published:** 2026-07-03
- **Tags:** methodology, eval
- **Source:** https://fedorthinks.com/es/blog/you-cant-unit-test-a-dice-roll

---

Aquí hay un error que he visto lanzar a ingenieros inteligentes una y otra vez. Conectan un LLM a una
funcionalidad y luego hacen lo responsable y escriben un test: entra la entrada, afirma que sale exactamente
la cadena esperada. Pasa en su máquina. Falla en CI. Vuelve a pasar en un reintento. Así que hacen una de dos
cosas — borrar el test, o mockear el modelo para que devuelva una respuesta enlatada — y ahora la parte del
sistema con más probabilidades de portarse mal es la única parte sin ningún test.

El error no es el test inestable. Es el marco. **Estás intentando hacer un test unitario a una tirada de
dados.**

## Afirmar sobre una sola ejecución es la herramienta equivocada

Un test unitario hace una pregunta de sí/no sobre una función determinista: dado `x`, ¿obtengo exactamente
`y`? Esa es la pregunta correcta para un parser y una pregunta sin sentido para un modelo, al que se le permite
— por diseño — decir lo mismo cierto de cinco maneras distintas. Ejecútalo suficientes veces y el mismo prompt
te da una distribución, no un valor. Afirmar sobre una sola extracción de esa distribución no te dice casi
nada; solo mueve la moneda al aire a tu pipeline de CI.

Por esto los números de productividad en programación con IA son tan turbios. Los individuos se sienten
rápidos, pero [se midió a desarrolladores experimentados _más lentos_ en tareas reales](https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/),
y los equipos ven [más pull requests pero revisiones más largas y una rotación creciente](https://arxiv.org/pdf/2601.18341).
Buena parte de eso es gente intentando validar salidas no deterministas con hábitos deterministas, una
afirmación frágil a la vez, y ahogándose.

> "No es determinista" es una afirmación cierta sobre el modelo y una excusa perezosa sobre el sistema. No
> puedes fijar el dado. Sí puedes acotar por completo cómo se le permite caer.

## Prueba la distribución, no la muestra

La jugada es dejar de probar una única respuesta correcta y empezar a probar la forma del comportamiento:

- **Puntúa un conjunto dorado, no compares una cadena.** Guarda 30–100 pares reales de entrada/salida y
  califica las nuevas ejecuciones por similitud, una rúbrica o un modelo-como-juez — no por igualdad exacta.
  Estás midiendo calidad, que tiene un rango, no identidad, que no lo tiene.
- **Condiciona el paso a una tasa de aciertos, no a un solo verde.** Ejecuta el caso _N_ veces y exige, por
  ejemplo, un 95% de aciertos. Un fallo de cada veinte no es un build roto — es el dado comportándose como un
  dado. Una tasa de aciertos que cruza una línea _sí_ es una regresión que puedes detectar.
- **Afirma las invariantes que deben cumplirse absolutamente siempre.** El contenido varía; el contrato no
  debe. Siempre JSON válido. Nunca filtra los datos de otro usuario. Siempre dentro del presupuesto de tokens.
  Rechaza los tres prompts que debe rechazar. Esos _sí_ son deterministas, y los pruebas como cualquier otra
  cosa.
- **Separa el núcleo estocástico de la cáscara determinista.** El enrutamiento, el parsing, la validación, los
  reintentos y los fallbacks alrededor del modelo son código ordinario — hazles tests unitarios a fondo, con el
  modelo mockeado. Reserva las pruebas probabilísticas para la única frontera que de verdad es probabilística.

## En resumen

El no-determinismo no es una razón para saltarse las pruebas — es una razón para probar de otra manera. Un
modelo que no puedes fijar es exactamente la parte de tu sistema que más necesita una correa medida, porque
["normalmente funciona" es cómo se siente el software poco fiable desde dentro justo hasta que deja de hacerlo](/es/blog/smarter-but-not-more-reliable).

**Deja de afirmar sobre una tirada afortunada. Califica un conjunto dorado con tolerancia, condiciona el paso a
una tasa de aciertos, blinda las invariantes y hazle tests unitarios a la cáscara determinista como si tu vida
dependiera de ello — porque en producción, esa cáscara es lo que sostiene los dados.**
