コンタクトセンターのAIチャットボットや自動応答システムで、問い合わせ内容を部署振り分けするルーティング処理にGPT-4oやClaude 3.5 Sonnetのようなフロンティアモデル(最も性能の高い大規模言語モデル群)をそのまま使っているなら、一度構成を見直す価値があります。この記事では、単純な分類タスクに高性能LLMを使い続けることで生じる遅延・コスト・可用性の問題と、具体的な切り分け方法を整理します。
対象は、LangGraphなどのエージェントフレームワーク(複数のAI処理を順序立てて組み合わせる仕組み)でカスタマーサポートの自動振り分けを構築している開発者やアーキテクトです。すでに本番稼働していて、応答が遅い・API料金が想定を超えているという悩みを抱えている方にも参考になるはずです。
何が起きるか:ルーティングのためにフルパワーのLLMを呼ぶという過剰設計
典型的な多段エージェント型のコンタクトセンターAIは、ユーザーの問い合わせを「技術サポート」「請求」「データ利用量」「解約・引き止め」のようなカテゴリに振り分けてから、それぞれの専門処理に渡す構造を取ります。
この最初の振り分け判断(ルーティング)に、GPT-4oのような汎用フロンティアLLMを使うケースが珍しくありません。振り分け自体は「どのカテゴリに属するか」を当てるだけの分類タスクですが、応答生成までフルで担える強力なモデルにそのまま判断させてしまう構成です。
結果として何が起きるかというと、単純な分類のためだけに1リクエスト1000ms〜2500ms程度の応答時間がかかります。ピーク時やAPI側のリトライが絡むと20秒〜30秒まで伸びるケースも報告されています。チャットやIVR(音声自動応答)のようなリアルタイム対話では、この待ち時間がそのままユーザー体験の劣化に直結します。
なぜ起きるか:分類問題と生成問題を同じモデルに任せている
原因を分解すると、まず「タスクの難易度とモデルの性能を揃えていない」という設計判断のズレがあります。ルーティングは本来、4〜5択程度のカテゴリ分類であり、決定木や軽量な分類器でも十分対応できる場合があるタスクです。
それにもかかわらず、数十億から数千億パラメータ規模の汎用モデルに毎回フルリクエストを投げる構成にすると、モデルの計算コストに見合わない処理を繰り返すことになります。これは処理能力とタスクの規模が釣り合っていない、典型的なアーキテクチャ上の無駄です。
次に、外部API依存によるレート制限(429エラー、短時間に大量リクエストを送ると拒否される制御)のリスクがあります。通信障害や災害時に問い合わせ件数が通常の5倍に急増するような局面では、ルーティングのためのLLM呼び出しそのものが先に詰まり、本来対応すべき緊急の問い合わせが処理待ちになる可能性があります。
さらにコスト構造の問題もあります。ルーティング判断のたびにフロンティアモデルのトークン課金が発生するため、問い合わせ件数が月間数百万件規模になる通信キャリアやISPでは、この振り分けだけの処理が無視できない費用を積み上げます。可用性・性能・コストの3つが同時に劣化する構造になっているわけです。
自分のプロジェクトが該当するか確認する方法
まず、エージェントのグラフ定義やルーティング処理の実装を開き、条件分岐の中でLLM呼び出しが発生しているかを確認します。LangGraphを使っている場合は、add_conditional_edges の分岐関数内でChatOpenAIやChatAnthropicのようなLLMクライアントを直接呼んでいないかを見てください。
grep -rn "add_conditional_edges" ./src | head -20
grep -rn "ChatOpenAI\|ChatAnthropic\|gemini" ./src/router*.py次に、ルーティング用のプロンプトがどの程度複雑かを確認します。「以下のテキストを4つのカテゴリのどれかに分類してください」程度の指示であれば、分類専用の軽量な仕組みに置き換えられる可能性が高いです。逆に、文脈理解や微妙な意図判断を伴う分岐であれば、LLMの判断力がそのまま必要になるケースもあります。
最後に、APIのレイテンシログとコスト請求を実際に確認します。クラウドプロバイダのダッシュボードやAPM(アプリケーション性能監視)ツールで、ルーティング用エンドポイントの呼び出し回数とp95レイテンシ(全体の95%がその時間以内に収まる応答速度の指標)を見てみると、想定以上にルーティングだけで時間とコストを消費している実態が見えてくることがあります。
対策の手順:確信度ゲート型ルーティングへの置き換え
対策の基本方針は、確信度が高い場合は軽量モデルやルールベースで即決し、曖昧な場合だけLLMにエスカレーションするという二段構えの設計です。これは確信度ゲーティング(confidence-gated routing)と呼ばれる考え方です。
手順としては、まず軽量な分類モデルまたは埋め込みベースの類似度判定(文章をベクトル化してカテゴリの代表例と比較する手法)を用意します。この一次判定にかかる時間はミリ秒単位(56msから167ms程度のレンジが一つの目安)に収めることを目指します。
次に、一次判定の結果に確信度スコアを持たせ、しきい値を設定します。しきい値を超えた場合はそのまま自律的に振り分け、下回った場合のみ既存のフロンティアLLMに判断を委ねるフォールバック経路を残します。これにより、曖昧なケースの精度は従来のLLMルーターと同等以上を維持しつつ、大部分の定型的な問い合わせを高速処理できます。
result = fast_classifier.predict(ticket_text)
if result.confidence >= 0.85:
route_to(result.category)
else:
category = llm_router.classify(ticket_text)
route_to(category)最後に、障害時の挙動を必ず検証します。LLM API側で429エラーが返ってきた場合に、一次分類器だけでどこまで処理を継続できるかをロードテストで確認してください。通信障害時の問い合わせ急増のようなバースト負荷を想定したテストが特に重要です。
導入後は、全体のLLM呼び出し削減率・分類精度・平均レイテンシの3指標をモニタリングし、しきい値を継続的に調整していくことになります。精度が落ちた場合はしきい値を引き上げ、LLM呼び出し比率とのバランスを取り直す運用が必要です。
まとめ
ルーティング処理にフロンティアLLMをそのまま使う構成は、分類タスクの難易度に対してモデルの計算コストが過剰になりやすいという非機能要件上の落とし穴です。
まず自分のコードベースで条件分岐内のLLM呼び出し箇所をgrepで洗い出し、プロンプトの複雑さとレイテンシログを確認してください。
そのうえで、軽量分類器による一次判定としきい値ベースのフォールバックを組み合わせる二段構えの設計に切り替えることで、通常時のコストと遅延を抑えつつ、障害時の負荷急増にも耐えやすい構成に近づけられます。