티켓 라우팅에 Claude를 사용할지 여부 결정

다음은 분류 작업에 기존 ML 접근 방식 대신 Claude와 같은 LLM을 사용해야 하는 주요 지표입니다:


LLM 지원 워크플로 구축 및 배포

현재 지원 접근 방식 이해

자동화에 뛰어들기 전에 기존 티켓팅 시스템을 이해하는 것이 중요합니다. 지원 팀이 현재 티켓 라우팅을 처리하는 방법을 조사하는 것부터 시작하세요.

다음과 같은 질문을 고려해 보세요:

  • 어떤 SLA/서비스 제공이 적용되는지 결정하는 데 사용되는 기준은 무엇입니까?
  • 티켓 라우팅이 티켓이 전달되는 지원 또는 제품 전문가의 계층을 결정하는 데 사용됩니까?
  • 이미 자동화된 규칙이나 워크플로가 있습니까? 어떤 경우에 실패합니까?
  • 예외 사례 또는 모호한 티켓은 어떻게 처리됩니까?
  • 팀은 어떻게 티켓의 우선순위를 정합니까?

사람이 특정 사례를 처리하는 방법에 대해 더 많이 알수록 Claude와 협력하여 작업을 수행하는 데 더 도움이 될 것입니다.

사용자 의도 범주 정의

잘 정의된 사용자 의도 범주 목록은 Claude를 사용한 정확한 지원 티켓 분류에 매우 중요합니다. 시스템 내에서 티켓을 효과적으로 라우팅하는 Claude의 능력은 시스템의 범주가 얼마나 잘 정의되어 있는지에 직접적으로 비례합니다.

다음은 사용자 의도 범주 및 하위 범주의 몇 가지 예입니다.

의도 외에도 티켓 라우팅 및 우선순위는 긴급성, 고객 유형, SLA 또는 언어와 같은 다른 요소의 영향을 받을 수 있습니다. 자동화된 라우팅 시스템을 구축할 때 다른 라우팅 기준을 고려해야 합니다.

성공 기준 수립

지원 팀과 협력하여 측정 가능한 벤치마크, 임계값 및 목표를 포함한 명확한 성공 기준을 정의하세요.

다음은 지원 티켓 라우팅에 LLM을 사용할 때의 표준 기준 및 벤치마크입니다:

다음은 LLM 사용 여부와 관계없이 유용할 수 있는 몇 가지 일반적인 성공 기준입니다:

적합한 Claude 모델 선택

모델 선택은 비용, 정확도 및 응답 시간 간의 절충에 따라 달라집니다.

많은 고객이 claude-3-haiku-20240307를 티켓 라우팅에 이상적인 모델로 평가했습니다. Claude 3 제품군에서 가장 빠르고 비용 효율적인 모델이면서도 여전히 우수한 결과를 제공하기 때문입니다. 분류 문제에 깊은 주제 전문 지식이나 복잡한 추론이 필요한 대량의 의도 범주가 필요한 경우 더 큰 Sonnet 모델을 선택할 수 있습니다.

강력한 프롬프트 작성

티켓 라우팅은 일종의 분류 작업입니다. Claude는 지원 티켓의 내용을 분석하고 문제 유형, 긴급성, 필요한 전문 지식 또는 기타 관련 요소를 기반으로 미리 정의된 범주로 분류합니다.

티켓 분류 프롬프트를 작성해 보겠습니다. 초기 프롬프트에는 사용자 요청의 내용이 포함되어야 하며 추론과 의도를 모두 반환해야 합니다.

Anthropic Console프롬프트 생성기를 사용하여 Claude가 초안을 작성하도록 해보세요.

다음은 티켓 라우팅 분류 프롬프트의 예입니다:

