Switchyard——NVIDIAのRust製LLMルーターで、Claude Codeをローカルモデルに振り向ける
NVIDIA NeMo発のRust製LLMトラフィックルーター。OpenAIとAnthropicのAPIを変換しつつ、弱いモデルと強いモデルを振り分ける。Claude Codeをローカルモデルに向ける手順と罠を整理。
NVIDIA NeMo発のRust製LLMトラフィックルーター。OpenAIとAnthropicのAPIを変換しつつ、弱いモデルと強いモデルを振り分ける。Claude Codeをローカルモデルに向ける手順と罠を整理。
📑 目次
ふむふむ。コーディングエージェントを使っている人なら、一度はぶつかる壁があります。
「Claude Code をローカルで動かしたくて、Ollama のモデルを向けた。そしたら途中から API の形式違いでエラーを吐き始めた」。あるいは「GPT-4o と o4-mini、どっちに投げるか、そのたびに手で切り替えてる」。どちらも、モデルを選ぶこととAPIを繋ぐことが、まだごちゃ混ぜのまま放置されている、という問題です。
そこに、NVIDIA の NeMo チームが静かに出してきたのが Switchyard です。ひと言でいうと、LLM のトラフィックを振り分ける Rust 製のプロキシ兼ライブラリ。OpenAI と Anthropic の API を相互に翻訳しながら、弱いモデルと強いモデルをルールに沿って出し分けます。GitHub スターは執筆時点で約2,000、直近1週間で +900 超と、まだ生まれたての勢いです(リポジトリ開設は2026年5月)。
でもね、チカちゃん的には「NVIDIA が出したから強い」で終わらせたくない。これは pre-alpha、つまり公式が「本番に使うな」と明言している道具です。どこまでなら触って面白くて、どこからが危ないか——今日はそこまで含めて、How-to として歩いてみます。
本記事は公開情報をもとにした個人的な技術メモです。第三者ツール・AIサービス・モデルの仕様、料金、利用条件、安全性は変わる可能性があります。Switchyard は執筆時点で pre-alpha(本番利用は公式に非推奨)であり、API や設定形式は今後大きく変わる見込みです。導入前に公式ドキュメント、ライセンス、利用規約、データ送信先を確認してください。業務環境や秘密情報を含む環境では、隔離環境で検証してから利用することをおすすめします。
Switchyard は何をするのか——30秒でつかむ
Switchyard は、ひと言でいうと 「LLM リクエストの中継所」 です。
- クライアント(Claude Code、Codex、OpenClaw など)は、自分の慣れた API のまま話しかける
- Switchyard が、設定に従って「今回はどのモデルに投げるか」を決める
- 選んだ先のモデルが喋る形式(OpenAI / Anthropic / OpenAI Responses)に翻訳して転送する
- 返ってきた応答を、またクライアントの形式に翻訳して返す
- リクエスト数・エラー・レイテンシ・トークン・ルーティングのオーバーヘッドを Prometheus メトリクスで記録する
ポイントは「翻訳」と「振り分け」がセットになっていることです。だから、Claude Code に Ollama や vLLM、NVIDIA NIM のモデルを向けても、エージェント側は 「いつもの Claude の API」 のまま喋り続けられる。裏でモデルが差し替わっていても、フロントのコードは一行も変えなくていい——という設計です。
裏で動いているのは Rust です。プロキシとして低オーバーヘッドに振る舞いながら、同じルーティングのロジックをライブラリ(switchyard-libsy)として自前のアプリに埋め込むこともできます。ここが、単なるプロキシとの一番の違いです。
LiteLLM / OpenRouter と何が違うの?
「それ、LiteLLM や OpenRouter でよくない?」と思う人も多いはず。ここ、いちばん誤解しやすいので一度並べます。
| 観点 | Switchyard | LiteLLM(Python プロキシ) | OpenRouter(ホスト型) |
|---|---|---|---|
| 実装 | Rust ネイティブ | Python | ホスト型サービス |
| 動かす場所 | 自前プロキシ or 自前アプリ内 | 自前プロキシ | 他社クラウド |
| プロトコル | OpenAI Chat / Responses / Anthropic の相互翻訳 | OpenAI 互換中心 | OpenAI 互換中心 |
| ルーティング | 分類器・ステージ・エスカレーション等を型付きで | フォールバック・ロードバランス中心 | サービスのルール |
| ライブラリ埋め込み | switchyard-libsy で可能 | 基本はプロキシ | 不可 |
| 成熟度 | pre-alpha | 実績豊富 | 商用 |
ざっくり、LiteLLM は「OpenAI 互換の一本化」に強く、OpenRouter は「いろんなモデルに鍵一本で触る」のに強い。Switchyard は、Anthropic 形式と OpenAI 形式を双方向に通す翻訳器であることと、ルーティングを自分の Rust コードに埋め込めることの二点が独自です。
「どれが勝ちか」ではなく、重さと自由度の置き方が違う。チカちゃん的には、Switchyard はまだ「試すための道具」で、本番の一本化は成熟した選択肢に任せるのが無難、という位置づけです。
まず触る——3つの入口
Switchyard には実行経路が3つあります。目的で選びます。
- ランチャー経路 —
switchyard launchで、Claude Code や Codex を Switchyard 越しに起動する - サーバー経路 — スタンドアロンのプロキシとして立てて、API クライアントから使う
- ライブラリ経路 —
switchyard-libsyを自分の Rust アプリに埋め込む
まずは一番ラクな「ランチャー経路」からいきましょう。
インストール①:ランチャー経路(最短ルート)
Python の uv を使います。未導入なら先に入れます。
curl -LsSf https://astral.sh/uv/install.sh | sh
source "$HOME/.local/bin/env"
そのうえで、Switchyard の CLI を隔離環境に入れます。
uv tool install --python 3.10 "nemo-switchyard[cli]"
これで switchyard コマンドが使えます。あとは OpenRouter の鍵を環境変数に入れて、エージェントを起動するだけです。
export OPENROUTER_API_KEY="your-openrouter-key"
switchyard launch claude --model switchyard
claude のところは codex や openclaw にも変えられます。--model switchyard は、同梱のデフォルト設定(route ID が switchyard)を指しています。起動したエージェントは、見た目はいつもの Claude Code のまま、裏で Switchyard 経由のモデルに接続されます。
注意点がひとつ。 ランチャー経路は、起動したいエージェント本体(Claude Code など)が別途インストール済みで、PATH に通っている必要があります。Switchyard がエージェントをインストールしてくれるわけではありません。
インストール②:サーバー経路(本番寄り)
自前のプロキシとして立てたい場合は、Rust の cargo でバイナリを入れます。
# Rust(rustup)が未導入なら公式の手順で入れる
cargo install --locked switchyard-server
switchyard-server --help
ビルドしたバイナリは ~/.cargo/bin に入ります。次に設定ファイル routes.toml を作ります。これが Switchyard の心臓部です。
schema_version = 1
[llm_clients.openrouter]
format = "openai_chat"
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
[targets.weak]
id = "openai/gpt-4o-mini"
llm_client = "openrouter"
[targets.strong]
id = "openai/gpt-4o"
llm_client = "openrouter"
[routes.smart]
id = "switchyard"
type = "llm_classifier"
mode = "capability"
classifier_target = "weak"
strong_target = "strong"
weak_target = "weak"
base_threshold = 0.5
設定は3層でできています。
llm_clients— 接続先(base URL・形式・鍵の環境変数名・リトライ方針)targets— 実際に呼ぶモデル(ID と、どの client を使うか)routes— クライアントに見せるモデル名と、どのアルゴリズムで target を選ぶか
ここ、大事です。 鍵は TOML に直接書かず、api_key_env で「どの環境変数名か」だけを指定します。秘密情報は設定ファイルの外に置く設計です。
設定を検証してから起動します。--dry-run はソケットを開かずに、スキーマ・環境変数の参照・target の参照・route の構築までを確認してくれます。
export OPENROUTER_API_KEY="your-openrouter-key"
switchyard-server --config routes.toml --dry-run
switchyard-server --config routes.toml --host 127.0.0.1 --port 4000
別のターミナルから確認します。route の id が、クライアントから見えるモデル名になります。
curl http://localhost:4000/health
curl http://localhost:4000/v1/models
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"switchyard","messages":[{"role":"user","content":"hello"}]}'
OpenAI Chat Completions / OpenAI Responses / Anthropic Messages、どの形式で話しかけても受け付ける、というのがミソです。
ルーティング戦略——「どのモデルに投げるか」の型
Switchyard の面白さは、振り分けロジックが型付きのアルゴリズムとして用意されていることです。
| アルゴリズム | いつ使うか | route の type |
|---|---|---|
passthrough | モデルを一つに固定(ルーティングなし) | passthrough |
random | 重み付きで分割して A/B テストや基準値を取る | random |
llm_classifier | 依頼内容で「弱い層/強い層」を判定する | llm_classifier |
stage_router | ツール結果やエラーなど、会話中のシグナルで振り分ける | stage_router |
| エスカレーション | まず弱い層で走らせ、判定役が「足りない」と見たら同じ依頼を強い層へ | llm_classifier(mode = "escalation") |
ここで注意してほしいのは、「弱い/強い」はアルゴリズム内の役割であって、モデルそのものの性質ではないということ。同じモデルが、別の route では「強い層」にも「弱い層」にもなれます。
チカちゃん的にいちばん好きなのはエスカレーション方式です。まず安いモデルに投げて、その答えを判定役(judge)が読んで、「これは強いモデルじゃないと無理だ」と判断したときだけ同じ依頼をもう一度強いモデルへ回す。これ、会社でいうと「まず若手に振って、ヤバそうなら先輩に上げる」動きとそっくりです。コストを抑えたい場面で、賢い「上の判断」を自動化する。
一方で、エスカレーションは難しい依頼では二重にコストがかかる(弱い層+判定+強い層)ことを忘れないでください。全部が安くなる魔法ではなく、「平均的に安くなる」ための賭けです。
実践パターン:Claude Code をローカルモデルへ
じゃあ、実際に何ができて嬉しいのか。典型的なのがこれです。
Claude Code を、OpenRouter 経由の格安モデルや、手元の Ollama / vLLM に向ける。 エージェントは「いつもの Claude の API」のまま話すので、設定ファイルを書き換えるだけでモデルを差し替えられます。ルーティングを llm_classifier にすれば、単純な質問は軽いモデル、設計判断のような重いターンは強いモデル、という出し分けもできます。
ランチャー経路でローカルを試すなら、--config で自前の TOML を渡します。
switchyard launch claude --model my-route --config routes.toml
もうひとつ、サーバー経路で面白いのは A/B ベンチマークです。random で重みを付ければ「新モデルと旧モデルを半々に流して、レイテンシと応答品質を比べる」が、同じ API の形のままでできます。その結果が Prometheus メトリクスに乗ってくるので、「どっちが速いか」を体感ではなく数字で見られます。
知っておくべき罠と注意点
ここ、めっちゃ大事です。README の冒頭に、公式が太字でこう書いています。
Experimental software. Not for production use.
つまり pre-alpha。罠は「すごい」のあとに並べておきます。
罠1:API も設定形式も、これから変わる
公式が「v1.0 までに API とアルゴリズムは大きく変わる見込み」と明言しています。いま書いた routes.toml の書き方も、数ヶ月後には別物になっている可能性が高い。ブログやメモとして試すのはいいけど、業務フローに組み込む前提では触らないのが安全です。
罠2:プロキシが一枚増える、というコスト
ルーターを挟むということは、レイテンシが1ホップ増え、故障点がひとつ増えるということです。モデルと直接話していた構成に比べれば、必ず「間に何か」が入ります。Switchyard は Rust 製で軽く作られていますが、「薄い」と「ゼロ」は違います。
罠3:「なぜそのモデルが選ばれたか」が見えにくい
分類器やエスカレーションで振り分けが自動化されると、「今どのモデルが答えているか」が、使っている人には不透明になります。Switchyard は Prometheus メトリクスで可視化を目指していますが、それでも「この返答はどっちの層が作ったの?」という問いに答えられる運用設計は、自分で整える必要があります。エージェントの出力を鵜呑みにしがちな場面ほど、この透明性が効いてきます。
罠4:鍵の置き場所と forward_auth
デフォルトは api_key_env で環境変数を指しますが、forward_auth = true にすると呼び出し元の認証情報をそのまま上流に転送する設定もあります。OpenAI クライアントなら authorization やアカウント ID まで丸ごと渡るので、「上流に渡してはいけない鍵」が流れないよう、設定は必ず確認を。公式も、この設定は「上流が呼び出し元のログインを受け取るべき場面」だけに絞るよう注記しています。
罠5:テレメトリヘッダが付く
Switchyard は、外向きの LLM 呼び出しに X-Switchyard-Version ヘッダを付けてリリースの帰属を取っています。公式いわく「リクエスト内容や応答内容は含まない」とのことですが、気になるなら無効化できます。
export SWITCHYARD_TELEMETRY_OPT_OUT=1
罠6:ライブラリ経路は「呼び出しは自分で」
switchyard-libsy は、モデルを自分では呼びません。アルゴリズムが「どの target を使うか」を決めて、そのモデル呼び出しをあなたのコードに返してくるだけです。HTTP スタックやリトライ、認証は自分で持つ——という割り切りです。これを「全部やってくれるライブラリ」だと勘違いすると、いざ組み込んだときに面食らいます。呼び出しまで任せたいなら switchyard-llm-client と組ませる、という公式の案内になっています。
チカちゃん的な見立て——「振り分け」が、新しい職人技になる
ちょっと待って。ここで一度、技術の外側に目を向けます。
長いあいだ、「どのモデルにどの仕事を頼むか」は人間の采配でした。GPT 系が得意、Claude 系が長文、ローカルは安い、API は速い——その見立てを頭に入れて、そのたびに手で切り替える。それが、いま「ルーティング」という形で、コードに落ちようとしています。
Switchyard の面白いところは、その「采配」を型付きのアルゴリズムとして公開している点です。分類器、ステージ、エスカレーション、ランダム——どれも、人間が職場でやっている「この仕事はこの人」という判断の自動化です。「どの知性を呼ぶか」を選ぶこと自体が、ひとつの技術になり始めている。
反対側の見方も置いておきます。
- 過剰な最適化の罠 — モデルを固定した方が予測可能でデバッグしやすいのに、振り分けを賢くしすぎると、かえって挙動が読めなくなる
- メタ判断の不透明化 — 采配を自動化すると、「なぜその判断になったか」の説明責任が薄れる(罠3の裏返し)
- まだ早すぎる — pre-alpha の現物は、思想としては面白いが、道具として頼るには若すぎる
つまりこれは、プロキシの話でありながら、「モデル選択という営みを、誰が・どこで・どう担うか」の話でもあります。NVIDIA がここに Rust で参入したという事実自体が、「ルーティングは薄い接着剤ではなく、真面目なインフラの一角だ」という宣言に見える。チカちゃん的には、そこが一番おいしい読みどころです。
まとめ——まずはランチャー一行、本番はまだ待つ
今日の歩き方を短くすると:
uv tool install --python 3.10 "nemo-switchyard[cli]"で CLI を入れるswitchyard launch claude --model switchyardで、まず OpenRouter 越しに試す- 本番寄りなら
cargo install --locked switchyard-server+routes.toml - 鍵は
api_key_envで環境変数を指し、TOML に直書きしない - ルーティングは passthrough / random / classifier / stage / escalation から選ぶ
- pre-alpha なので、本番に載せるのは待つ。テレメトリや forward_auth も確認を
Switchyard は、「モデルを振り分ける」という、これまで雑に扱われてきた領域に、NVIDIA が真面目な型を持ち込んだ道具です。日本語の情報はまだほぼなく、英語 README をそのまま読んでも「3つの経路の違い」や「弱い/強いが役割だという点」は抜けがちなので、今日はそこを厚めに書きました。
答えを急がなくても大丈夫です。あなたのコーディングエージェントを、安いモデルと強いモデルが裏で交代しながら支える——そんな風景が、もう目の前に来ています。それを「使う」か「待つ」かは、それぞれの足場で決めればいい。
技術の話から始まって、最後は「どの知性を、いつ呼ぶか」という采配の話に戻ってくる。チカちゃん的には、そこが一番おいしいところです。思索は冒険です。今日の話も、その入口のひとつでした。
参考URL
Switchyard(GitHub) → https://github.com/NVIDIA-NeMo/Switchyard
Getting Started → https://github.com/NVIDIA-NeMo/Switchyard/blob/main/docs/getting_started.md
Core Concepts → https://github.com/NVIDIA-NeMo/Switchyard/blob/main/docs/core_concepts.md
Routing Overview → https://github.com/NVIDIA-NeMo/Switchyard/blob/main/docs/routing_algorithms/overview.md
OpenRouter → https://openrouter.ai
uv(astral) → https://docs.astral.sh/uv/getting-started/installation/
Rust(rustup) → https://rust-lang.org/tools/install
GitHub Trending(weekly) → https://github.com/trending?since=weekly
- インターネット上のツールは第三者が提供するものです。開発工程や配布経路を悪用した攻撃(サプライチェーン攻撃)が仕掛けられる可能性もゼロではありません。ご利用の際は公式リポジトリの情報をご確認いただき、自己責任でお使いください。
- AIに関する技術や情報は急速に変化します。本記事の内容が公開後に古くなる可能性があります。各サービスの公式ドキュメントや最新情報をご確認ください。