Routage des tickets et logique d’escalade
Classer l’intention, orienter vers des agents spécialisés et définir les déclencheurs d’escalade.
Routage des tickets et logique d’escalade est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.
Le problème du routage
Un agent du service client reçoit chaque jour des milliers de messages variés : litiges de facturation, réinitialisations de mot de passe, défauts de produit, retards de livraison et demandes de fonctionnalités. Envoyer chaque message au même gestionnaire produit des réponses lentes et de faible qualité.
Le routage des demandes classe chaque message et l'envoie à l'équipe la mieux à même de le résoudre.
Classification des intentions avec un LLM
La couche de routage appelle un LLM avec une invite de classification. Le modèle renvoie une réponse structurée contenant une étiquette intent et un score 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)Routage vers des files d'attente spécialisées
Une fois l'intention connue, acheminez la demande vers la file d'attente spécialisée appropriée. Chaque file possède ses propres modèles de réponse, SLA et règles d'escalade.
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 queueSeuil de confiance pour l'escalade
Si le classifieur est incertain (confiance inférieure à 0,7), le routage automatique peut être incorrect. Les demandes à faible confiance doivent être transmises à un humain pour un triage manuel plutôt que d'être automatiquement orientées vers un spécialiste.
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
}Escalade des priorités basée sur le SLA
Même les demandes automatiquement orientées peuvent dépasser leur SLA si elles ne sont pas résolues à temps. Une tâche en arrière-plan compare l'ancienneté des demandes aux objectifs SLA et transmet les demandes en retard à une file d'attente de supervision.
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'])
Routage multi-étiquettes pour les demandes complexes
Certains messages concernent plusieurs domaines : « Ma commande est arrivée cassée et j'ai été facturé deux fois. » Un classifieur multi-étiquettes renvoie plusieurs intentions ; la demande est dupliquée dans les deux files d'attente et les agents coordonnent sa résolution.
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]Extraction des métadonnées d'une demande
Avant le routage, extrayez les métadonnées du message pour aider les spécialistes : numéros de commande, noms de produits et identifiants de compte. Cela accélère la résolution en éliminant la première série de questions de clarification.
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}Augmentation de la priorité basée sur le sentiment
Les clients mécontents sont plus susceptibles de partir. Détectez le sentiment négatif et augmentez la priorité de la demande afin que les clients insatisfaits obtiennent une réponse plus rapidement, même si leur délai SLA n'est pas encore expiré.
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']Définition de la chaîne d'escalade
Définissez une chaîne d'escalade claire afin que chaque file d'attente dispose d'une solution de repli. Lorsque la file du premier niveau ne parvient pas à résoudre la demande dans le délai SLA, celle-ci passe au niveau 2, puis au niveau 3 (spécialiste senior), et enfin au superviseur.
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
Chaîne complète de traitement du routage
Combinez la classification, l'extraction des métadonnées, l'analyse du sentiment et la vérification du SLA dans une seule chaîne de traitement exécutée pour chaque demande 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)Surveillance de la précision du routage
Suivez la précision du routage en soumettant un pourcentage des demandes automatiquement orientées à un contrôle humain. Lorsqu'un spécialiste réaffecte une demande à une autre file d'attente, il s'agit d'une erreur de routage. Réinjectez ces erreurs pour améliorer l'invite ou affiner un classifieur.
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')
Quel seuil de confiance doit déclencher une escalade humaine plutôt qu'un routage automatique ?
Le choix du bon seuil de confiance permet d'équilibrer le taux d'automatisation et la précision du routage. Un seuil trop élevé entraîne trop d'escalades ; un seuil trop bas conduit à de mauvais routages.
Récapitulatif du routage des demandes
Un routage efficace des demandes combine la classification des intentions par un LLM avec un seuil de confiance pour l'escalade humaine, l'extraction des métadonnées pour accélérer la résolution, la priorité basée sur le sentiment pour les clients à risque et une chaîne d'escalade SLA afin qu'aucune demande ne soit oubliée.
Questions Fréquemment Posées
La leçon « Routage des tickets et logique d’escalade » est-elle gratuite ?
Oui — le texte complet de « Routage des tickets et logique d’escalade » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Routage des tickets et logique d’escalade » ?
Classer l’intention, orienter vers des agents spécialisés et définir les déclencheurs d’escalade. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Agents ?
Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Routage des tickets et logique d’escalade » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?
Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Routage des tickets et logique d’escalade
- Intégration CRM : Salesforce et HubSpot
- Protocoles de transfert vers un humain
- Gestion du contexte et de l’historique client