Guarda la probabilidad, nunca el veredicto

Una decisión de diseño me ha rendido más que cualquier otra en los pequeños sistemas de IA que construyo: cuando un modelo toma una decisión, guarda la probabilidad, nunca el veredicto.
Suena a un detalle de base de datos. En realidad es una decisión sobre quién tiene derecho a cambiar de opinión más adelante, y cuánto cuesta eso.
El contexto
El ejemplo viene de un proyecto personal, un avatar de livestream que reacciona a lo que se dice. Cuando aparece una palabra nueva en la transcripción, el sistema tiene que decidir si esa palabra merece su propio sprite ilustrado. Generar un sprite es lento, cuesta una generación de imagen y tiene un tope por stream, así que la decisión importa.
La decisión la toma un pequeño modelo juez, Jev, de TypeSafe. No escribe nada. Responde a una sola pregunta, esta palabra merece un sprite, con una probabilidad entre 0 y 1. Una llamada usa unos 375 tokens de entrada y cuesta unos 0,000016 $ al precio público de 42 $ por mil millones de tokens de entrada.
El error tentador
La implementación obvia compara la probabilidad con un umbral, digamos 0,5, y guarda en caché el resultado: sí o no. La próxima vez que aparece la palabra, lees la caché y te saltas la llamada.
El problema aparece la primera vez que mueves el umbral. Y lo vas a mover, porque nadie acierta con el umbral correcto el primer día. En el momento en que lo haces, cada veredicto en caché queda mal de una forma que no puedes ver. Digamos que una palabra obtuvo 0,48: se guardó en caché como "no", y sigue siendo "no" después de bajar el umbral a 0,45. Para arreglarlo, tienes que volver a llamar al modelo para todo.
Un veredicto ata cada decisión al umbral del momento. Una probabilidad no.
Lo que ganas guardando la probabilidad
Mantengo un diario: una línea por decisión, con la palabra, la probabilidad y el contexto. El diario sobrevive a los reinicios, porque un umbral debería calibrarse sobre todo un stream, no sobre las últimas tres palabras.
Encima hay un deslizador. Lo mueves, y la interfaz resalta cada palabra que cambiaría, y en qué dirección, si el umbral estuviera ahí. No se llama a ningún modelo. Cuando el corte parece correcto, un botón escribe el nuevo umbral en la configuración en vivo, sin reiniciar.
Calibrar el umbral de un modelo pasó de "rehacerlo todo y esperar" a una breve revisión de decisiones reales.
La caché también resultó importar más de lo que esperaba. En ocho sesiones reales hubo 16.098 palabras candidatas, de las cuales solo 2.127 eran distintas. Eso es un 87 % de repetición. Cada llamada es casi gratis, pero el 87 % de ellas nunca necesita ocurrir, y las que no ocurren tampoco añaden latencia a un stream en vivo.
Dos lecciones relacionadas
La primera es que la confianza de un modelo no es su acierto. La capa de voz a texto que alimentaba este sistema a veces se quedaba en bucle con el silencio y producía la misma frase una y otra vez. Esas transcripciones en bucle tenían una confianza mediana más alta que el habla normal, 0,83 frente a 0,74. El modelo estaba más seguro de sí mismo justo cuando estaba atascado. Un umbral de confianza no puede detectar ese fallo; solo la forma de la transcripción puede.
La segunda es sobre los modos de fallo. Si el juez no está disponible, ¿qué debería hacer el filtro? Mi primera respuesta fue dejar pasar las palabras por defecto, para que el stream siga vivo. Pero cada palabra que pasa dispara una generación de imagen que no se puede deshacer y consume un tope de 50 por stream. Así que el filtro deja pasar durante un tiempo, y tras ocho fallos consecutivos se invierte y empieza a rechazar, con un error ruidoso en el registro. El repliegue correcto depende de qué error es reversible.
Más allá de un proyecto personal
La misma regla se aplica en cualquier lugar donde un modelo tome una decisión de sí o no dentro de un software: moderación de contenido, puntuación de leads, enrutamiento de tickets, señales de fraude, filtros de relevancia en retrieval. Guarda el número. Decide en el momento de la lectura. Registra el umbral vigente por separado, para poder explicar una decisión antigua sin confundirla con la regla actual.
Cuesta unos pocos bytes por decisión. A cambio, cada futuro cambio de opinión es gratis.
Fuentes
- Documentación de TypeSafe, "Models" (precios de Jev)
- Documentación de TypeSafe, "Noul" (la primitiva de probabilidad)
- Mis propias mediciones del proyecto, septiembre de 2026
