Definir si usar Claude para el enrutamiento de tickets

Aquí hay algunos indicadores clave de que debería usar un LLM como Claude en lugar de enfoques tradicionales de ML para su tarea de clasificación:


Construir e implementar tu flujo de trabajo de soporte con LLM

Comprender tu enfoque de soporte actual

Antes de sumergirte en la automatización, es crucial entender tu sistema de tickets existente. Comienza investigando cómo tu equipo de soporte maneja actualmente el enrutamiento de tickets.

Considera preguntas como:

  • ¿Qué criterios se utilizan para determinar qué SLA/oferta de servicio se aplica?
  • ¿Se utiliza el enrutamiento de tickets para determinar a qué nivel de soporte o especialista de producto va un ticket?
  • ¿Hay reglas o flujos de trabajo automatizados ya implementados? ¿En qué casos fallan?
  • ¿Cómo se manejan los casos extremos o tickets ambiguos?
  • ¿Cómo prioriza el equipo los tickets?

Cuanto más sepas sobre cómo los humanos manejan ciertos casos, mejor podrás trabajar con Claude para realizar la tarea.

Definir categorías de intención del usuario

Una lista bien definida de categorías de intención del usuario es crucial para la clasificación precisa de tickets de soporte con Claude. La capacidad de Claude para enrutar tickets de manera efectiva dentro de tu sistema es directamente proporcional a qué tan bien definidas están las categorías de tu sistema.

Aquí hay algunas categorías y subcategorías de intención del usuario de ejemplo.

Además de la intención, el enrutamiento y la priorización de tickets también pueden estar influenciados por otros factores como la urgencia, el tipo de cliente, los SLA o el idioma. Asegúrate de considerar otros criterios de enrutamiento al construir tu sistema de enrutamiento automatizado.

Establecer criterios de éxito

Trabaja con tu equipo de soporte para definir criterios de éxito claros con puntos de referencia medibles, umbrales y objetivos.

Aquí hay algunos criterios estándar y puntos de referencia al usar LLMs para el enrutamiento de tickets de soporte:

Aquí hay algunos criterios de éxito comunes que pueden ser útiles independientemente de si se usa un LLM:

Elegir el modelo Claude adecuado

La elección del modelo depende de los compromisos entre costo, precisión y tiempo de respuesta.

Muchos clientes han encontrado que claude-3-5-haiku-20241022 es un modelo ideal para el enrutamiento de tickets, ya que es el modelo más rápido y rentable de la familia Claude 3 mientras sigue ofreciendo excelentes resultados. Si tu problema de clasificación requiere un profundo conocimiento de la materia o un gran volumen de categorías de intención con razonamiento complejo, puedes optar por el modelo Sonnet más grande.

Construir un prompt sólido

El enrutamiento de tickets es un tipo de tarea de clasificación. Claude analiza el contenido de un ticket de soporte y lo clasifica en categorías predefinidas basadas en el tipo de problema, urgencia, experiencia requerida u otros factores relevantes.

Vamos a escribir un prompt de clasificación de tickets. Nuestro prompt inicial debe contener el contenido de la solicitud del usuario y devolver tanto el razonamiento como la intención.

Prueba el generador de prompts en la Consola de Anthropic para que Claude escriba un primer borrador para ti.

Aquí hay un ejemplo de prompt de clasificación para enrutamiento de tickets:

