Switchyard lets LLM applications route traffic across models and providers while preserving native OpenAI and Anthropic API compatibility - enabling flexible model selection, benchmarking, and cost/performance optimization.
Switchyard
Switchyard 会将每次 LLM 调用路由到仍可胜任该任务的最便宜模型,而无需改动你智能体的任何一行代码。
*总成本基于平均 ISP token 成本
什么是 Switchyard
Switchyard 负责决定由哪个模型处理每次 LLM 调用。
使用 Switchyard
Switchyard 可运行在你已有的网关内。
- NeMo Relay — 原生插件。将
routes.toml加载到你已在运行的 Relay 部署中。配置 → - LiteLLM — 适用于 LiteLLM 的
Router和代理的路由插件。examples/litellm - 更多集成即将推出。
flowchart LR
subgraph R["LiteLLM · NeMo Relay"]
P["Switchyard"]
end
P--> M["Efficient model"]
P--> N["Capable model"]
P--> O[etc.]
G[You] -->|"request"| P
style P fill:#76B900,stroke:#5A8F00,color:#000
将 Switchyard 集成到你的网关或宿主框架
将路由算法嵌入到你自己的宿主框架中。Switchyard 负责选择模型,你的 宿主框架负责发起调用,因此你的传输、重试与凭证均保持原样。
- 安装:
pip install nemo-switchyard - 然后按照 Path 2 — 嵌入库: 构造一个算法,驱动其步骤流,并发起回答调用。
- Rust 中也可使用
switchyard-libsy;Path 2 中提供了Cargo.toml配置块。
flowchart LR
subgraph R["Your LLM gateway / harness"]
P["Switchyard"]
end
P--> M["Efficient model"]
P--> N["Capable model"]
P--> O[etc.]
G["Your users"] -->|"request"| P
style P fill:#76B900,stroke:#5A8F00,color:#000
将 Switchyard 作为独立代理服务运行
作为位于智能体前方的服务器,当你没有可部署 Switchyard 的网关时:
cargo install --locked switchyard-server
switchyard-server --config routes.toml --port 4000
将 Claude Code、Codex CLI 或任意 OpenAI/Anthropic SDK 客户端指向 proxy。 Switchyard 会逐轮决定由哪个模型来响应。
flowchart LR
P["Switchyard<br/>standalone proxy"]
P--> M["Efficient model"]
P--> N["Capable model"]
P--> O[etc.]
G[You] -->|"unchanged native API"| P
style P fill:#76B900,stroke:#5A8F00,color:#000
组件
当前为 1.0 之前的软件。API、配置和路由行为可能随版本发布而变化——请锁定你要集成的版本。
| 组件 | 稳定性 | 适用场景 | 说明 |
|---|---|---|---|
switchyard-libsy |
Beta | 将路由嵌入到你自己的网关或运行框架中。模型调用、凭据和重试策略均由你负责。 | 适用于试用集成。v1.0 之前 API 可能变化。 |
switchyard-llm-client |
Alpha | 配合 libsy 执行 HTTP 模型调用和协议转换。 |
适用于实验和试点。 |
switchyard-runner |
Alpha | 在其他运行时中运行已配置的路由,例如 NeMo Relay。 | 适用于集成开发和受控试点。 |
switchyard-server |
Demo | 独立运行的 OpenAI 和 Anthropic 兼容代理。 | 仅用于演示和评估,不适用于生产环境。 |
快速开始
提供三条路径,顺序与上文一致。每条路径均独立完整:从第 1 步开始,直到达成标题中所述结果即可停止。
路径 1 — 加载 NeMo Relay 插件
完成后,现有 NeMo Relay 部署将通过 Switchyard 进行路由。
需要 NeMo Relay >=0.8.1,<0.9.0,并使用 Rust 工具链构建该插件。
1. 构建、打包并注册插件。 按照插件 README 中的安装指南执行第 1 至 3 步。
这些步骤会构建共享库,将其打包为包含带摘要 relay-plugin.toml 的插件包,并通过 nemo-relay plugins add 完成注册。
2. 编写 Switchyard 部署配置,写入 /etc/switchyard/routes.toml——与代理使用的 version-1 TOML 相同。可复制下方路径 3 第 2 步中的文件。
3. 将插件指向部署配置。 在 nemo-relay plugins add 生成的 [[plugins.dynamic]] 条目中添加一个 config 表,并添加允许 Relay 加载未签名插件包的策略覆盖。部署来源必须且只能使用一种:此处所示的路径,或嵌套在 switchyard_config 下的配置。
[[plugins.dynamic]]
manifest = "./plugins/switchyard/relay-plugin.toml"
[plugins.dynamic.config]
priority = 0
switchyard_config_path = "/etc/switchyard/routes.toml"
[plugins.policy.overrides."nvidia.switchyard"]
attestation = "integrity_only"
4. 启用、校验并重启 Relay。
nemo-relay plugins enable nvidia.switchyard
nemo-relay plugins validate nvidia.switchyard
Relay 现在可以运行 switchyard-runner 支持的任意算法,而 Switchyard
负责提供商 HTTP 调度。
详情:switchyard-nemo-relay-plugin
和 TOML schema 参考。
路径 2 —— 嵌入库
最终,你自己的运行框架会根据每个请求选择模型,并自行发起每一次模型调用。 以下示例使用 Python;Rust API 具有相同结构。
1. 安装。 下文中的 Step 和 LlmResponse API 比 PyPI 上的
nemo-switchyard 0.2.0 发布版本更新,后者提供的是基于旧版 LlmTarget
的接口。在下一次发布之前,请从源代码构建(需要 Rust 工具链):
pip install git+https://github.com/NVIDIA-NeMo/Switchyard.git
对于 Rust,v0.2.0 标签中也有旧版 run_stream 接口形态,因此请依赖该仓库的 main 分支,并锁定你已测试过的 rev:
[dependencies]
async-trait = "0.1"
futures = "0.3"
switchyard-libsy = { git = "https://github.com/NVIDIA-NeMo/Switchyard.git", branch = "main" }
switchyard-protocol = { git = "https://github.com/NVIDIA-NeMo/Switchyard.git", branch = "main" }
tokio = { version = "1", features = ["macros", "rt"] }
2. 构造一个算法。 目标名称就是你的 harness 对模型所起的名称。这是基准测试中的阶段路由器;random、
llm_task_classifier 和 llm_classifier 都以相同方式构建。
from switchyard.libsy import LlmResponse, Step
from switchyard.libsy.algorithms import stage_router
algorithm = stage_router(
"capable",
"efficient",
picker="efficient_first",
confidence_threshold=0.5,
)
3. 驱动它。 run_stream 接受的是规范化后的 Switchyard 请求字典,而不是 OpenAI 原始请求负载:即来自 switchyard-protocol 的 Request 结构,其中 messages 的 content 是一组类型化内容块。它会逐步输出执行步骤。CallModel 步骤是一次分类器或评审调用——请用自己的客户端发起该调用,并将规范化后的响应包装为 LlmResponse.Agg 返回。Done 携带最终选择。
async def call_with_fallback(request: dict, models: list[str], clients: dict) -> LlmResponse.Agg:
error: Exception | None = None
for model in models:
try:
return LlmResponse.Agg(await clients[model].call({**request, "model": model}))
except Exception as exc:
error = exc
raise error or RuntimeError("no candidate models")
async def route(request: dict, clients: dict) -> LlmResponse.Agg | LlmResponse.Stream:
async for step in algorithm.run_stream(request):
match step:
case Step.CallModel(call):
try:
call.respond(await call_with_fallback(call.request, call.models, clients))
except Exception as error:
call.fail(error)
case Step.Done(outcome):
if outcome.response is not None:
return outcome.response
return await call_with_fallback(
outcome.request, outcome.selected_model_ids, clients
)
raise RuntimeError("algorithm ended without a decision")
clients 将每个目标名称映射到你现有的客户端;每个 call 接收一个规范化请求字典,并返回一个规范化响应字典。call.models 和 outcome.selected_model_ids 按顺序列出候选项,因此辅助函数会依次尝试每一个,直到放弃。outcome.request 是需要发送的请求,其中可能包含算法施加的改写。当 outcome.response 已设置时,路由已经生成答案,无需再进一步调用。
4. 发起回答调用 使用你自己的 HTTP 客户端、重试和凭证,就像上面的 call_with_fallback 所做的那样。一个包含流式响应的完整可运行版本见 examples/libsy.py。
类型参考:switchyard-libsy 和 switchyard-protocol。在 Rust 中,该循环为 Algorithm::run_stream,依次产出 Step::CallModel 和 Step::Done,并且可以使用 switchyard-llm-client 的 run 来替你驱动它。
路径 3 — 运行独立代理
最终你会得到一个位于 localhost:4000 的服务器,任何 OpenAI 或 Anthropic 客户端都可以调用。需要 Rust with Cargo。
1. 安装服务器。
cargo install --locked switchyard-server
2. 编写 routes.toml。 一个针对上述基准测试中相同模型对的阶段路由器:如何访问提供商、
使用哪些模型、以及如何在它们之间进行选择。--config 可接受任意路径;此操作会将其写入当前目录。
cat > routes.toml <<'TOML'
schema_version = 1
[llm_clients.openrouter]
format = "openai_chat"
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
[targets.capable]
id = "anthropic/claude-opus-4.8"
llm_client = "openrouter"
[targets.efficient]
id = "z-ai/glm-5.2"
llm_client = "openrouter"
[routes.switchyard]
id = "switchyard"
type = "stage_router"
capable_target = "capable"
efficient_target = "efficient"
picker = "efficient_first"
confidence_threshold = 0.5
TOML
所有键均已在 TOML schema 参考 中说明。
3. 启动它。 --dry-run 会加载配置,打印 server OK: 及其对外暴露的模型 ID,然后退出,而不会启动服务器。
export OPENROUTER_API_KEY="your-openrouter-key" # pragma: allowlist secret
switchyard-server --config routes.toml --dry-run
switchyard-server --config routes.toml --host 127.0.0.1 --port 4000
4. 发送请求。 路由的 id 即为客户端请求时使用的模型名称。
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"switchyard","messages":[{"role":"user","content":"hello"}]}'
同一路由也会在 /v1/messages(Anthropic Messages)和
/v1/responses(OpenAI Responses)上提供响应。/v1/stats 会报告各个目标分别处理了哪些请求,/metrics 则提供 Prometheus 计数器,用于统计请求、错误、延迟、token 和路由开销。
5. 将编码智能体指向它。
export ANTHROPIC_BASE_URL="http://localhost:4000"
export ANTHROPIC_MODEL="switchyard"
claude
Codex CLI 以及其他 OpenAI 客户端会使用 OpenAI 变量替代:
export OPENAI_BASE_URL="http://localhost:4000/v1"
路由算法
大多数算法使用 LLM 作为裁判。它们都在 高效 模型与 高能力 模型之间进行选择;差异在于决策何时做出以及如何做出。
| 算法 | 决策方式 | 路由 type |
基准结果 |
|---|---|---|---|
| 能力 | 首个请求由 LLM 判定。 | llm_classifier |
71.2%,成本 $79.32 |
| 阶段 | 工具响应通过模式匹配或 LLM 判定。 | stage_router |
72.7%,成本 $68.19 |
| 能力 + 阶段 | 组合上述两种算法。 | composite |
尚未完成基准测试 |
| 升级 | 初始使用高效模型;响应由 LLM 判定是否存在问题,再升级。 | llm_classifier + mode = "escalation" |
75.7%,成本 $85.00 |
| 顾问门控 | 单一模型负责每一轮;更强的顾问模型批准其计划和“已完成”声明,或将其退回。 | advisor |
将弱执行器从 43.8% 提升至 54.7% |
| 子智能体感知 | 委派的子智能体流量与父智能体分开路由。 | passthrough 或 stage_router 上的 subagents |
尚未完成基准测试 |
| 自定义 | 首个请求由 LLM 根据你定义的标准判定,并在你拥有的两个及以上模型之间路由。 | llm_classifier + target_selector 策略 |
尚未完成基准测试 |
| 随机 | 每个请求按均匀或加权随机方式路由。 | random |
基线机制 |
基准测试基于 Terminal-Bench 2.1,并以 $98.06 的 Opus 4.8 基线(76.0%)作为对照。
passthrough 路由在单个模型 ID 下注册一个目标,且不进行路由决策。有关常见路由结构和自托管目标,请参见 路由概览。
文档
- 核心概念:LLM 客户端、目标、路由、模型 ID 与路由算法
- 路由概览:选择和配置路由算法
- TOML 配置模式:所有配置键
- 架构:代理与库组件如何协同工作
switchyard-server:服务器配置、路由算法与指标switchyard-libsy:在 Rust 应用中嵌入路由算法switchyard-protocol:提供商无关的请求、响应与流式类型switchyard-translation:请求、响应与流式转换switchyard-nemo-relay-plugin:将 Switchyard 安装为原生 NeMo Relay 插件
基准测试来源
| 配置 | 准确率 | 总成本 | 相比 Opus 4.8 基线 |
|---|---|---|---|
| Opus 4.8 基线 | 76.0% | $98.06 | — |
| 升级 | 75.7% | $85.00 | 准确率达基线的 99.6%,成本降低 13.3% |
| 分级 | 72.7% | $68.19 | 准确率达基线的 95.7%,成本降低 30.5% |
| 能力 | 71.2% | $79.32 | 准确率达基线的 93.7%,成本降低 19.1% |
| 仅使用 Kimi K2.6 | 55.8% | $76.28 | |
| 仅使用 GLM 5.2 | 52.4% | $16.47 | |
| 仅使用 DeepSeek V4 Pro | 48.7% | $96.92 | |
| 仅使用 Ultra 3 | 39.0% | $29.66 |
这些是 v0.2.0 版本的 Terminal-Bench 2.1 基准测试结果,来自 使用 NVIDIA NeMo Switchyard 跨模型路由 AI 智能体工作负载。 这些测试运行使用了 NVIDIA 内部推理端点,因此在其他服务栈上,绝对任务成功率可能会有所变化;这里的路由参数即为实际运行参数。
升级部署已提交至 benchmark/routing-profiles/tb21-escalation-opus-glm-deepseek.toml,并已将目标替换为 OpenRouter 目标,使其可公开运行。要运行测试框架,请参见 benchmark/README.md;如需关注延迟和路由开销而非任务成功率,请参见浸泡测试。
社区
许可证
Apache 2.0 许可证。版权所有 NVIDIA Corporation。
Introduction
Switchyard lets LLM applications route traffic across models and providers while preserving native OpenAI and Anthropic API compatibility - enabling flexible model selection, benchmarking, and cost/performance optimization.
Customize your domain