I benchmarked Fable 5 against Opus 4.6, then blew my monthly quota anyway. Here's the routing playbook that came out of it.
Boys and girls. This is not that complicated. But nobody's writing it down, so here it is.
Two things happened this week. First I ran a real benchmark... Fable 5 at every effort level against Opus 4.6 on max effort, same coding task, blind audits. Second, I let a 116-agent fleet loose on a refactor job and burned 1.6 million tokens in under 4 minutes. Hit my monthly spend cap mid-flight. 75% of my Fable quota gone with 5 days left before reset.
Both taught the same lesson. The model is not the strategy. The ROUTING is the strategy.
One task: "chronosort," a TypeScript dependency-aware task scheduler. DAG cycle detection, topological sort, critical path calculation, parallel wave grouping. 6 source files, 15+ tests, 9 edge cases. Same 3,458-char prompt for every run, each in its own isolated directory, launched headless with claude -p --output-format json. Wall clock, cost, turns, and token counts captured straight off the JSON. Then every run got audited on a 7-dimension rubric (architecture, algorithm correctness, edge cases, error messages, test quality, output format, TypeScript quality) by a separate context. Never let a model grade its own homework. It gets sycophantic the second it does.
| Run | Actual model | Effort | Wall | Cost | Tests | Quality /10 | Logic bugs |
|---|---|---|---|---|---|---|---|
| Fable low | claude-fable-5 | low | 186s | $2.48 | 20 | 8.4 | 0 |
| Fable medium | claude-fable-5 | medium | 210s | $2.60 | 22 | 8.6 | 1 |
| Fable high | claude-fable-5 | high | 248s | $2.94 | 28 | 9.0 | 0 |
| Fable xhigh | claude-fable-5 | xhigh | 320s | $3.24 | 33 | 9.1 | 0* |
| Opus 4.6 | claude-opus-4-6 | max | 138s | $0.80 | 22 | 7.7 | 1 |
| Opus 4.8 | claude-opus-4-8 | max | 770s | $3.61 | 36 | 9.1 | 0 |
| Fable max | fable-5 + opus-4.8[1m] | max | 822s | $5.86 | 42 | 9.4 | 0 |
*Fable xhigh's one flaw was a missing barrel file in package.json, config not logic.
Read that table again. Opus 4.6 on MAX effort was the fastest and cheapest run on the board. 138 seconds. 80 cents. It was also the lowest quality with a real logic bug: its input guard was typeof task.duration !== 'number' || task.duration <= 0... which waves NaN right through, because typeof NaN === 'number' is true and NaN <= 0 is false. NaN propagates into Math.max() and corrupts every wave duration downstream. Every single Fable run validated with Number.isFinite(). Opus 4.6 didn't. It also ran topological sort twice and discarded the first result.
Three findings that actually matter:
-
The effort ladder has a cliff, and it's medium to high. Fable medium: 8.6 with a bug. Fable high: 9.0, zero bugs. Below high you're getting code that needs human review for correctness. High and above is production-ready. That threshold is worth more than any single benchmark score.
-
Fable high is the value play. 9.0/10, zero bugs, $2.94, 4 minutes. That replaced Opus 4.6 max as my daily coding default the same night.
-
Fable max is a trap. $5.86, slowest run at 822 seconds, and the transcript shows it spun up claude-opus-4-8[1m] as a SECOND model under the hood. Dual-model, which is why it costs double. If you're paying for Opus anyway, just use Opus. And don't burn xhigh or max on Fable without a specific reason... xhigh matched Opus 4.8's quality at 42% of the wall time, but high is the sweet spot.
The first "Opus" run in that benchmark wasn't 4.6. I asked for Opus 4.6 max. The run went out as --model opus, and that alias resolves to the LATEST Opus. Which is 4.8. Caught it in the results JSON, re-ran with --model claude-opus-4-6 explicit, kept both rows in the table.
Two days later it got me AGAIN. Two subagents spawned with model "opus" through the agent framework. Both came up 4.8 in the transcripts. I don't run 4.8. It's all over the place, unstable, and I banned it from my entire stack. Didn't matter. The alias walked it right back in through a different door, and this time there was no settings pin behind it to catch the fall.
If you ban a model, the ban is only as good as the aliases you didn't check. Grep everything. Pin exact model IDs everywhere a model gets named: claude-opus-4-6, never opus. Single-version aliases like haiku and fable are safe today and a liability the day a new version ships. The fix that actually holds is an agent definition with the exact ID pinned in frontmatter (opus-worker.md, included below), because then there is exactly one place the model gets resolved and it can't drift.
The refactor job: 58 skill files. My orchestrator spawned one refactor agent per file plus one adversarial reviewer per file. 116 agents, high effort, ~16 concurrent. 1.6 million tokens in under 4 minutes. Monthly spend cap. Dead stop, mid-fleet.
Nothing was wrong with any individual agent. The architecture was wrong. One agent per small file means every agent pays the full context setup cost to do 3 minutes of work. Batching 5-8 files per agent does the same job with 85% fewer agents.
So now it's law in my config, not a lesson I hope I remember:
- Batch 5-8 items per agent. Never one agent per small file.
- Effort ceilings per seat. Workers cap at high. Reasoning seats default to medium. Max is for irreversible decisions only.
- Any fan-out over 10 agents requires a token estimate against remaining quota BEFORE launch.
- The expensive model gets at most ~10% of any fleet.
Here's the part you can steal. Quota is a real constraint. Pretending it isn't means your best model is unavailable exactly when you need it. So the system has two launch modes and the SEATS never change, only who drives.
MODE 2, Fable primary. When the weekly quota is fresh. The strongest reasoner holds the orchestrator seat because orchestration mistakes are the most expensive mistakes in an agent system... one bad dispatch decision multiplies into six figures of wasted subagent tokens. My 116-agent incident was an orchestration mistake, not a worker mistake.
MODE 1, Opus 4.6 primary. When Fable quota runs hot (~50%+) or limits loom. Opus 4.6 on high drives, and Fable gets called out surgically for the moments that need actual thought. You keep most of the benefit at a fraction of the burn.
The seats, in both modes:
| Seat | Model + effort | What it does |
|---|---|---|
| REASONER | Fable 5, medium | architecture, spec review, assessment, adjudication. Genuine thought only |
| WORKER | Opus 4.6, high | coding, refactors, file ops, reads, writes, docs |
| EXTRACTOR | Haiku 4.5 | grep sweeps, status checks, verification reads. Misfires are cheap and obvious |
| ESCALATOR | Fable 5, high | audit-and-fix when a worker's output fails validation |
| AUDITORS | GLM 5.2 + GPT 5.5 | independent blind code audits, cross-family on purpose |
Why Fable at MEDIUM in the reasoner seat when the benchmark crowned Fable high? Because the benchmark was a coding task and coding goes to workers now. For pure reasoning, a stronger base model at medium effort beats a weaker one at max, and it spends fewer thinking tokens doing it. The table above shows Opus 4.6 burning max effort to land at 7.7. Effort doesn't fix judgment.
The auditors are GLM 5.2 (OpenCode subscription, $87/mo) and GPT 5.5 (Codex, $100/mo). Both flat-rate. Marginal cost per audit: zero. That changes how you think about code review entirely. You stop rationing reviews and start throwing them at everything.
Here's why the headless cross-family setup matters so much for anything you actually care about shipping.
GLM and GPT run as headless CLI processes. opencode run --variant max for GLM, codex exec --ephemeral for GPT. They spin up in their own isolated contexts, audit the code blind (no knowledge of each other's findings, no knowledge of who wrote the code or why), and dump structured output. Your primary Claude session never sees their raw context. No window pollution, no token bleed, no "here's what the other reviewer said" confirmation bias.
Cross-family is the real unlock. Claude reviewing Claude code is like asking your coworker to proofread the email they helped you write. They share training lineage, they share blind spots, they'll miss the same class of bugs and nod at the same plausible-but-wrong patterns. GLM was trained by a completely different team on different data with different optimization targets. GPT, same story, third family. When GLM and GPT independently flag the same line of code, that's three separate training lineages agreeing something is wrong. Those dual-flagged findings are almost always real. Single-model findings? They hallucinate more than you'd think.
The pipeline for every non-trivial code change:
- GLM 5.2 and GPT 5.5 run independent blind audits, parallel, headless.
- Two Opus instances do a 5-7 turn back-and-forth: what did the auditors find, what's real, what's noise, what should we keep from each.
- The Fable reasoner seat issues the final accept/reject/merge.
That's four models across three families touching every serious diff before it lands. $187/mo in flat-rate subscriptions doing the volume work, Claude reserved for the judgment call at the end. The subscriptions are already paid whether you use them or not. Not using them is leaving money on the table.
I ran this exact pipeline on the skill refactor that blew my quota. The GLM pass caught two staleness violations (wrong API endpoint, dead skill references) that both Opus instances missed. The GPT pass caught a template that would have leaked a localhost proxy address into shipped output. Neither would have survived a same-family review because the original code was written by Claude and Claude doesn't flag its own assumptions.
Subagents can spawn subagents. Verified it in my own harness this week: an Opus primary spawned a Fable reasoning agent, and that Fable agent spawned its own Haiku worker and relayed the result back up.
That changes the economics completely. The pattern is: cheap primary drives the session, Fable lead gets dispatched with a mission and a batch of context, and the Fable lead runs its OWN fleet of Opus and Haiku workers. Fable tokens go to fleet sizing, defect adjudication, and final verdicts. Volume work happens two levels down on models you can afford to burn. The expensive brain directs. It doesn't type.
Everything referenced is in this gist, verbatim from my running config:
02-benchmark-results.md: full data, dimension scores, throughput, bug forensics03-MODEL-ROUTING.md: the routing law my agents actually load04-fable-lead.md: REASONER seat agent definition (spawns its own workers)05-fable-audit.md: ESCALATOR seat06-opus-worker.md: WORKER seat, exact model ID pinned, the alias-trap fix
Steal all of it. The model names will age out. The structure won't.
One benchmark, one task, n=1, my rubric. Run your own before you bet your stack on mine. But run SOMETHING, because "the big model on max effort" is not a strategy, and the table above is what it costs to assume it is.
Thank me later.