def classify_support_request(ticket_contents):
    # Define el prompt para la tarea de clasificación
    classification_prompt = f"""Actuarás como un sistema de clasificación de tickets de soporte al cliente. Tu tarea es analizar las solicitudes de soporte al cliente y generar la clasificación de intención apropiada para cada solicitud, junto con tu razonamiento. 

        Aquí está la solicitud de soporte al cliente que necesitas clasificar:

        <request>{ticket_contents}</request>

        Por favor, analiza cuidadosamente la solicitud anterior para determinar la intención principal y las necesidades del cliente. Considera lo que el cliente está pidiendo o sobre lo que tiene preocupaciones.

        Primero, escribe tu razonamiento y análisis de cómo clasificar esta solicitud dentro de etiquetas <reasoning>.

        Luego, genera la etiqueta de clasificación apropiada para la solicitud dentro de una etiqueta <intent>. Las intenciones válidas son:
        <intents>
        <intent>Soporte, Comentarios, Queja</intent>
        <intent>Seguimiento de Pedido</intent>
        <intent>Reembolso/Cambio</intent>
        </intents>

        Una solicitud puede tener SOLO UNA intención aplicable. Solo incluye la intención que sea más aplicable a la solicitud.

        Como ejemplo, considera la siguiente solicitud:
        <request>¡Hola! Me instalaron internet de fibra de alta velocidad el sábado y mi instalador, Kevin, fue absolutamente fantástico. ¿Dónde puedo enviar mi opinión positiva? ¡Gracias por tu ayuda!</request>

        Aquí hay un ejemplo de cómo debería ser el formato de tu salida (para el ejemplo de solicitud anterior):
        <reasoning>El usuario busca información para dejar comentarios positivos.</reasoning>
        <intent>Soporte, Comentarios, Queja</intent>

        Aquí hay algunos ejemplos más:
        <examples>
        <example 2>
        Ejemplo 2 Entrada:
        <request>Quería escribir y agradecerle personalmente por la compasión que mostró hacia mi familia durante el funeral de mi padre este fin de semana pasado. Su personal fue tan considerado y servicial durante todo este proceso; realmente nos quitó un peso de encima. Los folletos de visita fueron hermosos. Nunca olvidaremos la amabilidad que nos mostró y estamos muy agradecidos por lo bien que transcurrieron los procedimientos. Gracias, de nuevo, Amarantha Hill en nombre de la Familia Hill.</request>

        Ejemplo 2 Salida:
        <reasoning>El usuario deja una reseña positiva de su experiencia.</reasoning>
        <intent>Soporte, Comentarios, Queja</intent>
        </example 2>
        <example 3>

        ...

        </example 8>
        <example 9>
        Ejemplo 9 Entrada:
        <request>Su sitio web sigue enviando ventanas emergentes de publicidad que bloquean toda la pantalla. Me tomó veinte minutos solo para finalmente encontrar el número de teléfono para llamar y quejarme. ¿Cómo puedo acceder a la información de mi cuenta con todas estas ventanas emergentes? ¿Puede acceder a mi cuenta por mí, ya que su sitio web está roto? Necesito saber cuál es la dirección registrada.</request>

        Ejemplo 9 Salida:
        <reasoning>El usuario solicita ayuda para acceder a la información de su cuenta web.</reasoning>
        <intent>Soporte, Comentarios, Queja</intent>
        </example 9>

        Recuerda incluir siempre tu razonamiento de clasificación antes de tu salida de intención real. El razonamiento debe estar encerrado en etiquetas <reasoning> y la intención en etiquetas <intent>. Devuelve solo el razonamiento y la intención.
        """

Analicemos los componentes clave de este prompt:

  • Usamos f-strings de Python para crear la plantilla de prompt, permitiendo que el ticket_contents se inserte en las etiquetas <request>.
  • Le damos a Claude un rol claramente definido como sistema de clasificación que analiza cuidadosamente el contenido del ticket para determinar la intención principal y las necesidades del cliente.
  • Instruimos a Claude sobre el formato de salida adecuado, en este caso proporcionar su razonamiento y análisis dentro de etiquetas <reasoning>, seguido por la etiqueta de clasificación apropiada dentro de etiquetas <intent>.
  • Especificamos las categorías de intención válidas: “Soporte, Comentarios, Queja”, “Seguimiento de Pedido” y “Reembolso/Cambio”.
  • Incluimos algunos ejemplos (también conocido como prompting con pocos ejemplos) para ilustrar cómo debe formatearse la salida, lo que mejora la precisión y consistencia.

La razón por la que queremos que Claude divida su respuesta en varias secciones de etiquetas XML es para que podamos usar expresiones regulares para extraer por separado el razonamiento y la intención de la salida. Esto nos permite crear pasos siguientes específicos en el flujo de trabajo de enrutamiento de tickets, como usar solo la intención para decidir a qué persona enrutar el ticket.

Implementar tu prompt

Es difícil saber qué tan bien funciona tu prompt sin implementarlo en un entorno de producción de prueba y ejecutar evaluaciones.

Vamos a construir la estructura de implementación. Comencemos definiendo la firma del método para envolver nuestra llamada a Claude. Tomaremos el método que ya hemos comenzado a escribir, que tiene ticket_contents como entrada, y ahora devolveremos una tupla de reasoning e intent como salida. Si tienes una automatización existente que usa ML tradicional, querrás seguir esa firma de método en su lugar.

import anthropic
import re

# Crea una instancia del cliente de la API de Anthropic
client = anthropic.Anthropic()

# Establece el modelo predeterminado
DEFAULT_MODEL="claude-3-5-haiku-20241022"

