Agent Team Structures: Who Owns What in a Multi-Agent System
Why "just add more agents" breaks things
The first time you build a single agent that calls a few tools, life is simple. One system prompt, one context window, one place to look when something goes wrong. Then the agent starts doing too much — it's supposed to research, write, review its own writing, call APIs, and keep track of a project plan, all inside one loop. Latency creeps up. The model starts confusing "what I already did" with "what I still need to do." So the natural next move is to split the work into multiple agents.
This is where most teams get into trouble, not because multi-agent systems are a bad idea, but because they skip the actual design step. They spin up a "researcher" and a "writer" and a "reviewer," wire them together with a framework, and assume the architecture will sort itself out. It doesn't. The moment you have more than one agent touching the same task, you have introduced an org chart, whether you meant to or not. Somebody has to decide who reads what, who writes what, who has the authority to override whom, and what happens when two agents disagree.
Human teams solve this with job titles, reporting lines, and Slack etiquette. Agent teams need the equivalent, except it has to be explicit, because agents don't pick up on implicit norms the way a new hire does after a week of osmosis. If you don't define ownership boundaries, you get the multi-agent equivalent of five cooks in one kitchen: duplicated work, silent overwrites, and a final output that reads like it was stitched together by committee — because it was.
This article is about the actual mechanics of ownership in a multi-agent system: what "ownership" means for an agent, the common team topologies, how to assign responsibility for state and side effects, and where things go wrong in practice. It's written for anyone building agentic systems with frameworks like LangGraph, CrewAI, AutoGen, or a hand-rolled orchestrator — the concepts are framework-agnostic.
What "ownership" actually means for an agent
Ownership in a multi-agent system isn't a vague management metaphor. It cashes out into four concrete things, and if you can't answer all four for every agent in your system, you don't have a real design yet — you have a demo.
1. Write access. Which agent is allowed to change which piece of state? If you have a shared "project plan" object, exactly one agent (or one clearly-sequenced set of agents) should be able to mutate it at any given point. Read access can be broad; write access has to be narrow, or you get race conditions in the semantic sense — two agents each convinced they have the latest truth.
2. Decision authority. When two agents produce conflicting outputs — a researcher says the API is deprecated, a coder says it still works — who resolves the conflict? Ownership means someone (or some agent) has the explicit authority to make the final call, and that authority is known in advance, not improvised at runtime.
3. Side-effect responsibility. Which agent is allowed to actually do things in the world — send an email, commit code, call a paid API, place an order? This is the most important one to get right early, because it's the one that costs real money or reputation when it goes wrong. Side effects should be owned by as few agents as possible, ideally one, and that agent should be the most constrained and most heavily validated part of the system.
4. Failure accountability. When something breaks, which agent's output do you inspect first? If your system can't answer this in under thirty seconds, your ownership model is too diffuse. Good agent team design makes debugging a matter of "check the owner," not "trace the whole graph."
Notice that none of these four are about the agent's personality or its system prompt tone. They're about state, authority, side effects, and blame — the same four things you'd nail down for a human team on day one. The mistake people make is spending hours tuning a sub-agent's prompt style while leaving these four questions to "figure out later." Later is always during an incident.
The four common team topologies
Most multi-agent systems, once you strip away the framework-specific naming, fall into one of four shapes. Each has a different ownership model baked in, and picking the wrong one for your problem is the single most common design mistake.
Manager-worker (hub and spoke). A single orchestrator agent owns the task list and the final decision. It delegates sub-tasks to worker agents, each of which owns a narrow slice of execution but nothing else. The manager owns synthesis; the workers own execution. This is the easiest topology to reason about because ownership is centralized — there's exactly one place where conflicting worker outputs get reconciled. The tradeoff is that the manager becomes a bottleneck, both for latency (everything routes through it) and for context (it has to hold enough of the picture to judge worker output it didn't produce itself).
Pipeline (sequential handoff). Agent A finishes and hands its output to Agent B, which hands to Agent C. Ownership here is temporal — each agent owns the state completely during its turn, and that ownership transfers cleanly at handoff. A research agent owns the research phase, a drafting agent owns the draft, an editing agent owns the polish. Nobody's writing to the same object at the same time, which eliminates a whole category of bugs. The failure mode is different: garbage in, garbage out, with no way to recover except starting over or building an expensive feedback loop backward through the pipeline.
Peer review (writer-critic loop). One agent produces, another agent critiques, and control passes back and forth until the critic is satisfied or a round limit is hit. Ownership splits along a different axis than the previous two: the writer owns content, the critic owns the acceptance criteria. This is a genuinely useful pattern for anything where quality matters more than speed — code review, editorial review, plan validation. The trap is unbounded loops: if you don't define what "done" means numerically (a max round count, a specific rubric, a confidence threshold) the critic can reject forever and you've built an expensive stalling machine instead of a quality gate.
Swarm / market-based (bidding or voting). Multiple agents propose independently and a selection mechanism — voting, scoring, or a dedicated arbiter — picks a winner. Ownership is provisional until the selection step; nobody owns the final answer until they've won it. This topology is powerful for problems with a genuinely correct answer that's cheap to verify (does this code pass the tests, does this SQL query return the right row count), because you can generate several candidates and let a verifier pick. It's a poor fit for problems where "correct" is subjective, because voting mechanisms just average out disagreement instead of resolving it.
Here's a way to sketch the ownership boundaries before you write a line of orchestration code — a simple ownership table:
Agent | Owns (write) | Reads | Can trigger side effects
----------------|------------------------|--------------------|---------------------------
Planner | task_list, priorities | user_request | no
Researcher | research_notes | task_list | no (read-only web calls)
Coder | code_diff | research_notes | no
Reviewer | approval_status | code_diff | no
Deployer | deploy_log | approval_status | yes (deploy, only agent)If you can fill in a table like this for your system and every row is unambiguous, you're in good shape. If you find yourself writing "Coder and Reviewer both can edit code_diff," stop — that's the seam that will produce contradictory edits down the line.
Assigning ownership of shared state
Shared state is where multi-agent systems quietly rot. Everyone agrees on the topology in the design doc, and then six weeks later there's a "context" or "memory" object that four different agents write to because it was convenient at the time.
The fix is to treat shared state like you'd treat a shared database table in a normal backend system: define a schema, and define exactly which service (agent) owns writes to which fields. A few practical rules that hold up in production:
- One writer per field, always. If two agents genuinely both need to update, say, a "status" field, that's a sign the field is doing two jobs and should be split into two fields, each with a single owner.
- Readers don't need permission, writers do. Make read access cheap and broad — agents generally benefit from more context, not less. Make write access something you have to justify in the design table above.
- Version or timestamp shared objects. When an agent writes to shared state, have it stamp what it changed and why, even just a one-line note. This turns a silent overwrite into a debuggable event.
- Prefer append-only logs over mutable blobs for anything you'll want to audit. A list of "research_notes" entries, each attributed to the researcher agent with a timestamp, is far easier to debug than a single "notes" string that's been rewritten five times by three different agents.
Here's a minimal example of what an ownership-aware state object looks like in code, using a plain Python dataclass as a stand-in for whatever state store you're actually using:
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class AgentEvent:
agent: str
action: str
payload: dict
timestamp: datetime = field(default_factory=datetime.utcnow)
class SharedState:
def __init__(self):
self._log: list[AgentEvent] = []
self._owners = {
"task_list": "planner",
"research_notes": "researcher",
"code_diff": "coder",
"approval_status": "reviewer",
}
def write(self, agent: str, field_name: str, value):
owner = self._owners.get(field_name)
if owner and owner != agent:
raise PermissionError(
f"{agent} tried to write '{field_name}', "
f"but it's owned by '{owner}'"
)
self._log.append(AgentEvent(agent, f"write:{field_name}", {"value": value}))
setattr(self, field_name, value)This is deliberately unglamorous. It's not a framework feature, it's a guard rail you write yourself, and it pays for itself the first time an agent tries to write outside its lane and you get a clear exception instead of a silently corrupted plan.
Decision rights: who breaks the tie
Ownership of state answers "who can change what." Decision rights answer a harder question: "when two correct-looking outputs conflict, who wins?" This shows up constantly in practice — a research agent flags a security risk, a coding agent says the risk is out of scope, and now what?
There are three defensible patterns here, and picking one explicitly beats leaving it to whichever agent happens to run last.
Hierarchical override. One agent — usually the orchestrator or a designated "supervisor" role — has the explicit last word. This is the simplest model and the right default for most production systems, because it means every disagreement has a deterministic resolution path. The cost is that the supervisor needs enough context to actually judge the disagreement, not just rubber-stamp whichever agent spoke last.
Domain authority. Instead of one agent always winning, different agents have final say within their declared domain — the security-focused agent's veto stands on security questions, the performance-focused agent's veto stands on latency questions, regardless of hierarchy. This works well when your agents map cleanly to distinct expertise areas, but it requires you to have pre-defined what each domain covers, or you'll get boundary disputes ("is this a security issue or a design issue?") that nobody has authority to resolve.
Escalation to a human. For anything with real-world consequences — spending money, sending external communications, deleting data — the right "decision right" is often "no agent decides, a human does." This isn't a cop-out; it's the correct ownership assignment for high-stakes, low-frequency decisions. Build the escalation path as a first-class part of the architecture, not an afterthought bolted on after an incident.
Whichever pattern you choose, write it down as a rule the orchestrator enforces in code, not as a suggestion in a system prompt. "The reviewer agent's rejection blocks deployment" is an architectural invariant if it's enforced by your orchestration logic, and it's a suggestion the model can override with a persuasive rationalization if it's just a sentence of prompt text.
Side effects: the part you can't afford to get wrong
Everything discussed so far is about internal coordination — who owns state, who owns decisions. Side effects are different because they leave the sandbox: sending a real email, executing a real trade, pushing a real commit, calling a paid API. Get ownership wrong here and the blast radius is outside your system.
The pattern that holds up: minimize the number of agents that can trigger side effects, and make the side-effect-capable agent the most tightly scoped, most heavily validated part of your system, not the smartest or most autonomous one.
Concretely:
- Separate proposing from executing. An agent that decides "we should deploy this" should not be the same agent whose tool call actually deploys it. Insert a validation step — even a simple rules check — between decision and execution.
- Give side-effect agents the narrowest possible tool set. A "deployer" agent should have exactly one tool: deploy. Not deploy-plus-delete-plus-modify-permissions. The narrower the tool surface, the smaller the space of things that can go wrong when the model does something unexpected.
- Log every side effect with the triggering agent's identity and the upstream decision chain. When a customer asks "why did the system send this email," you want an answer in seconds, not a forensic investigation through raw logs.
- Put a human approval gate on anything irreversible, at least until you've built enough track record with the system to trust it. Irreversible actions are exactly where "the agent seemed confident" is not sufficient justification.
This is the one place in agent team design where being conservative costs you almost nothing. A slightly slower approval flow is a rounding error compared to the cost of an agent confidently executing the wrong side effect because ownership of "who's allowed to actually do this" was left ambiguous.
Failure accountability: designing for the incident, not just the happy path
Every multi-agent system will eventually produce a bad output. The question is whether your architecture tells you where to look, or whether it forces you into a multi-hour trace through logs from six different agents.
Good ownership design makes this fast, almost mechanical:
- Every output carries provenance. Which agent produced this, based on which inputs, at which step. If your orchestrator can't answer "who wrote this line" for any given piece of output, you don't have observability, you have vibes.
- Failures should be attributable to exactly one owner. If the researcher's notes were wrong, that's a researcher problem. If the coder correctly implemented wrong research, that's not a coder problem. This sounds obvious, but it only works if you actually built the ownership boundaries clean enough to trace it — which loops back to everything above.
- Build a "replay" capability if you can. Being able to re-run a single agent's step in isolation, with the same inputs, is worth more for debugging multi-agent systems than almost any other tooling investment. It turns "the whole pipeline produced garbage" into "step 3 produced garbage, here's exactly why."
- Track disagreement rates, not just final outputs. If your reviewer agent rejects the coder's output 40% of the time, that's signal about where your ownership boundary is drawn wrong — maybe the coder needs more context up front, maybe the reviewer's bar is miscalibrated. Ownership boundaries aren't static; they should get adjusted based on where friction actually shows up in production.
A useful mental model: design your agent team the way you'd design an incident response runbook before the incident happens. If the honest answer to "who do we page when this breaks" is "we're not sure, let's look," that's not a monitoring gap, it's an ownership gap, and it was there from the design phase.
A worked example: content pipeline with three agents
To make this concrete, here's how ownership plays out in a realistic small system — say, an agent team that researches a topic, drafts an article, and checks it for factual accuracy before publishing.
class ContentPipeline:
def __init__(self, researcher, writer, fact_checker):
self.researcher = researcher
self.writer = writer
self.fact_checker = fact_checker
def run(self, topic: str, max_revision_rounds: int = 2):
# Researcher owns: research_notes. Read-only web access, no writes elsewhere.
notes = self.researcher.gather(topic)
# Writer owns: draft. Reads research_notes, cannot touch them.
draft = self.writer.write(topic, notes)
# Fact-checker owns: approval_status. Reads draft, cannot edit it directly —
# it can only return a verdict plus flagged claims.
for round_num in range(max_revision_rounds):
verdict = self.fact_checker.review(draft, notes)
if verdict.approved:
return {"draft": draft, "status": "approved", "rounds": round_num}
# Writer owns revision; fact-checker's flags are input, not an edit.
draft = self.writer.revise(draft, verdict.flagged_claims)
# Escalate instead of silently publishing something unverified.
return {"draft": draft, "status": "needs_human_review", "rounds": max_revision_rounds}Notice what this small example enforces even without a heavyweight framework: the fact-checker can never directly rewrite the draft, even though it would be technically easy to let it. That constraint is deliberate — if the fact-checker starts editing content instead of just flagging problems, you've collapsed two distinct roles (verification and authorship) into one, and now a factual dispute and a stylistic dispute look identical in your logs. Keeping the fact-checker's output limited to "approved or not, here's why" preserves a clean accountability line: bad facts are a research problem, bad prose is a writer problem, and a wrongly-approved article is a fact-checker problem. Three agents, three unambiguous owners, and a bounded revision loop with an explicit escalation path instead of an infinite argument.
Getting started without overengineering it
None of this means every project needs four agents, a formal ownership table, and a permission-checked state store on day one. If your task fits comfortably in one agent's context and doesn't require independent parallel work, one agent is the right architecture — multi-agent systems add coordination overhead, and that overhead only pays off once a single agent is genuinely straining against scope, context length, or the need for specialized judgment in different sub-tasks.
But the moment you do split into multiple agents, do the ownership design explicitly before you write orchestration code. Sketch the table: who writes what, who decides ties, who's allowed to trigger real-world side effects, who gets paged when it breaks. It takes twenty minutes on a whiteboard and it will save you from the specific failure mode that kills most multi-agent prototypes — not that the agents are individually dumb, but that nobody defined who was in charge of what, so the system behaves unpredictably the moment two agents' outputs touch.
If you want to go deeper on building these systems hands-on — orchestration patterns, state management, tool design, and the debugging workflow for when agent teams misbehave — 30 Days of Hermes Agent walks through building a real multi-agent system from a single-agent baseline up through manager-worker and peer-review topologies, with the ownership and accountability patterns covered here implemented as actual working code rather than diagrams. It's built for engineers who want to ship agent teams that hold up under real production load, not just demo well once.
BootcampA 30-day guided bootcamp: build, harden and ship a production autonomous agent from scratch.
AI AgentsUnderstand how AI agents really work: the loop, the tools, the memory, and why most agent projects fail.