Inicio / Artículos

Modelos de decisión basados en texto frente a llamadas a LLM: latencia y estabilidad en el límite

Un experimento de 240 llamadas que compara las probabilidades nativas de Jev con las autoinformadas por un LLM, y cómo convertir esa señal en un router de modelos LangChain.

Editor: REACTAPP.TOP12 min de lectura2657 palabras

Fuentes: **Does Every AI Decision Need an LLM? Testing Jev with LangChain**

El código de los agentes modernos está repleto de pequeñas decisiones de tipo sí o no: ¿es este ticket urgente?, ¿la llamada a esta herramienta se ajusta a la solicitud?, ¿vale la pena recuperar este fragmento? La costumbre habitual es responder a cada una de ellas con otra llamada a un modelo LLM generativo y analizar la respuesta estructurada, lo cual funciona pero consume segundos por paso y genera números de significado incierto. Esta guía ejecuta la misma decisión limitada a través de un modelo de toma de decisiones diseñado específicamente y mediante un LLM general, un total de 240 veces, y luego conecta la probabilidad resultante a un enrutador de LangChain. Al final, sabrá cómo medir de manera justa dicha comparación, cuáles son las diferencias en latencia y estabilidad, y cómo mantener la política de enrutamiento en código puro en lugar de dentro de un prompt.

Las decisiones limitadas no son tareas de generación

Mire las decisiones que se encuentran en una aplicación típica de LLM y muchas de ellas no tienen realmente que ver con la generación de lenguaje:

  • ¿Debería este ticket de soporte considerarse urgente?
  • ¿El nombre del herramienta propuesta coincide realmente con lo que solicitó el usuario?
  • ¿Un documento cumple con una condición específica?
  • ¿El fragmento recuperado es lo suficientemente relevante como para incluirlo en el contexto?

La implementación habitual pasa el estado actual a un LLM, solicita una respuesta estructurada y convierte esa respuesta en un ramal en el código. En principio, no hay nada de malo en eso. La pregunta abierta es si cada uno de estos puntos de ramificación merece un modelo autoregresivo completo.

Jev es el primer modelo de TypeSafe AI dentro de lo que la empresa denomina su línea “System One”, y adopta un enfoque opuesto: nunca genera texto libre. Se le proporciona un estado determinado junto con un conjunto de preguntas restringidas, y él responde con decisiones tipadas y probabilidades. El proveedor lo presenta como un elemento básico para el desarrollo de software, no como sustituto de un modelo de chat o de razonamiento. LangChain ha publicado una integración que utiliza a Jev dentro de herramientas para agentes, con funciones como seleccionar un modelo y verificar las llamadas a herramientas. Ambos productos eran novedosos en el momento de redactar este texto, por lo que es necesario confirmar las API actuales antes de utilizarlos. Si su interés principal radica en el aspecto económico de este modelo, el artículo sobre el cálculo de costos para un enrutador de decisiones tipadas frente a llamadas a LLMs de vanguardia aborda ese tema; aquí, en cambio, el foco está en el comportamiento y la latencia.

Diseño de la comparación

A ambos sistemas se les planteó exactamente una pregunta a responder, que se puede reformular así: ¿la solicitud requiere un razonamiento real de múltiples pasos, o se trata de algo más simple, como una búsqueda directa, la obtención de un valor, un cálculo básico, una reescritura o una pequeña edición local?

