Skip to main content

Typed, composable LLM routing with request/response translation and multi-backend orchestration

Project description

Switchyard

Switchyard

Switchyard is a Python proxy for LLM traffic. It routes requests across providers, translates between the OpenAI and Anthropic APIs, collects usage statistics, and lets you build typed, profile-backed routing flows with little boilerplate.

Why Switchyard? Point a coding agent such as Claude Code or Codex at an open-source model. Switchyard translates between the OpenAI Chat, Anthropic Messages, and OpenAI Responses formats, so the agent keeps speaking its native API while the request is served by vLLM, NVIDIA NIM, Ollama, or any OpenAI-compatible endpoint. The same proxy can spread traffic across several models for A/B benchmarking, signal-driven cascade escalation, or a router you write yourself.

Launcher routing is explicit. By default, launchers use the built-in LLM-classifier router, which you tune with --weak-model, --classifier-model, --profile, and --classifier-min-confidence. Use --model X for single-model passthrough. The --routing-profiles FILE path is deprecated and remains only for launcher-owned legacy bundles.

Features

  • Protocol Translation: convert between OpenAI Chat, Anthropic Messages, and OpenAI Responses formats
  • Multi-Backend Routing: random routing, LLM-as-classifier routing, signal-driven cascade, or custom routers
  • Strong Types: typed request/response containers for OpenAI, Anthropic, and Responses APIs
  • Profile-Owned Routing: typed profiles own routing, backend calls, stats, and translation wiring
  • One-Command Launchers: switchyard launch claude, switchyard launch codex, and switchyard launch openclaw spin up a local proxy and drop you into the target CLI
  • Request Statistics: collect per-request latency, token, and cost data

Quick Start

Install from PyPI

pip install "nemo-switchyard[cli,server]"

Install from source for local use (requires uv)

git clone git@github.com:NVIDIA-NeMo/Switchyard.git
cd Switchyard
uv tool install --editable '.[server,cli]'

Install from source for contributors (requires uv)

git clone git@github.com:NVIDIA-NeMo/Switchyard.git
cd Switchyard
uv sync
uv run switchyard ...

1. Launch Claude Code, Codex, or OpenClaw through Switchyard

Create an OpenRouter account at openrouter.ai and generate an API key from the OpenRouter keys page, then export it:

export OPENROUTER_API_KEY="your-openrouter-key"  # pragma: allowlist secret
export OPENROUTER_BASE_URL="https://openrouter.ai/api/v1"
switchyard launch claude --model openai/gpt-4o-mini --api-key "$OPENROUTER_API_KEY" --base-url "$OPENROUTER_BASE_URL"
switchyard launch codex --model openai/gpt-4o-mini --api-key "$OPENROUTER_API_KEY" --base-url "$OPENROUTER_BASE_URL"
switchyard launch openclaw --model openai/gpt-4o-mini --api-key "$OPENROUTER_API_KEY" --base-url "$OPENROUTER_BASE_URL"

Each launcher starts a local proxy, points the agent at it, and shuts the proxy down when the agent exits. Use --model for single-model passthrough. The deprecated --routing-profiles flag remains for launcher-owned legacy bundles:

switchyard launch claude --model openai/gpt-4o-mini --base-url https://openrouter.ai/api/v1       # single-model passthrough
switchyard --routing-profiles routes.yaml -- launch claude                                        # legacy route bundle

Bedrock-backed profile caveat (Claude Code + MCP): Bedrock enforces a 64-character toolSpec.name cap. Claude Code's MCP bridge can auto-inject longer tool names, producing BedrockException 400s on tool-bearing requests. If you use a Bedrock-backed route and hit this, swap to an OpenAI-compatible model with --model openai/gpt-4o or a routing-profile YAML.

See Agent Launchers for supported harness versions, model requirements, troubleshooting, and Claude Code /model picker aliasing.

2. Run a standalone profile-config server

New standalone deployments use a profile config that separates provider connectivity, upstream targets, and client-facing profiles. A complete OpenRouter-backed random-routing config looks like this:

endpoints:
  openrouter:
    api_key: ${OPENROUTER_API_KEY}
    base_url: https://openrouter.ai/api/v1

