先に結論から言うと、カスタマーサポートボットがお金を食う原因は、八割方モデルの単価が高いからではなく、呼び出し方に問題があります。社内のある日次アクティブ数千のアフターサポートQ&Aボットは、リリース初月の請求書が予算の3倍に跳ね上がりました。調査してみると、モデル単価は一切変わっておらず、すべて呼び出し構造上の見えないコストでした。この記事では振り返りの過程を書き出します。大規模モデルAPIのコスト最適化に関わる方は、ご自身の請求書と照らし合わせて確認してみてください。
請求書の異常はどんな見た目か
異常の特徴は「総額が高い」ことではなく、「構造がおかしい」ことです。日別の呼び出し明細を集計したところ、3つのおかしな点が見つかりました。呼び出し量が最も多い日は、1リクエストあたりの平均トークン数が増加傾向にあること。リトライ回数の割合が2割近くに達していること。同じユーザーの質問でも、短ければ数百トークン、長ければ1万トークンと、分散が極端に大きいこと。この3つが揃えば、問題がモデル側ではなく、自分たちの呼び出しチェーンにあるとほぼ特定できます。
4つの見えないコスト、1つ1つがより隠蔽されている
第一に、フラッグシップモデルに雑用をさせている。当初は手間を省くため、すべてのリクエストを一律でフラッグシップモデルに通していました。しかしカスタマーサポートのシナリオでは、7割以上が「注文はどこか」「どう返品するか」といった意図認識と定型応答であり、こうしたタスクは小型モデルで十分に対応でき、コストは桁違いです。フラッグシップモデルに「営業時間は何時か」を答えさせるのは、トラックで出前を届けるようなものです。
第二に、コンテキストの無制限な膨張。マルチターン会話では履歴メッセージを全量詰め戻していました。ユーザーが10ターン目まで話すと、履歴だけでトークンの大部分を占めます。さらに厄介なのは、多くの履歴が現在の質問と全く関係なく、ただのお供状態であることです。コンテキストは長ければ賢くなるわけではなく、一定の長さを超えると精度の向上は限定的なのに、コストは線形に上昇します。
第三に、リトライの嵐。簡単な失敗時リトライを設定していましたが、バックオフとサーキットブレーカーを実装していませんでした。上流で偶発的なタイムアウトが起きると、同じバッチのリクエストが繰り返し投げられ、失敗すればリトライ、リトライしてまた失敗してまたリトライ。請求書上のこの部分の呼び出しはすべて無駄金で、ユーザー側に見えるのは依然としてエラーです。
第四に、ストリーミングと非ストリーミングの二重課金。これが最も見落とされやすいものです。ある処理系では完全な結果を取得して後処理するため非ストリーミングで1回呼び、フロントエンドではタイプライター効果のためにストリーミングでさらに1回呼んでいました。同じ質問に2回分のお金。後にストリーミング受信・ローカル組み立てに統一して、この重複コストはようやく解消しました。
階層型ルーティングをどう実装するか
考え方は複雑ではありません。タスクの難易度で振り分けるのです。意図認識、スロット抽出、定型応答といったものは軽量モデルに通し、本当に推論・多段判断・感情のケアが必要な複雑な会話だけをフラッグシップモデルに任せます。中間にモデルゲートウェイを1層挟んで判断させ、リクエストが入ってきたらまず分類器を通し、タスクタグを付けてからどのモデルにルーティングするか決めます。
私たちはタスクごとに最適なモデルを自動選択するこのロジックを使い、硅碳相変のマルチモデルルーティング上で一巡の比較を行いました。シンプルなタスクを軽量モデルに切り替えた後、全体コストは明らかに下がり、応答も速くなりました。ここでの鍵は「どのモデルを使うか」ではなく、「どのタスクにどのモデルを割り当てるか」というマッピングテーブルを継続的に調整することです。リリース初期は経験で設定し、2週間運用後に実際のヒット率で再キャリブレーションしたところ、勘で設定するよりはるかに良い結果でした。マルチモデル統一接続の利点もこの時に現れ、ルーティング戦略を変えてもビジネスコードを変更する必要がなく、ゲートウェイ層で調整するだけですみます。
最適化前後の請求書比較
具体的な数字は出さず、比率で報告します。総呼び出し量は変わっていません。ユーザー数が変わっていないからです。総コストは約6割減少し、うちフラッグシップモデルの呼び出し比率はほぼ100%から3割程度に下がり、残りは軽量モデルに分流しました。リトライ関連の呼び出しは2割近くから1桁台のパーセンテージに圧縮。1リクエストあたりの平均トークン数は約4割減少し、主にコンテキストのトリミングによるものです。ストリーミングの二重課金部分は直接ゼロになりました。全体で計算すると、予算の3倍超過から予算内に戻り、さらに余裕があります。
監視とアラートをどう設定するか
節約したお金を守るには、自己管理ではなく監視に頼ります。4つのアラートを設定しました。1リクエストのトークン数がしきい値を超えたら発報し、コンテキストの暴走を防ぐ。リトライ率が設定比率を超えたら発報し、リトライの嵐を防ぐ。フラッグシップモデルの呼び出し比率が異常に上昇したら発報し、ルーティングが機能していない可能性を示す。日次コストの前日比上昇率がしきい値を超えたら発報する。この4つは複雑にする必要はなく、日次集計とライン超過アラートで十分です。Token課金モデルでは、コストはリアルタイムで累積するため、月末に請求書を見てから最適化するのでは、お金はすでに使われてしまっています。
一言でまとめると、カスタマーサポートボットのコストの大半は呼び出し構造にあり、モデル単価にはありません。階層型ルーティング、コンテキストのトリミング、リトライ制御、ストリーミング統合の4つをしっかりやれば、請求書は自然に下がります。さらに一歩進めて、もしあなたのシナリオにRAG検索があるなら、ベクトルDBの召回件数も同じ考え方で一通り確認する価値があります。