Operant

In-path gateway for AI agents

One endpoint, every model, and a bill that keeps getting smaller.

Point your agents at Operant — one base URL, no code changes. It forwards every call, prices every turn, and then quietly adapts: caches what repeats, drops what is stale, and moves the work it has learned onto cheaper models carrying the right skill.

1base URL to change. Anthropic and OpenAI wires, both.
0changes to prompts, tools or SDKs. Your keys stay yours.
3automatic levers: cache shaping, compression, learned routing.
Savings · one conversation −64% saved

Without Operant this conversation would have cost $2.41; it cost $0.87−$1.54 (64%) saved.

CallServed byPotentialActualSaved
#1claude-sonnet-5$0.31$0.31
cachebreakpoints placed — the next turns read this prefix at 0.1×
#2claude-sonnet-5$0.58$0.19−$0.39
cache41,900 of 46,300 input tokens read from cache instead of re-sent
#3claude-sonnet-5$0.74$0.22−$0.52
compressionmasked 3 stale tool results (older than 2 turns) → 18,400 fewer tokens
#4claude-haiku-4-5
learned:7
$0.78$0.15−$0.63
routingrule “Compliance evidence pack” served haiku + skill v2 — gate 100%
Σ4 calls$2.41$0.87−$1.54

Illustrative ledger. Counterfactuals are stated estimates: same tokens priced at the model the agent asked for, masked tokens restored, gateway-shaped cache unwound.

Get started

Sign in, store a key, say hello, watch it settle.

Four screens from a fresh workspace to your first priced conversation. Nothing to install; your agents keep their own model keys.

01

Sign in

E-mail and password, Google, or your company's single sign-on. An organization is a tenant: your rows, your routers, your keys — isolated at the database, not just the app.

Sign in to your workspace. Your agents keep their own model keys; Operant sits in the path and learns which of your recurring work can run cheaper.

Continue with Google
Sign in E-mail me a sign-in link New here? Create an account
02

Configure

Store a provider key (encrypted at rest) and mint an Operant key for each agent. The gateway strips the Operant key, injects your provider key, and stamps every call on the key that sent it.

OverviewConversationsPatternsRoutersSkillsSettings
Settings
API keys+ New key

Point an agent at the gateway with your Operant key in the provider's own auth header. Every call is stamped with the key that sent it.

NameKeyCreated byCalls (MTD)Spend (MTD)Last used
claude-code · priyaoperant_3f9a…priya12,418$612.402 min ago
support-agent · prodoperant_b71c…dev88,902$1,988.15just now
dsh · ci-runneroperant_0e2d…ci3,106$431.451 h ago
Provider credentials

Your own model-provider keys, encrypted at rest. Used when a caller sends no key of its own.

ProviderStatus
Anthropic
sk-ant-… — used when a caller sends no key
stored · 12 Aug 2026Replace
OpenAI
sk-… — also powers goal embeddings
stored · 12 Aug 2026Replace
LiteLLM proxy
the proxy's virtual key
not setSet
03

Try a chat

The built-in chat client is a stock API client pointed at the gateway. Pick a router as the model and every reply says which model actually answered.

Operant Chat
+ New conversation
Refund for a duplicate charge on last month's invoicec_8f2a1c
Draft the SOC 2 access-review summary for Q3c_51be07
Modelrouter/standard PersonaAna · free plan Sent as metadata on every call — the router's rules read it to decide which model serves the turn. Each reply says which model answered.
/c/c_8f2a1cbase_url
user
I was charged twice for August. Can you refund the duplicate?
assistant served by claude-haiku-4-5
I can see two charges of $49.00 on 3 Aug for invoice #10422. I've issued a refund for the duplicate — it should appear on your statement in 3–5 business days. Would you like the confirmation e-mailed?
user
Yes please. Also, why did it happen?
assistant served by claude-haiku-4-5
Sent. The duplicate came from a retried payment webhook — the first attempt timed out but had already settled. I've flagged the invoice so it can't be charged again.
Message… (Enter to send, Shift+Enter for a new line)Send
04

Observe

Every conversation lands grouped and priced — chat, Claude Code sessions, framework agents — with its goal named, its calls counted and its spend to the cent.