targets:
  strong:
    endpoint: openrouter
    model: openai/gpt-4o
    format: openai
  weak:
    endpoint: openrouter
    model: openai/gpt-4o-mini
    format: openai

profiles:
  smart:
    type: random-routing
    strong: strong
    weak: weak
    strong_probability: 0.3

Serve it as a proxy. The smart profile and both target ids are exposed as models; clients select one through the request's model field:

switchyard serve --config profiles.yaml --port 4000
curl http://localhost:4000/v1/models
curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "smart", "messages": [{"role": "user", "content": "hi"}]}'

Launcher compatibility: Launcher subcommands do not accept --config. The deprecated --routing-profiles flag remains for launcher-owned legacy routes: bundles and saved bundle paths:

routes:
  fast:
    type: model
    target: openai/gpt-4o-mini
switchyard --routing-profiles routes.yaml -- launch claude
switchyard --routing-profiles routes.yaml -- configure

For profile selection and full configuration examples, start with Routing Overview, then open the strategy-specific page:

For multi-turn classifier sessions, see Session Affinity (Sticky Routing).

3. Use as a Python library

import asyncio

from switchyard import ChatRequest, PassthroughProfileConfig, ProfileSwitchyard

switchyard = ProfileSwitchyard(PassthroughProfileConfig(
    api_key="sk-...",
    base_url="https://api.openai.com/v1",
).build())

async def main():
    request = ChatRequest.openai_chat({
        "model": "gpt-4o",
        "messages": [{"role": "user", "content": "What is 2+2?"}],
    })
    response = await switchyard.call(request)
    # call() returns a JSON-compatible dict in the OpenAI Chat Completions shape.
    print(response["choices"][0]["message"]["content"])

asyncio.run(main())

Architecture

Switchyard sits between your client applications and one or more LLM backends:

flowchart LR
    clients["Clients"]
    switchyard["Switchyard<br/>routing · translation · fallback"]
    backends["Model backends"]

    clients -->|"OpenAI / Anthropic API"| switchyard
    switchyard -->|"provider-native format"| backends

Clients keep their native OpenAI or Anthropic API format. Switchyard picks a configured backend, forwards the request in that backend's own format, and translates the response back into the shape the client expects. See Architecture for the system context and the full request flow.

Installation Options

Install from PyPI:

pip install nemo-switchyard

Optional extras:

pip install "nemo-switchyard[server]"   # FastAPI / Uvicorn HTTP endpoints
pip install "nemo-switchyard[cli]"      # Interactive CLI launchers (Claude / Codex)
pip install "nemo-switchyard[all]"      # Server, CLI, GPU routing, and tracing extras

See Installation for a full breakdown of what each extra adds.

Documentation

  • Getting Started: step-by-step setup, first request, troubleshooting
  • Known Issues: known issues in 0.1.0
  • Agent Launchers: Claude Code, Codex, and OpenClaw launcher behavior
  • Cli Reference: canonical reference for every switchyard subcommand and flag
  • Architecture: system context and end-to-end request flow
  • Routing Algorithms: signal-driven weak/strong cascade routing: picker layers, signal dimensions, and calibration data.
  • Contributing: dev setup, testing, CI gates, PR process
  • Development: project structure, benchmarks, conventions
  • Agents: full design philosophy and architectural patterns

Supported Providers

  • OpenAI: Chat Completions API
  • Anthropic: Claude Messages API
  • OpenAI Responses API: structured output / reasoning
  • OpenAI-compatible APIs: vLLM, Ollama, Azure, etc. (anything with /v1/chat/completions)

Requirements

  • Python 3.12+
  • macOS, Linux, or Windows
  • API keys for your chosen backend (OpenAI, Anthropic, etc.)
  • Linux x86_64 wheels require an x86-64-v3 / AVX2-class CPU (post 2013).
  • Linux aarch64 wheels require a Neoverse N1-class CPU (post 2020).

Community

License

