0Pricing
AI Agents · Lección

Enrutamiento de tickets y lógica de escalado

Clasificación de la intención, enrutamiento a agentes especialistas y activadores de escalado.

Enrutamiento de tickets y lógica de escalado es una lección gratuita de AI Agents en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Agents, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Agents incluye 4 lecciones en total.

El problema del enrutamiento

Un agente de atención al cliente recibe a diario miles de mensajes diversos: disputas de facturación, restablecimientos de contraseñas, defectos de productos, retrasos en los envíos y solicitudes de funciones. Enviar todos los mensajes al mismo controlador produce respuestas lentas y de baja calidad.

El enrutamiento de tickets clasifica cada mensaje y lo envía al equipo mejor preparado para resolverlo.

Clasificación de intenciones con un LLM

La capa de enrutamiento llama a un LLM con un prompt de clasificación. El modelo devuelve una respuesta estructurada con una etiqueta de intent y una puntuación de confidence.

import openai, json

client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')

INTENTS = ['billing', 'technical_support', 'returns_refunds',
           'account_access', 'shipping', 'general_inquiry']

def classify_intent(message: str) -> dict:
    prompt = (
        f'Classify this customer message into exactly one intent.\n'
        f'Intents: {INTENTS}\n'
        f'Message: "{message}"\n'
        f'Respond with JSON: {{"intent": "...", "confidence": 0.0-1.0}}'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)

Enrutamiento a colas de especialistas

Una vez conocida la intención, dirija el ticket a la cola de especialistas adecuada. Cada cola tiene sus propias plantillas de respuesta, SLA y reglas de escalamiento.

ROUTING_MAP = {
    'billing':           'queue_billing',
    'technical_support': 'queue_tech',
    'returns_refunds':   'queue_returns',
    'account_access':    'queue_tech',
    'shipping':          'queue_fulfillment',
    'general_inquiry':   'queue_general'
}

def route_ticket(ticket: dict) -> str:
    result = classify_intent(ticket['message'])
    intent = result['intent']
    confidence = result['confidence']
    queue = ROUTING_MAP.get(intent, 'queue_general')
    ticket['intent'] = intent
    ticket['confidence'] = confidence
    ticket['queue'] = queue
    return queue

Umbral de confianza para el escalamiento

Si el clasificador no está seguro (confianza inferior a 0,7), el enrutamiento automático puede ser incorrecto. Los tickets con baja confianza deben escalarse a una persona para su clasificación manual, en lugar de enviarse automáticamente a un especialista.

CONFIDENCE_THRESHOLD = 0.70

def route_with_escalation(ticket: dict) -> dict:
    result = classify_intent(ticket['message'])
    intent = result['intent']
    confidence = result['confidence']

    if confidence < CONFIDENCE_THRESHOLD:
        return {
            'ticket_id': ticket['id'],
            'action': 'escalate_to_human',
            'reason': f'Low confidence: {confidence:.2f}',
            'suggested_intent': intent
        }

    queue = ROUTING_MAP.get(intent, 'queue_general')
    return {
        'ticket_id': ticket['id'],
        'action': 'route_to_queue',
        'queue': queue,
        'intent': intent,
        'confidence': confidence
    }

Escalamiento de prioridad basado en el SLA

Incluso los tickets enrutados automáticamente pueden incumplir su SLA si no se resuelven a tiempo. Un trabajo en segundo plano comprueba la antigüedad del ticket respecto a los objetivos del SLA y escala los tickets atrasados a una cola de supervisión.

from datetime import datetime, timezone

SLA_HOURS = {
    'queue_billing':      4,
    'queue_tech':         8,
    'queue_returns':      24,
    'queue_fulfillment':  12,
    'queue_general':      48
}

def check_sla_breach(ticket: dict) -> bool:
    created = datetime.fromisoformat(ticket['created_at'])
    age_hours = (datetime.now(timezone.utc) - created).total_seconds() / 3600
    sla = SLA_HOURS.get(ticket['queue'], 24)
    if age_hours > sla and ticket['status'] == 'open':
        ticket['queue'] = 'queue_supervisor_escalation'
        ticket['escalation_reason'] = f'SLA breach: {age_hours:.1f}h > {sla}h'
        return True
    return False

