モデルルーティング

1つのAPIキーで複数モデルを呼ぶ

OpenAI互換のBase URLとAPIキー1つでClaude、Gemini、DeepSeekなどを呼び出す方法。設定、モデル切り替え、費用確認、障害時の切り分けを解説します。

1つのキーですべてのモデルを呼び出す

「1つのAPIで複数のAIモデルをルーティングする」とは、アプリ側はBase URL、APIキー、リクエスト形式を1つずつ持ち、model フィールドでどの上流プロバイダーに処理させるかを決める構成です。ベンダーごとに認証情報を保存する必要がなく、新しいモデルが追加されてもクライアントを書き換えずに済みます。

実利は運用面にあります。残高が1つ、漏えいしたキーの交換が1か所、ログが1系統、モデル切り替えも1か所です。一方でゲートウェイがリクエスト経路に入るため、何を転送し、どうトークンを数えているかを検証する必要があります。本記事では最小構成、同じキーで異なるモデル系列を呼ぶ方法、請求との照合までを扱います。

モデル名を送った後に起きること

ルーティングを決める要素は通常4つです。モデル識別子、メッセージ本文、ストリーミング指定、そしてツール定義やキャッシュ制御などの任意フィールドです。ゲートウェイはモデル名を有効なチャネルと価格グループに解決し、リクエストをそのプロバイダーのネイティブ形式へ変換し、応答をSDKが期待する形式へ戻します。

本番前に確認すべき点は2つあります。第一に、モデル名にはバージョンがあります。試用環境で動く名前が、自分のキーのグループに存在するとは限りません。第二に、抽象化は無料ではありません。プロンプトキャッシュ、ツール呼び出し、構造化出力、推論トークンは、ゲートウェイが実際に転送した場合にのみ同等です。テキストが1回返っただけで互換と判断せず、依存する機能を個別に検証してください。

実際のルートを決めるフィールド
フィールド役割
modelどのチャネルと価格グループで処理するかを決める
messages / input上流へ送る文脈。入力トークンの主な要因
streamSSEで返すか、1つのJSONで返すか
tools、response_formatプロバイダー固有機能の転送が必要か

キーを1つ用意して最初のリクエストを送る

API接続でキーを作成し、料金ページで使うモデルを確認します。最初の確認はOpenAI互換エンドポイントで構いません。対象がOpenAIのモデルでなくてもゲートウェイが変換します。初回は出力上限を低くし、ツールもキャッシュも使わずに小さく試します。

キーはコードに書かず環境変数に置きます。macOSやLinuxでは export API_ROUTE_KEY=...、Windows PowerShellでは $env:API_ROUTE_KEY="..." を使います。以下の例はチャット補完を1回送って結果を表示します。

export API_ROUTE_KEY="sk-your-key"
curl https://global.api-route.com/v1/chat/completions \
  -H "Authorization: Bearer $API_ROUTE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "Name one trade-off of multi-model routing."}],
    "max_tokens": 80
  }'

200と choices 配列が返れば、リクエストがプロバイダーに届いたことは分かります。ただしストリーミング、ツール、キャッシュ、2つ目のモデル系列が動く証明にはなりません。機能ごとに検証を足し、応答本文のモデル名と usage を確認してください。

SDKを変えずにモデル系列を切り替える

同じキーでClaude、Gemini、DeepSeek、Qwenなどの系列を呼べるのは、ゲートウェイがプロトコル間を変換しているからです。チャット形式の通信はすべて /v1/chat/completions に送り、model の値だけを変えます。リクエストと応答の形はOpenAI互換のままです。

プロンプトキャッシュや特定のベータヘッダーなどAnthropic固有の動作が必要な場合は、/v1/messages とAnthropic形式を使います。両エンドポイントは同じ残高を共有するため、1つのキーで運用できます。参照仕様:OpenAI Chat Completions と Anthropic Messages。

from openai import OpenAI

client = OpenAI(
    base_url="https://global.api-route.com/v1",
    api_key="sk-your-key",
)

for model in ["claude-sonnet-4-6", "gemini-3.8-flash", "deepseek-v4.1-flash"]:
    reply = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": "Reply in one sentence."}],
        max_tokens=60,
    )
    print(model, "->", reply.choices[0].message.content)
const models = ["claude-sonnet-4-6", "gemini-3.8-flash"];

