0Pricing
AI Agents · 강의

티켓 라우팅 및 에스컬레이션 로직

의도를 분류하고 전문 에이전트로 라우팅하며 에스컬레이션 조건을 설정합니다.

티켓 라우팅 및 에스컬레이션 로직은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

라우팅 문제

고객 서비스 agent는 매일 결제 이의 제기, 비밀번호 재설정, 제품 결함, 배송 지연, 기능 요청 등 서로 다른 수천 개의 메시지를 받습니다. 모든 메시지를 같은 처리기에 보내면 응답이 느리고 품질도 낮아집니다.

티켓 라우팅은 각 메시지를 분류하고, 이를 해결하는 데 가장 적합한 팀으로 보냅니다.

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

에스컬레이션을 위한 신뢰도 기준

분류기의 확신이 낮으면(신뢰도가 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'])

복잡한 티켓을 위한 다중 레이블 라우팅

일부 메시지는 여러 영역에 걸쳐 있습니다. 예를 들어 '주문 상품이 파손된 채 도착했고 요금도 두 번 청구됐습니다.'와 같은 경우입니다. 다중 레이블 분류기는 여러 의도를 반환하고, 티켓은 두 대기열에 모두 복제되며, agent들이 해결을 위해 협력합니다.

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 안에 해결하지 못하면 티켓은 2단계, 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 확인을 각 수신 티켓에 실행되는 하나의 파이프라인으로 결합합니다.

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/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

“티켓 라우팅 및 에스컬레이션 로직”에서 뭘 배우나요?

의도를 분류하고 전문 에이전트로 라우팅하며 에스컬레이션 조건을 설정합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Agents을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“티켓 라우팅 및 에스컬레이션 로직” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 티켓 라우팅 및 에스컬레이션 로직
  2. CRM 통합: Salesforce와 HubSpot
  3. 사람에게 인계하는 프로토콜
  4. 고객 맥락 및 이력 관리
← AI Agents(으)로 돌아가기