Ir al contenido
tendencias

Guías

Enrutamiento de tickets con IA: modelo decisional en Python

Aprende a clasificar y enrutar incidencias con el modelo Strands Decider 2B en local, con umbrales de confianza y derivación automática a agentes humanos.

Texto: 9 min de lectura
Enrutamiento de tickets con IA: modelo decisional en Python

👁 113 lecturas

Un modelo decisional encaja mejor en el enrutamiento de incidencias que un modelo de chat conversacional: asigna directamente el departamento adecuado de tu lista, devuelve un índice de confianza y te permite remitir casos dudosos a un agente humano de forma automática. A continuación te mostramos un script funcional en Python con el modelo abierto Strands Decider 2B que probamos en local, junto con sus métricas y dos errores habituales que detectamos durante las pruebas. Explicamos qué son estos modelos y cómo rinden en nuestra guía sobre modelos decisionales de IA.

Las cantidades en EUR son conversiones orientativas de los precios publicados en USD, calculadas con el tipo de referencia del BCE del 2026-10-12: 1 EUR = 1.1181 USD. No son precios locales confirmados ni importes finales con impuestos. El proveedor y el banco pueden aplicar otros tipos o cargos. ECB.

Cómo funciona este flujo

El script procesa cada incidencia y devuelve cuatro datos clave:

  • departamento: uno de los 6 definidos (pagos, envíos, devoluciones, cuenta, incidencias técnicas, ventas) o bien «otros»,
  • confianza: la certeza de la elección, valorada entre 0 y 1,
  • cola de destino: el departamento correspondiente si la certeza supera el corte, o a_humano si no lo alcanza,
  • urgencia: si la incidencia requiere respuesta inmediata durante el día.

La salida genera una línea JSON por cada consulta, ideal para integrarla en herramientas de helpdesk, hojas de cálculo o flujos de automatización con IA.

Requisitos previos

  • Python 3.10 o superior.
  • PyTorch: preferiblemente compilado con soporte CUDA si dispones de una tarjeta NVIDIA (el modelo consume algo menos de 4 GB de VRAM). También funciona en CPU, aunque con menor velocidad.
  • La librería strands-decider (licencia Apache-2.0). Durante el primer inicio descargará unos 4,4 GB: el modelo base Qwen3.5-2B-Base junto con el adaptador desarrollado por AWS.
pip install strands-decider

En entornos Windows, el instalador pip a veces sustituye PyTorch por una variante sin soporte CUDA. Puedes comprobarlo ejecutando python -c "import torch; print(torch.cuda.is_available())" en tu terminal; si el resultado es False, reinstala PyTorch seleccionando tu versión de CUDA desde el índice oficial de pytorch.org. Nos ocurrió exactamente esto durante las pruebas en nuestro equipo.

Script routing.py

# Enrutamiento de tickets con el modelo decisional Strands Decider 2B (en local, Apache-2.0).
# pip install strands-decider   (ademas de PyTorch con CUDA si utilizas GPU NVIDIA)
import json, sys
from strands_decider.infer import load_engine
from strands_decider.schema import SystemOneRequest

MODEL = "StrandsAgents/strands-decider-2B-hobson-v19"
DZIALY = {
    "platnosci": "Płatności, faktury, obciążenia karty, abonament",
    "dostawa": "Wysyłka, kurier, śledzenie paczki, adres dostawy",
    "zwrot": "Zwroty towaru, reklamacje, wymiana, uszkodzony produkt",
    "konto": "Logowanie, hasło, dane konta, bezpieczeństwo konta, RODO",
    "awaria": "Błędy aplikacji lub strony, awarie, integracje, wydajność",
    "sprzedaz": "Pytania o ofertę, plany, rabaty, wdrożenia dla firm",
    "inne": "Z treści nie da się ustalić, czego dotyczy zgłoszenie",
}
PROG_DZIAL = 0.60   # Por debajo de esta confianza, el caso pasa a un humano
PROG_PILNE = 0.40   # Umbral ajustado en nuestras pruebas; calibralo con tus datos

silnik = load_engine(MODEL, device="cuda")  # "cpu" tambien funciona, con mayor latencia

def rozdziel(tekst: str) -> dict:
    zapytanie = SystemOneRequest(state=tekst, questions={
        "dzial": {"type": "choice", "instructions": "Do którego działu trafia to zgłoszenie?", "criteria": DZIALY},
        "pilne": {"type": "noul", "instructions": "Czy zgłoszenie wymaga reakcji jeszcze dziś (awaria, utrata pieniędzy, włamanie, nieprzekraczalny termin)?"},
    })
    odp = silnik.evaluate(zapytanie).answers
    dzial, pewnosc, p_pilne = odp["dzial"].choice, odp["dzial"].confidence, odp["pilne"].noul
    kolejka = dzial if pewnosc >= PROG_DZIAL and dzial != "inne" else "a_humano"
    return {"cola": kolejka, "departamento": dzial, "confianza": round(pewnosc, 2),
            "urgente": p_pilne >= PROG_PILNE, "p_urgente": round(p_pilne, 2)}

