TL;DR. I was an Opus fan. Most of what I’ve shipped with agents ran on it. Then Opus 5 worked a solvable problem for hours, declared it impossible, and handed me a polished brief whose one open question was the exact experiment that would have solved it. I gave that brief to Grok 4.5; it shipped the fix the same afternoon. Claude Code is still my shell. What changed is that I stopped pointing every hard job at one model and started routing: matching the engine to the task. GLM 5.2 takes the cheap bulk, Grok 4.5 takes the wire-level debugging, Opus keeps the jobs it’s still best at. The metric I now optimise isn’t cost per token. It’s tokens per shippable result.
I’ve written four of these posts about building things with agents, almost all inside Claude Code on Opus. That streak is what made this one sting. The harness held up. The model I trusted for hard work did not, and the newer, more powerful one answered every prompt with more tokens than the job was worth.
The task
One Claude Code session, more than one provider behind it: Max subscription for Claude, z.ai for GLM, xAI for Grok, switched from the /model picker without restarting, with no API rates for Opus when a Max subscription already covers it.
The obstacle is real and documented. Reaching a non-Anthropic model means pointing ANTHROPIC_BASE_URL at a translator, which drops the client into gateway mode where, per Anthropic’s own docs, the subscription is no longer used. But that’s a description of client behaviour, and client behaviour has a seam: in gateway mode, the client quietly stops sending the subscription credential at all and sends a plain API key instead. Once you know that, the design writes itself. The proxy stops waiting for a token to forward and goes and gets the subscription token itself. Finding that one fact requires looking at a request log, not another pass over the docs.
Where Opus 5 stalled and Grok 4.5 shipped
This wasn’t a writing task or a long refactor. It was adversarial debugging: fake greens, misread errors, a client that changes auth shape under a flag, and a fix that only appears if you distrust the tidy story and poke the wire.
Opus 5 is strong at coherent analysis, and here that strength became the failure mode. It found the right docs, quoted the right constraint, tested two candidate tools and correctly rejected both. It even discovered, by accident, that a claude- model prefix made the picker start working, one of the two load-bearing tricks in the final solution, then credited the success to the wrong cause and moved on. It found a skill file describing the exact working architecture and dismissed it because the repo shipped the docs without a compiled binary. The fix is about three hundred lines of Python, and the missing binary was never the point.
Then it ended the session with a handoff document. Its first open question:
Does Claude Code send the subscription credential at all when
ANTHROPIC_BASE_URLpoints at a gateway? Capture the raw inbound headers at the proxy. We never did this, and it determines whether forwarding is even possible.
It had a proxy running and the access log open. It was one command from the answer, it knew the command, it wrote the command down, and it filed the command as a question for someone else. The same session had already produced its own fake green: an obviously invalid credential returning 200 OK, logged as proof the auth passthrough worked. Nothing that can’t authenticate gets a 200, and this one hadn’t; a leaked environment variable had quietly routed the request to z.ai. Asked point-blank which model it was, that session answered: claude-opus-5. I’d told it to test end to end and not hold back, and it did neither. What came back was shaped like a result: hours of work, a structured document, confident conclusions, and the one test that would have settled the whole question sitting unrun at the top of the open-questions list.
An experiment you write down instead of running isn’t a finding. It’s a stall.
So I handed the document to Grok 4.5, and it ran the experiment. Same machine, same facts. It saw the plain API key where every “forward the token” design had assumed a subscription credential, inverted the whole auth flow, and cleared the two traps waiting behind it: a valid token on its own still reads as a rate-limit error until you send the full set of CLI headers, and gateway model names must start with claude or the picker silently drops them. Working proxy, same afternoon. Opus chose the document; Grok chose the experiment. That difference is the whole ranking.
The result: same harness, more engines
cla: GLM and Grok sit under the Anthropic models, switchable mid-session without restarting.cla is a reverse proxy on 127.0.0.1 plus a launcher. Claude Code points at it with a sentinel key whose only job is to make the client honour the base URL. It is never forwarded anywhere.
Claude Code ──▶ cla (:8787)
│ route on model id
├─ claude-* ─▶ api.anthropic.com
│ + subscription token, full CLI headers
├─ glm-* ─▶ api.z.ai/api/anthropic
│ + z.ai key
└─ grok-* ─▶ api.x.ai/v1/chat/completions
+ xAI login, request-format shim
I kept Claude Code because the harness is still the best I’ve used: tool loop, file editing, skills, subagents, permissions, terminal UX. That’s separate from which model is thinking. What sits behind the picker is now a choice I actually exercise:
| Engine | Billing | Where it goes |
|---|---|---|
| Fable / Opus | Max subscription | long refactors, writing, jobs that still fit |
| GLM 5.2 | z.ai key, per token | bulk edits, mechanical work, (replaces Sonnet) |
| Grok 4.5 | xAI login from the CLI | wire-level debugging, second pass when Opus has talked itself out of the goal |
| Kimi K3 | whenever moonshot.ai gets enought capacity | next shoot to replace my Antropic subscription entirely |
One hard rule, learned expensively: never put ANTHROPIC_BASE_URL into settings.json, because a dead proxy would then break every session, including plain claude. The launcher sets it per process, so claude on its own stays a direct, untouched path to Anthropic. Unsupported, localhost-only, personal use; expect breakage on CLI upgrades. The safe path is always one command away.
Routing is the skill
The useful lesson isn’t “Opus is dumb.” It’s narrower and more annoying: no single model is the right default for every job, and the failure modes are easy to miss if you only score on prose. Opus 5 will reason carefully, cite real docs, reject real dead ends — and still stop one command short of the answer three times in one session, then hand you a well-structured artifact arguing that stopping was correct. Fable, with more raw power, fails the other way: it hoards tokens, over-explains, and argues its own framing so hard that a five-line answer arrives wrapped in five hundred. Both are disappointments for a given task, and both pushed me to look outside Anthropic for the jobs they handle badly.
That reframed the metric. The number that matters isn’t cost per token; it’s tokens per shippable result: how much generation it takes to reach something I’d actually commit. A cheaper Sonnet isn’t a bargain if I have to re-run it twice. A more powerful Fable isn’t a saving if it spends its power narrating. The engine that gets to shippable in the fewest tokens wins the job, and which engine that is depends entirely on the job.
Optimise tokens per shippable result, not cost per token. Let the task pick the engine.
So the picker isn’t only a cost lever, though GLM does make bulk work cheaper. It’s also a disagreement mechanism, built because the default engine failed open in the wrong direction. When a session hands me an impossibility proof now, I re-run it on a different model before I believe it: same harness, same repo, same context, different opinion. That takes about thirty seconds, and it paid for the entire build the first time I did it: Grok shipped the proxy Opus had finished explaining away.
I still use Opus, on purpose, for jobs that match what it’s good at. I don’t hand it a wire mystery and wait for another elegant surrender. Kimi K3 goes in for the same reason the others did, not because I expect one model to dominate the board, but because the thing I was short of was never a better single brain. It was the discipline to match the frontier model to the task, plus a second opinion that hadn’t already made up its mind.