zepto-claw · Episode 7 · Season finale

I gave my AI agent a swappable brain

A new brain is a new personality — Opus, Sonnet, or Haiku, swapped mid-chat.

Building your own claw — a series where we build a tiny AI agent one small piece at a time.

▶ Watch the build on YouTube

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

  1. Add the BRAINS map and a currentBrain variable to claude.ts, the set_brain tool next to your other tools, and pass model: BRAINS[currentBrain] in the query() options.
  2. Run it: npm run whatsapp, then ask give me a one-line pep talk and read the answer in Opus's voice.
  3. Say switch to haiku, ask the same thing, and hear the new voice — same agent, same diary, a different mind.

Watch the finale: the zepto-claw E07 Short, and subscribe on YouTube for Season 2. The whole series: E01 · E02 · E03 · E04 · E05 · E06.