Guides

Migrate from TensorZero

Move a TensorZero gateway setup to BitRouter — drop the ClickHouse-backed LLMOps stack for a single agent-native binary, local or hosted.

Migrating from TensorZero to BitRouter

TensorZero is an open-source LLMOps platform — a Rust gateway bundled with observability, evaluations, optimization (fine-tuning, automated prompt engineering), and experimentation, all backed by a ClickHouse data warehouse and driven by a GitOps tensorzero.toml. BitRouter solves a narrower problem on purpose: an agent-native proxy with a single OpenAI-compatible surface, runnable as a local binary (BYOK, no infra) or as a hosted endpoint with autonomous agent payments.

This guide is for teams who adopted TensorZero mainly as a gateway — unified provider access, routing, retries, fallback — and want a leaner, agent-first surface without operating a database. If you lean on TensorZero's optimization and experimentation loop, read What BitRouter intentionally doesn't ship before you commit.

Why migrate?

TensorZeroBitRouter
RuntimeRust gatewayRust (single static binary)
Production depsClickHouse (observability store) + Docker/ComposeNone
Configurationtensorzero.toml — functions, variants, models, providersProvider keys + routing presets; no schema to maintain
Deployment modesSelf-hosted onlyLocal binary or hosted (api.bitrouter.ai) — same OpenAI-compatible endpoint
Design focusFull LLMOps loop: gateway + observability + evals + optimization + experimentationAgent-first proxy: MCP / ACP / Skills, agent firewall, agentic payment
Agent protocol surfaceNone (gateway is provider-facing)MCP, ACP, Skills, CLI — the product, not an add-on
Agentic auth & paymentNonex402 / MPP autonomous payment (cloud mode)
LicenseApache 2.0Apache 2.0

Two things worth highlighting

1. A proxy, not a platform

TensorZero is built around a feedback loop: route inference, store every call and its metrics in ClickHouse, then evaluate, fine-tune, and A/B test against that history. That's powerful if you run that loop — and it's why TensorZero needs a database and a typed config of functions and variants.

BitRouter deliberately stops at the gateway. There's no tensorzero.toml to maintain, no ClickHouse to operate — you set provider keys and route by provider/model id. OpenTelemetry gives you spans and metrics for every request (the same OTLP export TensorZero offers), but they go to a backend you already run, not a warehouse the proxy manages.

2. Agent-native, and cloud/local share one surface

TensorZero's gateway is provider-facing — it unifies the upstreams. BitRouter adds the agent-facing half: an MCP gateway for tools, an ACP gateway for agent identity and dispatch, a server-tool loop, and agentic payment so an agent can pay per request without you provisioning a key for it.

And the hosted cloud and local binary expose the same OpenAI-compatible endpoint — start local during development, point at api.bitrouter.ai for production (or vice versa) without changing client code. See the Quick Start for both flows.

Migration paths

From an OpenAI-compatible client

If your app already talks to TensorZero's OpenAI-compatible endpoint, migration is a base-URL swap plus dropping the tensorzero::… model prefix for a plain provider/model id:

import openai

client = openai.OpenAI(
    base_url="http://localhost:3000/openai/v1",
    api_key="not-used",
)

response = client.chat.completions.create(
    # TensorZero model / function reference
    model="tensorzero::model_name::openai::gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello"}],
)
import openai

# Local: `bitrouter` (BYOK via env vars) — see /docs/get-started/quickstart
# Cloud: base_url="https://api.bitrouter.ai/v1", api_key=$BITROUTER_API_KEY
client = openai.OpenAI(
    base_url="http://127.0.0.1:4356/v1",
    api_key="not-used-in-local-byok",
)

response = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello"}],
)

A TensorZero function (a named prompt template + schema with one or more variants) has no single equivalent — the routing half maps to BitRouter, the templating/variant half stays in your app or moves to a preset. See the feature mapping below.

From the gateway + ClickHouse stack

The infra migration replaces the Compose stack — gateway container plus ClickHouse — with one binary and no database:

# docker-compose.yml runs the gateway + a ClickHouse warehouse
export OPENAI_API_KEY=sk-...
export TENSORZERO_CLICKHOUSE_URL=http://chuser:chpass@clickhouse:8123/tensorzero
docker compose up   # gateway on :3000, ClickHouse on :8123
# config mounted from ./config/tensorzero.toml
# Install (curl, npm, brew, or cargo — see Quick Start)
curl -fsSL https://bitrouter.ai/install.sh | sh

# Set provider keys; BitRouter auto-detects on start
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

# Interactive wizard (Cloud or local); default local serves on :4356
bitrouter

To skip the local proxy entirely, point clients at https://api.bitrouter.ai/v1 with a BitRouter API key — no binary, no ClickHouse, no infra.

Feature mapping

TensorZero conceptBitRouter equivalentDocs
[models.*] + [models.*.providers.*] in tensorzero.tomlProvider keys (auto-detected) + the model registryBYOK, Models
[functions.*] (named prompt + schema)App-side, or a routing presetPresets
[functions.*.variants.*] (per-variant model)Routing preset variants / model idsPresets
routing / retries / fallbacksModel fallback rulesModel fallback
load_balancing across providersProvider selectionProvider selection
OpenAI-compatible /openai/v1 endpointOpenAI-compatible /v1 endpointAPI Reference
Native POST /inference endpointOpenAI-, Anthropic-, and Google-compatible protocolsAPI Reference
ClickHouse observability + UIOTLP traces & metrics to your own backend, or hosted Activity on CloudOpenTelemetry, Cloud Tracing
OpenTelemetry (OTLP) exportOpenTelemetry (OTLP) exportOpenTelemetry
Embedded structured outputs (JSON functions)Structured outputs across all providersStructured outputs
— (no equivalent)MCP / ACP / Skills agent gatewaysTools, Agents
— (no equivalent)Autonomous agent payment (x402 / MPP)Payment

What BitRouter intentionally doesn't ship

To set expectations honestly: BitRouter is a gateway, not an LLMOps platform. It does not ship TensorZero's optimization and experimentation loop — no built-in supervised fine-tuning, RLHF, automated prompt engineering, dynamic in-context learning, inference-level or workflow evaluations, or adaptive A/B testing, and no ClickHouse-backed UI for replaying historical inferences against alternative prompts.

If your workflow depends on that closed feedback loop — collect inferences and feedback, evaluate, optimize, experiment — TensorZero is the better fit and you should keep it for those workloads. BitRouter is the right move when the value you need from TensorZero is the gateway and the missing half is agent infrastructure: tool/agent gateways, an agent firewall, and pay-per-request autonomy.

Migration checklist

Before migration

  • List the providers and models you actually route through TensorZero (skip the rest)
  • Separate gateway use from platform use — are you using evals / optimization / experimentation, or just routing?
  • Note where [functions.*] templates and schemas live; plan to keep them app-side or move them to a preset
  • Decide cloud vs. local (or both — they share the endpoint)

Migration

  • Install the BitRouter CLI (Quick Start)
  • Export provider keys, or paste them into the cloud dashboard (sealed-box encrypted)
  • Update client base_url to http://127.0.0.1:4356/v1 (local) or https://api.bitrouter.ai/v1 (cloud)
  • Replace tensorzero::… model strings with provider/model ids
  • Re-point OTLP export at your backend (OpenTelemetry)
  • Verify with a sample request
  • Decommission the gateway container and ClickHouse if you no longer need the platform loop

Next steps

Get help

How is this guide?

On this page