if __name__ == '__main__':
    from datetime import datetime, timedelta, timezone
    old_ticket = {
        'created_at': (datetime.now(timezone.utc) - timedelta(hours=10)).isoformat(),
        'queue': 'queue_billing',
        'status': 'open',
    }
    breached = check_sla_breach(old_ticket)
    print(f'SLA breached: {breached}')
    if breached:
        print('Escalation reason:', old_ticket['escalation_reason'])

Enrutamiento de tickets complejos con múltiples etiquetas

Algunos mensajes abarcan varios ámbitos: 'Mi pedido llegó roto y me cobraron dos veces'. Un clasificador de múltiples etiquetas devuelve varias intenciones; el ticket se duplica en ambas colas y los agentes coordinan la resolución.

def classify_multi_intent(message: str) -> list[dict]:
    prompt = (
        f'A customer message may have multiple intents.\n'
        f'Intents: {INTENTS}\n'
        f'Message: "{message}"\n'
        f'Return JSON array: [{{"intent": "...", "confidence": 0.0}}]\n'
        f'Include only intents with confidence > 0.5'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    data = json.loads(resp.choices[0].message.content)
    return data.get('intents', [])

# Route to multiple queues
def route_multi(ticket: dict) -> list[str]:
    intents = classify_multi_intent(ticket['message'])
    return [ROUTING_MAP.get(i['intent'], 'queue_general') for i in intents]

Extracción de metadatos de tickets

Antes de enrutar el ticket, extraiga del mensaje los metadatos que puedan ayudar a los especialistas: números de pedido, nombres de productos e ID de cuenta. Esto acelera la resolución al eliminar la primera ronda de preguntas aclaratorias.

def extract_metadata(message: str) -> dict:
    prompt = (
        f'Extract structured metadata from this customer message.\n'
        f'Return JSON: {{"order_id": null, "product": null, "account_email": null}}\n'
        f'Use null for fields not mentioned.\n'
        f'Message: "{message}"'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)

meta = extract_metadata('My order #A12345 for the blue headphones never arrived.')
print(meta)  # {'order_id': 'A12345', 'product': 'blue headphones', 'account_email': None}

Aumento de prioridad basado en el sentimiento

Los clientes enfadados tienen más probabilidades de abandonar el servicio. Detecte el sentimiento negativo y aumente la prioridad del ticket para que los clientes insatisfechos reciban respuestas más rápidas, aunque su plazo de SLA todavía no haya vencido.

def detect_sentiment(message: str) -> str:
    prompt = f'Classify sentiment as positive/neutral/negative.\nMessage: "{message}"\nReturn JSON: {{"sentiment": "..."}}'
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)['sentiment']

def set_priority(ticket: dict) -> str:
    sentiment = detect_sentiment(ticket['message'])
    if sentiment == 'negative':
        ticket['priority'] = 'high'
    elif sentiment == 'positive':
        ticket['priority'] = 'low'
    else:
        ticket['priority'] = 'normal'
    return ticket['priority']

Definición de la cadena de escalamiento

Defina una cadena de escalamiento clara para que cada cola tenga una alternativa. Cuando la cola de primera línea no resuelva el problema dentro del SLA, el ticket pasa al nivel 2, después al nivel 3 (especialista sénior) y, por último, al supervisor.

ESCALATION_CHAIN = {
    'queue_tech':              'queue_tech_tier2',
    'queue_tech_tier2':        'queue_tech_senior',
    'queue_tech_senior':       'queue_supervisor_escalation',
    'queue_billing':           'queue_billing_senior',
    'queue_billing_senior':    'queue_supervisor_escalation',
    'queue_returns':           'queue_supervisor_escalation',
    'queue_fulfillment':       'queue_supervisor_escalation',
    'queue_general':           'queue_supervisor_escalation',
    'queue_supervisor_escalation': None  # terminal — human manager
}

