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.0.1.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.0.1-cp312-abi3-win_arm64.whl (4.0 MB view details)

Uploaded CPython 3.12+Windows ARM64

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

Uploaded CPython 3.12+Windows x86-64

nemo_switchyard-0.0.1-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.0.1-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.0.1-cp312-abi3-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

nemo_switchyard-0.0.1-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.0.1.tar.gz.

File metadata

  • Download URL: nemo_switchyard-0.0.1.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.0.1.tar.gz
Algorithm Hash digest
SHA256 57ef0d73688d5eabce4aa37bd42a5d760f9eda03932de9aeacffcf7565d04c7d
MD5 202e33346eb69c5db6c49cd58efd9418
BLAKE2b-256 9ab2f5003ee2138d53d7f04c8a5e61d8e782b04c950429caba6e1c941109d3c5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nemo_switchyard-0.0.1-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.0.1-cp312-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 707792a66980b34937c8e1963a3453072ce6b4ce6c4c933d5ad4001c1b2d42c6
MD5 02a8283c227defd2c882b6d0dd65a7ca
BLAKE2b-256 13c8a262c38184ccfa1eb5c2b537ebec3b42546b25fcb7f25ce3fbd863c00992

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nemo_switchyard-0.0.1-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.0.1-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a5ef548c293bb0e00ecb85addc026e6d83bcccef199132e6724c9e7fd6463d9c
MD5 53c95de878500809e317f6fc26d19f3d
BLAKE2b-256 6b61e7f17e04c6fc8e28ac2392f563fbf8b934fbcdd7f5ccb0fcbab5c4b052dc

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nemo_switchyard-0.0.1-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.0.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2d4ac4c6e7dbcdef179c13da3440b1504225076fc2054534306294d06c5f0f26
MD5 c4c6e31e976c5f6bf9b5b5abdaa26694
BLAKE2b-256 e903d2c3f00c4def1b885b21d33058927e8593febec2a5e41adc7ecaf1c044f0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nemo_switchyard-0.0.1-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.0.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 da2277e7c7424c713cedc7a42e9041558598f61cb9c2cea9ffc7208d6165843c
MD5 b50c8aee938f9586501e863d9358124a
BLAKE2b-256 58f5fe9122c8eab74845fde3e1aab9421af3735eddc33d2b7ba458d11bb88a4b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nemo_switchyard-0.0.1-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.0.1-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ede8ab9dd2a4d9bb163a7d6f8ee15df9e9dd60a50b67d29d9ef9376ddbe97927
MD5 caa5c52cf788cea6c281130bea7d0d77
BLAKE2b-256 c8865472d13030835ff20cc4f49d0713e2b183ee396a3ea5b6416eb7a1e197b1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nemo_switchyard-0.0.1-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.0.1-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9da362abf52b25b66ee110049344e5f698df03abfb77ca30c4b487104014a02d
MD5 773c775e24035badeb4a0d9af080edb6
BLAKE2b-256 80520905149652e19dcfd05eb7fc16939163b92b86d9f5f600b49f7b082e1316

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