モデルルーティング:すべてのタスクに1つのモデルを使うのをやめましょう
適切なタスクに最適なモデル。
700億パラメータのモデルを使って200語のメールを要約するのは無駄です。30億パラメータのモデルで本番環境のコードレビューを行うのは無謀です。多くのシステムはその中間に位置しており、そこがモデルルーティングの登場シーンです。
タスクの複雑さをモデルの性能に合わせます。トレードオフは現実的なものですが、その節約効果もまた現実的なものです。

ルーティングの問題
多くの人は1つのモデルを使い始め、そのまま使い続けます。これはコストやレイテンシ、あるいはその両方に気づくまで有効です。代替策はルーティング基盤(ルーター)を構築することです。つまり、どのリクエストをどのモデルが処理するかを決定する仕組みです。
実務で機能する戦略は以下の4つです。
- 能力ベース — モデルが何を行えるかでルーティング
- コスト意識型 — 支出許容額に基づいてルーティング
- レイテンシ意識型 — 必要な速度に基づいてルーティング
- ハイブリッド — これらを組み合わせる
それぞれが異なるものを最適化します。どれを選ぶかは、通常、どの問題が最も深刻かという決断になります。
能力ベースのルーティング
最もシンプルなアプローチです。タスクを分類し、それを処理できるモデルに送信します。
| タスク | モデル規模 | 例 |
|---|---|---|
| 分類、タグ付け | 10-30億 | Qwen3-1.7B, Gemma-2-2B |
| 要約、抽出 | 30-70億 | Qwen3-8B, Llama-3.1-8B |
| コード生成 | 70-140億 | Qwen2.5-Coder-7B, DeepSeek-Coder-V2 |
| 複雑な推論 | 140-320億 | Qwen3-32B, Llama-3.1-70B |
| 創造的執筆、分析 | 320億以上 | Qwen2.5-72B, Claude, GPT-4 |
タスクに大規模モデルが必要ないのであれば、使用すべきではありません。15億パラメータのモデルでも感情分類は十分に処理できます。ただし、まとまりのあるエッセイを書くことはできないでしょう。
実装は straightforward(直截的)です。
ROUTING_RULES = {
"classify": {"model": "qwen3-1.7B", "max_tokens": 100},
"summarize": {"model": "qwen3-8B", "max_tokens": 500},
"code_review": {"model": "qwen2.5-coder-7b", "max_tokens": 2000},
"reason": {"model": "qwen3-32b", "max_tokens": 4000},
"creative": {"model": "claude-sonnet-4", "max_tokens": 8000},
}
def route_request(task_type: str) -> dict:
return ROUTING_RULES.get(task_type, ROUTING_RULES["reason"])
落とし穴は分類自体にあります。タスクの種類を誤判断すると、間違ったモデルにルーティングされます。コードレビューを「要約」と誤分類し、品質が静かに低下するシステムを目にしたことがあります。
コスト意識型のルーティング
ローカル推論はここで真価を発揮します。ハードウェアの償却後、ローカルモデルは実質的に無料です。RTX 5080は、中程度なAPI使用量であれば約6ヶ月で元を取ります。
| モデル | 入力 ($/Mトークン) | 出力 ($/Mトークン) | ローカルコスト/時間 |
|---|---|---|---|
| GPT-4o | $2.50 | $10.00 | — |
| Claude Sonnet 4 | $3.00 | $15.00 | — |
| Qwen2.5-72B (API) | $0.50 | $2.00 | — |
| Qwen3-32B (ローカル) | $0.00 | $0.00 | ~$0.10 |
| Qwen3-8B (ローカル) | $0.00 | $0.00 | ~$0.05 |
1セッションで数千件のリクエストを処理する場合、電気代$0.05でも$15/Mトークンより安くなります。
予算ベースのルーティングは、支出に伴ってフォールバック(代替手段への切り替え)を行います。
class CostAwareRouter:
def __init__(self, budget_per_session: float = 0.10):
self.budget = budget_per_session
self.spent = 0.0
self.models = {
"cheap": {"model": "qwen3-8B", "cost": 0.0},
"medium": {"model": "qwen3-32b", "cost": 0.0},
"expensive": {"model": "claude-sonnet-4", "cost": 0.000015},
}
def route(self, task: str) -> str:
ratio = self.spent / self.budget
if ratio < 0.5:
return self.models["expensive"]["model"]
elif ratio < 0.8:
return self.models["medium"]["model"]
return self.models["cheap"]["model"]
フォールバックを行うと品質が低下します。最初はClaudeを使い、次にQwen3-32B、そしてQwen3-8Bへと移行します。長時間のセッション終了時には、出力品質の悪化が顕著になります。それが問題になるかどうかは、構築しているシステム次第です。
レイテンシ意識型のルーティング
インタラクティブなツールは最初のトークン生成速度が必要です。バッチ処理は待機できます。その差は通常、モデル規模の5倍の係数に相当します。
| 使用ケース | 最初のトークン | 完了まで | 最大モデル規模 |
|---|---|---|---|
| リアルタイムチャット | < 200ms | < 2s | < 70億 |
| インタラクティブツール | < 500ms | < 5s | < 140億 |
| バッチ処理 | < 1s | < 30s | 制限なし |
| 研究/分析 | < 2s | < 60s | 制限なし |
ユーザーにトークンをストリーミング配信する場合、ユーザーが感知するのは最初のトークンのレイテンシです。起動に0.5秒かかる320億パラメータのモデルは、瞬時に動作する15億パラメータのモデルと比較して、もっさりした印象を与えます。
class LatencyAwareRouter:
def __init__(self):
self.model_latencies = {
"qwen3-1.7b": {"first_token": 0.05, "complete": 0.5},
"qwen3-8B": {"first_token": 0.15, "complete": 2.0},
"qwen3-32b": {"first_token": 0.5, "complete": 10.0},
"claude-sonnet-4": {"first_token": 0.3, "complete": 5.0},
}
def route(self, target_latency: float) -> str:
for model, latencies in sorted(
self.model_latencies.items(),
key=lambda x: x[1]["complete"]
):
if latencies["complete"] <= target_latency:
return model
return "qwen3-1.7b"
レイテンシの数値は概算です。ハードウェア、量子化、バッチサイズに依存します。ご自身の環境で測定してください。
フォールバック戦略
モデルは失敗します。APIはレート制限がかかります。タイムアウトも発生します。機能するパターンは、最良から最も信頼性の高い順に並べられたフォールバックチェーンです。
class FallbackRouter:
def __init__(self):
self.fallback_chain = [
{"model": "claude-sonnet-4", "timeout": 30},
{"model": "qwen2.5-72b", "timeout": 60},
{"model": "qwen3-32b", "timeout": 120},
{"model": "qwen3-8b", "timeout": 300},
]
def route_with_fallback(self, prompt: str) -> str:
for config in self.fallback_chain:
try:
return self.call_model(
config["model"], prompt,
timeout=config["timeout"]
)
except (TimeoutError, APIError) as e:
log.warning(f"Model {config['model']} failed: {e}")
continue
raise RuntimeError("All fallback models failed")
チェーンの最後のモデルはローカルであるべきです。速度は遅いですが、ネットワーク問題やAPIキーの障害で失敗することはありません。
ルーティングが役立つ場合
ワークロードが混在している場合にルーティングは理にかなっています。同じシステム内で分類、要約、推論を行っている場合、ルーターはコストとレイテンシを節約します。
すべての作業が同じ複雑さである場合は理にかなっていません。そのタスクに優れたモデルを単に使用してください。ルーターは不要な複雑さを追加します。
早期のプロトタイピングも、ルーティングをスキップする理由の1つです。1つのモデルでタスクが動作することを確認し、コストやレイテンシが実際に問題となった時点でルーティングを追加してください。
トレードオフ
すべてのルーティング戦略は何かを最適化し、何かを犠牲にします。
- 単一モデル — 最もシンプル、最も高価、品質が一定
- 能力ベース — コスト効率が良い、タスクごとに品質が高い、複雑さは中程度
- コスト意識型 — 最も安価、品質が変動、複雑さは中程度
- レイテンシ意識型 — 最速、品質を犠牲にする可能性、複雑さは中程度
- ハイブリッド — すべてを兼ね備える、実装が最も複雑
本番環境のシステムは通常、ハイブリッドアプローチに収束します。能力ベースのルーティングから始め、請求書が届いたらコスト意識型を追加し、ユーザーが遅さを訴えたらレイテンシ意識型を追加します。
関連記事
- LLMシステムのコスト最適化 — トークン予算、キャッシュ、フォールバックモデル
- 実践的なLLMガードレール — 入力検証、出力フィルタリング、安全性
- マルチモデルシステム設計 — 複数モデルのためのアーキテクチャ
- LLMアーキテクチャ — システム設計の柱:ルーティング、コスト、ガードレール、オーケストレーション