El conjunto de instrucciones se inclinó intencionadamente hacia casos ambiguos. Los extremos obvios no aportan mucha información; el comportamiento interesante de un enrutador se encuentra cerca del punto en el que “solo responde” se convierte en “piensa bien la respuesta”. Se utilizaron ocho solicitudes de desarrolladores:

  1. Búsqueda en diccionario: por qué buscar una clave en un dict de Python suele ser O(1).
  2. Lista vs conjunto: cuál de estas dos estructuras es adecuada para una colección de IDs de usuario únicos.

  • Diseño de API REST: una revisión del endpoint POST /users/{id}/delete y si existe una forma más limpia de implementar REST.
  • Redis vs PostgreSQL: si se debería reemplazar la caché actual de Redis por PostgreSQL.
  • Python asíncrono: si trasladar un scraper web a modo asíncrono sería útil.
  • Cola de tareas vs pub/sub: cuál de los dos métodos utilizar para los mensajes de notificación de pedidos.
  • Indexación SQL: revisión de una consulta para determinar si un índice podría acelerarla.
  • Microservicios vs monolito: si un servicio en Python debería dividirse en microservicios o mantenerse como un todo.
  • Cada pregunta se ejecutó diez veces en cada una de tres configuraciones:

    • Jev, solicitado a través de un Noul que devuelve la probabilidad de que la solicitud requiera un razonamiento extenso.
  • GPT-5.6 Sol con una probabilidad, solicitado a través de LangChain con salida estructurada y que debe devolver un valor booleano además de una probabilidad autoinformada.
  • GPT-5.6 Sol, solo binario: se utiliza el mismo modelo pero solo se exigen valores True o False, sin ninguna mención a nivel de confianza.
  • El presupuesto de llamadas funciona de la siguiente manera.

    8 prompts
    × 10 repetitions
    × 3 conditions
    = 240 calls
    

    Cada llamada registraba su decisión, su probabilidad cuando existía, el nombre del modelo y la latencia de ida y vuelta. Es importante aclarar qué no intenta hacer el experimento: no existe una etiqueta de verdad objetiva que indique cuánto razonamiento necesita “realmente” una solicitud determinada, por lo que la corrección queda descartada. En su lugar, el estudio se centra en tres preguntas más específicas:

    1. ¿El modelo de toma de decisiones y el modelo generativo llegan a juicios similares sobre la ruta a seguir?
  • ¿Qué tan consistente es cada uno cuando se repite la misma solicitud?
  • ¿Cuál es el costo semántico en términos de latencia cuando lo realiza un modelo especializado frente a uno generativo?
  • Los hallazgos más importantes provinieron de las solicitudes en los límites, no de las claramente complejas.

    Tres implementaciones de una misma decisión

    Todos los tres sistemas se desarrollaron en Python con LangChain.

    Jev con un único Noul

    Un Noul modela una proposición binaria, pero en lugar de determinar directamente si es Verdadero o Falso, devuelve una probabilidad. Jev recibió la solicitud del desarrollador como su estado y un Noul que contenía la pregunta. En resumen, la definición de la pregunta es la siguiente:

    Noul(
        instructions="""
        Does this request require substantial multi-step reasoning
        rather than a direct lookup, extraction, simple calculation,
        rewriting task, or small localized edit?
        """
    )
    

    La respuesta es simplemente un número, por ejemplo:

    0.86
    

    Ese valor representa la probabilidad de que la afirmación sea cierta:

    P(requires substantial reasoning) = 0.86
    

    Para comparar Jev con la configuración binaria del LLM, una probabilidad de 0.5 o más se considera verdadera.

    GPT-5.6 Sol informando su propia probabilidad

    La línea de base generativa utilizó ChatOpenAI a través de LangChain, con un modelo Pydantic que restringe la forma del resultado. Los límites Field(ge=0.0, le=1.0) aseguran que el número esté al menos dentro del rango; no indican si ese valor tiene sentido o no.

    class ReasoningProbability(BaseModel):
        requires_reasoning: bool
        probability: float = Field(ge=0.0, le=1.0)
    

    Aquí el modelo tuvo que proporcionar tanto un veredicto como una estimación de cuán probable era un “sí”. Esa distinción merece atención. La salida de Jev es precisamente lo que fue diseñado el modelo para generar. El número del LLM es texto que genera porque el esquema exige un valor flotante, y no hay garantía de que refleje alguna probabilidad interna. Tratar ambos números como el mismo tipo de cantidad es una suposición, no un hecho establecido.

    GPT-5.6 Sol forzado a un valor booleano

    La tercera configuración eliminó toda referencia a la probabilidad y solicitó al mismo modelo un único campo:

    class ReasoningBinary(BaseModel):
        requires_reasoning: bool
    

    Esto deja tres señales distintas: una probabilidad nativa y dos variantes generativas.

    Jev
        → native probabilistic decision
    
    GPT-5.6 Sol
        → generated probability + decisionGPT-5.6 Sol
        → forced binary decision
    

    Lo que mostraron las 240 llamadas

    Surgieron tres patrones:

    1. Jev llegó a la decisión definida mucho más rápido.
    2. En las solicitudes que claramente requerían razonamiento, los sistemas en su mayoría estuvieron de acuerdo; divergieron cerca del límite.
    3. En una prompt en el límite, la probabilidad autoinformada del LLM varió ampliamente entre llamadas idénticas.

    Latencia: decenas de milisegundos frente a segundos

    Midiéndose como tiempo medio de ida y vuelta, Jev respondió en 128.8 ms por decisión. GPT-5.6 Sol tardó 2,828.1 ms al devolver una probabilidad y 4,072.1 ms en el modo con solo valores binarios. Eso representa aproximadamente 22 veces más lentitud en la variante con probabilidad y 32 veces más lentitud en la variante booleana.

    Considere esas cifras como una instantánea y no como un punto de referencia. La latencia de las APIs alojadas varía según la carga del proveedor, la versión del modelo, la región y la ruta de red. Lo importante es el orden de magnitud: cuando se trata de una decisión concreta, utilizar un modelo generativo general implica activar mucha más capacidad de la necesaria para resolver esa pregunta.

    El resultado que solo incluye datos binarios es una curiosidad digna de mención. Solicitar menos campos de salida no hizo que la llamada fuera más rápida; de hecho, fue más lenta. Un solo ensayo no puede explicar por qué, pero sirve como recordatorio de que la latencia total de los LLM está determinada por factores distintos al número de tokens de salida visibles, como la cola de espera, el relleno previo y cualquier razonamiento oculto que realice el modelo antes de responder.

    Acordo en los casos extremos, divergencia en los límites

    En las solicitudes claramente complejas, con el reemplazo de Redis y la distribución en microservicios, los dos sistemas estuvieron de acuerdo y evaluaron alta la necesidad de razonamiento. La brecha apareció en las solicitudes que parecían más sencillas. Para búsquedas en diccionario, cuestiones relacionadas con listas versus conjuntos y diseño REST, GPT-5.6 Sol reportó probabilidades cercanas a cero, mientras que Jev las situó notablemente más cerca del centro del rango.

    La revisión de REST fue el ejemplo más claro:

    La solicitud pide una crítica de POST /users/{id}/delete y una alternativa más adecuada según los principios RESTful.

    La probabilidad promedio de Jev fue 0.551, ligeramente por encima del umbral de 0.5. La media de GPT-5.6 Sol fue 0.071. Esto no se debió a ruido que rozara el umbral: en las diez pruebas realizadas, Jev clasificó la solicitud como de alto nivel de razonamiento, mientras que en las diez pruebas con ambos modelos, Sol la clasificó como tal.

    Eso no significa que Jev tenga razón. Sin una verdad de referencia etiquetada, no se puede determinar cuál juicio es mejor. Lo que sí se demuestra es que las dos señales no son intercambiables, y que difieren precisamente en la zona donde un router es más sensible a cómo se define su límite. Si reemplazas una fuente de decisión por otra, espera que la ruta tomada cambie exactamente en las solicitudes sobre las cuales tengas menos certeza.

    Dos números entre cero y uno que se comportan de manera diferente

    Al repetir cada solicitud diez veces, se hizo visible la estabilidad. La mayoría de las solicitudes generaron resultados bastante consistentes en ambos sistemas. La excepción fue la petición de elegir entre un sistema de cola y uno de pub/sub para las notificaciones de pedidos.

    En diez llamadas idénticas, la probabilidad autoinformada de GPT-5.6 Sol osciló entre aproximadamente 0.28 y 0.90, mientras que los valores de Jev se mantuvieron muy concentrados. La configuración de LLM binario respondió True en nueve de las diez pruebas, por lo que los veredictos fueron bastante estables, aunque la confianza declarada no lo fuera.

    La explicación es estructural. Ambos sistemas emiten un valor que se puede expresar en el rango [0, 1], pero los procesos detrás de ellos difieren. En el caso de Jev, la probabilidad es la salida nativa del modelo para una decisión acotada. En el caso del LLM, se trata de una secuencia de tokens generada porque la solicitud pedía una estimación, y el muestreo puede arrojar números bastante diferentes en cada ejecución. En esta tarea, la probabilidad autoinformada por un LLM no se comportó de manera fiable como la salida de un modelo diseñado para decisiones probabilísticas. Si planea utilizar tal número como umbral, mida su varianza en llamadas repetidas antes de confiar en él.

    Convierte la probabilidad en un router de LangChain

    Esa comparación motivó una prueba práctica: utilizar la probabilidad de Jev para enrutar solicitudes reales entre dos modelos de OpenAI.

    • GPT-5.6 Luna maneja las solicitudes que, según se considera, no requieren un razonamiento extenso.
  • GPT-5.6 Sol se encarga de aquellos casos que se consideran necesitados de él.
  • Jev nunca elige un modelo directamente. Responde a la misma pregunta Noul del experimento, determinando si la solicitud requiere un razonamiento multietapa sustancial, y devuelve una probabilidad como 0.54, que se interpreta como P(requiere razonamiento sustancial) = 0.54.

    Luego, el código de la aplicación compara ese valor con umbral definido en Python estándar:

    REASONING_THRESHOLD = 0.65
    

    La estructura en sí es igualmente sencilla:

    if reasoning_probability >= REASONING_THRESHOLD:
        model = powerful_model
    else:
        model = fast_model
    

    El punto clave es la división del trabajo. Jev proporciona la probabilidad; la aplicación decide qué hacer con ella. Con un umbral de 0.65, una puntuación de 0.54 dirige la solicitud a Luna y una puntuación de 0.86 la dirige a Sol. La política es explícita, determinista y puede revisarse mediante un diff de código, mientras que el juicio semántico queda en manos del modelo.

    El flujo completo se ve así:

    User request
         ↓
        Jev
         ↓
    P(requires substantial reasoning)
         ↓
    Python threshold = 0.65
       ↙                  ↘
    Luna                  Sol
    

    Una nota sobre ese umbral: 0.65 es meramente ilustrativo y no ha sido ajustado. Se eligió únicamente para que, en una demostración sencilla, las solicitudes obviamente simples terminaran en un lado y las preguntas relacionadas con el diseño y la arquitectura, que obtenían puntuaciones más altas, en el otro. En entornos de producción se elegiría este valor empíricamente, basándose en un conjunto más grande y etiquetado, teniendo en cuenta dos tipos diferentes de errores: el costo de utilizar un modelo costoso para una solicitud sencilla y el envío de una solicitud realmente compleja a uno menos potente. Estos costos rara vez son simétricos, por lo que el mejor umbral rara vez es 0.5.

    Cómo se comportó el enrutador

    Se procesaron seis solicitudes a través del enrutador, desde un cálculo simple hasta un problema de arquitectura multi-región. La mayoría de los resultados coincidieron con la intuición. Las tareas de cálculo y reescritura obtuvieron puntuaciones muy bajas y fueron dirigidas a Luna; las preguntas de arquitectura más complejas obtuvieron puntuaciones altas y fueron enviadas a Sol.

    Los casos informativos estuvieron en el medio:

    • la explicación basada en la búsqueda en diccionario obtuvo una puntuación de 0.46
    • la revisión de la API REST obtuvo una puntuación de 0.54
    • la pregunta sobre cola versus pub/sub obtuvo una puntuación de 0.86

    Dado que Jev devuelve una puntuación continua en lugar de una etiqueta fija de easy o hard, el grado de agresividad en la asignación de tareas se convierte en una decisión separada y ajustable. Con un valor de 0.65, la revisión de REST fue asignada a Luna y la pregunta sobre cola versus pub/sub a Sol. Aumentar el umbral enviaría menos solicitudes al modelo más grande y ahorraría costos; disminuirlo reduciría la posibilidad de no atender adecuadamente una solicitud compleja. El juicio del modelo no cambia al ajustar este umbral, lo que significa que se puede afinar la política, incluso de forma dinámica, sin tener que volver a formular las preguntas.

    Límites de este experimento

    Mantenga las afirmaciones en proporción:

    • Ocho pruebas no pueden caracterizar a ninguno de los modelos en general, y la propia pregunta de etiquetado es subjetiva.
    • No se midieron la precisión ni la calibración. La prueba compara el comportamiento, la consistencia y la latencia, no la corrección.
    • No se debe asumir que las probabilidades de Jev y los valores autoinformados del LLM tengan un significado estadístico común.
    • Las cifras de latencia dependen del proveedor y de las condiciones en el momento de la prueba.

    Un estudio más exhaustivo utilizaría un conjunto de datos etiquetado más grande y evaluaría el enrutador de extremo a extremo: precisión del enrutamiento, calibración, calidad de las respuestas finales, costo y sensibilidad a diferentes umbrales.

    Cuándo vale la pena usar un modelo de decisión separado

    Para una aplicación pequeña, dejar que un LLM se encargue del enrutamiento suele ser perfectamente adecuado; una llamada adicional rara vez tiene importancia. La situación cambia cuando un agente acumula pasos de enrutamiento, recuperación de información, validación y verificación de herramientas. Muchos de estos pasos son juicios con límites definidos, y si cada uno se convierte en otra llamada generativa de varios segundos, el ciclo del agente se vuelve lento y costoso por razones no relacionadas con el trabajo real.

    Una separación clara de responsabilidades sería la siguiente:

    • Un modelo de toma de decisiones se encarga de los juicios semánticos con límites definidos y devuelve una probabilidad.
    • El código de la aplicación gestiona los umbrales, las políticas y las ramificaciones.
    • El LLM se ocupa del razonamiento y la redacción abiertos.

    Un LLM capaz podría manejar cada uno de estos casos, pero eso no obliga a todas las partes del sistema a utilizar el mismo tipo de modelo, especialmente cuando la latencia es importante. La justificación general para adaptar el tamaño de los modelos a la tarea se explica en el artículo sobre cómo ajustar adecuadamente los LLMs con funciones de enrutamiento, recuperación y evaluación.

    Puntos clave

    • En esta prueba, el modelo de toma de decisiones tuvo un promedio de unos 129 ms por juicio, frente a varios segundos en los sistemas generativos.
    • Con entradas casi ambiguas, los dos sistemas discrepaban de manera consistente y no al azar; por lo tanto, reemplazar una señal por la otra cambiará el enrutamiento en los puntos más sensibles.
    • La probabilidad autoinformada de un LLM puede variar ampliamente en llamadas idénticas (aproximadamente de 0.28 a 0.90 en una misma solicitud); es necesario verificar su variabilidad antes de establecer umbrales.
  • Mantenga el umbral en el código, elija valores a partir de datos etiquetados y del costo asimétrico de cada error, y trate un modelo de decisión especializado como un complemento al LLM, no como una imitación más rápida de este.