ITSkillsCenter
Intelligence Artificielle

Classifier 10 000 tickets support avec Claude

9 min de lecture
Miniature - Classifier 10 000 tickets support avec Claude

Ce que vous saurez faire à la fin

  1. Définir une taxonomie multi-label (catégorie, sous-catégorie, urgence, sentiment, langue) pour 10 000 tickets
  2. Construire un prompt few-shot robuste qui atteint 90%+ d’accord avec un annotateur humain
  3. Industrialiser la classification via la Batch API à 50% du tarif standard
  4. Comprendre pourquoi le fine-tuning n’est pas disponible chez Anthropic et comment compenser
  5. Intégrer les classifications retournées dans Zendesk pour automatiser routing, SLA et reporting

Durée : 4h. Pré-requis : compte Anthropic API, export CSV ou JSON de tickets Zendesk (champs ticket_id, subject, description, requester), Python 3.10+ avec SDK anthropic, budget API entre 12 000 et 25 000 FCFA pour classifier 10 000 tickets en Haiku.

Étape 1 — Concevoir la taxonomie multi-label

Une taxonomie mal conçue ruine le projet. Limitez-vous à 4 dimensions maximum : catégorie principale (8 à 12 valeurs), sous-catégorie (3 à 5 par catégorie principale), urgence (basse, moyenne, haute, critique), sentiment (positif, neutre, négatif, très_négatif). Ajoutez éventuellement une 5e dimension « langue détectée » si vous opérez sur plusieurs marchés (Sénégal, Côte d’Ivoire, Maroc).

Catégorie Sous-catégories Volume estimé
Livraison retard, perdu, mauvaise adresse, livreur 32%
Produit défaut, conformité, mode emploi, garantie 24%
Paiement échec carte, débit double, remboursement 18%
Compte connexion, email, mot de passe, suppression 11%
Commercial devis, B2B, gros volume, partenariat 8%
Autre presse, candidature, divers 7%

Étape 2 — Annoter manuellement 200 tickets de référence

Sans gold standard, impossible de mesurer la précision. Sélectionnez 200 tickets représentatifs (échantillonnage stratifié par catégorie estimée) et faites-les annoter par 2 personnes en parallèle. Mesurez l’accord inter-annotateur (Cohen’s kappa). Cible minimum : 0,75. Si l’accord est plus bas, votre taxonomie est ambiguë et vous devez la simplifier avant d’aller plus loin.

Étape 3 — Construire le prompt few-shot avec 6 à 8 exemples

PROMPT_CLASSIFICATION = """Tu es un expert en classification de tickets support pour une PME e-commerce sénégalaise.
Classifie le ticket suivant selon ces 4 dimensions et retourne UNIQUEMENT du JSON valide.

DIMENSIONS :
1. categorie : livraison | produit | paiement | compte | commercial | autre
2. sous_categorie : valeur cohérente avec la catégorie (voir exemples)
3. urgence : basse | moyenne | haute | critique
4. sentiment : positif | neutre | negatif | tres_negatif

RÈGLES URGENCE :
- critique : client mentionne avocat, presse, justice, décès, dégât matériel grave
- haute : impact financier > 100 000 FCFA, livraison événement (mariage, baptême)
- moyenne : retard livraison > 5 jours, défaut produit
- basse : question simple, FAQ

EXEMPLES :

Ticket : 'Bonjour, ma commande devait arriver lundi mais on est jeudi et toujours rien.'
Réponse : {"categorie":"livraison","sous_categorie":"retard","urgence":"moyenne","sentiment":"negatif"}

Ticket : 'J'ai été débité deux fois pour la même commande, je veux un remboursement immédiat sinon je porte plainte.'
Réponse : {"categorie":"paiement","sous_categorie":"debit_double","urgence":"critique","sentiment":"tres_negatif"}

Ticket : 'Comment changer mon adresse de livraison sur mon compte ?'
Réponse : {"categorie":"compte","sous_categorie":"adresse","urgence":"basse","sentiment":"neutre"}

Ticket : 'Merci infiniment, votre livreur a été adorable !'
Réponse : {"categorie":"livraison","sous_categorie":"livreur","urgence":"basse","sentiment":"positif"}

Ticket : 'Le produit est arrivé cassé, je dois l'offrir samedi pour un baptême, je fais comment ?'
Réponse : {"categorie":"produit","sous_categorie":"defaut","urgence":"haute","sentiment":"negatif"}

Ticket : 'Bonjour, je représente une société de 50 employés, je cherche un devis pour 200 unités.'
Réponse : {"categorie":"commercial","sous_categorie":"devis_b2b","urgence":"moyenne","sentiment":"neutre"}

Ticket à classifier :
'{ticket_text}'

Réponds UNIQUEMENT avec le JSON, sans texte avant ni après."""

