I kept catching myself doing something dumb. I’d open Claude Code with the strongest model selected, because for the hard problem I sat down to solve, I wanted the strongest model. Then I’d spend the next hour also asking it to fix a typo, rename a variable, and update a line in the README. Every one of those billed at flagship rates. The model was wildly overqualified and I was paying for it forty times a day.
The fix in theory is obvious: use a cheaper model for the cheap tasks. The fix in practice is that switching models by hand forty times a day is a thing nobody actually does. It breaks your flow, you forget, and the friction isn’t worth the few cents, until you add up a month of it.
The models aren’t the problem. The routing is.
We have an embarrassment of good models now, at every price and speed. What we don’t have is anything deciding which one should answer a given turn. The harness just sends everything to whatever was selected. Across two agents, Claude Code here and Codex there, there isn’t even a shared notion of “the right model for this job.”
spawn is that missing layer. It reads each task on-device, classifies it in about 50ms (how that works), and routes it to the model that fits. Frontier quality where it matters; frontier prices only where they’re earned.
Routing is a config problem, not a model problem
The classifier deliberately doesn’t pick a model. It describes the task as task_type, complexity, and risk, and a plain YAML profile turns that description into a destination. That file is yours to edit.
# ~/.spawn/route.yaml (the part you actually own) default: sonnet-4.6 by_complexity: easy: haiku-4.5 hard: opus-4.8 by_task_type: design: opus-4.8 migration: gpt-5.5 risk: high: bump_to_top_tier
This is the part I care about most. Your idea of “cheap enough for this” is not mine. Maybe you never want a refactor touching auth code to leave the top tier. Maybe you trust the mid model with far more than I do. When a new model ships, you edit one line. No retraining, no waiting on me to push an update. The router adapts to your workflow instead of imposing one.
On-device, on purpose
Running the classifier locally isn’t a performance footnote, it’s the design.
- Zero added tokens. A router that costs tokens to decide where to spend tokens is self-defeating. The classification is free.
- No added latency you’ll feel. 50ms in front of a multi-second generation disappears.
- Your prompts stay yours. The thing reading your task to route it never leaves your machine. Nothing about the decision phones home.
It works with what you already use
spawn runs a local gateway and points your harness at it, with Claude Code routed through ANTHROPIC_BASE_URL and Codex through its model provider base_url. Same subscription, same tool loop, same agent UX. The only thing that changes is which model answers each turn. You shouldn’t have to adopt a new tool to stop overpaying; you should keep the one you like and slot routing underneath it.
Where it’s going
More harnesses behind the same gateway. A local, opt-in feedback loop so the classifier learns the shape of your work. And honest visibility into every routing decision, because a router you can’t inspect is just a different black box. The goal was never to be clever about models. It was to stop sending typos to the smartest one.