Crews and Multi-Agent Collaboration
A single agent can do a remarkable amount on its own. But the most interesting — and most fragile — territory in this field is the moment you put several agents together and ask them to cooperate. Multi-agent systems go by many names: crews, swarms, societies, orchestrations. The idea is the same: instead of one generalist grinding through every step, you assemble a team of specialists, each with a role, and let a planner divide the work between them. The promise is real — parallelism, specialization, and workloads too big for one context window. The reality is that coordination introduces a whole new breed of failure. This article walks through why crews are powerful, how they are built, and the parts that go wrong.
Why Put Agents in a Crowd at All?
The case for a single agent is simplicity. One loop, one memory, one set of tools — easy to reason about and debug. So why complicate it with a crew? Three reasons are legitimate. The first is parallelism: if a project has five independent workstreams, five agents can run them simultaneously and finish the whole thing in roughly the time one agent takes on the longest stream. The second is specialization: a researcher, a writer, and a reviewer each hold deep, role-specific skills, and a specialist consistently outperforms a generalist at its own job. The third is scale: a long task can overflow a single context window; splitting it across agents keeps each one within its limits. If none of these apply, you likely do not need a crew — and reaching for one anyway is how a lot of unnecessary complexity gets born.
"A crew is not one agent wearing many hats. It is many hats, each worn by a head that knows its one job and trusts the others — and that trust is the part you cannot fake."
The Anatomy of a Crew
Whatever framework you use, a multi-agent system has the same pieces. There is an orchestrator (or router or manager) that divides the task and assigns work. There are the worker agents, each scoped to a role with its own instructions and tools. There is a shared state or message bus through which they exchange results and updates. And there is a merge step where partial outputs are reconciled into a final deliverable. Here is a minimal crew skeleton in a framework-agnostic style:
orchestrator = Agent(role="planner",
prompt="Break the task into subtasks and assign each to research|writes|review.")
researcher = Agent(role="research", tools=[search, fetch])
writer = Agent(role="write", tools=[draft])
reviewer = Agent(role="review",
prompt="Check summary for accuracy vs the cited sources; send back to write if wrong.")
crew = Crew(agents=[researcher, writer, reviewer], orchestrator=orchestrator,
state=SharedState())
result = crew.run("Produce a 2000-word brief on grid energy storage.")
There is a temptation to find clever names for each role. Resist it. Named, accountable roles beat clever ones, because the next person (or the system) has to understand who owns what. A crew's quality is largely decided by the clarity of its role boundaries — the same lesson as good code structure, applied to a team of machines.
The Hard Part Is the Handoffs
Everything that goes wrong in a crew happens at the seams. Agents are probability machines, so when agent A hands work to agent B, B may quietly misunderstand the partial result and plow ahead with a corrupted assumption. A powerful pattern for fighting this is structured handoffs: require every agent's output to conform to a typed schema, and have the receiving agent validate it before proceeding. Free-text prose is a lossy interface; JSON with fixed fields is not. Pair that with a feedback loop, so if the reviewer finds the writer's output unsupported by the research, the writer gets a concrete note and a retry.
class ResearchResult(BaseModel):
claim: str
sources: list[str]
confidence: float
class WriterDraft(BaseModel):
sections: list[str]
claims_to_verify: list[str]
class ReviewVerdict(BaseModel):
pass: bool
missing_sources: list[str]
note: str
There is a second, sneakier failure hiding in crews: lost signal. As messages pass from agent to agent, nuance and important detail get dropped. The fix is to not let agents summarize away what downstream agents actually need. Keep source citations attached to claims, keep the original data pointers flowing alongside processed summaries, and let downstream agents reach back to primary sources. A crew whose members only trust each other's summaries is a game of telephone with a large language model at every hop.
When Coordination Itself Becomes the Cost
It is easy to underestimate the overhead of running a crew. Every handoff is another model call, more tokens, more opportunities for drift, more latency. For a small task, a single agent will often beat a crew on cost, speed, and reliability. The coordination overhead only pays back when the parallelism and specialization genuinely overcome it. Watch for the signs that you have overshot: most agents idle while one bottlenecks, handoffs happen more often than real work, or the orchestrator becomes a dominant cost without adding quality.
# heuristic: is a crew worth it for this task?
if workstreams < 2: single_agent()
elif horizon > context_limit: crew_needed()
elif specialist_matters: crew_needed()
else: single_agent() # likely cheaper and safer
The goal of a crew is not to have many agents. It is to have the right work done well. Fewer agents, doing fewer things, on purpose, is almost always the better engineering.
Governance: Who Is Accountable for What
The moment you have a crew, you have a distributed system, and distributed systems need accountability. Make every action attributable: each agent should log which agent did what, with which tools, and why. Human-in-the-loop is not optional at the boundaries. Decide in advance which actions required human approval before anyone starts — irreversible actions like sending messages, spending money, or modifying external records should always pause for a person. And build in a global budget and a kill switch, because a crew of autonomous agents will happily spend your entire token budget redoing each other's work.
- Log every handoff with its sender, receiver, and message digest.
- Require typed, validated handoffs rather than loose prose.
- Insert a human approval gate before any irreversible external action.
- Set an overall step or token budget and make escalation an option, not a panic.
The Future Is Teams of Specialists
Multi-agent collaboration is where the field is clearly heading, because real work is rarely a single competence — it is research plus drafting plus review plus compliance, chained together. The crews that work well in practice are the ones designed like disciplined human teams: clear roles, clean handoffs, shared state, and someone accountable for holding the thread. They fail the way untrained teams do — at the seams, from lost context, from silent misunderstanding — and they are fixed the same way too: with structure, validation, and review. Build a single agent until you hit a real scaling wall. Then, and only then, form a crew, define its handoffs ruthlessly, and hold it accountable for more than the sum of its parts.



