チケットの振り分けとエスカレーションロジック
意図を分類し、専門エージェントへ振り分け、エスカレーションのトリガーを設定します。
「チケットの振り分けとエスカレーションロジック」はCoddyKit上の無料AI Agentsレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Agents学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Agentsコースには全4レッスンが含まれています。
ルーティングの問題
カスタマーサービスエージェントは、請求に関する異議申し立て、パスワードのリセット、製品の不具合、配送の遅延、機能の要望など、毎日何千件もの多様なメッセージを受け取ります。すべてのメッセージを同じハンドラーに送ると、応答が遅くなり、品質も低下します。
チケットルーティングでは、各メッセージを分類し、解決に最も適したチームへ送ります。
LLMによるインテント分類
ルーティング層は、分類用のプロンプトを使ってLLMを呼び出します。モデルは、intentラベルと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)専門チームのキューへのルーティング
インテントが判明したら、チケットを適切な専門チームのキューにルーティングします。各キューには、それぞれ固有の応答テンプレート、SLA、エスカレーションルールがあります。
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エスカレーションの信頼度しきい値
分類器の確信度が低い場合(confidenceが0.7未満)、自動ルーティングを誤る可能性があります。信頼度の低いチケットは、専門チームへ自動ルーティングするのではなく、人間が手動で振り分けるようエスカレーションしてください。
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
}SLAに基づく優先度のエスカレーション
自動ルーティングされたチケットでも、時間内に解決できなければSLAに違反する可能性があります。バックグラウンドジョブでチケットの経過時間とSLA目標を確認し、期限を超過したチケットをスーパーバイザーのキューにエスカレーションします。
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'])
複雑なチケットに対するマルチラベルルーティング
複数の領域にまたがるメッセージもあります。たとえば、「注文品が壊れた状態で届き、二重に請求されました」というケースです。マルチラベル分類器は複数のインテントを返し、チケットを両方のキューに複製して、エージェントが連携して解決します。
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]チケットメタデータの抽出
ルーティングの前に、専門担当者を支援するため、メッセージから注文番号、製品名、アカウントIDなどのメタデータを抽出します。最初の確認質問を省けるため、解決までの時間が短縮されます。
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}感情に基づく優先度の引き上げ
怒っている顧客は、解約する可能性が高くなります。否定的な感情を検出してチケットの優先度を引き上げ、SLAの期限がまだ切れていない場合でも、不満を抱えている顧客により速く対応できるようにします。
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']エスカレーションチェーンの定義
すべてのキューに引き継ぎ先を用意できるよう、明確なエスカレーションチェーンを定義します。一次対応キューでSLA内に解決できなかった場合、チケットをtier 2、次にtier 3(上級スペシャリスト)、最後にスーパーバイザーへ移します。
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
ルーティングパイプライン全体
分類、メタデータ抽出、感情分析、SLAチェックを1つのパイプラインにまとめ、着信する各チケットに対して実行します。
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)ルーティング精度の監視
自動ルーティングされたチケットの一定割合を抽出して人間が確認し、ルーティング精度を追跡します。専門担当者がチケットを別のキューに再割り当てした場合、それはルーティングエラーです。エラーをフィードバックし、プロンプトの改善や分類器のファインチューニングに役立てます。
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')
自動ルーティングではなく人間へのエスカレーションを行うべき信頼度のしきい値はどのくらいですか
適切な信頼度のしきい値を選ぶことで、自動化率とルーティング精度のバランスを取ります。しきい値が高すぎると過剰にエスカレーションされ、低すぎると誤ったルーティングにつながります。
チケットルーティングのまとめ
効果的なチケットルーティングでは、LLMによるインテント分類に加え、人間へのエスカレーションのための信頼度のしきい値、迅速な解決のためのメタデータ抽出、リスクの高い顧客に対応する感情に基づく優先度、そしてチケットの取りこぼしを防ぐSLAエスカレーションチェーンを組み合わせます。
よくある質問
「チケットの振り分けとエスカレーションロジック」レッスンは無料ですか?
はい。「チケットの振り分けとエスカレーションロジック」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Agentsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Agentsコースには全4レッスンが含まれています。
「チケットの振り分けとエスカレーションロジック」で何を学びますか?
意図を分類し、専門エージェントへ振り分け、エスカレーションのトリガーを設定します。 ブラウザで直接実行するハンズオンコードでAI Agentsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Agentsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Agentsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「チケットの振り分けとエスカレーションロジック」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Agentsレッスンでコードを書いて実行できますか?
はい。すべてのAI Agentsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- チケットの振り分けとエスカレーションロジック
- CRM 連携:Salesforce と HubSpot
- 有人引き継ぎのプロトコル
- 顧客コンテキストと履歴の管理