はじめに — つまずきに寄り添って
複数のモデルやプロバイダが増えてくると「どの入力をどのモデルに送るか」を決めるだけで運用が止まってしまうことがあります。精度重視にするとコストが跳ね上がる、低コストにするとクレームが増える、人手レビューキューが詰まる──こうした現場の悩みに寄り添い、現実的に動くルール設計とPythonベースのルーター実装・テスト・運用手順を示します。第106回で扱った段階的ロールアウトや第99回のフェイルオーバーの知見を前提に、実務でそのまま役立つ手順を優先します。
1) なぜリクエストルーティングが必要か(ユースケースと期待効果)
複数モデルを使い分ける理由は主に次の4点です。
- コスト最適化:高頻度の簡易応答は安価なモデルへ、重要度が高いものは高品質モデルへ
- 品質確保:敏感領域や法規制のあるケースはより厳格なモデルへ振り分ける
- レイテンシ管理:即時応答が必要な処理は低遅延モデルへ振る
- 信頼性向上:プロバイダ障害時のフェールオーバーや再試行戦略の実現
2) 要件整理:精度・コスト・レイテンシ・信頼度・法規制
ルーティング設計の出発点は要件の優先順位付けです。以下の表は要件定義のチェックリスト例です。
| 観点 | 確認項目(例) | 運用上の閾値例 |
|---|---|---|
| 精度 | 誤答の許容度、重要度タグ | 高重要度は誤答率1%未満 |
| コスト | 1リクエスト当たり予算、月間限度 | 平均コスト0.02USD以下(例) |
| レイテンシ | 許容応答時間、SLA | インタラクティブは200ms以内 |
| 信頼度 | 回答の信頼度スコア、外部検証 | 信頼度<0.6はレビュー行き |
| 法規制・安全 | 個人情報、医療、金融領域の扱い | 該当は閉域モデルまたはオンプレ優先 |
3) ルール設計:優先度、閾値、入力分類、ブラックリスト
実際のルーティングは複数ルールの組み合わせです。重要なのはシンプルさと可観測性です。
基本ルールテンプレート(優先度順):
| 優先度 | 判定条件 | 振り分け先 | 備考 |
|---|---|---|---|
| 1(最優先) | 法規制対象または機密フラグ | オンプレ/厳格モデル | 外部送信禁止ルール |
| 2 | 高重要度タグ(契約書レビュー等) | 高品質モデル | コスト固定化の対象 |
| 3 | 入力長が短く即時応答が必要 | 低レイテンシ高速モデル | コスト優先プール |
| 4 | 信頼度スコアが低い(モデル予測値) | 人手レビューキュー | 自動応答を止める |
| 5(デフォルト) | それ以外 | バランスモデル | コストと品質の折衷 |
4) Pythonで作るルーター設計図(モジュール構成)
実装は小さなモジュールに分割してテストしやすくします。主なモジュール構成例は次の通りです。
| モジュール | 役割 |
|---|---|
| request_parser | 入力からintent、length、metadataを抽出 |
| scorer | 信頼度スコア・リスクスコアを算出 |
| cost_estimator | モデル別の予想コスト・遅延を返す |
| router | ルールに基づいて振り分け決定 |
| adapters | 各プロバイダ・モデルへの送信を抽象化 |
| monitoring | ログ出力、メトリクス集計、アラート発行 |
| tests | ルーティングの単体テスト、シミュレーション |
5) 具体実装例(決定ロジック・コスト推定・信頼度計算・フェールバック)
ここでは実装方針の要点と簡潔な記述例を示します。詳細なリポジトリは付録提案として後述します。
リクエスト判定の流れ(擬似コード説明)
単純化したルーターの流れは次の通りです。各行は一つの判断で、上から順に評価します。
| 処理 | 一行サンプル(Python風) |
|---|---|
| パース | intent, length, metadata = parse_request(req) |
| 法規制チェック | if metadata.get(‘sensitive’): return ‘onprem_strict’ |
| 重要度判定 | if metadata.get(‘priority’)==’high’: return ‘high_quality’ |
| 短文高速対応 | if length < 128 and req.latency_need: return ‘fast_model’ |
| 信頼度低 | if scorer.score(req)<0.6: return ‘human_review’ |
| デフォルト | return cost_estimator.best_balance() |
コストとレイテンシの見積り
モデルごとに平均コスト、95パーセンタイルレイテンシを定義します。運用では日次で実績を更新し、静的な値にしないことが重要です。
| モデル | 想定単価(USD) | 95p レイテンシ(ms) |
|---|---|---|
| high_quality | 0.10 | 800 |
| fast_model | 0.005 | 120 |
| balance | 0.03 | 300 |
信頼度スコア算出(簡易例)
モデル返却の確信度、与えられたプロンプトとの整合性、過去の誤答率を組み合わせます。簡易スコア例(説明のみ):
- モデル自己出力のlogit差分を正規化
- 過去同種の入力での誤答率を逆数的に加算
- 外部検知ルール(敏感語含有)はペナルティ
フェールバックと再試行
一回の失敗で人手介入に回すのではなく、段階的に降格します。基本パターン:
- ネットワーク/タイムアウト:自動的に別プロバイダへ再試行(最大2回)
- 意味的エラー(信頼度低):一度低コストモデルで再照会→変化なければ人手レビュー
- コスト超過動作:予算監視で動的ダウングレード
6) テスト・A/B併用・段階的展開
ルーティングのテストはルール単体の正しさだけでなく、割合とコストのシミュレーションが重要です。
| テスト項目 | 手法・期待値 |
|---|---|
| 単体ルールテスト | 入力セット毎に期待される振り分け先をassert |
| シミュレーション | 過去ログでルーティングを実行、コスト/誤答率を算出 |
| A/Bテスト | 割合を0→5→20→100%と段階的に増やしKPIを監視 |
| 耐障害テスト | プロバイダ遮断を模擬してフェイルオーバー検証 |
7) 監視・メトリクス・ログ設計
監視はルーティング毎に分けて行います。ダッシュボードに最低限置くべきメトリクスは次の通りです。
| メトリクス | 用途 | アラート条件(例) |
|---|---|---|
| 振り分け成功率 | 送信失敗や例外検知 | 5分で成功率<95% |
| 平均コスト/リクエスト | 予算管理 | 日次平均が閾値の120%超 |
| 平均レイテンシ | SLA監視 | 95pが閾値超 |
| 信頼度分布 | レビュー流量の予測 | 信頼度<0.6が急増 |
8) 運用チェックリストと落とし穴
導入後のよくある失敗と対策をチェックリスト形式でまとめます。
| 問題 | 原因 | 短期対処 |
|---|---|---|
| ルール過多で追えない | 運用者がルールを増やし続ける | 半年ごとにルール整理と効果測定 |
| コスト見積りが古い | 静的値を放置 | 日次実績で自動更新 |
| 偏ったログサンプリング | 一部ルートのみログ取得 | 全ルートで同一粒度のログを必須化 |
| 人手レビュー遅延 | バッファ定義がない | レビュー受入上限を設け、代替対応を準備 |
| ガバナンス未整備 | 権限・チェックが不明確 | ルール変更はPRで承認、変更履歴を保管 |
付録:運用テンプレートと小さなリポジトリ案
実際に試すための最小構成の提案です。ダウンロードリンクは記事末の付録案にて配布を検討してください。
| ファイル/フォルダ | 説明 |
|---|---|
| manageai_router/ | パッケージ本体(上記モジュール群) |
| tests/ | ルール単体テスト、シミュレーションスクリプト |
| config/policies.csv | ルーティングポリシーのCSVテンプレート |
| monitoring/ | 簡易ダッシュボードのサンプル(メトリクス出力) |
まとめ
複数モデルを実務で使い分けるには、要件を明確にし、ルールを優先度順にシンプルに設計することが重要です。Pythonでの実装はモジュール分割とログの可観測性を優先し、コスト推定や信頼度スコアは静的にせず実績で更新してください。段階的なロールアウトと監視・アラートを組み合わせることで、予期せぬコスト増やレビュー遅延を抑えられます。
次回は、今回のルーターを実際に小さなリポジトリとして動かすためのサンプル実装とデプロイ手順を具体的に示します。付録ではCSVテンプレートや運用チェックリストの配布を予定しています。