def classify_support_request(ticket_contents):
    # 분류 작업을 위한 프롬프트 정의
    classification_prompt = f"""고객 지원 티켓 분류 시스템 역할을 수행할 것입니다. 귀하의 작업은 고객 지원 요청을 분석하고 각 요청에 대한 적절한 분류 의도와 추론을 출력하는 것입니다.

        분류해야 할 고객 지원 요청은 다음과 같습니다:

        <request>{ticket_contents}</request>

        위의 요청을 주의 깊게 분석하여 고객의 핵심 의도와 요구 사항을 파악하세요. 고객이 무엇을 요청하고 우려하는지 고려하세요.

        먼저 <reasoning> 태그 안에 이 요청을 분류하는 방법에 대한 추론과 분석을 작성하세요.

        그런 다음 <intent> 태그 안에 요청에 대한 적절한 분류 레이블을 출력하세요. 유효한 의도는 다음과 같습니다:
        <intents>
        <intent>지원, 피드백, 불만</intent>
        <intent>주문 추적</intent>
        <intent>환불/교환</intent>
        </intents>

        요청에는 하나의 적용 가능한 의도만 있을 수 있습니다. 요청에 가장 적합한 의도만 포함하세요.

        예를 들어 다음 요청을 고려해 보세요:
        <request>안녕하세요! 토요일에 고속 광섬유 인터넷을 설치했는데 설치 기사 Kevin이 정말 훌륭했어요! 어디에 긍정적인 리뷰를 보내면 될까요? 도와주셔서 감사합니다!</request>

        출력 형식의 예는 다음과 같습니다(위의 예시 요청의 경우):
        <reasoning>사용자는 긍정적인 피드백을 남기기 위해 정보를 찾고 있습니다.</reasoning>
        <intent>지원, 피드백, 불만</intent>

        몇 가지 더 예를 들면 다음과 같습니다:
        <examples>
        <example 2>
        예제 2 입력:
        <request>지난 주말 아버지 장례식에서 우리 가족에게 보여주신 연민에 대해 개인적으로 감사드리고 싶었습니다. 귀하의 직원들은 이 모든 과정에서 매우 배려심 있고 도움이 되었습니다. 정말 우리 어깨의 짐을 덜어주었습니다. 방문 브로셔는 아름다웠습니다. 우리는 귀하가 보여주신 친절과 절차가 원활하게 진행된 것에 대해 매우 감사하고 있습니다. Hill 가족을 대신하여 다시 한번 감사드립니다. Amarantha Hill.</request>

        예제 2 출력:
        <reasoning>사용자는 자신의 경험에 대해 긍정적인 리뷰를 남깁니다.</reasoning>
        <intent>지원, 피드백, 불만</intent>
        </example 2>
        <example 3>

        ...

        </example 8>
        <example 9>
        예제 9 입력:
        <request>귀하의 웹사이트는 전체 화면을 가리는 광고 팝업을 계속 보내고 있습니다. 전화번호를 찾아 불만을 제기하는 데만 20분이 걸렸습니다. 이 모든 팝업으로 어떻게 내 계정 정보에 액세스할 수 있습니까? 귀하의 웹사이트가 고장 났으니 내 계정에 액세스할 수 있나요? 등록된 주소가 무엇인지 알아야 합니다.</request>

        예제 9 출력:
        <reasoning>사용자는 웹 계정 정보에 액세스하는 데 도움을 요청합니다.</reasoning>
        <intent>지원, 피드백, 불만</intent>
        </example 9>

        실제 의도 출력 전에 항상 분류 추론을 포함해야 합니다. 추론은 <reasoning> 태그로, 의도는 <intent> 태그로 묶어야 합니다. 추론과 의도만 반환하세요.
        """

이 프롬프트의 주요 구성 요소를 분석해 보겠습니다:

  • Python f-strings를 사용하여 프롬프트 템플릿을 만들어 ticket_contents<request> 태그에 삽입할 수 있도록 합니다.
  • Claude에게 고객의 핵심 의도와 요구 사항을 파악하기 위해 티켓 내용을 주의 깊게 분석하는 분류 시스템으로서의 명확한 역할을 부여합니다.
  • Claude에게 적절한 출력 형식을 지시합니다. 이 경우 <reasoning> 태그 안에 추론과 분석을 제공한 다음 <intent> 태그 안에 적절한 분류 레이블을 제공하도록 합니다.
  • 유효한 의도 범주인 “지원, 피드백, 불만”, “주문 추적”, “환불/교환”을 지정합니다.
  • 출력 형식이 어떠해야 하는지 설명하기 위해 몇 가지 예제(일명 few-shot 프롬프팅)를 포함하여 정확성과 일관성을 향상시킵니다.

Claude의 응답을 다양한 XML 태그 섹션으로 분할하도록 하는 이유는 정규 표현식을 사용하여 출력에서 추론과 의도를 별도로 추출할 수 있기 때문입니다. 이를 통해 티켓을 라우팅할 사람을 결정하는 데 의도만 사용하는 등 티켓 라우팅 워크플로에서 대상 지정된 다음 단계를 만들 수 있습니다.

프롬프트 배포

프롬프트가 얼마나 잘 작동하는지 알기 어려운 경우 테스트 프로덕션 환경에 배포하고 평가를 실행해 보세요.

배포 구조를 만들어 보겠습니다. Claude 호출을 래핑하는 메서드 시그니처를 정의하는 것부터 시작하세요. 이미 작성하기 시작한 메서드를 가져와서 ticket_contents를 입력으로, reasoningintent의 튜플을 출력으로 반환하겠습니다. 기존 ML을 사용하는 기존 자동화가 있는 경우 대신 해당 메서드 시그니처를 따라야 합니다.

import anthropic
import re

# Anthropic API 클라이언트의 인스턴스 생성
client = anthropic.Anthropic()

