Claudeでサポートチケットを自動振り分けする評価関数と階層化
Anthropic公式のチケット振り分けガイドを、意図カテゴリの定義・評価関数・20超カテゴリ時の階層化に絞って読み解きます。閾値の置き方と階層ごとの測り方まで扱います。
Claudeでサポートチケットを振り分けるとき、成否を分けるのは意図カテゴリの定義と、動かす前に決める評価関数です。カテゴリが20を超えたら、1つのプロンプトに詰め込まず分類器を木構造に分ける手があります。Anthropic公式のチケット振り分けガイドに沿って、この3点を順に見ます。
チケット振り分けにClaudeを使う判断基準
振り分けは分類タスクの一種です。ガイドは、従来の機械学習ではなくClaudeのようなLLMを選ぶ目安を7つ挙げています。
- ラベル付きの学習データが少ない(数十件の例で足りるとされる)
- カテゴリが時間とともに変わりそう
- 非構造の長文を扱う
- 分類規則が例ではなく意味の条件で書ける
- 判断理由を人が読める形で残したい
- 曖昧なチケットや外れ値を扱いたい
- モデルを分けずに多言語へ対応したい
逆に言えば、カテゴリが固定で、ラベル付きデータが潤沢にあり、規則が単純な現場では、LLMに切り替える利点は薄れます。導入前に自社の現状を確かめる問いもガイドは用意しています。SLAはどの基準で決まるか、担当の階層や製品専門家への割り当てに振り分けを使っているか、既存の自動ルールはどこで失敗するか、曖昧なチケットを誰がどう扱っているか、の4点です。人間の運用を言語化できるほど、Claudeへの指示も書きやすくなります。
意図カテゴリの定義で精度の上限が決まる
ガイドは、Claudeの振り分け精度はカテゴリの定義の明確さに比例すると述べています。例として挙がるのは次の12分類です。
- 技術的な問題
- アカウント管理
- 製品情報
- ユーザー案内
- フィードバック
- 注文関連
- サービス依頼
- セキュリティ
- コンプライアンスと法務
- 緊急対応
- トレーニングと教育
- 連携とAPI
ガイドの例示は自社の分類を作る叩き台で、それぞれに下位分類が3〜4個ずつぶら下がります。下位の43項目を平たく並べれば、選択肢は20を優に超えます。
ここが階層化の出発点です。ガイドの例のプロンプトが平たいまま扱うのは、「サポート・フィードバック・苦情」「注文追跡」「返金・交換」の3ラベルだけです。
意図以外の軸も振り分けに効きます。ガイドは緊急度、顧客の種別、SLA、言語を挙げています。意図の1軸に全部を押し込まず、別の判定として分ける設計を考えておくと、カテゴリ名が膨らむのを防げます。
最小のプロンプトは理由と意図を別タグで返させる
公式の例は、Claudeを「チケット分類システム」として振る舞わせ、<reasoning>タグに分析を、<intent>タグに分類ラベルを出させます。有効な意図は列挙し、「1件につき当てはまる意図は1つだけ」と明示し、出力例を複数添えます。
出力を2つのタグに分ける理由は、正規表現で別々に取り出せるからです。振り分け先の決定にはintentだけを使い、reasoningは監査や誤分類の調査に回せます。
import re
def parse(text):
r = re.search(r"<reasoning>(.*?)</reasoning>", text, re.DOTALL)
i = re.search(r"<intent>(.*?)</intent>", text, re.DOTALL)
return (r.group(1).strip() if r else "",
i.group(1).strip() if i else "")ガイドの実装は、既定モデルにclaude-haiku-4-5-20251001を置き、max_tokensは500、stream=Falseです。理由と意図の全文を生成し終えてから解析するので、ストリーミングにする利点がないためです。モデルの選び方は、費用・精度・応答時間の天秤で決めます。ガイドは多くの顧客がHaikuを適任とみていると述べ、専門知識や多数のカテゴリ、複雑な推論が要るならSonnetを選択肢に挙げています。最新のモデル構成はClaudeモデル一覧で確認できます。
評価関数は精度・費用・時間をまとめて返す
プロンプトが動いたら、本番に出す前に評価関数を作ります。公式の評価版は、classify_support_requestに正解ラベルactual_intentを渡し、予測と一致したかをcorrectとして返します。あわせてmessage.usageから入出力トークンを取り、費用計算に使います。
ガイドの記述には1点ずれがあります。評価の指標を「3つ」と書きながら、箇条書きは精度と分類あたりの費用の2項目で、本文は応答時間の計測にも触れています。実際に測るのは精度・費用・時間の3つと読むのが自然です。
次は、その3つをまとめて集計する評価ループの一例です。公式のコードではなく、公式のcorrectとusageを使う形に沿って組んだ例です。
import time
# 単価は自社の契約値に置き換える(100万トークンあたり)
PRICE_IN, PRICE_OUT = 1.0, 5.0
def evaluate(cases):
ok, cost, secs = 0, 0.0, []
for text, actual in cases:
t0 = time.time()
_, intent, correct, usage = classify_support_request(
text, actual)
secs.append(time.time() - t0)
ok += correct
cost += (usage.input_tokens * PRICE_IN
+ usage.output_tokens * PRICE_OUT) / 1e6
n = len(cases)
return {"accuracy": ok / n, "cost_per_ticket": cost / n,
"p50_sec": sorted(secs)[n // 2]}大事なのは関数より閾値です。ガイドは、精度95%(100件のテストで)と、分類あたりの費用が現行の振り分け方法より平均50%減、という例を挙げています。閾値がないと、どの変更が改善なのかを客観的に言えません。
成功基準は2系統に分かれる
ガイドの成功基準は、LLM特有のものと、手段を問わないものに分かれます。
| 系統 | 指標 | ガイドの目安 |
|---|---|---|
| LLM特有 | 指標分類の一貫性 | ガイドの目安同種のチケットで95%以上 |
| LLM特有 | 指標適応速度 | ガイドの目安新カテゴリを50〜100件で90%超 |
| LLM特有 | 指標多言語 | ガイドの目安主言語以外の精度低下を5〜10%以内 |
| LLM特有 | 指標エッジケース | ガイドの目安難しい入力で80%以上 |
| LLM特有 | 指標公平性 | ガイドの目安顧客グループ間の精度差を2〜3%以内 |
| LLM特有 | 指標プロンプト効率 | ガイドの目安題名と短い説明だけで90%以上 |
| LLM特有 | 指標説明の質 | ガイドの目安5段階評価の平均4以上 |
| 共通 | 指標振り分け精度 | ガイドの目安90〜95% |
| 共通 | 指標再振り分け率 | ガイドの目安10%未満(上位で5%以下) |
| 共通 | 指標エスカレーション率 | ガイドの目安20%未満(上位で10%以下) |
共通側にはほかに、割り当てまでの時間・初回解決率・平均対応時間・満足度・担当者の生産性・セルフサービス解決率・チケット単価も並びます。これらは業界の目安として書かれたもので、ガイドは「業界により幅がある」と添えています。
評価データの作り方
テストデータの作り方は、公式の評価設計ガイドが原則を3つ示しています。実際のタスクの分布を映すこと、可能な限り自動採点にすること、少数の高品質な手採点より多数の自動採点を優先することです。
振り分けに当てはめると、次のような作りになります。
- 正解ラベルは過去のチケットの最終的な担当先から起こし、人の判断が割れるものは別の束に分ける
- 曖昧なチケット、空や極端に長い入力、複数の用件が混ざる入力を意図的に入れる
- 集計は全体の精度だけでなく、カテゴリ別の正答数も出す
3つ目が実務では効きます。全体で95%でも、件数の少ない「セキュリティ」や「緊急対応」で外していれば、被害が大きいのはそちらです。カテゴリ別の誤りを見れば、定義のあいまいな分類が見つかります。
カテゴリが20を超えたら分類器を木構造に分ける
カテゴリが増えると、必要な例も増え、プロンプトが扱いにくくなります。ガイドの提案は、意図を木構造に整理し、各階層に分類器を置いて段階的に振り分ける方法です。
例では、最上位が「技術的な問題」「請求」「一般的な問い合わせ」に大きく分け、それぞれに専用の下位分類器を持たせます。長所は、親の経路ごとに別のプロンプトを書けるため、文脈に合った分類ができて精度も上がりやすいことです。短所は、分類器が複数になるぶん遅延が増えることで、ガイドは最速のHaikuで実装するよう勧めています。
次は、この段階分類の骨格の例です。公式の実装ではなく、classify_support_requestと同じ形の関数を階層ごとに呼び分ける想定で組んでいます。
TREE = {
"技術的な問題": ["ソフトのバグ", "互換性", "性能"],
"請求": ["請求内容", "返金", "プラン変更"],
"一般的な問い合わせ": ["機能", "価格", "在庫"],
}
def route(text):
top = classify(text, list(TREE)) # 1段目
if top not in TREE:
return "manual_review"
sub = classify(text, TREE[top]) # 2段目
return sub if sub in TREE[top] else "manual_review"classifyは、渡した選択肢だけを<intent>の候補に入れるように、公式のプロンプトを差し替えた関数を指します。2段目のプロンプトには、その親に固有の定義や例だけを載せられます。木の外の答えが返ったら人の確認に回す分岐は、ガイドにはない筆者の追加です。
階層ごとに測ると誤りの場所が分かる
段階分類の評価は、最終ラベルの精度だけでは足りません。1段目の精度、1段目が正しかったときの2段目の精度、最終精度の3つを並べて見ます。誤りが積み重なる構造なので、たとえば各段が95%なら、単純計算で最終は約90%です。これはガイドの数字ではなく掛け算の結果ですが、階層を増やすほど閾値を上げないと最終精度を保てないことは読み取れます。
木の分け方にも判断が要ります。3〜4個の子を持つ枝を2層にするのと、7個前後を1層にするのとでは、遅延と精度の得失が変わります。ガイドは具体的な分岐数を示していません。自社のデータで両案を評価関数にかけて決めます。
例が足りないときは類似検索で例を選ぶ
ガイドは、例を示すのが精度を上げる最も効く方法だとしつつ、問い合わせのばらつきが大きいと、1つのプロンプトに十分な例を入れにくいと述べています。その場合に、ベクトルデータベースの類似検索で、入力に近い例だけを取り出す手を挙げています。公式のクラシフィケーション用レシピでは、この方法で精度が71%から93%に上がったとされています。
階層化と類似検索は別の解決策です。カテゴリ数が多いなら階層化、同じカテゴリ内で表現がばらつくなら例の検索、と課題で切り分けます。
誤分類しやすい3つの場面
ガイドは、Claudeが外しやすい場面を3つ挙げ、対処をプロンプトへの明記に置いています。
| 場面 | 例 | 対処 |
|---|---|---|
| 遠回しな依頼 | 例「荷物が2週間届かない」が注文状況の問い合わせにあたる | 対処実例と意図の組を示す。判断理由を添えると一般化しやすい |
| 感情への引きずられ | 例不満の表明に反応して根本の用件を見落とす | 対処感情を無視して意図だけを分析するよう指示する |
| 複数の用件 | 例主たる用件を決められない | 対処意図の優先順位を明記する |
評価データには、この3つを1件ずつ以上入れておくと、プロンプトを直したときの回帰を早く見つけられます。
既存のヘルプデスクにつなぐ2つの方式
つなぎ込みには、プッシュ型とプル型があります。プッシュ型はZendeskのようなチケット管理システムがウェブフックで振り分けサービスを呼び出す形で、スケールしやすい一方、公開エンドポイントが要ります。プル型は一定間隔で新着を取りに行く形で、実装は楽ですが、間隔が短いと無駄な呼び出しが増え、長いと遅くなります。どちらを選ぶかは、チケット管理システムが提供するAPIで決まります。
Zendeskでの実装例はZendeskチケット分析に、応対側のチャットボットはカスタマーサポートチャットボットの実装にあります。導入企業ごとの自動化の設計はClaudeカスタマーサポート導入事例が比較しています。
まとめ
振り分けの精度は、モデルの賢さより、カテゴリの定義と評価の設計で決まる部分が大きい作業です。カテゴリ名を決める前に閾値を書き、評価関数で全体とカテゴリ別の精度を測り、20を超えるなら階層ごとに測る。この順に進めると、変更のたびに良くなったかを数字で言えます。