def escalate(ticket: dict) -> str | None:
    next_queue = ESCALATION_CHAIN.get(ticket['queue'])
    if next_queue:
        ticket['queue'] = next_queue
    return next_queue

if __name__ == '__main__':
    ticket = {'queue': 'queue_tech'}
    for _ in range(3):
        nxt = escalate(ticket)
        print(f"Escalated to: {ticket['queue']}")
        if nxt is None:
            break

Pipeline completo de enrutamiento

Combine la clasificación, la extracción de metadatos, el análisis de sentimiento y la comprobación del SLA en un único pipeline que se ejecute con cada ticket entrante.

def process_ticket(raw_ticket: dict) -> dict:
    ticket = dict(raw_ticket)

    # Step 1: Classify and route
    routing = route_with_escalation(ticket)
    ticket.update(routing)

    # Step 2: Extract metadata
    ticket['metadata'] = extract_metadata(ticket['message'])

    # Step 3: Set priority from sentiment
    ticket['priority'] = set_priority(ticket)

    # Step 4: Check if already breaching SLA
    if ticket.get('created_at'):
        check_sla_breach(ticket)

    return ticket

result = process_ticket({
    'id': 'T001',
    'message': 'I was charged twice for my subscription last month!',
    'created_at': '2026-05-28T10:00:00+00:00',
    'status': 'open'
})
print(result)

Supervisión de la precisión del enrutamiento

Realice un seguimiento de la precisión del enrutamiento mediante el muestreo de un porcentaje de los tickets enrutados automáticamente para que los revise una persona. Cuando un especialista reasigna un ticket a otra cola, se trata de un error de enrutamiento. Utilice esos errores para mejorar el prompt o ajustar un clasificador.

import random

def log_routing_decision(ticket: dict, final_queue: str):
    was_correct = ticket.get('queue') == final_queue
    if not was_correct:
        print(f'[ROUTING_ERROR] ticket={ticket["id"]} '
              f'predicted={ticket["queue"]} actual={final_queue} '
              f'confidence={ticket.get("confidence", 0):.2f}')

# Specialist reassigns ticket: log the discrepancy
def specialist_reassign(ticket: dict, new_queue: str):
    log_routing_decision(ticket, new_queue)
    ticket['queue'] = new_queue
    return ticket

if __name__ == '__main__':
    ticket = {'id': 'T-1001', 'queue': 'queue_billing', 'confidence': 0.62}
    specialist_reassign(ticket, 'queue_tech')

¿Qué umbral de confianza debe activar el escalamiento a una persona en lugar del enrutamiento automático?

Elegir el umbral de confianza adecuado permite equilibrar el nivel de automatización con la precisión del enrutamiento. Un umbral demasiado alto provoca un exceso de escalamientos; uno demasiado bajo genera enrutamientos incorrectos.

Repaso del enrutamiento de tickets

El enrutamiento eficaz de tickets combina la clasificación de intenciones mediante un LLM con un umbral de confianza para el escalamiento a una persona, la extracción de metadatos para acelerar la resolución, la prioridad basada en el sentimiento para clientes en riesgo y una cadena de escalamiento basada en el SLA para garantizar que ningún ticket quede desatendido.

Preguntas frecuentes

¿La lección «Enrutamiento de tickets y lógica de escalado» es gratis?

Sí — el texto completo de «Enrutamiento de tickets y lógica de escalado» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Agents, actualiza a CoddyKit PRO. El curso de AI Agents incluye 4 lecciones en total.

¿Qué aprenderé en «Enrutamiento de tickets y lógica de escalado»?

Clasificación de la intención, enrutamiento a agentes especialistas y activadores de escalado. Practicas AI Agents con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar AI Agents?

No se requiere experiencia previa. AI Agents en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Enrutamiento de tickets y lógica de escalado»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de AI Agents?

Sí. Cada lección de AI Agents incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Enrutamiento de tickets y lógica de escalado
  2. Integración con CRM: Salesforce y HubSpot
  3. Protocolos de transferencia a agentes humanos
  4. Gestión del contexto y el historial del cliente
← Volver a AI Agents