A mediados de septiembre salió JEV, de TypeSafe AI: un modelo que no escribe. Le das un contexto y una pregunta con respuestas cerradas, y te devuelve una probabilidad por cada opción. Sin redacción, sin «como modelo de lenguaje…», sin JSON roto que parsear.
La idea es buenísima. El problema es el de siempre: tus datos viajan a una API alojada en EE. UU. Y aquí viene lo interesante… el LLM generalista que puedes tener en local ya lleva dentro casi todo lo necesario. Solo hay que saber leerlo.
En esta entrada os cuento cómo montarlo con LM Studio, las trampas que me encontré por el camino, cómo queda frente a JEV en sus propios benchmarks y dónde tiene sentido usarlo.
Un «System 1»: decidir rápido, no pensar mucho
JEV se vende como un modelo System 1: la decisión rápida e intuitiva, no el razonamiento largo. Todo se reduce a tres tipos de pregunta:
- noul: sí o no, con una probabilidad entre 0 y 1. «¿Este correo es una reclamación?»
- choice: una opción de una lista, con la probabilidad de cada una. «¿Pedido, oferta o consulta técnica?»
- score: un nivel en una escala, con su valor esperado. «Urgencia de 1 a 5.»
Lo valioso no es la respuesta, es el número que la acompaña. Con él decides qué hacer: confianza alta, lo hace la máquina; media, que alguien confirme; baja, a una persona. El umbral lo pone el riesgo de cada acción, no un número mágico.
Y una regla que ya os he contado alguna vez: las preguntas son atómicas y la composición se hace en código. Si hay que sumar, comparar fechas o aplicar una fórmula, eso no se le pregunta al modelo. El LLM no es una calculadora, y aquí tampoco.
No le pidas que conteste: mira lo que iba a contestar
Un LLM genera texto token a token. Antes de soltar cada token calcula una distribución de probabilidad sobre todo su vocabulario y luego elige uno. Esa distribución es justo lo que queremos.
El truco es sencillo: numeras las opciones con letras (A, B, C…) y le pides que responda solo con la letra. La probabilidad de cada letra en ese primer token es la probabilidad de cada opción. Una llamada, un token de salida y unos 0,5 segundos.
A eso se le llama leer los logprobs. No hace falta fine-tuning, ni un modelo especial, ni pagar a nadie. La confianza se calcula igual que en JEV:
confianza = (n · pmáx − 1) / (n − 1)
Donde n es el número de opciones: vale 0 si el modelo reparte por igual y 1 si lo tiene clarísimo.
¿Y entonces qué aporta JEV? Su modelo está entrenado para que esa probabilidad sea honesta (si dice 80 %, acierta el 80 % de las veces). Un generalista tiende a ser más chulo de la cuenta. Lo veremos más abajo, porque tiene arreglo y, para la mayoría de usos, ni siquiera hace falta arreglarlo.
La receta en LM Studio (y las trampas que muerden)
La llamada es esta. Fíjate en que va a /v1/responses, no al /chat/completions de toda la vida:
POST /v1/responses{ "model": "<tu modelo>", "input": [ {"role": "system", "content": "<criterio + opciones con letra>. Responde SOLO con la letra."}, {"role": "user", "content": "<el caso a decidir>"} ], "max_output_tokens": 1, "temperature": 0, "repeat_penalty": 1.0, "reasoning": {"effort": "none"}, "include": ["message.output_text.logprobs"], "top_logprobs": 20}
Parece trivial. No lo es. Estas son las cuatro trampas que me comieron horas:
- Sin
includeno hay logprobs, y nadie te avisa. El parámetro se acepta y se ignora en silencio. Yo llegué a concluir que LM Studio no los soportaba… y sí los soporta. - El
repeat_penaltypor defecto sesga la decisión. Castiga los tokens que ya aparecen en el prompt. Si el caso contiene una referencia tipo «16B-1», la opción B sale perjudicada. En una prueba llegó a cambiar la opción ganadora. Siemprerepeat_penalty: 1.0. - «B» y « B» son tokens distintos. Con espacio y sin espacio, y los dos aparecen entre los candidatos. Hay que sumarlos, no quedarse con uno.
- Razonamiento apagado. Si el modelo «piensa» antes de contestar, el primer token ya no es la letra. Para decidir,
reasoning: none.
Dos detalles más que marcan la diferencia:
- Lo fijo, primero. Las opciones van en el system y el caso en el user. Así la caché de prefijo reutiliza la parte común y la segunda pregunta sobre el mismo caso sale casi gratis.
- Vigila la fuga. Suma la probabilidad que cae en las letras válidas. Si queda lejos de 1, el modelo quería decir otra cosa: casi siempre la pregunta está mal planteada, no el modelo.
¿Y si el desplegable tiene 77 opciones?
El abecedario se acaba en la Z. Y en la vida real los desplegables tienen 50, 80 o 200 valores: familias de producto, motivos de incidencia, códigos de cliente…
La solución es darle a cada opción un código de letra + dígito (A0, A1… A9, B0…). Eso da hasta 260 opciones. En la familia Qwen los dígitos son siempre un token suelto, así que «C6» son dos tokens: «C» y «6». Y entonces aplica la regla de la cadena de toda la vida:
P(opción) = P(letra) × P(dígito | letra)
En la práctica:
- Primera llamada con
max_output_tokens: 2. Te da la distribución completa de la letra y la del dígito para la letra que el modelo eligió. - Para las demás letras con peso, una llamada más en la que tú escribes la letra como inicio de la respuesta del asistente (prefill). El modelo continúa desde ahí y te da el dígito.
- Paras cuando has cubierto el 99 % de la probabilidad o llevas cuatro letras.
Con la caché de prefijo, la media sale en unas 2 llamadas y medio segundo.
¿Y el código no despista al modelo? Lo medí con 18 opciones, que caben en letras, sobre los mismos 1.500 casos: 87,5 % con letras frente a 87,3 % con códigos. Ruido. El código no cuesta nada.
Una trampa más, para que no os pase: si fuerzas una letra muy improbable, a veces el modelo cierra el turno sin dar dígito y la respuesta llega sin logprobs. No es un error: trátalo como fuga y reparte esa probabilidad a partes iguales.
¿Funciona? Cara a cara con JEV
Sobre los mismos casos, el generalista local empata con JEV en acierto y calibra algo mejor. Lo probé con qwen3.8-flash-next, un MoE de 125.000 millones de parámetros con solo 6.000 millones activos por token, cuantizado y servido en LM Studio sobre una NVIDIA DGX Spark, con 128 GB de memoria unificada (un AMD Ryzen AI Max+ 395, el «Strix Halo», también llega a 128 GB; ahí no lo he probado). Sin fine-tuning y sin calibrar.
Lo bonito: el repo de OpenDecider publica las respuestas de JEV caso a caso. Así que la comparación es por pares y sin mandarle un solo dato a TypeSafe.
| Prueba (mismos casos para los dos) | Qué mide | JEV 1.13 | Generalista local |
|---|---|---|---|
| JevBench «original» (72 casos) | Decisiones tipadas variadas | 98,6 % | 98,6 % |
| BANKING77 (400 casos, 77 opciones) | Intención de un cliente de banca | 84,5 % | 83,5 % |
| Suite general de OpenDecider (200 decisiones) | Intención, sí/no, estrellas, ambigüedad | 73,0 % | 74,0 % |
| Calibración en BANKING77 (ECE, menos es mejor) | Si dice 80 %, ¿acierta el 80 %? | 0,075 | 0,056 |
Antes de que alguien lo saque en una reunión, los matices:
- Un punto arriba o abajo es ruido. Con 200 o 400 casos el margen ronda los ±3 puntos. Esto es un empate, no una victoria.
- Todo está en inglés. JEV no publica nada en español. En mis pruebas en español (59 intenciones de un asistente de voz, con etiquetas traducidas a máquina) el local acertó el 80 %, pero no hay contra qué compararlo.
- Donde pierde: fechas y números (6 de 15 en esa familia de JevBench) y reproducir la ambigüedad humana, donde modelos pequeños destilados como OpenDecider lo hacen mejor.
- Un denso de 27B también vale. Con qwen3.8-27b sale un 95,8 % en el mismo JevBench, algo por debajo pero en tarjetas de 24 GB.
¿Cuándo te puedes fiar del número?
El generalista, tal cual, es algo chulo: en una de mis pruebas declaraba de media un 82 % de seguridad y acertaba un 65 %. La corrección clásica es una temperatura: dividir las puntuaciones por un factor antes de convertirlas en probabilidades. Con eso el modelo baja los humos sin cambiar de opinión.
Lo que aprendí midiéndolo:
- Una temperatura ajustada para una tarea no sirve para otra. Llevada de un dataset a otro, el error de calibración pasó de 0,060 a 0,140. Justo lo contrario de lo que promete JEV.
- Una temperatura global moderada (en torno a 1,7) nunca empeoró nada en mis pruebas. Es un buen punto de partida.
- Para decidir, ni siquiera hace falta calibrar. Lo que necesita un filtro automático es que la confianza ordene: que lo seguro esté arriba y lo dudoso abajo. Y eso el modelo ya lo hace de serie.
En la práctica, el umbral se fija con tus datos: 150-200 casos revisados por alguien que sepa del tema. Un ejemplo de cómo se ve, con 59 opciones:
| Si solo aceptas lo que tenga confianza… | Se decide solo | Acierto en ese tramo |
|---|---|---|
| ≥ 0,5 | 94 % de los casos | 83 % |
| ≥ 0,8 | 76 % | 90 % |
| ≥ 0,9 | 66 % | 93 % |
El resto va a una persona. Y esa persona ahora revisa un tercio, no todo.
Dónde tiene sentido
Cualquier sitio donde hoy alguien lee algo y elige de una lista cerrada es candidato. Algunos casos:
- Triaje de correo o tickets. ¿Pedido, oferta, reclamación o consulta técnica? Y en paralelo un noul de urgencia. Los datos no salen de casa, que con correos de clientes no es un detalle menor.
- Rellenar desplegables. Asignar una familia de producto, un motivo de incidencia o un centro de coste de entre decenas de valores. Lo seguro entra solo; lo dudoso se le propone a una persona con las tres opciones más probables.
- Validar lo que extrae otro proceso. «¿El material que ha sacado el extractor aparece de verdad en la descripción?» Un noul por campo y solo se revisa lo dudoso. Truco: incluye siempre una opción «no consta», o el modelo se inventará una.
- Enrutar peticiones. A qué cola, a qué equipo o a qué agente va cada mensaje, en medio segundo y antes de gastar nada caro.
- Guardarraíles. ¿Intenta colar instrucciones? ¿Lleva datos personales? Preguntas de sí o no con un umbral estricto.
- Priorizar. Un score de 1 a 5 con su valor esperado ordena una cola mejor que un «alta/media/baja» a ojo.
Y un truco que viene de la propia documentación de JEV: si la confianza en la categoría fina es baja, sube un nivel. Suma las probabilidades de las hojas bajo cada padre y responde con el padre. «¿Qué tipo exacto de reclamación?» puede ser dudoso; «¿es una reclamación?» casi nunca. Ojo: si lo que necesitas de verdad es el padre, pregúntale directamente por el padre, que acierta algo más.
Cuándo no usarlo
Un decisor probabilístico es una herramienta, no una religión. No lo usaría:
- Si existe una regla. Si un código de artículo empieza por X y eso ya te dice la familia, un
ifacierta el 100 % y no cuesta nada. El modelo es para lo que la regla no cubre. - Para calcular. Fechas, importes, plazos, comparaciones numéricas: en código. Es justo donde más falla.
- Para razonar en varios pasos. Si la decisión exige encadenar argumentos, esto no es un System 1 y necesitas otra cosa.
- Sin medir con tus datos. Todos los benchmarks de arriba son en inglés y de terceros. Antes de automatizar nada, 150-200 casos tuyos revisados. Sin eso, el número es una opinión.
¿Y si no tengo hardware? Entonces JEV es muy buena opción: es rapidísimo y barato hasta lo ridículo (para cien decisiones al día salen céntimos al mes). La pregunta no es el dinero, es dónde viven tus datos. Si son de clientes o de personas, la respuesta suele estar clara.
La conclusión: el modelo ya sabía, solo había que preguntarle bien
No hace falta un modelo nuevo para tener decisiones con probabilidad. Hace falta dejar de pedirle al LLM que hable y leer lo que iba a decir. Una llamada, medio segundo, los datos en casa y, en sus propios benchmarks, a la par de JEV.
Lo difícil no es la técnica. Es tener casos propios revisados para saber dónde poner el umbral. Ese trabajo no te lo ahorra ningún modelo, ni local ni en la nube.
Espero que os sea útil, suscribiros para que os lleguen avisos de la próxima entrada y no dudéis en comentar o mandar un mensaje con cualquier consulta, aportación o inquietud que tengáis… … y si algo sale mal… La Culpa de Sistemas 😉
Fuentes: JEV / TypeSafe AI · JevBench · OpenDecider y sus resultados por caso · Documentación de LM Studio