# 기본 모델 설정
DEFAULT_MODEL="claude-3-haiku-20240307"

def classify_support_request(ticket_contents):
    # 분류 작업을 위한 프롬프트 정의
    classification_prompt = f"""고객 지원 티켓 분류 시스템 역할을 수행할 것입니다.
        ...
        ... 추론은 <reasoning> 태그로, 의도는 <intent> 태그로 묶어야 합니다. 추론과 의도만 반환하세요.
        """
    # 지원 요청을 분류하기 위해 프롬프트를 API로 전송합니다.
    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

    # Python의 정규 표현식 라이브러리를 사용하여 `reasoning`을 추출합니다.
    reasoning_match = re.search(
        r"<reasoning>(.*?)</reasoning>", reasoning_and_intent, re.DOTALL
    )
    reasoning = reasoning_match.group(1).strip() if reasoning_match else ""

    # 마찬가지로 `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

이 코드는 다음과 같은 작업을 수행합니다:

  • Anthropic 라이브러리를 가져오고 API 키를 사용하여 클라이언트 인스턴스를 생성합니다.
  • ticket_contents 문자열을 받는 classify_support_request 함수를 정의합니다.
  • classification_prompt를 사용하여 ticket_contents를 Claude에 분류하도록 보냅니다.
  • 응답에서 추출한 모델의 reasoningintent를 반환합니다.

파싱 전에 전체 추론 및 의도 텍스트가 생성될 때까지 기다려야 하므로 stream=False(기본값)로 설정합니다.


프롬프트 평가

프롬프트를 프로덕션 준비 상태로 만들려면 테스트와 최적화가 필요한 경우가 많습니다. 솔루션의 준비 상태를 판단하려면 앞서 설정한 성공 기준과 임계값을 기반으로 성능을 평가하세요.

평가를 실행하려면 실행할 테스트 케이스가 필요합니다. 이 가이드의 나머지 부분에서는 이미 테스트 케이스를 개발했다고 가정합니다.

평가 함수 작성

이 가이드의 예제 평가는 세 가지 주요 지표에 대한 Claude의 성능을 측정합니다:

  • 정확도
  • 분류당 비용

중요한 요소에 따라 다른 축에서 Claude를 평가해야 할 수도 있습니다.

이를 평가하려면 먼저 작성한 스크립트를 수정하고 예측된 의도와 실제 의도를 비교하고 올바른 예측의 백분율을 계산하는 함수를 추가해야 합니다. 또한 비용 계산 및 시간 측정 기능을 추가해야 합니다.

import anthropic
import re

# Anthropic API 클라이언트의 인스턴스 생성
client = anthropic.Anthropic()

# 기본 모델 설정
DEFAULT_MODEL="claude-3-haiku-20240307"

def classify_support_request(request, actual_intent):
    # 분류 작업을 위한 프롬프트 정의
    classification_prompt = f"""고객 지원 티켓 분류 시스템 역할을 수행할 것입니다.
        ...
        ...추론은 <reasoning> 태그로, 의도는 <intent> 태그로 묶어야 합니다. 추론과 의도만 반환하세요.
        """

    message = client.messages.create(
        model=DEFAULT_MODEL,
        max_tokens=500,
        temperature=0,
        messages=[{"role": "user", "content": classification_prompt}],
    )
    usage = message.usage  # 사용된 입력 및 출력 토큰 수에 대한 API 호출의 사용 통계를 가져옵니다.
    reasoning_and_intent = message.content[0].text

    # Python의 정규 표현식 라이브러리를 사용하여 `reasoning`을 추출합니다.
    reasoning_match = re.search(
        r"<reasoning>(.*?)</reasoning>", reasoning_and_intent, re.DOTALL
    )
    reasoning = reasoning_match.group(1).strip() if reasoning_match else ""

    # 마찬가지로 `intent`도 추출합니다.
    intent_match = re.search(r"<intent>(.*?)</intent>", reasoning_and_intent, re.DOTALL)
    intent = intent_match.group(1).strip() if intent_match else ""

      # 모델의 예측이 올바른지 확인합니다.
    correct = actual_intent.strip() == intent.strip()

    # 추론, 의도, 정답 여부 및 사용량을 반환합니다.
    return reasoning, intent, correct, usage

수정한 내용을 분석해 보겠습니다:

  • 테스트 케이스에서 actual_intentclassify_support_request 메서드에 추가하고 Claude의 의도 분류가 우리의 golden 의도 분류와 일치하는지 평가하기 위한 비교를 설정했습니다.
  • 사용된 입력 및 출력 토큰을 기반으로 비용을 계산하기 위해 API 호출에 대한 사용 통계를 추출했습니다.

평가 실행