if __name__ == "__main__":
    for linia in sys.stdin:
        if linia.strip():
            print(json.dumps({"texto": linia.strip()[:60], **rozdziel(linia)}, ensure_ascii=False))

Traducción de las instrucciones y criterios evaluados en el código anterior:

  • Instrucción de departamento: «¿A qué departamento corresponde esta consulta?». Criterios: platnosci («Pagos, facturas, cargos en tarjeta, suscripción»), dostawa («Envíos, mensajería, seguimiento de paquete, dirección de entrega»), zwrot («Devolución de producto, reclamaciones, cambios, producto dañado»), konto («Inicio de sesión, contraseña, datos de cuenta, seguridad, RGPD»), awaria («Errores de app o web, caídas del servicio, integraciones, rendimiento»), sprzedaz («Preguntas sobre oferta comercial, planes, descuentos, cuentas corporativas»), inne («Por el contenido no es posible determinar de qué trata la consulta»).
  • Instrucción de urgencia: «¿Requiere esta consulta atención hoy mismo (caída del servicio, pérdida económica, brecha de seguridad, plazo improrrogable)?».

Decisiones de diseño aplicadas:

  • Probamos el sistema en polaco. En nuestro banco de pruebas mantuvimos las etiquetas y descripciones en polaco, comprobando que el modelo comprende descripciones en ese idioma con la misma precisión que en inglés.
  • Dos consultas agrupadas en una sola petición. El modelo evalúa el texto de entrada una sola vez y procesa las preguntas adicionales casi sin coste computacional extra. Añadir una tercera variable (por ejemplo, «¿el cliente amenaza con cancelar el servicio?») apenas incrementa la latencia.
  • La lógica de decisión reside en el código, no en el modelo. El modelo devuelve exclusivamente probabilidades normalizadas; los umbrales de decisión y el enrutamiento a colas se gestionan desde Python, lo que permite reajustar reglas sin volver a entrenar nada.

Puesta en marcha y resultados

El script lee incidencias directamente desde la entrada estándar, una por línea:

python routing.py < incidencias.txt

Estos fueron los resultados obtenidos en nuestra tarjeta RTX 4090 con seis mensajes reales que el modelo no había visto previamente en el entrenamiento:

Incidencia Sin opción «otros» Con opción «otros»
Od rana nie działa logowanie przez Google, cały zespół stoi. («Desde la mañana no funciona el login con Google, todo el equipo está parado») cuenta 0,54 - a humano, urgente cuenta 0,46 - a humano, urgente
Proszę o fakturę VAT na firmę do zamówienia 77120. («Solicito factura con IVA para empresa del pedido 77120») pagos 0,46 - a humano otros 0,63 - a humano
Paczka wróciła do nadawcy, bo kurier nie mógł znaleźć adresu. («El paquete ha vuelto al remitente porque el transportista no encontró la dirección») envíos 0,96 envíos 0,90
Czy macie zniżki dla szkół i uczelni? («¿Tenéis descuentos para colegios y universidades?») ventas 0,58 - a humano ventas 0,31 - a humano
Hej, mam pytanie. Coś mi nie gra. («Hola, tengo una pregunta. Algo no me cuadra») incidencia técnica 0,80 incidencia técnica 0,41 - a humano
Zwracam kurtkę, ale nie wiem, czy zwrot pójdzie na kartę czy na konto. («Devuelvo una chaqueta, pero no sé si el reembolso irá a la tarjeta o a la cuenta») devolución 0,94 devolución 0,84

Cada inferencia tardó aproximadamente 135 ms en la tarjeta gráfica, tras un tiempo inicial de carga del modelo de 16 segundos. Todas las consultas que el modelo enrutó de forma automática fueron asignadas a su departamento correcto. Además, solo marcó como urgente el problema crítico de acceso que bloqueaba el trabajo del equipo.

Trampa 1: exceso de confianza ante mensajes vagos

En nuestra primera iteración no contemplamos la categoría «otros». Ante un mensaje vacío de contexto como Hej, mam pytanie. Coś mi nie gra. («Hola, tengo una pregunta. Algo no me cuadra»), el modelo lo asignó a fallos técnicos con una confianza de 0,80. Como superaba el umbral de corte, habría acabado en la bandeja del equipo de soporte técnico sin motivo. No se trata de un fallo del modelo: al forzarle a elegir entre seis categorías cerradas, las probabilidades deben sumar obligatoriamente 1. Un modelo decisional no responderá «no lo sé» a menos que le proporciones explícitamente esa alternativa.

La solución consiste en definir la opción inne (otros) con una descripción clara: «Por el contenido no es posible determinar de qué trata la consulta», acompañada de una instrucción en el script para derivar siempre esa categoría al equipo humano. Tras este ajuste, la confianza del mensaje vago cayó a 0,41 y fue desviado correctamente a revisión manual.