OverviewConversationsPatternsRoutersSkillsSettings
Conversations
Refund a duplicate charge on the August invoice and explain the cause
Two $49 charges on invoice #10422; refund issued, invoice flagged against re-charge.
2 calls · 2 user turns · 1 min ago conversation_id
c_8f2a1c$0.0041
Assemble the Q3 SOC 2 evidence pack for access reviews
Pull the IAM audit export, incident tracker and deploy approvals into the standard four-section pack.
3 calls · 3 user turns · 14 min ago session claude-code
cc-4d1e…9b2$0.14
Migrate the billing service's retry logic off the deprecated queue client
Main thread plus three Explore sub-agents; two sidecar title calls.
31 calls · 5 user turns · 2 h ago session deepseek-harness
dsh-a90f…c31$4.62
Unlock a customer account locked after repeated failed logins
Reset issued; user asked to be told when the lock lifts.
3 calls · 2 user turns · 3 h ago conversation_id
c_2210af$0.0063

Configure your client

Change the base URL. Name a router as the model. Done.

Operant speaks the Anthropic and OpenAI wires, so whatever already talks to a model can talk to Operant. Address a router as router/<name> and the gateway chooses the model per turn — deep, standard and fast are seeded on day one.

Any agent framework

LangGraph · any SDK

Set base_url where you build the model; add /c/<thread-id> and Operant groups the thread as one conversation. Frameworks on the OpenAI wire point at /v1 the same way.

graph.py · LangGraphanthropic wire
from langchain_anthropic import ChatAnthropicdef model_for(thread_id: str) -> ChatAnthropic:return ChatAnthropic(model="router/standard",base_url=f"https://app.operantlabs.com/c/{thread_id}",)

Claude Code

.claude/settings.local.json

One env block. The three model slots map onto the tier routers, so opus, sonnet and haiku each become a router Operant can learn on. Sub-agents and sidecar calls are grouped under the session automatically.

settings.local.jsonanthropic wire
{"env": {"ANTHROPIC_BASE_URL": "https://app.operantlabs.com","ANTHROPIC_API_KEY": "strata_…","ANTHROPIC_DEFAULT_OPUS_MODEL": "router/deep","ANTHROPIC_DEFAULT_SONNET_MODEL": "router/standard","ANTHROPIC_DEFAULT_HAIKU_MODEL": "router/fast"}}

DeepSeek Harness

~/.dsh/settings.yaml

Export the base URL from the shell you launch dsh from and name the router as the default model. Each dsh session is one Operant conversation; its sub-agents fold in.

shell · then settings.yamlopenai wire
export DEEPSEEK_BASE_URL=https://app.operantlabs.com/v1export DEEPSEEK_API_KEY=strata_…# ~/.dsh/settings.yamlagent-default-model:provider: deepseek-officialmodel: router/standardllm-deepseek:thinking: disabledmaxTokens: 16384

Codex CLI

~/.codex/config.toml

Declare Operant as a model provider on the chat wire and make it the default. Everything else in Codex — sandbox, approvals, MCP servers — is untouched.

config.tomlopenai wire
model = "router/standard"model_provider = "operant"[model_providers.operant]name = "Operant"base_url = "https://app.operantlabs.com/v1"env_key = "OPERANT_API_KEY"wire_api = "chat"

Save on model use

Three adaptations Operant makes on its own.

A model call costs tokens × price per token. Cache shaping and compression cut the tokens; learned routing cuts the price. They are independent levers, and they multiply.

01 · Cache shaping

Agents re-send the whole conversation every turn. Operant makes sure it's read from cache.

That is how the wire works: system prompt, tool schemas, every earlier turn and every earlier tool result travel again on each call, and the new user turn is the smallest part. A provider will bill a re-used prefix at about 0.1× — but only if the request marks where the prefix ends.

  • Most agents don't. Operant sees a call that is not shaping its cache and places the cache_control breakpoints itself: after the stable tools + system block, and at the tail of the history so the prefix that grew last turn is a cache read this turn.
  • Additive only. No reordering, no content change; callers that already set breakpoints are left untouched.
  • Measured, not assumed. The ledger attributes exactly the tokens that were read from cache because of Operant's breakpoints.

What the agent sends · turn 7

system prompt + 14 tool schemas 6,200 tok
turns 1–3 · user, assistant 3,100 tok
tool_result · read_file ×3 11,400 tok
turns 4–6 · user, assistant 4,300 tok
tool_result · grep, run_tests 19,200 tok
turn 7 · the new user message 140 tok
input44,340 tok · full price

What Operant sends

system prompt + 14 tool schemas cache read
cache_control · breakpoint 1
turns 1–3 · user, assistant cache read
tool_result · read_file ×3 cache read
turns 4–6 · user, assistant cache read
tool_result · grep, run_tests cache read
cache_control · breakpoint 2
turn 7 · the new user message 140 tok · full price
billed as44,200 × 0.1 + 140 ≈ 4,560 tok
the rewrite · one annotation per breakpoint, nothing else changes
{ "role": "user", "content": [ { "type": "tool_result", "tool_use_id": "toolu_01Rj…","content": "…", "cache_control": { "type": "ephemeral" } } ] }
Cache health

