← Learning

The crew · the differentiator

The multi-agent crew

Four specialized agents, one deterministic coordinator. The interesting decision wasn't making them autonomous — it was deciding not to.

How it works

Four roles, a fixed pipeline

The product has four agents, each a specialized system prompt with a job: the Strategist proposes angles, the Writer drafts variants per channel, the Editor scores brand voice and gives feedback, and the Analyst reads the data. A coordinator decides who handles a given message.

That coordinator is deterministic — keyword and pattern matching, not a model deciding. A content request runs a fixed pipeline: the Strategist proposes angles, those angles are fed into the Writer’s prompt, the Writer’s drafts are fed into the Editor’s prompt, and the result is persisted and streamed back token-by-token. Each agent’s output is literally the next one’s input — a relay, not a free-for-all.

Every agent call injects organizational memory into the system prompt — brand voice, company facts, executive profiles, and what the system has learned from your past edits. That’s the part a generic chatbot can’t do: the crew answers from your organization, not from the open internet.

The crew pipelineA user message enters a deterministic keyword router, which runs the fixed Strategist, Writer, Editor pipeline; organizational memory is injected into every agent's system prompt, and the result is persisted and streamed to the UI.User messageOrchestratorkeyword routerStrategistanglesWritervariantsEditorbrand-voice scorePersist + streamDB · SSE → UIORG MEMORY — INJECTED EACH CALLbrand voice · facts · execs · what it learned from your edits

A deterministic keyword router picks the path; content requests run the fixed Strategist → Writer → Editor pipeline, each agent’s output feeding the next. Org memory is injected into every agent’s system prompt. No agent decides its own steps — that’s the point.

The cost control lives in the prompt layout. The system prompt is built as a list of blocks. The stable stuff — the agent’s role and the org context — goes first, with a cache breakpoint after it. The volatile stuff — the few past examples retrieved for this specific query — is appended last, after the breakpoint, uncached. So in a five- or ten-message chat, every follow-up reuses the cached prefix and pays roughly a tenth of the input-token cost. Get that ordering backwards and every turn busts the cache.

Decisions & trade-offs

What each choice cost

Deterministic router, not an LLM

predictable · cheap · debuggable

A model could route too, and flex to oddly-phrased requests. But then routing is a non-deterministic call I pay for and can’t easily trace. Keyword matching is boring, free, and when it misroutes I can see exactly why. For a fixed set of intents, boring wins.

A fixed pipeline, not a planner

legible · bounded cost

The content flow is hard-coded Strategist → Writer → Editor — no agent picks its own next step. That caps the token spend per request and makes every run reproducible. Autonomy is a deliberate later phase, not a missing feature; I wanted the deterministic version solid first.

Per-call state, not instance mutation

concurrency-safe

Agents are shared across requests. Exec-ghostwriting context rides in as a per-call argument, never set on the agent object — otherwise two users’ requests would bleed into each other’s voice. The bug is invisible until load, then ugly.

Prose to humans, schemas to systems

right rigor per consumer

The chat streams readable prose; where output feeds another system (campaign planning) it is a tool-enforced schema. Where I blurred that line — regex-parsing the chat’s prose to persist it — I got a fragile seam. (More on that in the backend.)

The learning

Four “agents” that are really specialized prompts, handed off through a deterministic coordinator. I chose that for debuggability and cost — autonomy is a later phase, not a gap.

What I'd tell you

Three things I'd say out loud

Most of my “agents” are workflows — and that’s the honest, better answer. Anthropic’s own writing on building effective agents draws a line: a workflow follows predefined paths; an agent directs its own process. My crew is mostly a workflow — a fixed relay of specialized prompts. Calling it a “crew” is product framing; architecturally it’s an orchestrated workflow, and for this job that’s the right tool. Naming it accurately is more credible than dressing it up as something it isn’t.

The caching win was about ordering, not caching. Anyone can turn prompt caching on. The lesson was structural: put what’s identical every turn (the org context) before the cache breakpoint, and what changes per query (the retrieved examples) after it. Same tokens, different order — one layout runs a chat at ~10% input cost, the other pays full freight every message.

Decide autonomy on purpose. It would have been easy to wire up a planner that picks its own steps and call it sophisticated. I didn’t, because I couldn’t yet say what it would cost or how I’d debug it. Knowing when not to add autonomy is the same muscle as knowing when to — and on a budget, the legible version earns its keep first.

The crew is four specialized prompts and a dumb, reliable router. That isn’t the limitation of the design — on this budget, it is the design. The autonomous version is the next thing I build, once I can name what it buys and what it costs. Until then, boring and legible is the senior choice.

A personal experiment — cost-capped and opinionated. The views here are my own, not my employer’s, and this is a learning writeup, not an enterprise blueprint.