for (const model of models) {
  const res = await fetch("https://global.api-route.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.API_ROUTE_KEY}`,
    },
    body: JSON.stringify({
      model,
      messages: [{ role: "user", content: "Reply in one sentence." }],
      max_tokens: 60,
    }),
  });
  const data = await res.json();
  console.log(model, "->", data.choices?.[0]?.message?.content ?? data.error?.message);
}

ループで2つのモデルを呼べば、ルーティング層が期待どおり動くかを確認できます。呼び出しごとに返却モデル名とusageを記録してください。別系列へ静かにフォールバックしていても文章は自然に見えますが、品質と料金は変わっています。

プロジェクト単位ではなくリクエスト単位でモデルを選ぶ

1つのキーですべてのモデルに届くようになると、判断は「どのベンダーと契約するか」から「このリクエストはどのモデルに任せるか」へ移ります。まず通信を分類します。短い分類や抽出に最上位モデルは通常不要で、長い文脈の分析には必要です。コード生成とチャットでは優先順位が異なります。タスク別にルーティングし、ベンチマークの見出しではなく自社の評価セットで品質を測ってください。

モデル名と同じくらい価格グループが重要です。同じモデルでも既定グループと割引・企業グループでは単価が異なり、実際の支払額はキーが属するグループで決まります。宣伝されている数字で予算を組む前に、料金ページと利用ログのグループを確認してください。

モデルルーティングの実用的な出発点
ワークロード最適化する対象典型的な選択
分類・抽出・タグ付け1000回あたりの費用小型で高速なモデル
長文脈の分析・RAG回答コンテキスト長とキャッシュ費用中位モデルとプロンプトキャッシュ
複雑なコーディング・エージェント正確さとツール利用最上位モデル、低い温度
一括生成出力単価とスループット中位モデルとバッチ処理

ルートと請求を照合する

規模を広げる前に3点を確認します。同じキーで予定しているモデルを一覧できること、応答が要求したモデルを返すこと、ログの課金がusageと一致することです。モデル一覧が最も安価な確認で、狭いグループに固定されたキーを見つけられます。

curl -s https://global.api-route.com/v1/models \
  -H "Authorization: Bearer $API_ROUTE_KEY" \
  | jq -r '.data[].id' | sort

次に1回の応答を利用ログの該当行と比較します。モデル、入力と出力の内訳、キャッシュ関連フィールドの有無を確認してください。キャッシュされたリクエストは読み取りを別項目で報告するはずです。報告が一切ない場合は割引ではなく未検証として扱います。モデル系列ごとに1件の記録を残すと、後の価格やルート変更に気づけます。

よくある失敗とその意味

最初の1週間の問題はモデル品質ではなく設定であることが大半です。まず確認したいエラーを表にまとめます。報告時は時刻、HTTPステータス、モデル名、リクエストIDを添え、キーそのものは貼らないでください。

ルーティングのエラーと最初の確認
症状想定される原因最初に確認すること
404 モデルが見つからないキーのグループで有効化されていない/v1/models で一覧し、料金ページと照合する
401 または 403キー欠落・失効・誤ったヘッダーAuthorization: Bearer を使い、露出していれば交換する
400 がschemaの項目を指す未変換のキーワードをプロバイダーが拒否該当項目を外して再試行し、パラメータを報告する
ストリーミングが止まる/一括で届くプロキシのバッファリングや未対応の指定streamを外して再試行し、短いプロンプトで試す
想定より高いグループ違い、または読み取りではなく書き込みusageとログ行を突き合わせ、グループを確認する

200なのに別モデルのように振る舞う場合は、固定プロンプトで数回比較し、返却モデル名も確認してください。ばらつきは多くの場合、プロンプトではなくルーティングやフォールバックの方針に起因します。

本番運用のチェックリスト

  1. キーはシークレット管理か環境変数に置き、交換用の2本目を用意する。
  2. 浮動エイリアスではなく明示的なモデルIDを固定し、検証したバージョンを記録する。
  3. 設定変更のたびに、モデル系列ごとの固定スモークリクエストを送る。
  4. 総額だけでなく、エラー率と1リクエストあたりの費用にアラートを設定する。
  5. トラフィックを増やす前に、最初の請求と記録したusageを照合する。

この5点が揃えば、1つのキーと1つのBase URLでモデル系列をまたいでルーティングできます。少額の残高でアカウントを作成し、キーで利用可能なモデル一覧を確認して、クイックスタートに沿って最初のリクエストを送ってください。