Cache-read share of input tokens per day, last 30 days · $612.40 still re-sent uncached over the window (measured)

12%2026-07-30 → 2026-08-28 · cache shaping switched on 2026-08-0686%

Illustrative turn and figures. Cache-read pricing and breakpoint limits are the provider's; Operant only decides where the breakpoints go.

02 · Compression

Stale tool output is the biggest slice of a long session. Operant masks it.

On a late turn, most of the input is old tool results — file dumps, search hits, test logs the model already acted on and rarely reads again. A router rule can say so: mask tool results older than n turns with a short, deterministic placeholder.

  • Cache-cooperating. Masking is a byte-stable text edit, so the compressed form caches too; Operant compresses only what the cache is not already saving, and never changes the same bytes twice.
  • Governed like a route. Compression is an equivalence claim about a slice of traffic, so it lives on a rule and inherits the same lifecycle: shadow → eval gate → ratify → one-click demote.
  • Audited both ways. The trace shows what the app said and what the provider was sent.
RULES — EVALUATED TOP-DOWN, FIRST MATCH WINS
↑↓ManualPlan-status checks → Haiku, without the old tool dumpsTurn offEdit
WHENmetadata.task == "evaluate"claude-haiku-4-5 · 100%failover → claude-sonnet-5masks tool results > 2 turns old

What the agent sends · turn 9

system + tools 5,800 tok
turn 2 · tool_result · read_file plan.md 7,900 tok
turn 4 · tool_result · list_dir, read ×4 12,600 tok
turn 6 · tool_result · run_tests (log) 9,300 tok
turn 8 · tool_result · git diff 3,100 tok
assistant / user text, turns 1–8 2,900 tok
turn 9 · “is the plan on track?” 60 tok
input41,660 tok

What Operant sends to the model

system + tools 5,800 tok
[tool result masked · 7,900 tok · turn 2 · read_file plan.md — call the tool again if needed] 38 tok
[tool result masked · 12,600 tok · turn 4 · list_dir, read ×4] 34 tok
[tool result masked · 9,300 tok · turn 6 · run_tests] 31 tok
turn 8 · tool_result · git diff 3,100 tok
assistant / user text, turns 1–8 2,900 tok
turn 9 · “is the plan on track?” 60 tok
input11,963 tok · −71%

Illustrative turn. Placeholders name the turn and the tool, so the model can re-fetch; the trace keeps the original bytes.

03 · Skill + cheaper model

The work that keeps recurring moves to a cheaper model — carrying the skill it needs.

Operant clusters conversations by goal, writes the skill a smaller model needs to do that goal well, and proposes a rule: this pattern → cheaper model + skill. The rule runs in shadow, is replayed against the frontier's own answers, and takes traffic only when the gate passes and you ratify.

  • Learned rules sit beside yours in the same router, evaluated top-down.
  • One click back. Demote to shadow at any time; the frontier model is always the failover.
  • Savings are counterfactual and stated as such — same tokens, priced at the model the agent asked for.
← Routersrouter/standardLivePauseCopy endpoint snippet
RULES — EVALUATED TOP-DOWN, FIRST MATCH WINS
↑↓LearnedPattern: Compliance evidence packGate 100%Active$812/mo + $96/mo tokens (est.)
matches by cortex classifier · → claude-haiku-4-5 + skill compliance-evidence-pack v2 · failover → claude-sonnet-5 · masks tool results > 2 turns old (would drop 32M tok/mo, est.)
Demote to shadowRe-run gate

Condition managed by the cortex; the skill is edited on its page. The target model, reordering and demoting stay here — an active rule must be demoted to shadow before its target can change.

↑↓LearnedPattern: Weekly incident digestGate 92%Shadow$318/mo (est.)
matches by cortex classifier · → claude-haiku-4-5 + skill incident-digest v1 · failover → claude-sonnet-5
Re-run gateRatify to activeEdit target
DEFAULT ROUTEsticky: user_id → key
claude-sonnet-5 · 100%failover → claude-opus-5

The gate replays held-out exemplars through the candidate and asks a judge model for parity against the frontier's answers. 100% here means every exemplar passed.

How it learns

Observe. Learn. Codify. Save.

One pattern, followed through the console: from a cluster of look-alike conversations to a skill, a ratified rule, and the next conversation running two rungs down the cost ladder.