Trampa 2: la opción «otros» reduce la confianza general

Añadir una categoría cajón de sastre tiene un precio: la certeza también disminuye en consultas claras (el paquete bajó de 0,96 a 0,90; la devolución de la prenda, de 0,94 a 0,84), y la solicitud de factura con IVA fue clasificada erróneamente en «otros» en lugar de pagos. Para mitigar este efecto:

  • Añade al criterio el vocabulario real de tus usuarios. Si la petición de factura con IVA acaba en «otros», amplía la descripción de pagos incluyendo términos específicos como «factura con IVA, rectificativa, desglose de impuestos».
  • Determina los umbrales con tu propio historial. Reúne entre 50 y 100 incidencias clasificadas manualmente, procésalas con el script y evalúa a partir de qué umbral de corte el sistema no comete falsos positivos. Nuestro corte de 0,60 sirve como punto de partida, no como regla universal.
  • Monitoriza el porcentaje de derivación humana. Si supera el 30-40% del volumen total, suele indicar que las descripciones de las áreas son excesivamente genéricas o que sus competencias se solapan.

Ajuste del umbral de urgencia

En nuestra batería de 30 consultas reales probadas en polaco, Strands Decider asignó a los casos urgentes valores de probabilidad situados entre 0,22 y 0,47. Si hubiéramos mantenido el umbral teórico estándar de 0,5, ningún ticket se habría marcado como prioritario; de ahí que fijáramos el corte en 0,40 en el código. En cambio, el modelo de mayor escala Clef-flash de Cloudflare mostró el sesgo opuesto y rindió de forma óptima situando el umbral en 0,95. La conclusión es clara: trata los valores numéricos del modelo como un orden de clasificación relativo y calibra la frontera con tus propios datos.

Cómo migrar a otros modelos

Strands Decider, Cloudflare Clef, junto con Kev y Jev de TypeSafe, comparten la misma estructura de consultas (formato System One: state + questions). Adaptar el script a cualquiera de ellos requiere únicamente cambiar el conector de inferencia:

  • Clef-flash en local (tarjeta de 24 GB de VRAM): utiliza la función systemone() incluida en joint_schema_model.py dentro del repositorio Cloudflare/clef-flash. En nuestro entorno demostró ser algo más veloz (112 ms) y consistente, aunque exige 18 GB de memoria de vídeo dedicada. Analizamos su lanzamiento en nuestro artículo sobre Cloudflare Clef.
  • Workers AI de Cloudflare: petición POST contra /ai/run/@cf/cloudflare/clef-flash con la misma estructura JSON, a un coste de 0,0805 EUR (0,09 USD) por millón de tokens de entrada con cuota diaria gratuita. Requiere cuenta en Cloudflare.
  • Servidor HTTP de Strands: ejecutando strands-decider serve ... --port 8000 y realizando llamadas a /v1/systemone, lo que evita que cada script deba cargar los pesos en memoria de forma independiente.

Puedes profundizar en las especificaciones, licencias y rendimiento de este modelo en nuestro análisis de Strands Decider 2B.

Cuándo no conviene usar un modelo decisional

  • Si necesitas redactar directamente una contestación para el usuario; en ese caso precisas un LLM generativo, aunque el modelo decisional puede seleccionar previamente la plantilla adecuada.
  • Si gestionas un volumen muy bajo de incidencias diarias; resulta más directo pedirle un JSON a un modelo comercial estándar, tal como explicamos en nuestra guía sobre salidas estructuradas con IA.
  • Si la estructura organizativa de tus departamentos cambia semanalmente y careces de datos históricos etiquetados, pues será imposible fijar umbrales fiables.
Google · Tus fuentesBrilla más alto en tu Google - con un solo clicAñadir a fuentes preferidas →

Fuentes

Kinetyra

// read next

More on this from FULGOR

lee también¿Qué IA elegir para música de vídeo? Eleven Music, Stable o Sunoherramientas de ia¿Qué IA elegir para música de vídeo? Eleven Music, Stable o SunoPara música de fondo en vídeo, Eleven Music destaca por control y licencia desde 6 USD. Stable Audio 3 y Suno completan las mejores alternativas.

Más leídos

  1. 1Para quién es GPT-6 Astra y quién debería elegir otro modelo
  2. 2Eleven v4: test en español, precio y comparativa con v4 Turbo
  3. 3Claude Sonnet 5.5 precio: cuánto cuesta en 2026
// mapa del sitio

Esta página en otros idiomas6

fulgor en números 0textos en el archivo0noticias de los últimos 7 días0modelos de vídeo en el observatorio
🎬 Cine IA: Higgsfield AI DoP Presets de Cámara y Calculadora • Código Descuento Higgsfield AI -50% • Higgsfield vs Kling AI
× ‹ ampliación ›