Apache 2.0 License. Copyright NVIDIA Corporation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nemo_switchyard-0.1.0.tar.gz (629.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

nemo_switchyard-0.1.0-cp312-abi3-win_arm64.whl (4.0 MB view details)

Uploaded CPython 3.12+Windows ARM64

nemo_switchyard-0.1.0-cp312-abi3-win_amd64.whl (4.3 MB view details)

Uploaded CPython 3.12+Windows x86-64

nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ x86-64

nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (5.0 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ ARM64

nemo_switchyard-0.1.0-cp312-abi3-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

nemo_switchyard-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.12+macOS 10.12+ x86-64

File details

Details for the file nemo_switchyard-0.1.0.tar.gz.

File metadata

  • Download URL: nemo_switchyard-0.1.0.tar.gz
  • Upload date:
  • Size: 629.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d8345d48b95375924daba39a7eb3af0e3a301d11d0fea7125db325aea4491a1b
MD5 e9594a0754dd1a32c6c4d6b3f1509347
BLAKE2b-256 281377338269ab06dcad5b81bf7d969d618308fb745fbf79f45a6224d4cafea5

See more details on using hashes here.

File details

Details for the file nemo_switchyard-0.1.0-cp312-abi3-win_arm64.whl.

File metadata

  • Download URL: nemo_switchyard-0.1.0-cp312-abi3-win_arm64.whl
  • Upload date:
  • Size: 4.0 MB
  • Tags: CPython 3.12+, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0-cp312-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 cb8458ae4a79ac92b70a7265d6e6b057295c123cf93455803bd76187069e3e37
MD5 36a063cf600890207837ba03da06be53
BLAKE2b-256 43a382575e6a41d60cd174aa77e24e31a0a8babb2107724ac22474a2a28075a5

See more details on using hashes here.

File details

Details for the file nemo_switchyard-0.1.0-cp312-abi3-win_amd64.whl.

File metadata

  • Download URL: nemo_switchyard-0.1.0-cp312-abi3-win_amd64.whl
  • Upload date:
  • Size: 4.3 MB
  • Tags: CPython 3.12+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 3f7a4d1ddefe96bad618104c5a3dc603562445d320c9093d3edc8c0149a46668
MD5 8b2e9267d24926a5f17071625199349f
BLAKE2b-256 ee3e33b0c99712565a5055ac0b7b12ca896d4d85508580143b3a125be046e1f7

See more details on using hashes here.

File details

Details for the file nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 5.0 MB
  • Tags: CPython 3.12+, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e5155ffd3439a38ec7a7092644866305bf7b791363cd85702e93b42ba9f20220
MD5 0e6a3c426f259d1c3e68b2041ca1d211
BLAKE2b-256 0e6c37919de9cf2730bbcf11e4d0e960b5b0065e6a1626b3955045bdb7845c5e

See more details on using hashes here.

File details

Details for the file nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 5.0 MB
  • Tags: CPython 3.12+, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 350117ff7f584fcd93fc1937e842f2c26ad604514984af32e9d64084f61de6ea
MD5 8caa17495d4b28b9b128be6a08667073
BLAKE2b-256 c7443a72f331598cf891607c8a1d1f6ff6ab3923796acce10f922c891e721871

See more details on using hashes here.

File details

Details for the file nemo_switchyard-0.1.0-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

  • Download URL: nemo_switchyard-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 4.6 MB
  • Tags: CPython 3.12+, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c6dfad1585e1917fc82168a4301d579f4d3bc37069693bb588d7cee0633b7015
MD5 c6758a10cc1bc3c30278bfc71943de6c
BLAKE2b-256 571a4343ed7364b7fb138a8dd20c780347e7c05b0c5e20d133cba155caa6925c

See more details on using hashes here.

File details

Details for the file nemo_switchyard-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: nemo_switchyard-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 4.7 MB
  • Tags: CPython 3.12+, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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}

File hashes

Hashes for nemo_switchyard-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2a40c943b9d841067472f92b4a163772290fa314cff9515c9c9793549843b30e
MD5 7fe6391ea14bfa75a3f4effe5edbe10b
BLAKE2b-256 6d9d435b33896dfe54daf04018af4cbeb4c08066fcca9f68c69ba28b6e238480

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page