def classify_support_request(ticket_contents):
    # Define el prompt para la tarea de clasificación
    classification_prompt = f"""Actuarás como un sistema de clasificación de tickets de soporte al cliente. 
        ...
        ... El razonamiento debe estar encerrado en etiquetas <reasoning> y la intención en etiquetas <intent>. Devuelve solo el razonamiento y la intención.
        """
    # Envía el prompt a la API para clasificar la solicitud de soporte.
    message = client.messages.create(
        model=DEFAULT_MODEL,
        max_tokens=500,
        temperature=0,
        messages=[{"role": "user", "content": classification_prompt}],
        stream=False,
    )
    reasoning_and_intent = message.content[0].text

    # Usa la biblioteca de expresiones regulares de Python para extraer `reasoning`.
    reasoning_match = re.search(
        r"<reasoning>(.*?)</reasoning>", reasoning_and_intent, re.DOTALL
    )
    reasoning = reasoning_match.group(1).strip() if reasoning_match else ""

    # De manera similar, también extrae la `intent`.
    intent_match = re.search(r"<intent>(.*?)</intent>", reasoning_and_intent, re.DOTALL)
    intent = intent_match.group(1).strip() if intent_match else ""

    return reasoning, intent

Este código:

  • Importa la biblioteca Anthropic y crea una instancia de cliente usando tu clave API.
  • Define una función classify_support_request que toma una cadena ticket_contents.
  • Envía el ticket_contents a Claude para clasificación usando el classification_prompt
  • Devuelve el reasoning e intent del modelo extraídos de la respuesta.

Dado que necesitamos esperar a que se genere todo el texto de razonamiento e intención antes de analizarlo, establecemos stream=False (el valor predeterminado).


Evaluar tu prompt

El prompting a menudo requiere pruebas y optimización para estar listo para producción. Para determinar la preparación de tu solución, evalúa el rendimiento basándote en los criterios de éxito y umbrales que estableciste anteriormente.

Para ejecutar tu evaluación, necesitarás casos de prueba para ejecutarla. El resto de esta guía asume que ya has desarrollado tus casos de prueba.

Construir una función de evaluación

Nuestra evaluación de ejemplo para esta guía mide el rendimiento de Claude a lo largo de tres métricas clave:

  • Precisión
  • Costo por clasificación

Es posible que necesites evaluar a Claude en otros ejes dependiendo de qué factores son importantes para ti.

Para evaluar esto, primero tenemos que modificar el script que escribimos y agregar una función para comparar la intención predicha con la intención real y calcular el porcentaje de predicciones correctas. También tenemos que agregar funcionalidad de cálculo de costos y medición de tiempo.

import anthropic
import re

# Crea una instancia del cliente de la API de Anthropic
client = anthropic.Anthropic()

# Establece el modelo predeterminado
DEFAULT_MODEL="claude-3-5-haiku-20241022"

def classify_support_request(request, actual_intent):
    # Define el prompt para la tarea de clasificación
    classification_prompt = f"""Actuarás como un sistema de clasificación de tickets de soporte al cliente. 
        ...
        ...El razonamiento debe estar encerrado en etiquetas <reasoning> y la intención en etiquetas <intent>. Devuelve solo el razonamiento y la intención.
        """

    message = client.messages.create(
        model=DEFAULT_MODEL,
        max_tokens=500,
        temperature=0,
        messages=[{"role": "user", "content": classification_prompt}],
    )
    usage = message.usage  # Obtiene las estadísticas de uso de la llamada a la API para saber cuántos tokens de entrada y salida se usaron.
    reasoning_and_intent = message.content[0].text

    # Usa la biblioteca de expresiones regulares de Python para extraer `reasoning`.
    reasoning_match = re.search(
        r"<reasoning>(.*?)</reasoning>", reasoning_and_intent, re.DOTALL
    )
    reasoning = reasoning_match.group(1).strip() if reasoning_match else ""

    # De manera similar, también extrae la `intent`.
    intent_match = re.search(r"<intent>(.*?)</intent>", reasoning_and_intent, re.DOTALL)
    intent = intent_match.group(1).strip() if intent_match else ""

      # Comprueba si la predicción del modelo es correcta.
    correct = actual_intent.strip() == intent.strip()

    # Devuelve el razonamiento, la intención, si es correcto y el uso.
    return reasoning, intent, correct, usage