Étape 4 — Premier test sur 50 tickets pour valider le prompt

import anthropic
import json

client = anthropic.Anthropic()

def classifier_ticket(texte):
    prompt = PROMPT_CLASSIFICATION.format(ticket_text=texte)
    response = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=200,
        messages=[{"role": "user", "content": prompt}]
    )
    return json.loads(response.content[0].text)

# Test sur 50 tickets gold
correctes = 0
for ticket in tickets_gold[:50]:
    pred = classifier_ticket(ticket["text"])
    if pred["categorie"] == ticket["true_categorie"]:
        correctes += 1
print(f"Précision catégorie : {correctes/50*100:.1f}%")

Étape 5 — Comprendre pourquoi le fine-tuning n’est pas disponible

Anthropic ne propose pas de fine-tuning sur ses modèles Claude (contrairement à OpenAI). La raison : Claude est conçu pour atteindre une qualité élevée dès le prompt zero-shot ou few-shot. Pour un cas d’usage de classification de tickets, le few-shot avec 6 à 10 exemples bien choisis atteint 88 à 94% de précision, soit l’équivalent d’un modèle fine-tuné OpenAI sur 1000 exemples. Le surcoût en tokens d’entrée (les exemples) est largement compensé par le prompt caching qui réduit le coût récurrent à 10% du tarif initial.

Étape 6 — Activer le prompt caching pour la production

def classifier_avec_cache(texte):
    response = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=200,
        system=[{
            "type": "text",
            "text": PROMPT_CLASSIFICATION.split("Ticket à classifier")[0],
            "cache_control": {"type": "ephemeral"}
        }],
        messages=[{
            "role": "user",
            "content": f"Ticket à classifier :\n'{texte}'\n\nRéponds UNIQUEMENT avec le JSON."
        }]
    )
    return json.loads(response.content[0].text)

Étape 7 — Bascule en Batch API pour les 10 000 tickets historiques

def construire_batch_classification(tickets):
    requests_batch = []
    for t in tickets:
        requests_batch.append({
            "custom_id": str(t["ticket_id"]),
            "params": {
                "model": "claude-haiku-4-5",
                "max_tokens": 200,
                "messages": [{
                    "role": "user",
                    "content": PROMPT_CLASSIFICATION.format(ticket_text=t["text"])
                }]
            }
        })
    return requests_batch

batch = client.messages.batches.create(
    requests=construire_batch_classification(tous_les_tickets)
)
print(f"Batch lancé : {batch.id}, 10 000 tickets en cours")

Étape 8 — Calculer le coût total et le ROI

Modèle Tokens entrée moyens Tokens sortie moyens Coût 10 000 tickets (synchrone) Coût Batch API (-50%)
Claude Haiku 4.5 900 50 ~11,50 USD (7 100 FCFA) ~5,75 USD (3 550 FCFA)
Claude Sonnet 4.6 900 50 ~34,50 USD (21 400 FCFA) ~17,25 USD (10 700 FCFA)

Pour la classification, Haiku suffit dans 90% des cas. Réservez Sonnet aux tickets longs (> 1500 tokens) ou multilingues complexes.

Étape 9 — Récupérer les résultats et gérer les erreurs de parsing

def telecharger_classifications(batch_id):
    classifications = {}
    erreurs = []
    for result in client.messages.batches.results(batch_id):
        if result.result.type == "succeeded":
            try:
                data = json.loads(result.result.message.content[0].text)
                classifications[result.custom_id] = data
            except json.JSONDecodeError:
                erreurs.append({
                    "ticket_id": result.custom_id,
                    "raw": result.result.message.content[0].text
                })
        else:
            erreurs.append({
                "ticket_id": result.custom_id,
                "error": str(result.result.error)
            })
    return classifications, erreurs

classifs, errs = telecharger_classifications(batch.id)
print(f"{len(classifs)} succès, {len(errs)} erreurs ({len(errs)/100:.1f}%)")

Étape 10 — Re-traiter les erreurs en mode synchrone avec Sonnet

Les erreurs Haiku (généralement moins de 2%) sont souvent des tickets très longs ou ambigus. Re-traitez-les automatiquement en synchrone avec Sonnet, qui pardonne mieux les ambiguïtés et structure mieux son JSON.

