Skip to main content

Switchyard

Switchyard

Switchyard routes each LLM call to the cheapest model that can still do the job. Without changing a line of your agent.

Get started →

Accuracy versus total cost on Terminal-Bench 2.1. Switchyard's staged, escalation, and classifier routes reach 71-76% accuracy for 13-30% less than the Opus 4.8 baseline, while single fixed models stay below 56%.

*Total cost based on average ISP token cost

What is Switchyard

Switchyard picks which model serves each LLM call.

Use Switchyard

Switchyard runs inside gateways you may already have.

  • NeMo Relay — a native plugin. Load a routes.toml into a Relay deployment you already run. Setup →
  • LiteLLM — a routing plugin for LiteLLM's Router and proxy. Setup →
  • More integrations coming soon.
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

Integrate Switchyard into your gateway or harness

Embed the routing algorithms in your own. Switchyard picks the model; your harness makes the call, so your transport, retries, and credentials stay untouched.

  • Install: pip install nemo-switchyard
  • Then follow Path 2 — Embed the Library: construct an algorithm, drive its step stream, make the answer call.
  • Also available for Rust as switchyard-libsy; Path 2 has the Cargo.toml block.
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

Run Switchyard as a standalone proxy

A server in front of an agent, when you have no gateway to put Switchyard in. Point Claude Code, Codex CLI, or any OpenAI/Anthropic SDK client at it; Switchyard decides per turn which model serves it.

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

Components

Pre-1.0 software. APIs, configuration, and routing behavior can change between releases — pin the version you integrate.

Component Stability Use it for Guidance
switchyard-libsy Beta Routing embedded in your own gateway or harness. You own model calls, credentials, and retries. Trial integrations. API will change before v1.0.
switchyard-llm-client Alpha HTTP model calls and protocol translation alongside libsy. Experiments and pilots.
switchyard-runner Alpha Running configured routes inside another runtime, such as NeMo Relay. Integration work and supervised pilots.
switchyard-server Demo A standalone OpenAI- and Anthropic-compatible proxy. Demos and evaluation only. Not for production.

Get Started

Three paths, in the same order as above. Using Claude Code or Codex? Point it at this README and ask it to set up the path you want.

Path 1 — Load the NeMo Relay Plugin

You finish with an existing NeMo Relay deployment routing through Switchyard. Requires NeMo Relay >=0.8.0, <1.0.0 and a Rust toolchain.

Follow the plugin README's Install and Configure Relay sections. For the deployment file, use the routes.toml from Path 3, step 2.

Path 2 — Embed the Library

You finish with your own harness picking a model per request and still making every model call itself. Shown in Python; the Rust API has the same shape.

1. Install.

pip install git+https://github.com/NVIDIA-NeMo/Switchyard.git

The API below is newer than nemo-switchyard 0.2.0 on PyPI, so install from source until the next release. Rust: depend on switchyard-libsy and switchyard-protocol from this repository instead. Pin both to the commit you tested — @<sha> for pip, rev = "<sha>" for Cargo — before depending on them.

2. Construct an algorithm. It selects a category — efficient or capable — and you map categories to model IDs when each request runs.

from switchyard.libsy import LlmResponse, Step
from switchyard.libsy.algorithms import stage_router

algorithm = stage_router(picker="efficient_first", confidence_threshold=0.5)

3. Drive it. run_stream yields steps. Serve each CallModel with your own client — call.models is ordered by preference, and call.fail(error) reports a failed call; Done carries the pick.

models = {"efficient": ["fast"], "capable": ["quality"], "any": ["quality", "fast"]}

async for step in algorithm.run_stream(request, models):
    match step:
        case Step.CallModel(call):
            call.respond(LlmResponse.Agg(await my_client(call.request, call.models[0])))
        case Step.Done(outcome):
            model, request = outcome.selected_model_ids[0], outcome.request

4. Make the answer call with model and request, using your own HTTP client, retries, and credentials.

The complete runnable version — streaming and a working client — is examples/libsy.py. Types: switchyard-libsy, switchyard-protocol.

Path 3 — Run the Standalone Proxy

You finish with a server on localhost:4000 that any OpenAI or Anthropic client can call. Needs Rust with Cargo. For v0.3.0, the standalone server is release-validated on Ubuntu 24.04, Linux x86_64. Other platforms are outside the release-validation scope.

1. Install the server.

cargo install --locked switchyard-server

2. Write routes.toml. A stage router over the same model pair as the benchmark above: how to reach a provider, which models to use, how to choose between them. --config takes any path; this writes it to the current directory.

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

Every key is documented in the TOML schema reference.

3. Start it. --dry-run loads the config, prints server OK: and the model IDs it exposes, then exits without starting the server.

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. Send a request. The route's id is the model name clients ask for.

curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"switchyard","messages":[{"role":"user","content":"hello"}]}'

The same route also answers on /v1/messages (Anthropic Messages) and /v1/responses (OpenAI Responses). /v1/stats reports which target served what, and /metrics exposes Prometheus counters for requests, errors, latency, tokens, and routing overhead.

5. Point a coding agent at it.

export ANTHROPIC_BASE_URL="http://localhost:4000"
export ANTHROPIC_MODEL="switchyard"
export ANTHROPIC_API_KEY="placeholder"  # pragma: allowlist secret
claude

The placeholder satisfies Claude Code's client-side auth check. In this local setup, Switchyard uses the server's OPENROUTER_API_KEY for upstream requests. Do not use the placeholder with forward_auth = true or a gateway that requires a real client credential.

For Codex CLI, add this provider to ~/.codex/config.toml:

