チケットのルーティング
このガイドでは、顧客の意図、緊急度、優先度、顧客プロファイルなどに基づいて、大規模な顧客サポートチケットを分類するためにClaudeの高度な自然言語理解機能を活用する方法について説明します。
チケットのルーティングにClaudeを使用するかどうかを定義する
以下は、分類タスクに従来のMLアプローチではなくClaudeのようなLLMを使用すべき重要な指標です。
LLMサポートワークフローの構築とデプロイ
現在のサポートアプローチを理解する
自動化に飛び込む前に、既存のチケットシステムを理解することが重要です。まず、サポートチームが現在どのようにチケットのルーティングを処理しているかを調査します。
以下のような質問を検討してください:
- どのSLA/サービスオファリングを適用するかを決定するために使用される基準は何ですか?
- チケットのルーティングは、チケットがどのサポートレベルまたは製品スペシャリストに送られるかを決定するために使用されていますか?
- すでに自動化されたルールまたはワークフローがありますか? それらが失敗するのはどのような場合ですか?
- エッジケースまたはあいまいなチケットはどのように処理されますか?
- チームはどのようにチケットに優先順位を付けていますか?
人間が特定のケースをどのように処理しているかをより理解すればするほど、Claudeとの連携によりそのタスクを実行することができるようになります。
ユーザーの意図カテゴリを定義する
Claudeを使用して正確にサポートチケットを分類するには、ユーザーの意図カテゴリを明確に定義することが重要です。システム内でチケットを効果的にルーティングするClaudeの能力は、システムのカテゴリがどれだけ明確に定義されているかに直接比例します。
以下は、ユーザーの意図カテゴリとサブカテゴリの例です。
意図に加えて、チケットのルーティングと優先順位付けは、緊急度、顧客タイプ、SLA、言語などの他の要因によっても影響を受ける可能性があります。自動ルーティングシステムを構築する際は、他のルーティング基準も考慮するようにしてください。
成功基準を確立する
サポートチームと協力して、測定可能なベンチマーク、しきい値、目標を含む明確な成功基準を定義します。
以下は、サポートチケットのルーティングにLLMを使用する際の標準的な基準とベンチマークです。
以下は、LLMを使用するかどうかに関係なく、役立つ可能性のある一般的な成功基準です。
適切なClaudeモデルを選択する
モデルの選択は、コスト、精度、応答時間のトレードオフに依存します。
多くの顧客は、Claude 3ファミリーの中で最も高速でコスト効率の良いモデルでありながら、優れた結果を提供するため、claude-3-haiku-20240307
を理想的なモデルであると考えています。分類問題が深い専門知識や大量の意図カテゴリの複雑な推論を必要とする場合は、より大きな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>
リクエストには、適用可能な意図が1つだけある場合があります。リクエストに最も適した意図のみを含めてください。
例として、次のリクエストを考えてみましょう:
<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文字列を使用してプロンプトテンプレートを作成し、
ticket_contents
を<request>
タグに挿入できるようにします。 - Claudeに、チケットの内容を注意深く分析して顧客の中心的な意図とニーズを判断する分類システムとしての明確に定義された役割を与えます。
- 適切な出力フォーマットについてClaudeに指示します。この場合、
<reasoning>
タグ内に推論と分析を提供し、その後に<intent>
タグ内に適切な分類ラベルを提供します。 - 有効な意図カテゴリを指定します: “サポート、フィードバック、苦情”、“注文追跡”、“返金/交換”。
- 出力のフォーマット方法を示すいくつかの例(few-shot promptingとも呼ばれます)を含めます。これにより、精度と一貫性が向上します。
Claudeに応答を様々なXMLタグセクションに分割させる理由は、正規表現を使用して推論と意図を出力から個別に抽出できるようにするためです。これにより、チケットのルーティングワークフローで、意図のみを使用してチケットのルーティング先の人を決定するなど、ターゲットを絞った次のステップを作成できます。
プロンプトをデプロイする
テスト環境にデプロイして評価を実行しないと、プロンプトがどれだけうまく機能するかを知るのは難しいです。
デプロイ構造を構築しましょう。Claudeへの呼び出しをラップするメソッドシグネチャを定義することから始めます。すでに書き始めているメソッドを使用します。このメソッドは、入力としてticket_contents
を受け取り、出力としてreasoning
とintent
のタプルを返します。既存の自動化で従来の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に分類のために送信します。- モデルの
reasoning
とintent
を応答から抽出して返します。
推論と意図のテキスト全体が生成されるまで待つ必要があるため、解析する前にstream=False
(デフォルト)に設定します。
プロンプトを評価する
プロンプトを本番環境で使用できるようにするには、テストと最適化が必要になることがよくあります。ソリューションの準備状況を判断するには、前に確立した成功基準とスレッショルドに基づいてパフォーマンスを評価します。
評価を実行するには、実行するためのテストケースが必要です。このガイドの残りの部分では、すでにテストケースを開発済みであることを前提としています。
評価関数を作成する
このガイドの評価例では、Claudeのパフォーマンスを3つの主要な指標で測定します:
- 精度
- 分類あたりのコスト
あなたにとって重要な要因に応じて、他の軸で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_intent
をclassify_support_request
メソッドに追加し、Claudeの意図分類が私たちのゴールデン意図分類と一致するかどうかを評価する比較を設定しました。 - 入力トークンと出力トークンの使用量に基づいてコストを計算するために、API呼び出しの使用状況統計を抽出しました。
評価を実行する
適切な評価には、良い結果とは何かを判断するための明確なしきい値とベンチマークが必要です。上記のスクリプトでは、精度、応答時間、分類あたりのコストの実行時の値が得られますが、明確に確立されたしきい値が必要です。例えば:
- 精度: 95% (100回のテストのうち)
- 分類あたりのコスト: 現在のルーティング方法から平均50%削減 (100回のテストで)
これらのしきい値があれば、大規模に、そして公平な経験則で、どの方法があなたにとって最適であり、要件により適合するためにどのような変更が必要かを迅速かつ容易に判断できます。
パフォーマンスを改善する
複雑なシナリオでは、標準的なプロンプトエンジニアリングの手法とガードレール実装戦略を超えて、パフォーマンスを改善するための追加の戦略を検討すると役立つ場合があります。以下は一般的なシナリオです:
20以上の意図カテゴリがある場合は、分類階層を使用する
クラスの数が増えると、必要な例の数も増え、プロンプトが扱いにくくなる可能性があります。代替案として、分類器の組み合わせを使用して階層的な分類システムを実装することを検討できます。
- 意図を分類ツリー構造で整理します。
- ツリーのすべてのレベルで一連の分類器を作成し、カスケードルーティングアプローチを可能にします。
例えば、チケットを “技術的な問題”、“請求に関する質問”、“一般的な問い合わせ” に大まかに分類するトップレベルの分類器を用意することができます。これらの各カテゴリには、分類をさらに絞り込むための独自のサブ分類器を設定できます。
-
長所 - より大きなニュアンスと精度: 各親パスに異なるプロンプトを作成できるため、より的を絞ったコンテキストに特化した分類が可能になります。これにより、精度が向上し、顧客のリクエストをよりニュアンスを持って処理できるようになります。
-
短所 - レイテンシーの増加: 複数の分類器を使用すると、レイテンシーが増加する可能性があることに注意してください。最速のモデルであるHaikuでこのアプローチを実装することをお勧めします。
高度に可変なチケットを処理するためにベクトルデータベースと類似性検索検索を使用する
例を提供することがパフォーマンスを向上させる最も効果的な方法ですが、サポートリクエストの変動が大きい場合、1つのプロンプトに十分な例を含めるのは難しい場合があります。
このシナリオでは、ベクトルデータベースを使用して、例のデータセットから類似性検索を行い、特定のクエリに最も関連性の高い例を取得することができます。
この分類レシピで詳しく説明されているこのアプローチは、パフォーマンスを71%の精度から93%の精度に向上させることが示されています。
予想されるエッジケースを具体的に考慮する
以下は、Claudeがチケットを誤って分類する可能性のあるシナリオです(状況によっては他にもある可能性があります)。これらのシナリオでは、Claudeがエッジケースをどのように処理すべきかについて、プロンプトに明示的な指示または例を提供することを検討してください:
Claudeをより大きなサポートワークフローに統合する
適切な統合には、Claude ベースのチケットルーティングスクリプトが、より大きなチケットルーティングシステムのアーキテクチャにどのように適合するかについていくつかの決定を下す必要があります。これを行う方法は2つあります:
- プッシュベース: 使用しているサポートチケットシステム(例: Zendesk)が、Webhookイベントをルーティングサービスに送信することでコードをトリガーし、意図を分類してルーティングします。
- このアプローチは、Webスケーラビリティが高くなりますが、パブリックエンドポイントを公開する必要があります。
- プルベース: コードは、特定のスケジュールに基づいて最新のチケットをプルし、プルの時点でそれらをルーティングします。
- このアプローチは実装が容易ですが、プルの頻度が高すぎる場合は不必要にサポートチケットシステムを呼び出す可能性があり、プルの頻度が低すぎる場合は遅すぎる可能性があります。
これらのアプローチのいずれかについて、スクリプトをサービスでラップする必要があります。アプローチの選択は、サポートチケットシステムが提供するAPIによって異なります。