I gave my AI agent a swappable brain
A new brain is a new personality — Opus, Sonnet, or Haiku, swapped mid-chat.
For two episodes I kept promising a personality. Here's the truth I'd been circling: a personality isn't really a set of catchphrases or a tone you paste on top. A personality is a mind. And the deepest way to change how something thinks and talks isn't a prompt tweak — it's a whole new brain. So for the finale, I gave the claw exactly that.
Watch what that buys you. I ask the claw, "give me a one-line pep talk." On Opus it answers warm and full, the kind of line you'd want on a hard morning. Then I say "switch to Haiku" and ask the same thing — and the answer comes back snappy and clipped, a different character entirely. Same agent, same memory, new voice. That's a personality swap you can hear.
The problem
Everything in this series so far ran on one model. The loop, the memory, the WhatsApp mouth, the tools, the heartbeat, the diary — all of it sat on top of a single fixed brain that I picked once and never touched. That's fine until you realize what a personality actually is. The voice you hear from an agent — how warm it is, how terse, how it reaches for a joke or doesn't — comes mostly from the model underneath. Change the model and you change the character.
So the real personality knob was never a clever system prompt. It was the brain itself. And a brain shouldn't be a thing you hard-code once at the top of a file — it should be swappable, live, mid-conversation, the same way you'd ask a friend a question and then ask a different friend the same thing.
The code
It's smaller than you'd guess, because of one fact we've leaned on since E01: the agent loop never cared which model it called. So the brain is just a setting. First, a map of friendly names to model ids, and a variable holding the current pick.
// claude.ts — the swappable brain: friendly name -> model id.
const BRAINS: Record<string, string> = {
opus: "claude-opus-4-8", // smartest
sonnet: "claude-sonnet-4-6", // balanced
haiku: "claude-haiku-4-5", // fastest
};
let currentBrain = "opus";
Then a tool — just like the tools from E04 — that flips which brain is loaded. The model calls it when you ask to switch.
// claude.ts — one tool to swap the mind, live.
tool("set_brain",
"Switch which AI model powers you: opus (smartest), sonnet (balanced), haiku (fastest).",
{ brain: z.enum(["opus", "sonnet", "haiku"]) },
async ({ brain }) => {
currentBrain = brain;
return text(`brain swapped to ${brain} (${BRAINS[brain]}) — active from your next message`);
});
And the whole payoff is one line in ask(): every answer runs on whatever
brain is currently loaded, by passing it as the model option to the Claude
Agent SDK's query().
// claude.ts — every answer runs on whatever brain is loaded.
query({
prompt: fullPrompt,
options: {
model: BRAINS[currentBrain], // <- the swap lives here
systemPrompt,
mcpServers: { claw }, // tools + diary, same as before
},
});
How it works
The agent loop is model-agnostic — it sends a prompt, reads a reply, runs any tool calls, loops. It has no opinion about which model produced the reply. That's the whole reason this episode is so short: because the loop never depended on the brain, the brain becomes a setting you can change without touching anything else.
So set_brain flips currentBrain, and the next time
ask() runs, it passes that brain as options.model to
query(). Nothing else moves. The Claude brains all share the same plumbing:
every one of them keeps the claw's tools (E04) and reads the same
diary (E06) at the top of the prompt. You swap the mind, not the memories
— so a new brain knows everything the old one knew, it just says it in a different voice.
Same question, two brains
This is the demo, and it's the cleanest way to feel what "a new brain is a new personality" means. One prompt: "give me a one-line pep talk."
On Opus — the smartest brain — the answer is warm and complete, a
sentence with some shape to it, the kind of thing that lands. Then I say "switch to Haiku,"
the model calls set_brain, and I ask the exact same thing. Haiku
— the fastest brain — fires back something short and punchy, almost terse. Neither is wrong.
They're just different minds, and you can hear it instantly. Same agent, same
diary, same tools — a different character, chosen by one tool call.
Bonus: a non-Claude brain
One aside, because it's a fun extension: the same code can also run a brain that isn't
Claude at all. There's a separate branch that shells out to OpenAI's GPT-5
through the Codex CLI as its own subprocess —
a wholly different company's mind, in its own voice. Note that this is a separate path,
not the Claude Agent SDK: the SDK's model option swaps between Claude brains
only; GPT-5 rides in through the CLI alongside it. A different mind entirely, if you want
to hear one.
Try it yourself
- Add the
BRAINSmap and acurrentBrainvariable toclaude.ts, theset_braintool next to your other tools, and passmodel: BRAINS[currentBrain]in thequery()options. - Run it:
npm run whatsapp, then askgive me a one-line pep talkand read the answer in Opus's voice. - Say
switch to haiku, ask the same thing, and hear the new voice — same agent, same diary, a different mind.
That's Season 1
Seven small pieces, one tiny agent. We started with a loop that talks (E01), gave it a memory (E02), a mouth on WhatsApp (E03), hands — real tools (E04), a heartbeat that messages you first (E05), a diary of durable facts (E06), and now a swappable brain (E07). That's your claw — built from scratch, one piece at a time. Season 2 soon. Thanks for building it with me.
Watch the finale: the zepto-claw E07 Short, and subscribe on YouTube for Season 2. The whole series: E01 · E02 · E03 · E04 · E05 · E06.