Analicemos las ediciones que hemos hecho:

  • Agregamos el actual_intent de nuestros casos de prueba al método classify_support_request y configuramos una comparación para evaluar si la clasificación de intención de Claude coincide con nuestra clasificación de intención dorada.
  • Extrajimos estadísticas de uso para la llamada a la API para calcular el costo basado en los tokens de entrada y salida utilizados

Ejecutar tu evaluación

Una evaluación adecuada requiere umbrales y puntos de referencia claros para determinar qué es un buen resultado. El script anterior nos dará los valores de tiempo de ejecución para precisión, tiempo de respuesta y costo por clasificación, pero aún necesitaríamos umbrales claramente establecidos. Por ejemplo:

  • Precisión: 95% (de 100 pruebas)
  • Costo por clasificación: 50% de reducción en promedio (en 100 pruebas) del método de enrutamiento actual

Tener estos umbrales te permite determinar rápida y fácilmente a escala, y con empirismo imparcial, qué método es mejor para ti y qué cambios podrían necesitarse para adaptarse mejor a tus requisitos.


Mejorar el rendimiento

En escenarios complejos, puede ser útil considerar estrategias adicionales para mejorar el rendimiento más allá de las técnicas estándar de ingeniería de prompts y estrategias de implementación de barreras de protección. Aquí hay algunos escenarios comunes:

Usar una jerarquía taxonómica para casos con más de 20 categorías de intención

A medida que crece el número de clases, el número de ejemplos requeridos también se expande, potencialmente haciendo que el prompt sea difícil de manejar. Como alternativa, puedes considerar implementar un sistema de clasificación jerárquico usando una mezcla de clasificadores.

  1. Organiza tus intenciones en una estructura de árbol taxonómico.
  2. Crea una serie de clasificadores en cada nivel del árbol, permitiendo un enfoque de enrutamiento en cascada.

Por ejemplo, podrías tener un clasificador de nivel superior que categorice ampliamente los tickets en “Problemas Técnicos”, “Preguntas de Facturación” y “Consultas Generales”. Cada una de estas categorías puede tener su propio subclasificador para refinar aún más la clasificación.

  • Pros - mayor matiz y precisión: Puedes crear diferentes prompts para cada ruta principal, permitiendo una clasificación más dirigida y específica al contexto. Esto puede llevar a una mejor precisión y un manejo más matizado de las solicitudes de los clientes.

  • Contras - mayor latencia: Ten en cuenta que múltiples clasificadores pueden llevar a una mayor latencia, y recomendamos implementar este enfoque con nuestro modelo más rápido, Haiku.

Usar bases de datos vectoriales y búsqueda de similitud para manejar tickets altamente variables

A pesar de que proporcionar ejemplos es la forma más efectiva de mejorar el rendimiento, si las solicitudes de soporte son altamente variables, puede ser difícil incluir suficientes ejemplos en un solo prompt.

En este escenario, podrías emplear una base de datos vectorial para hacer búsquedas de similitud desde un conjunto de datos de ejemplos y recuperar los ejemplos más relevantes para una consulta dada.

Este enfoque, detallado en nuestra receta de clasificación, ha demostrado mejorar el rendimiento de un 71% de precisión a un 93% de precisión.

Tener en cuenta específicamente los casos extremos esperados

Aquí hay algunos escenarios donde Claude puede clasificar erróneamente tickets (puede haber otros que sean únicos para tu situación). En estos escenarios, considera proporcionar instrucciones explícitas o ejemplos en el prompt de cómo Claude debería manejar el caso extremo:


Integrar Claude en tu flujo de trabajo de soporte más amplio

La integración adecuada requiere que tomes algunas decisiones con respecto a cómo tu script de enrutamiento de tickets basado en Claude se ajusta a la arquitectura de tu sistema de enrutamiento de tickets más amplio. Hay dos formas en que podrías hacer esto:

  • Basado en push: El sistema de tickets de soporte que estás usando (por ejemplo, Zendesk) activa tu código enviando un evento de webhook a tu servicio de enrutamiento, que luego clasifica la intención y la enruta.
    • Este enfoque es más escalable para la web, pero necesita que expongas un punto final público.
  • Basado en pull: Tu código extrae los últimos tickets según un horario dado y los enruta en el momento de la extracción.
    • Este enfoque es más fácil de implementar pero podría hacer llamadas innecesarias al sistema de tickets de soporte cuando la frecuencia de extracción es demasiado alta o podría ser excesivamente lento cuando la frecuencia de extracción es demasiado baja.

Para cualquiera de estos enfoques, necesitarás envolver tu script en un servicio. La elección del enfoque depende de qué APIs proporciona tu sistema de tickets de soporte.