01

Observe — clusters of common conversations

The cortex embeds every conversation's goal and clusters them. Spend has a fat head: a handful of patterns account for most of it.

OverviewConversationsPatternsRoutersSkillsSettings
PatternsRecluster
Your spend has a fat head. The top 4 patterns account for 63% of spend — routing them to a cheaper model could save 44%.Review patterns →
Patterns

Conversations clustered by goal (Cortex)

PatternConvsSpendCompressible / moShare of spend
Compliance evidence pack
Assemble audit evidence with the standard four-section structure from the systems of record.
148$1,240$312
Weekly incident digest
Summarize the week's incidents with owners, status and follow-ups.
52$402$88
Refund and duplicate-charge handling
Locate the charge, refund, explain the cause, prevent recurrence.
611$151$14
Codebase exploration (sub-agent)
Locate files, symbols and call sites for a named task; report paths, not dumps.
296$121$63
Long tail (unclustered)
one-off goals — not repetitive enough to name
1,204$1,118
02

Learn — a skill for the cluster

From the cluster's exemplars, Scribe writes the instruction unit a cheaper model needs. Versioned, editable in a text box, with its provenance attached.

OverviewConversationsPatternsRoutersSkillsSettings
Skills
← All skills
Compliance evidence pack
compliance-evidence-pack · v2readyCompliance evidence pack
New versionRetire

Assemble audit evidence packs with the standard structure and sources.

LEARNED BY SCRIBE
claude-sonnet-5$0.84 learning cost14 agentic turnsbundle 9c1f0a2b7e12 exemplar conversations

Structure

Four sections, always in this order: access reviews, incident summaries, change management, and exceptions. Work through them in order and keep each section's evidence traceable to its system of record.

Sources

Pull from the system of record, never from memory: the IAM audit export, the incident tracker filtered to the period, and the deploy log with approval links. Name the export and its timestamp in the section header.

When something is missing

Do not infer. Record the gap as an exception with the owner who can close it, and continue.

03

Codify — a rule, gated and ratified

The cortex proposes cheaper model + skill for the pattern. It runs in shadow, its gate replays the exemplars, and you ratify with the evidence in front of you.

Cortex proposal Pattern Compliance evidence pack (148 convs) can route to claude-haiku-4-5 + skill compliance-evidence-pack v2 — est. $812/mo. Shadow it inside router/standard? Add as shadow ruleDismiss
↑↓LearnedPattern: Compliance evidence packGate 100%Shadow$812/mo + $96/mo tokens (est.)
matches by cortex classifier · → claude-haiku-4-5 + skill compliance-evidence-pack v2 · failover → claude-sonnet-5
Re-run gateRatify to activeEdit targetRemove
Ratify this rule?

Production calls matching Compliance evidence pack will be rewritten: model swap to claude-haiku-4-5 + skill append (compliance-evidence-pack v2).

Gate 100%12 of 12 exemplars at parity · judge claude-opus-5 · you can demote at any time
CancelRatify to active
04

Save — the next conversation, priced

The same goal, one week later: a cheaper rung on the ladder, under observation, with the frontier cost of its look-alike beside it.

← All conversations
Assemble the Q3 SOC 2 evidence pack for access reviews and change management
cc-4d1e5b2f…9b2claude-codeFull depth · escalated · Compliance evidence packsuccessTraceSavings

Without Operant this conversation would have cost $0.55; it cost $0.14−$0.41 (75%) saved. Nearest earlier look-alike, on the frontier model before the rule: $1.79 (claude-opus-5, cc-2a77…, 22 Aug).

CallServed byPotentialActualSaved
#1claude-haiku-4-5 · learned:7$0.10$0.03−$0.07
routingWithout Operant this call runs on claude-sonnet-5; rule “Compliance evidence pack” served claude-haiku-4-5
#2claude-haiku-4-5 · learned:7$0.19$0.05−$0.14
routingrule “Compliance evidence pack” served claude-haiku-4-5 · cache19,100 of 21,400 input tokens read from cache instead of re-sent at full price
#3claude-haiku-4-5 · learned:7$0.26$0.06−$0.20
routingrule “Compliance evidence pack” served claude-haiku-4-5 · compressionRequest carried ~28,300 input tokens; Operant masked 2 stale tool results (older than 2 turns) → 14,900 sent
Σ3 calls$0.55$0.14−$0.41
COST LADDER$0.14 of $0.55
#1claude-haiku-4-5$0.03
learned:7 · Compliance evidence pack24.1k in · 2.1k out · cache r 0 · TTFT 412ms
#2claude-haiku-4-5$0.05
learned:7 · cache r 19.1k
#3claude-haiku-4-5$0.06
learned:7 · masked 2 tool results
Look-alike before the rule, 22 Aug · claude-opus-5 · 3 calls · $1.79

