Per-turn model routing for Claude Code and Codex: classify the turn, pick the tier, keep the native tools.
Community routers (jev-router, pi-jev-model-router, LangChain’s ModelRouterMiddleware) wrap the CLI, ask a System One model three typed questions per turn, and switch model tiers. A 7-day replay of 237 real turns reported ~60% cost savings against an all-frontier baseline. The decision itself is the cheap part — and it does not have to be hosted.
In development — the benchmark numbers on this page are measured; the Decide-1 model is in training.
Every turn pays frontier prices
A rename, a test run and an architecture question all go to the same model. Most turns do not need it.
A router prompt is another thing to debug
Asking a chat model “is this hard?” returns prose, invents buckets, and gives no signal when it guessed.
Switching has a cache cost
Moving a 100k-token context between models wastes cache. The router needs a probability, not a label, so you can set a switch threshold.
- 1
Ask three typed questions per turn
`task_kind` (choice: edit / explain / debug / architect / run), `complexity` (score 0–3), `needs_reasoning` (noul).
- 2
Route on the probabilities
Haiku when complexity < 1 and p(needs_reasoning) < 0.3; Opus when > 0.8; else Sonnet. Hold the tier when the switch gain is smaller than the cache you would drop.
- 3
Keep the native session
The router only changes the model flag. Tools, sessions and auth stay Claude Code’s own.
# Claude Code hook / router: one decision per turn, ~40 ms
r = client.system_one(state=turn.prompt_and_context, questions={
"task_kind": {"type": "choice", "instructions": "What is this turn asking for?",
"criteria": {"edit": "...", "explain": "...", "debug": "...", "architect": "...", "run": "..."}},
"complexity": {"type": "score", "instructions": "How hard is it?",
"criteria": ["trivial", "routine", "needs judgment", "novel"]},
"needs_reasoning": {"type": "noul", "instructions": "Multi-step reasoning is required."},
})
tier = "opus" if r.answers["needs_reasoning"].noul > 0.8 else \
"haiku" if r.answers["complexity"].score < 1 else "sonnet"- Choice — pick one option, a probability on each
- Score — a position on your ordered rubric
- Noul — a calibrated yes/no probability
jev-router reports a per-turn decision at ~$0.00003 and ~0.6 s, and ~60% cost savings on a 7-day replay of 237 turns (its numbers, hosted Jev). The same decision on a self-hosted encoder is ~40 ms on one GPU or ~400 ms on four CPU cores in our benchmark.
Numbers about Jev are its authors' or the cited source's; numbers from the benchmark are ours, on one harness, with the raw JSON published. Full table.
Get early access — and tell us which decision you'd hand over first
We're building Metatext Decide with the first teams that use it. Leave your email, answer as much as you like, and say yes to a short interview if you want a say in what ships.
- Early access to Decide as it opens up
- A 20-minute interview if you want one — research, not a pitch
- The benchmark harness and raw results, today
- No spam — early-access updates only
Questions
- Does this replace Claude?
- No. It decides which Claude gets the turn. The decision model never generates text.
- Where does the decision run?
- Hosted, or in your VPC — or on the laptop, since the encoder is small. Your prompts do not have to leave the machine to be routed.
- Can I tune it on my own turns?
- Yes. A few hundred labelled turns (which tier was right, in hindsight) is exactly the fine-tune the benchmark measured.