Cómo llamar a Jev en AiHubMix: un tutorial de clasificación estructurada

AIHubMix5 min de lectura
Cómo llamar a Jev en AiHubMix: un tutorial de clasificación estructurada

Respuesta corta: jev-1.13 no genera texto. Envías un fragmento de texto junto con un conjunto de preguntas con nombre a https://aihubmix.com/v1/systemone y recibes respuestas tipadas indexadas por los nombres de tus preguntas: una categoría, una puntuación o una probabilidad. No hay nada que analizar. A continuación encontrarás una solicitud funcional, el formato completo de la respuesta y el error de diseño que reducirá tu precisión sin que lo notes.

Para qué sirve Jev

Úsalo cuando necesites un juicio, no un párrafo: enrutar un ticket de soporte, puntuar la gravedad, marcar la urgencia o filtrar contenido. La página del modelo lo indica claramente: «Sin generación de texto, nada que analizar».

Usa en cambio un modelo de chat normal cuando necesites explicaciones, resúmenes o cualquier salida de formato libre. Jev no puede producir nada de eso.

Antes de empezar

  • [ ] Python 3 instalado (la biblioteca estándar es suficiente)
  • [ ] Una cuenta de AiHubMix y una clave de API
  • [ ] Clave exportada como AIHUBMIX_API_KEY, nunca escrita directamente en el código fuente

 No necesitas el SDK de OpenAI, LangChain ni el paquete requests.

Paso 1: conoce el endpoint

POST https://aihubmix.com/v1/systemone
Authorization: Bearer YOUR_KEY
Content-Type: application/json

Es una ruta específica del modelo, no /v1/chat/completions. Los clientes compatibles con OpenAI no pueden llamarla. Usa HTTP sin más.

Paso 2: elige los tipos de pregunta

Hay tres, y puedes combinarlos libremente en una misma solicitud:

TipoÚsalo paraLo que proporcionas
choiceElegir una categoríacriteria como diccionario: etiqueta → definición
scoreCalificación en una escala ordenadacriteria como lista, del valor más bajo al más alto
noulUn juicio de sí o nonada más que instructions

Paso 3: construye la solicitud

state es el texto que se va a juzgar. Las claves de questions son nombres que tú inventas; la respuesta usa los mismos nombres.

payload = {
    "model": "jev-1.13",
    "state": "Hi, I have been trying to connect my Stripe account for 3 days "
             "and it keeps failing. I am losing sales. Please help ASAP.",
    "questions": {
        "department": {
            "type": "choice",
            "instructions": "Which team should handle this",
            "criteria": {
                "billing":   "Payment or subscription issues",
                "technical": "Bugs or integration problems",
                "sales":     "Pricing or account questions",
            },
        },
        "frustration": {
            "type": "score",
            "instructions": "How frustrated the customer appears",
            "criteria": [
                "Calm, just stating facts",
                "Frustrated but civil",
                "Very angry, strong language",
            ],
        },
        "is_urgent": {
            "type": "noul",
            "instructions": "The message conveys urgency or time-sensitivity",
        },
    },
}

Paso 4: envíala con la biblioteca estándar

import json, os, urllib.error, urllib.request

