A brainstorming companion
Build one like this.
The blog is a retrospective: what CommsCrew is, and what each decision cost. This page runs the other direction. Seven questions worth asking before you architect a multi-agent system of your own, each with the answer that looks obvious first, what actually decides it, and how this project answered it for real.
Before you read
These seven are a starting set, not an exhaustive checklist, and the “here” answer for each is one system’s answer, not a template. The exercise is asking the question in your own context and sitting with the tradeoff, the same way the builder’s playbook approaches any new decision: propose the real options, weigh what each one costs, then commit.
How many agents does this actually need?
The answer that looks obvious
One agent per task type, because that maps cleanly onto how the work is described.
What actually decides it
For each agent, ask whether it exists to route around a model being weak at something, or for a structural reason in the work itself. The first kind disappears as models improve. The second kind does not.
Here, it was
Ten agents at the start. Six of them were one writer per content format, a lookup table wearing an architecture's clothes. Four survived: a strategist, a writer, an editor, an analyst.
Read the full account in The gap →Do the survivors need separate memory, or just separate names?
The answer that looks obvious
Fewer agents means one shared prompt is simpler, cheaper, and easier to reason about.
What actually decides it
Try the merge and read the output for leakage: does reasoning that belongs to one stage show up distorting another stage's judgment? If yes, the contexts are doing real work even after the agent count drops.
Here, it was
One long prompt made strategy reasoning bleed into the copy itself, drafts that argued for the plan instead of executing it. The number of agents is a question about the model. The number of contexts is a question about the work.
Read the full account in The gap →Is this a pipeline, or four features standing next to each other?
The answer that looks obvious
As long as every stage's page exists and works, the product is connected.
What actually decides it
For every claimed connection, ask literally whether the last stage's output reaches the next stage's input as data a system reads, not as a page a human happens to click through on the way.
Here, it was
An audit a year in found the arrows had been built as endpoints and pages rather than as connections. The database schema supported the join between campaign, content, and results. Nothing read it.
Read the full account in The campaign pipeline →If you would never accept "no" from the model here, why is the rule only in the prompt?
The answer that looks obvious
A clear instruction in the system prompt is enough, e.g. "never exceed 2 revisions."
What actually decides it
Ask what happens if a capable, eager model just keeps asking anyway. If the honest answer is a real problem, the rule has to live in code that can refuse the move, not in language the model can politely decline.
Here, it was
max_revisions = 2 lived in the prompt. Measured against a model that kept asking, it did not hold. The cap moved into the dispatcher, the one place that can actually say no.
Read the full account in The agent layer →When you say "that can't happen," what actually stops it?
The answer that looks obvious
A check in the API route, or a comment explaining why it shouldn't occur.
What actually decides it
Find the lowest layer available, a database constraint, a type, a fixed schema width, and ask whether the invariant is also true there, not only at the one call site you happened to think of.
Here, it was
An unknown role was refused at the API and could still be silently written to a plain column with no constraint. The rule became: make the unsafe state unrepresentable, not merely unreached.
Read the full account in Security →Does your test environment actually resemble the one you ship to?
The answer that looks obvious
If it passes locally and in CI, it is ready.
What actually decides it
Name the specific ways your test environment differs from production on purpose, a fresh database versus one with years of history, a host filesystem versus the real container build context, and assume the next real bug lives in exactly that gap, because nothing has ever exercised it.
Here, it was
A schema migration passed everywhere it was checked, because every check ran against a table created fresh. The one environment with history was production. A fresh database is a flattering test double for a production one.
Read the full account in The data layer →Does your eval know what a bad answer looks like, or only what a good one looks like?
The answer that looks obvious
If the real system scores well on the eval, the eval is working.
What actually decides it
Build one input designed to be obviously bad and confirm the eval actually calls it bad. If you cannot construct one, or it passes anyway, the eval may only be agreeing with you.
Here, it was
A control built from embeddings with no real semantics has to score near chance, and its gate inverts: if that control scores well, the whole suite fails, because a harness that rewards any output produces a green table for nothing.
Read the full account in Evals →All fourteen decisions, with what each one cost, are in the blog.