적절한 평가를 위해서는 좋은 결과가 무엇인지 판단하기 위한 명확한 임계값과 벤치마크가 필요합니다. 위의 스크립트는 정확도, 응답 시간 및 분류당 비용에 대한 런타임 값을 제공하지만, 여전히 명확하게 설정된 임계값이 필요합니다. 예를 들면 다음과 같습니다:

  • 정확도: 95% (100개 테스트 중)
  • 분류당 비용: 현재 라우팅 방법에서 평균 50% 감소 (100개 테스트에서)

이러한 임계값이 있으면 규모에 맞게 빠르고 쉽게, 그리고 공정한 경험적 방법으로 어떤 방법이 가장 적합한지, 요구 사항에 더 잘 맞추기 위해 어떤 변경이 필요한지 알 수 있습니다.


성능 개선

복잡한 시나리오에서는 표준 프롬프트 엔지니어링 기술가드레일 구현 전략 이상의 추가 전략을 고려하는 것이 도움될 수 있습니다. 다음은 몇 가지 일반적인 시나리오입니다:

20개 이상의 의도 범주가 있는 경우 분류 계층 구조 사용

클래스 수가 증가함에 따라 필요한 예제 수도 증가하여 프롬프트가 다루기 힘들어질 수 있습니다. 대안으로 분류기 혼합을 사용하여 계층적 분류 시스템을 구현하는 것을 고려할 수 있습니다.

  1. 의도를 분류 트리 구조로 구성합니다.
  2. 트리의 모든 수준에서 일련의 분류기를 만들어 계단식 라우팅 접근 방식을 가능하게 합니다.

예를 들어, 티켓을 “기술 문제”, “청구 질문” 및 “일반 문의”로 광범위하게 분류하는 최상위 분류기가 있을 수 있습니다. 그런 다음 이러한 각 범주에는 분류를 더 세분화하기 위한 고유한 하위 분류기가 있을 수 있습니다.

  • 장점 - 더 큰 뉘앙스와 정확성: 각 상위 경로에 대해 다른 프롬프트를 만들어 보다 대상 지정되고 맥락에 맞는 분류가 가능합니다. 이는 정확도 향상과 고객 요청의 더 세분화된 처리로 이어질 수 있습니다.

  • 단점 - 대기 시간 증가: 여러 분류기로 인해 대기 시간이 증가할 수 있으므로 가장 빠른 모델인 Haiku로 이 접근 방식을 구현하는 것이 좋습니다.

가변성이 높은 티켓을 처리하기 위해 벡터 데이터베이스와 유사성 검색 검색 사용

예제 제공이 성능 향상에 가장 효과적인 방법이지만, 지원 요청이 매우 다양한 경우 단일 프롬프트에 충분한 예제를 포함하기 어려울 수 있습니다.

이 시나리오에서는 벡터 데이터베이스를 사용하여 예제 데이터 세트에서 유사성 검색을 수행하고 주어진 쿼리에 대해 가장 관련성이 높은 예제를 검색할 수 있습니다.

분류 레시피에 자세히 설명된 이 접근 방식은 정확도를 71%에서 93%로 향상시키는 것으로 나타났습니다.

예상되는 예외 사례를 구체적으로 고려

다음은 Claude가 티켓을 잘못 분류할 수 있는 시나리오입니다(상황에 따라 다른 시나리오가 있을 수 있음). 이러한 시나리오에서는 Claude가 예외 사례를 처리하는 방법에 대한 명시적인 지침이나 예제를 프롬프트에 제공하는 것을 고려하세요:


Claude를 더 큰 지원 워크플로에 통합

적절한 통합을 위해서는 Claude 기반 티켓 라우팅 스크립트가 더 큰 티켓 라우팅 시스템의 아키텍처에 어떻게 적합한지에 대한 몇 가지 결정을 내려야 합니다. 이를 수행하는 방법에는 두 가지가 있습니다:

  • 푸시 기반: 사용 중인 지원 티켓 시스템(예: Zendesk)이 웹훅 이벤트를 라우팅 서비스로 전송하여 코드를 트리거하고, 이는 의도를 분류하고 라우팅합니다.
    • 이 접근 방식은 웹 확장성이 더 뛰어나지만 공개 엔드포인트를 노출해야 합니다.
  • 풀 기반: 코드는 주어진 일정에 따라 최신 티켓을 가져와 풀 시간에 라우팅합니다.
    • 이 접근 방식은 구현이 더 쉽지만 풀 빈도가 너무 높으면 지원 티켓 시스템에 불필요한 호출을 할 수 있고 풀 빈도가 너무 낮으면 지나치게 느릴 수 있습니다.

이러한 접근 방식 중 하나를 위해서는 스크립트를 서비스로 래핑해야 합니다. 접근 방식의 선택은 지원 티켓팅 시스템이 제공하는 API에 따라 달라집니다.