def ask(payload):
    req = urllib.request.Request(
        "https://aihubmix.com/v1/systemone",
        data=json.dumps(payload).encode(),
        headers={"Authorization": "Bearer " + os.environ["AIHUBMIX_API_KEY"],
                 "Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as r:
            return json.loads(r.read())
    except urllib.error.HTTPError as e:
        raise SystemExit(f"HTTP {e.code}: {e.read().decode(errors='replace')[:500]}")

Mantén la construcción de la solicitud dentro de una función. Si construyes y envías a nivel de módulo, al importar el archivo se volverá a ejecutar la llamada y se gastarán tokens.

Paso 5: lee las respuestas

Cada respuesta guarda su valor bajo una clave que coincide con su type, así que un solo accesor sirve para los tres:

data = ask(payload)
for name, ans in data["answers"].items():
    kind = ans["type"]
    print(name, kind, ans[kind], ans.get("confidence"))
print("usage:", data.get("usage"))

Salida verificada:

department   choice  billing   0.51
frustration  score   1         1
is_urgent    noul    1         None
usage: {'input_tokens': 424, 'output_tokens': 73}

Paso 6: entiende la estructura completa de la respuesta

El bucle de impresión oculta campos útiles. El JSON sin procesar de una respuesta de tipo score:

{
  "type": "score",
  "score": 1,
  "legend": {"0": "Calm, just stating facts", "1": "Frustrated but civil", "2": "Very angry, strong language"},
  "probabilities": {"0": 0, "1": 1, "2": 0},
  "confidence": 1
}
  • legend asigna el índice de vuelta a tu propia redacción: el entero se explica por sí mismo, así que no necesitas una tabla de búsqueda en tu código.
  • probabilities ofrece la distribución completa, útil para detectar un empate muy cercano.
  • noul no tiene campo confidence. Su probabilidad es la señal.

El nivel superior también devuelve usage, id, provider (TypeSafe) y la versión resuelta del backend typesafe/jev-1.13-20260917.

El error que reduce tu precisión

En la solicitud anterior, department devolvió billing con una confianza de 0.51. Al repetir exactamente la misma solicitud, la etiqueta fue la misma, con 0.38: la respuesta fue estable, pero la certeza declarada no.

La causa está en los criterios, no en el modelo. billing es «Problemas de pago o de suscripción» y technical es «Errores o problemas de integración». Una integración de Stripe que sigue fallando encaja de verdad con ambas. El modelo estaba informando de una ambigüedad que estaba escrita en el esquema.

Dos reglas antes de pasar a producción:

  1. Escribe criterios de tipo choice que sean mutuamente excluyentes. Si una persona dudaría entre dos etiquetas, el modelo también dudará.
  2. Define un umbral de confianza y envía los resultados de baja confianza a una cola de revisión humana en lugar de aceptarlos como decisiones. Un modelo que admite su incertidumbre vale más que uno que la oculta.

Lista de verificación antes del lanzamiento

  • [ ] Clave cargada desde el entorno o desde un archivo 600 que tu VCS ignora
  • [ ] Criterios choice revisados para detectar solapamientos
  • [ ] Umbral de confianza definido, con una ruta alternativa por debajo de él
  • [ ] Respuestas noul tratadas por separado, ya que no incluyen confidence
  • [ ] Preguntas no utilizadas eliminadas (3 preguntas cuestan 424 tokens de entrada; 2 cuestan 355)
  • [ ] Respuestas no 2xx registradas con el cuerpo sin procesar

Preguntas frecuentes

¿Puedo usar el SDK de OpenAI? No. /v1/systemone no es una ruta compatible con OpenAI.

¿Jev puede devolver una frase o un resumen? No. Solo responde las preguntas tipadas que defines.

¿Cuántas preguntas por solicitud? Las pruebas verificadas usaron dos y tres. Cada pregunta añade tokens de entrada y de salida, así que incluye solo las que vayas a utilizar.

¿Existe un alias de versión? La página del modelo enumera un alias jev-latest junto a jev-1.13. Fija la versión explícita si la reproducibilidad es importante.

¿Cuánto cuesta? La página del modelo publica $0.0462 / M tokens de entrada y $0 / M tokens de salida. Son cifras del proveedor: confirma el precio vigente antes de presupuestar.

¿Cuál es la ventana de contexto? La página del modelo es inconsistente: 64K en su encabezado y 32K en la tabla del proveedor. Verifícalo con tu entrada más larga antes de confiar en cualquiera de los dos.

Alcance de esta guía

Todo lo anterior se verificó con tres llamadas reales sobre una sola entrada. No cubre latencia, procesamiento por lotes, rendimiento ni el comportamiento con entradas distintas al ejemplo. La deriva de confianza es una observación reproducida, no una tasa de error medida: repítela con tus propios datos antes de fijar un umbral.

Empieza en AiHubMix

jev-1.13 está disponible a través de AiHubMix, y la página del modelo incluye todo lo que menciona este tutorial: el endpoint /v1/systemone, los tres tipos de pregunta con sus formatos de criteria, los campos completos de la respuesta y el precio publicado de $0.0462 / M tokens de entrada con $0 / M tokens de salida. El alias jev-latest apunta a la versión más reciente, así que se mantiene actualizado a medida que cambian las versiones.

Empieza aquí: https://aihubmix.com/model/jev-latest

Próximos pasos:

  1. Crea una cuenta de AiHubMix y genera una clave de API
  2. Copia la solicitud del Paso 3 y la función ask() del Paso 4
  3. Sustituye state por un registro real de tu propia cola
  4. Compara el resultado con la forma en que clasificas ese registro hoy

Si esta guía te ha resultado útil, suscríbete para recibir futuras publicaciones sobre modelos de salida estructurada y pipelines de clasificación.

Un solo gateway para varios proveedores de IA. Diseñado para producción.

Visitar AIHubMix