How to build an agent factory

January 12, 2026

Christmas week. Terminal open. A blank Rust crate that won't compile yet, and a model in another pane waiting for the next instruction. I'd already written about how simple an agent is — a loop, some tools, a request in and a response out. Tonight I'm building the thing around it.

People call that thing an agent harness. Claude Code is the one everyone knows. I built my own over the holidays, with different bets in a few places. To me it's an agent factory: work goes in one side, the output you asked for comes out the other.

If you haven't read "The Agentic Loop" yet, that's the foundation. This is the car you put around the engine.

The car and the engine

In Formula One, ten teams build ten cars. Engines come from suppliers. Mercedes builds engines for itself, and also for McLaren, Aston Martin, and Williams. Same power unit. Different chassis, aero, pit strategy. In 2025 McLaren took the constructors championship without making their own engine — great engine, great drivers, and a car that got more out of that unit than the other Mercedes customers did.

Your agent factory is that car. The model underneath is the engine.

You can run Claude Opus, or whatever's strongest this month, and still lose time in the corners if the harness is wrong. How you carve work into agents, how you route context between them, how you handle state and handoffs — that's the chassis. That's the race you're actually running.

Don't compact. Spawn.

Every system that works has a constraint it takes seriously. In F1 it's the budget cap. In my factory it's simpler: I refuse to use context compaction.

Most harnesses, when the conversation gets long, squash the history so it fits a token budget. It works. Something still gets lost. I've watched performance fall off a cliff the moment compaction kicks in — the agent forgets the sharp edges of the problem and starts solving a softer version of it.

So: don't compact anything. When a thread is done, or too fat, spawn a new agent and pass context as files — detailed reports, links, a short description of what's inside. The next agent reads a file only if it needs it.

You stop treating the context window like a suitcase you can sit on, and start treating it like working memory: small, precious, and easy to overwhelm. I picked fresh agents and shared files, and let that shape everything else.

Beads and mailboxes

Somewhere in that stretch I read about beads. I never used beads, or Gastown, but I recognised the shape immediately.

Beads are work items that live next to the code — a Jira card that actually sits in the repo. When you finish one, it stays with the change that solved it. The commit carries both the what and the why.

Mailboxes were already in my code. That's how one agent hands another a message: context, a request, a place to post the result. Asynchronous coordination without cramming the whole conversation into one brain.

Beads keep the why from evaporating. Mailboxes keep the handoff clean. Same bet underneath: keep context close to the work, and scale by storing relationships, not by stuffing everything into one place.

Rust, and no hand-written lines

I built the whole factory in Rust. I'd never written Rust before. The goal was complete configurability — webpack's plugin model stuck in my head — so every behaviour could be swapped, audited, plugged into.

And I still haven't written a single line by hand.

Why Rust, then. Two reasons, both selfish. If it compiles, it probably runs. The type system is a reviewer that never gets tired. And the compiler errors are descriptive enough that a model can read them, understand the miss, and fix the code before anything hits runtime. That feedback loop is the point. I describe what I want. Claude hits the compiler. We iterate. The harness grows.

I won't pretend this is the easy design. You give up the comfort of compaction. You invent mailboxes and file reports so agents don't trip over each other. You accept that your own typing isn't the bottleneck anymore — judgement is.

An agent factory isn't about owning the biggest engine. It's about building a car that gets more out of the engine you already have.

Christmas week, blank crate, a rule about not compacting — that was the start. The victory, if there is one, isn't that the model writes the code. It's that the architecture holds when you stop sitting on the suitcase.

July update

Leaving the Christmas framing where it is. This is later.

Lately I've had a good run with Codex compaction. Looks like they compact somewhere around 200–300 thousand tokens, and a lot of what mattered doesn't seem to get lost. I'm curious how they approach it.

My guess — and I'm not sure — is that the conversation stays as one giant thread, a write-ahead log on disk. Something like embeddings, or a vector database, points at sections of that WAL. Clear the window, hand over a summary of what's going on, and if something lived in history, give a lookup into the write-ahead log.

That's the design I'd try if I had to compact: a handover summary, plus deterministic memory inserted alongside the user messages — kinda automatic, so you're not burning tool calls on memory searches. I still don't love compaction as a default. But if the sharp edges stay reachable without a scavenger hunt, maybe less falls off the cliff. Take it as a take, not a claim.

Have thoughts on this? Discuss it online: