ルーティング

ルーティング

CC-Relay は、プロバイダー間でリクエストを分配するための複数のルーティング戦略をサポートしています。このページでは、各戦略とその設定方法について説明します。

概要

ルーティングは、cc-relay がどのプロバイダーに各リクエストを処理させるかを決定します。適切な戦略は、可用性、コスト、レイテンシー、負荷分散など、あなたの優先事項によって異なります。

戦略設定値説明ユースケース
Round-Robinround_robinプロバイダー間を順番にローテーション均等分配
Weighted Round-Robinweighted_round_robin重みに基づく比例分配容量ベースの分配
Shuffleshuffleフェアランダム(「カード配り」パターン)ランダム化された負荷分散
Failoverfailover(デフォルト)優先度ベースで自動リトライ高可用性
Model-Basedmodel_basedモデル名プレフィックスでルーティングマルチモデルデプロイメント

設定

config.yaml でルーティングを設定します:

routing:
# 戦略: round_robin, weighted_round_robin, shuffle, failover(デフォルト), model_based
strategy: failover

# フェイルオーバー試行のタイムアウト(ミリ秒、デフォルト: 5000)
failover_timeout: 5000

# デバッグヘッダーを有効化(X-CC-Relay-Strategy, X-CC-Relay-Provider)
debug: false

# モデルベースルーティング設定(strategy: model_based の場合のみ使用)
model_mapping:
  claude-opus: anthropic    # claude-opus-* models → anthropic provider
  claude-sonnet: anthropic  # claude-sonnet-* models → anthropic provider
  glm-4: zai                # glm-4* models → zai provider
  qwen: ollama              # qwen* models → ollama provider

# Default provider when no model mapping matches
default_provider: anthropic
[routing]
# Strategy: round_robin, weighted_round_robin, shuffle, failover (default), model_based
strategy = "failover"

# Timeout for failover attempts in milliseconds (default: 5000)
failover_timeout = 5000

# Enable debug headers (X-CC-Relay-Strategy, X-CC-Relay-Provider)
debug = false

# Default provider when no model mapping matches
default_provider = "anthropic"

# Model-based routing configuration (only used when strategy: model_based)
[routing.model_mapping]
claude-opus = "anthropic"    # claude-opus-* models → anthropic provider
claude-sonnet = "anthropic"  # claude-sonnet-* models → anthropic provider
glm-4 = "zai"                # glm-4* models → zai provider
qwen = "ollama"              # qwen* models → ollama provider

デフォルト: strategy が指定されていない場合、cc-relay は最も安全なオプションとして failover を使用します。

戦略

Round-Robin

アトミックカウンターを使用した順次分配。どのプロバイダーも2回目のリクエストを受ける前に、各プロバイダーが1つのリクエストを受け取ります。

routing:
strategy: round_robin
[routing]
strategy = "round_robin"

動作の仕組み:

  1. リクエスト 1 → プロバイダー A
  2. リクエスト 2 → プロバイダー B
  3. リクエスト 3 → プロバイダー C
  4. リクエスト 4 → プロバイダー A(サイクルが繰り返される)

最適な用途: 同等の容量を持つプロバイダー間での均等分配。

Weighted Round-Robin

プロバイダーの重みに基づいてリクエストを比例配分します。均等な分配のために Nginx smooth weighted round-robin アルゴリズムを使用します。

routing:
strategy: weighted_round_robin

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"
      weight: 3  # 3倍のリクエストを受け取る

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"
      weight: 1  # 1倍のリクエストを受け取る
[routing]
strategy = "weighted_round_robin"

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"
weight = 3  # Receives 3x more requests

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"
weight = 1  # Receives 1x requests

動作の仕組み:

重みが 3:1 の場合、4リクエストごとに:

  • 3 リクエスト → anthropic
  • 1 リクエスト → zai

デフォルトの重み: 1(指定されていない場合)

最適な用途: プロバイダーの容量、レート制限、またはコスト配分に基づく負荷分散。

Shuffle

Fisher-Yates「カード配り」パターンを使用したフェアランダム分配。誰かが2枚目のカードを受け取る前に、全員が1枚ずつ受け取ります。

routing:
strategy: shuffle
[routing]
strategy = "shuffle"

動作の仕組み:

  1. すべてのプロバイダーが「デッキ」に入る
  2. ランダムなプロバイダーが選択されデッキから除外される
  3. デッキが空になったら、すべてのプロバイダーを再シャッフル
  4. 時間経過で公平な分配を保証

最適な用途: 公平性を確保しながらランダム化された負荷分散。

Failover

優先度順にプロバイダーを試行します。失敗した場合、最も速い成功レスポンスを得るために残りのプロバイダーへ並列リクエストを実行します。これがデフォルト戦略です。

routing:
strategy: failover

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"
      priority: 2  # 最初に試行される(高い = 高優先度)

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"
      priority: 1  # フォールバック
[routing]
strategy = "failover"

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"
priority = 2  # Tried first (higher = higher priority)

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"
priority = 1  # Fallback

動作の仕組み:

  1. 最高優先度のプロバイダーを最初に試行
  2. 失敗した場合(フェイルオーバートリガー参照)、残りのすべてのプロバイダーへ並列リクエストを発行
  3. 最初に成功したレスポンスを返し、他をキャンセル
  4. 全体の操作時間は failover_timeout を尊重

デフォルトの優先度: 1(指定されていない場合)

最適な用途: 自動フォールバック付きの高可用性。

Model-Based

リクエスト内のモデル名に基づいてプロバイダーにリクエストをルーティングします。特異性のために最長プレフィックスマッチングを使用します。

routing:
strategy: model_based

model_mapping:
  claude-opus: anthropic
  claude-sonnet: anthropic
  glm-4: zai
  qwen: ollama
  llama: ollama

default_provider: anthropic

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"

- name: "ollama"
  type: "ollama"
  base_url: "http://localhost:11434"
[routing]
strategy = "model_based"
default_provider = "anthropic"

[routing.model_mapping]
claude-opus = "anthropic"
claude-sonnet = "anthropic"
glm-4 = "zai"
qwen = "ollama"
llama = "ollama"

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"

[[providers]]
name = "ollama"
type = "ollama"
base_url = "http://localhost:11434"

動作の仕組み:

  1. リクエストから model パラメータを抽出
  2. model_mapping で最長プレフィックスマッチを見つける
  3. 対応するプロバイダーにルーティング
  4. マッチが見つからない場合は default_provider にフォールバック
  5. マッチもデフォルトもない場合は、すべてのプロバイダーを候補として使用する(フィルタリングなし)

プレフィックスマッチングの例:

リクエストモデルマッピング結果
claude-opus-4claude-opus: anthropicanthropic
claude-sonnet-4-20250514claude-sonnet: anthropicanthropic
glm-4.7glm-4: zaizai
qwen3:8bqwen: ollamaollama
unknown-model(マッチなし)default_provider

最適な用途: 異なるモデルを異なるプロバイダーにルーティングする必要があるマルチモデルデプロイメント。

デバッグヘッダー

routing.debug: true の場合、cc-relay はレスポンスに診断ヘッダーを追加します:

ヘッダー説明
X-CC-Relay-Strategy戦略名使用されたルーティング戦略
X-CC-Relay-Providerプロバイダー名リクエストを処理したプロバイダー

レスポンスヘッダーの例:

X-CC-Relay-Strategy: failover
X-CC-Relay-Provider: anthropic

セキュリティ警告: デバッグヘッダーは内部のルーティング決定を公開します。開発環境または信頼できる環境でのみ使用してください。信頼できないクライアントがいる本番環境では決して有効にしないでください。

フェイルオーバートリガー

failover 戦略は特定のエラー条件でリトライをトリガーします:

トリガー条件説明
ステータスコード429, 500, 502, 503, 504レート制限またはサーバーエラー
タイムアウトcontext.DeadlineExceededリクエストタイムアウト超過
接続net.Errorネットワークエラー、DNS失敗、接続拒否

重要: クライアントエラー(429を除く4xx)はフェイルオーバーをトリガーしません。これらはプロバイダーではなく、リクエスト自体の問題を示しています。

ステータスコードの説明

コード意味フェイルオーバー?
429レート制限はい - 別のプロバイダーを試す
500内部サーバーエラーはい - サーバーの問題
502Bad Gatewayはい - アップストリームの問題
503サービス利用不可はい - 一時的にダウン
504Gateway Timeoutはい - アップストリームタイムアウト
400Bad Requestいいえ - リクエストを修正
401Unauthorizedいいえ - 認証を修正
403Forbiddenいいえ - 権限の問題

シンプルな Failover(ほとんどのユーザーに推奨)

優先度付きプロバイダーでデフォルト戦略を使用:

routing:
strategy: failover

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"
      priority: 2

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"
      priority: 1
[routing]
strategy = "failover"

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"
priority = 2

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"
priority = 1

重み付きロードバランシング

プロバイダーの容量に基づいて負荷を分散:

routing:
strategy: weighted_round_robin

providers:
- name: "primary"
  type: "anthropic"
  keys:
    - key: "${PRIMARY_KEY}"
      weight: 3  # トラフィックの 75%

- name: "secondary"
  type: "anthropic"
  keys:
    - key: "${SECONDARY_KEY}"
      weight: 1  # トラフィックの 25%
[routing]
strategy = "weighted_round_robin"

[[providers]]
name = "primary"
type = "anthropic"

[[providers.keys]]
key = "${PRIMARY_KEY}"
weight = 3  # 75% of traffic

[[providers]]
name = "secondary"
type = "anthropic"

[[providers.keys]]
key = "${SECONDARY_KEY}"
weight = 1  # 25% of traffic

デバッグヘッダー付き開発環境

トラブルシューティング用にデバッグヘッダーを有効化:

routing:
strategy: round_robin
debug: true

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"
[routing]
strategy = "round_robin"
debug = true

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"

高速フェイルオーバーによる高可用性

フェイルオーバーのレイテンシーを最小化:

routing:
strategy: failover
failover_timeout: 3000  # 3秒タイムアウト

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"
      priority: 2

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"
      priority: 1
[routing]
strategy = "failover"
failover_timeout = 3000  # 3 second timeout

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"
priority = 2

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"
priority = 1

モデルベースルーティングを使用したマルチモデル

異なるモデルを専用プロバイダーにルーティング:

routing:
strategy: model_based

model_mapping:
  claude-opus: anthropic
  claude-sonnet: anthropic
  claude-haiku: anthropic
  glm-4: zai
  glm-3: zai
  qwen: ollama
  llama: ollama

default_provider: anthropic

providers:
- name: "anthropic"
  type: "anthropic"
  keys:
    - key: "${ANTHROPIC_API_KEY}"

- name: "zai"
  type: "zai"
  keys:
    - key: "${ZAI_API_KEY}"

- name: "ollama"
  type: "ollama"
  base_url: "http://localhost:11434"
[routing]
strategy = "model_based"
default_provider = "anthropic"

[routing.model_mapping]
claude-opus = "anthropic"
claude-sonnet = "anthropic"
claude-haiku = "anthropic"
glm-4 = "zai"
glm-3 = "zai"
qwen = "ollama"
llama = "ollama"

[[providers]]
name = "anthropic"
type = "anthropic"

[[providers.keys]]
key = "${ANTHROPIC_API_KEY}"

[[providers]]
name = "zai"
type = "zai"

[[providers.keys]]
key = "${ZAI_API_KEY}"

[[providers]]
name = "ollama"
type = "ollama"
base_url = "http://localhost:11434"

この設定により:

  • claude-opus-4 → anthropic
  • glm-4.7 → zai
  • qwen3:8b → ollama
  • unknown-model → anthropic(デフォルト)

プロバイダーの重みと優先度

重みと優先度はプロバイダーのキー設定で指定します:

providers:
- name: "example"
  type: "anthropic"
  keys:
    - key: "${API_KEY}"
      weight: 3      # weighted-round-robin 用(高い = より多くのトラフィック)
      priority: 2    # failover 用(高い = 最初に試行)
      rpm_limit: 60  # レート制限トラッキング
[[providers]]
name = "example"
type = "anthropic"

[[providers.keys]]
key = "${API_KEY}"
weight = 3      # For weighted-round-robin (higher = more traffic)
priority = 2    # For failover (higher = tried first)
rpm_limit = 60  # Rate limit tracking

注: 重みと優先度はプロバイダーのキーリストの最初のキーから読み取られます。

次のステップ