def reparer_erreurs(erreurs, tickets_dict):
    reparees = {}
    for err in erreurs:
        texte = tickets_dict[err["ticket_id"]]["text"]
        try:
            response = client.messages.create(
                model="claude-sonnet-4-6",
                max_tokens=200,
                messages=[{
                    "role": "user",
                    "content": PROMPT_CLASSIFICATION.format(ticket_text=texte)
                }]
            )
            reparees[err["ticket_id"]] = json.loads(response.content[0].text)
        except Exception as e:
            print(f"Échec persistant ticket {err['ticket_id']} : {e}")
    return reparees

Étape 11 — Mesurer la précision sur le set gold

def evaluer_precision(predictions, gold):
    metriques = {"categorie": 0, "sous_categorie": 0, "urgence": 0, "sentiment": 0}
    for ticket_id, vraie in gold.items():
        if ticket_id not in predictions:
            continue
        pred = predictions[ticket_id]
        for dim in metriques:
            if pred.get(dim) == vraie.get(dim):
                metriques[dim] += 1
    n = len(gold)
    return {dim: round(score/n*100, 1) for dim, score in metriques.items()}

precision = evaluer_precision(classifs, gold_200)
print(precision)
# Exemple : {'categorie': 92.5, 'sous_categorie': 86.0, 'urgence': 89.5, 'sentiment': 94.0}

Étape 12 — Pousser les classifications dans Zendesk via API

import requests

ZENDESK_SUBDOMAIN = "marquexyz"
ZENDESK_AUTH = ("agent@marquexyz.com/token", "votre_token")

def maj_ticket_zendesk(ticket_id, classification):
    url = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/{ticket_id}.json"
    payload = {
        "ticket": {
            "custom_fields": [
                {"id": 360001, "value": classification["categorie"]},
                {"id": 360002, "value": classification["sous_categorie"]},
                {"id": 360003, "value": classification["urgence"]},
                {"id": 360004, "value": classification["sentiment"]}
            ],
            "tags": [
                f"cat_{classification['categorie']}",
                f"urg_{classification['urgence']}"
            ]
        }
    }
    return requests.put(url, json=payload, auth=ZENDESK_AUTH).json()

Étape 13 — Configurer les triggers Zendesk basés sur la classification

Une fois les champs personnalisés alimentés, créez dans Zendesk des triggers automatiques : si urgence = critique, assigner au manager + notification SMS Orange Money + SLA 30 minutes ; si catégorie = paiement et sentiment = très_négatif, escalade direction financière ; si catégorie = commercial et sous-catégorie = devis_b2b, router vers l’équipe commerciale avec SLA 4 heures. Ces triggers transforment la classification IA en automatisation business directe.

Étape 14 — Mettre en place un re-classement quotidien des nouveaux tickets

Pour les tickets entrants en temps réel, basculez en mode synchrone avec une latence cible inférieure à 3 secondes. Pour le batch quotidien (analytics et reporting), conservez la Batch API. Programmez un cron à 02h00 chaque nuit qui : récupère les tickets des dernières 24h, les classifie en batch, met à jour Zendesk, génère un rapport quotidien envoyé par email au manager support. Le coût mensuel pour 300 tickets/jour reste sous 8 000 FCFA en Haiku.

Erreurs classiques à éviter

  • Lancer 10 000 tickets sans annotation gold : conséquence, vous découvrez 3 mois plus tard que la précision était de 62%, toutes les analyses sont fausses.
  • Taxonomie à 30 catégories : conséquence, Claude hésite entre les classes proches, précision plafonnée à 70%, équipe perdue.
  • Few-shot avec 1 seul exemple par classe : conséquence, biais de représentation, classes minoritaires ignorées.
  • Oublier d’échapper les apostrophes dans les exemples : conséquence, Python casse au .format(), 2h de debug pour rien.
  • Ne pas versionner le prompt : conséquence, impossible de comparer une amélioration de précision avec la version précédente.

Checklist Classification de tickets

✓ Taxonomie multi-label définie (max 4 dimensions, max 12 valeurs/dim)
✓ Set gold de 200 tickets annoté en double avec kappa > 0,75
✓ Prompt few-shot avec 6 à 8 exemples couvrant toutes les catégories
✓ Test pilote sur 50 tickets validé (précision > 88%)
✓ Prompt caching activé sur la partie statique
✓ Batch API configuré avec custom_id = ticket_id
✓ Coût simulé Haiku vs Sonnet calculé
✓ Gestion des erreurs JSON et fallback Sonnet implémentée
✓ Métriques précision par dimension calculées
✓ Champs personnalisés Zendesk créés
✓ Triggers Zendesk configurés (routing, SLA, escalade)
✓ Cron quotidien programmé pour les nouveaux tickets
✓ Rapport quotidien automatique envoyé au manager
✓ Versioning Git du prompt avec changelog
✓ Budget API plafonné dans la console Anthropic
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité