Yesterday we asked ourselves one short question: can we switch between claude and qlaude without leaving the session? qlaude is the second brain we set up on the same machine; the first part of this post explains what it is and why it exists.
It sounds like a small question. Following it into the actual tooling landed on a line that anyone building on AI agents runs into eventually: the line between what you can fix by writing more code, and what you have to accept about the tool before designing the way you work around it.
This post starts by explaining what the second brain is and why it exists, then covers three things. First, why switching models mid-session cannot be done. Second, the two moves we use instead of it. Third, the layer where automatic bouncing does not work at all, and what the orchestrator has to check by hand there.
Part 1What qlaude is, and why we built it
qlaude is not a new program. It is the same coding agent we open every day, invoked with a different set of values so it talks to a different model at a different endpoint. The name comes from the q in Qwen, the model behind it. Using it feels identical; only the brain inside is different.
The reason it exists is purely cost. Not every job we hand an AI is equally hard. Reading long files and summarizing, classifying a large pile, converting data from one shape to another: these need stamina and consistency, not the sharpest judgment on the market.
Paying top-tier prices for work that does not need them is an expense that hides well, because it never arrives as one alarming bill. It leaks out one small unremarkable job at a time.
So we set aside a separate quota on a cheaper model and built a second doorway on the same machine. The grind goes through that door. The main brain is kept for work where being wrong is expensive: structural decisions, bugs tangled across several files, anything that will reach someone else.
Once two brains live on the same machine, the next question asks itself: mid-task, how do you move from one to the other without abandoning the work already in progress?
Part 2Can you switch models mid-session?
No, and the reason is the order things get read, not a feature nobody has shipped yet. The process reads its endpoint and its credential when it starts, then holds that set for the whole run. Changing the endpoint means a new process that starts with a different set.
On our machine the backup brain is not a separate program. It is the same program invoked with three different values in front of it.
| Variable | What it decides |
|---|---|
ANTHROPIC_BASE_URL | Where requests go |
ANTHROPIC_AUTH_TOKEN | Which key gets you in |
ANTHROPIC_MODEL | Which model to ask for |
Put those three in front of the normal command and you get the same program with a different brain. This is the documented path for pointing the agent at a team gateway or another provider.
So why not write a hook that switches by task type?
Because a hook runs inside a process that has already booted. It cannot tell a running process to change its own endpoint. What a hook can do is intercept a command and hand the work to a different process. That is not switching brains, it is delegating, and delegating is a different thing from becoming something else.
The cleverest-sounding move is usually the one that has not yet asked whether the machinery underneath allows it.
On the first pass we proposed a wrapper (a script wrapped around the normal command) that would find the previous session automatically, even though the standard command already has a flag that does exactly that. It took a second pass to notice. It felt like cutting a spare key for a door that was never locked.
We also ruled out the other escape hatch: exit and resume. The reasoning was direct. The work in progress inside the running agent's memory has value, and exiting to come back means paying the startup cost every time. With that path closed, the problem got clearer: how do you have two brains available without killing either one?
Part 3Move one: two brains side by side
If you cannot switch, do not switch. Keep both running in separate panes and move your attention instead of moving the process.
We wrote one short command that does two things. If a pane in this window is already running the backup brain, jump to it. If not, split the window and open one in the same directory. Press it once and you get a new pane; press it again and you land back in the same pane, not a third one.
The unplanned benefit: the two conversations do not contaminate each other. One side is holding an architecture discussion while the other grinds through config files, and each keeps its own memory of what it is doing.
The bug our own test caught first
In the first version, the pane-finding logic read the wrong column. It never found an existing pane, so it opened a new one every time. Three presses, three panes. We caught it because the test ran both directions: press with no pane open, expect a new one; press with a pane already open, expect no additional pane.
The second direction is what caught it. Test only the direction you expect to pass and everything is green on the first run, and the bug surfaces the first time a person actually uses it. A test that shows the thing runs has not yet shown the thing is right.
Part 4Move two: let the caller bounce
The first move handles the person at the keyboard. The second handles work dispatched headlessly, which is most of what we hand to the cheap model: reading long files and summarizing, classifying large piles, reshaping data.
Our dispatcher is tiny. The whole logic is three lines.
- Send the job to the cheap model first, headless.
- If it exits with a success code and actually returns output, pass that output along.
- If either of those fails, print a line saying it is bouncing, and send the same job to the main model.
Two details there matter more than they look.
First, the condition checks for returned output, not just the exit code. A process that exits cleanly and returns nothing is a process that failed without saying so. Trust the code alone and you forward emptiness to whoever asked, and nobody finds out.
Second, it does not remember. Every call tries the cheap model again first. We went back and forth on this: if we already know the quota is gone, why keep trying? Because remembered state goes stale and nothing comes along to correct it. The quota resets overnight, we do not know, and we spend a day on the expensive option for no reason. Retrying costs a few seconds and buys a fact that is current.
The decoy we did not have to build
Normally, testing a fallback means deliberately breaking the primary to see whether the backup fires, because a fallback that has never been invoked and a fallback that is broken look identical. Both are silent.
We did not have to fake it. On the day we finished writing it, the prepaid quota ran out on its own. The next dispatched job was genuinely refused, the dispatcher printed its bounce line, and the work carried on to completion on the main model.
A fallback that has never been invoked does not count as existing yet. It is code you are hoping about.
We logged that one as proven, which is a different word from the one we used for several other things built the same day: written, but nobody has pressed it. Two weeks later those two states are indistinguishable unless you wrote them down differently at the time.
Part 5Can subagents bounce on their own?
No, and this is where the layer differs most from the two moves above. A subagent the main agent spawns is not a fresh process reading its own configuration. It comes up inside the parent's house, which means it cannot route itself somewhere else.
Worse, when it cannot get through, it does not make a sound. We hit this while running six subagents to read a book in parallel. The ones pinned to a model tier the gateway does not carry died in the first second with a "model does not exist" error. The ones pinned to a model that gateway genuinely serves worked all night.
From the orchestrator's seat, the silence of a subagent that is thinking and the silence of a subagent that is dead look the same. So the orchestrator needs a third signal.
We use the simplest one available: each subagent's transcript file has to grow within two or three minutes. Any file that sits still means relaunch that one immediately on a different reader tier already covered by the flat-rate plan.
That same day, we nearly measured the wrong object
Checking file sizes the first time, all six came back at exactly 115 bytes. The obvious read was "the whole batch is dead," because the shape matched a failure we had seen before.
The sentence reporting it was already typed. What saved it was opening one of those 115-byte files. It was a symlink pointing at the real transcript. The real files were two to three hundred kilobytes each, and every one of them was still growing.
Identical numbers across every sample is a signal that you are measuring the container, not the contents.
Part 6The principle, and five things you can take
What survived the day is not thirty lines of shell. It is accepting something that sounds at first like giving up: model selection is a rule the orchestrator holds, not a capability the infrastructure provides.
We already knew this without noticing. Another lane, where we hand work to a peer engineer from a different vendor, has no automation in it whatsoever. It has a sentence written in a manual saying which kind of work goes to whom, and we follow it. That lane has never failed, not because it is robust, but because the rule is clear and someone holds it.
Five things that transfer to other systems.
- Know what is read at startup versus what is read per call. Anything read at startup cannot change mid-run, no matter how good the code is.
- Put the fallback in the caller, not the callee. The one who knows the job failed is the one who dispatched it, not the one who fell over.
- Do not let it remember the failure. Try the cheap option every time. Remembered state goes stale quietly and keeps you on the expensive path.
- A success code alone is not success. Require returned output too. Something that exits cleanly and returns nothing failed without telling you.
- Where nothing can bounce on its own, take a pulse. Pick a signal that is hard to fake, such as a file that actually grows within a couple of minutes, and make sure you are measuring the real thing rather than a pointer to it.
Where to start
To try this today without touching anything real, take one job you can afford to get wrong, such as summarizing a log file, and write a short dispatcher that tries the cheap model first and bounces to the main one on failure. Then do the part that matters most: feed it a wrong key once and watch it bounce. Until you have seen it fire, you do not know that it can.
Which work belongs on which model, and the rules we use to split a budget across flat-rate, local, and pay-per-use options, are written up separately in 14 LLMs, one budget: how to route work to the right one. This post is the part that comes after: once the work is routed, what happens when the model it should go to is not available?
Sources and references
- Anthropic, Connect to an LLM gateway for setting
ANTHROPIC_BASE_URLalongsideANTHROPIC_AUTH_TOKEN, both as shell variables and in a settings file. - Anthropic, Third-party integrations for the variables that point the agent at a team gateway or another provider.
- Anthropic, Claude Code settings for
ANTHROPIC_MODEL, retrieved 7 Aug 2026. - The exhausted quota, the bounce that fired for real, the duplicate-pane bug our own test caught, the subagents that died silently because the gateway did not carry their model tier, and the symlink we nearly mistook for a dead transcript were all measured directly from our own work on 7 Aug 2026, not borrowed figures.