Agent harnesses

Every thread of a coding agent, priced and learned from.

A Claude Code or DeepSeek Harness session is not one conversation. It is a main thread, a handful of sub-agents, and the harness's own sidecar calls — title, permission classifier, compaction. Operant captures the whole tree from what the harness already sends, with no wire change.

OverviewConversationsPatternsRoutersSkillsSettings
Conversations
Migrate the billing service's retry logic off the deprecated queue client
dsh-a90f3c…c31deepseek-harnessFull depth · escalated · Codebase migrationsuccess
All · 31User · 5Assistant · 12Tools · 14Errors · 1 MainSub-agents · 3Harness sidecars · 2
call 4
ASSISTANT
I'll fan out three Explore agents: one for call sites of QueueClient, one for the retry tests, one for the deploy config.
TOOL_USEsubagentFind every call site of QueueClient.publish and .ack in services/billing…→ sub-agent #1
TOOL_USEsubagentList the tests that exercise retry behaviour and how they stub the queue…→ sub-agent #2
TOOL_USEsubagentRead the deploy config for the billing worker and report queue env vars…→ sub-agent #3
call 11 · active$0.31
TOOL_RESULTsubagent12 call sites in 6 files. publish(): billing/worker.ts:41, :88; retry.ts:17…masked on call 14+
ASSISTANT
All three back. The retry path is in retry.ts only; the tests stub QueueClient directly, so the migration is mechanical. Starting with the worker.
COST LADDER$4.62 of $9.10
#4claude-sonnet-5$0.22
main · cache r 38.2k
#5claude-haiku-4-5$0.04
sub-agent · learned:9 codebase-exploration v3
#6claude-haiku-4-5$0.03
sub-agent · learned:9 codebase-exploration v3
#7claude-haiku-4-5$0.02
sub-agent · learned:9 codebase-exploration v3
#8claude-haiku-4-5$0.001
title · sidecar
#11claude-sonnet-5$0.31
main · cache r 51.4k · masked 358.9k in · 1.2k out · cache r 51.4k · TTFT 690ms

Full observability, thread by thread

Main, sub-agents and sidecars are one conversation with lineage: which turn delegated which sub-agent, what each thread cost, how much of each call was a cache read, what was masked. Lineage is inferred from the delegated prompt crossing the wire twice — labeled as such, no harness fork needed.

Insights you can act on

insightAcross 296 coding sessions, an Explore-style sub-agent thread recurs in 71% of them — the sessions' goals never repeat; the sub-agent's does.
insightSessions longer than 20 calls re-send 41,200 stale tool tokens per turn on average; masking on the main thread would drop it by 62%.

Several skills from one session

The conversation as a whole may never recur — but its sub-agent threads do, across hundreds of sessions. Operant clusters threads, not just conversations, so a session can yield more than one skill: codebase-exploration for the Explore sub-agent, test-triage for the one that reads failing logs. Each gets its own rule on the router the harness already calls.

Compare

Operant vs. the alternatives.

A unified endpoint and fallback are table stakes. The difference is what happens to the bill after week one.

CapabilityDirect provider APIsOpenRouterLiteLLM / generic gatewayOperant
One base URL, Anthropic + OpenAI wiresN/A (native)OpenAI wireBothBoth, no code changes
Bring your own provider keys, no markupYesCredits, fee on purchaseYesEncrypted at rest, stripped on forward
Conversations grouped and priced, with sub-agent lineageBuild it yourselfPer-request logsPer-request logs, tagsPer conversation, per thread, per key
Automatic cache-breakpoint placementManual, in your codePasses yours throughPasses yours throughPlaced and measured per call
Stale tool-result masking (compression)Build it yourselfNot availableNot availableCache-cooperating, on a rule
Skills learned from your own trafficNot availableNot availableNot availableVersioned, with provenance
Routing rules with an eval gate and ratificationBuild it yourselfStatic routing, fallbackConfig-driven routing, fallbackManual + learned; shadow → gate → ratify
Counterfactual savings ledgerNot availableSpend onlySpend onlyPer call, per lever, stated as estimates
Run it in your own VPCN/AHosted onlySelf-hostHosted, or four containers and one origin

Competitor columns summarise publicly documented behavior as of August 2026.