[model_providers.switchyard]
name = "Switchyard"
base_url = "http://localhost:4000/v1"
wire_api = "responses"
requires_openai_auth = false

Then select the provider and route:

codex --model switchyard -c 'model_provider="switchyard"'

No Codex API key is needed for this local setup. Switchyard uses the server's OPENROUTER_API_KEY for upstream requests.

Routing Algorithms

Start with Auto. Choose Task or Execution when you want more control over how requests move between an efficient model and a capable one.

Choice Use it when Route type
Auto You want Switchyard's recommended preset. auto
Task You want an LLM to judge which model can handle the task. llm_classifier
Execution You want tool results and agent progress to guide each request. stage_router

Auto currently uses Execution with fixed defaults and no LLM judge. Task uses the LLM classifier's capability mode. Execution uses the stage router. These names do not change the TOML configuration keys.

Auto requires a source build until v0.3.0 is published. The quickstart above uses stage_router directly.

See the full routing catalog for composite routing, escalation, custom policies, and other options. Performance results are listed under Benchmark Provenance.

Documentation

Benchmark Provenance

Configuration Accuracy Total cost vs. Opus 4.8 baseline
Opus 4.8 baseline 76.0% $98.06 —
Escalation 75.7% $85.00 99.6% of accuracy, 13.3% cheaper
Execution (Stage) 72.7% $68.19 95.7% of accuracy, 30.5% cheaper
Task (Capability) 71.2% $79.32 93.7% of accuracy, 19.1% cheaper
Kimi K2.6 alone 55.8% $76.28
GLM 5.2 alone 52.4% $16.47
DeepSeek V4 Pro alone 48.7% $96.92
Ultra 3 alone 39.0% $29.66

These are the v0.2.0 Terminal-Bench 2.1 results from Route AI Agent Workloads Across Models with NVIDIA NeMo Switchyard. Those runs used NVIDIA-internal inference endpoints, so absolute solve rates may shift on another serving stack; the routing parameters are the ones that ran.

The escalation deployment is checked in at benchmark/routing-profiles/tb21-escalation-opus-glm-deepseek.toml, with OpenRouter targets substituted so it is publicly runnable. To run the harness, see benchmark/README.md; for latency and routing overhead rather than task success, see Soak Testing.

Community

License

Apache 2.0 License. Copyright NVIDIA Corporation.

Metadata

Release files for nemo-switchyard 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nemo-switchyard 0.3.0
File Size Uploaded
nemo_switchyard-0.3.0.tar.gz 580.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for nemo-switchyard 0.3.0
File
nemo_switchyard-0.3.0-cp310-abi3-win_arm64.whl CPython 3.10 abi3 Windows ARM64 Details
nemo_switchyard-0.3.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
nemo_switchyard-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
nemo_switchyard-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
nemo_switchyard-0.3.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
nemo_switchyard-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 50.4 MB

Release files / nemo_switchyard-0.3.0.tar.gz

Download URL nemo_switchyard-0.3.0.tar.gz
Size 580.0 kB
Tags Source
SHA-256 checksum
How to use checksums
8eb5cf8ff9cb51d50aa9b1927559d4add807eef5041de9c27ab51ccf111d7b4c
BLAKE2b-256 checksum
How to use checksums
292b60bba54499585dad82fb37643577ffde2cc6de0ea283ddaefe4c2f73ab9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nemo_switchyard-0.3.0-cp310-abi3-win_arm64.whl

Download URL nemo_switchyard-0.3.0-cp310-abi3-win_arm64.whl
Size 7.3 MB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
d363408274523c804033ae470420379370db5e8b73e953dc880143591ad24283
BLAKE2b-256 checksum
How to use checksums
bcf07999e147c5646e57bb8d1f38fe6e7d32dd8c7f26026e0f8a9ca7e9be9c87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nemo_switchyard-0.3.0-cp310-abi3-win_amd64.whl

Download URL nemo_switchyard-0.3.0-cp310-abi3-win_amd64.whl
Size 7.6 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
45b76e1e5caa0e08fdb15a2ae97646ab901672a78e743c2a055629d393762070
BLAKE2b-256 checksum
How to use checksums
d23cf47e0d133205c07b4c56035a898c9a19d7a9e5bc1b23ba32fa701a931693
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nemo_switchyard-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL nemo_switchyard-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 9.1 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f0c3728517a7015d87bbdf6a21303a344c9d886ae98d910dee6a01c67f8657d3
BLAKE2b-256 checksum
How to use checksums
375e013e2ca5b866d6235b4be482a3ef78e49ad571e6a6c1972f8c89686f32ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nemo_switchyard-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL nemo_switchyard-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 9.0 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
bb40a39da460cc28d0c2143044233fef69b2c113813c511255f813ef0ac5bf1b
BLAKE2b-256 checksum
How to use checksums
af262424b9987c82917146d0533627eb7cd59819487dd86abc35dc8671039514
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nemo_switchyard-0.3.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL nemo_switchyard-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Size 8.3 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
cdc64503e427095c73e7840f0de093f0ee35fc3e306825e522050cd6e6825039
BLAKE2b-256 checksum
How to use checksums
50dee6a812c444b897f091649bf83ca60f483abab7fec92b30ce289f1a968101
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nemo_switchyard-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL nemo_switchyard-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 8.6 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
6b265e2cc399d487706140a8d949f5c6bab2ec2d4da9216fc06046df2a5e26d6
BLAKE2b-256 checksum
How to use checksums
62bc8c413bc9df00a0972934d6ea1265982360ad9ece2b15df67a3374eff66f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.0 This release

7 release files

0.2.0

7 release files

0.1.0

7 release files

0.0.1

7 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page