From a single agent to a coordinated agent landscape
A single Claude agent eventually hits limits on complex, multi step tasks: too much context, too many role switches, too little parallelism. A multi agent workflow distributes the work across specialized agents with clear roles, their own context and limited tools, coordinated by an orchestrator that collects and merges partial results.
Table of Contents
- 1. What a multi agent workflow is and why a single agent hits limits
- 2. Base architecture patterns: orchestrator, worker and reviewer
- 3. Role distribution: how tasks are cleanly separated
- 4. Sharing context and state between agents
- 5. Limiting tools and permissions per agent
- 6. Practical example: a multi agent workflow for a feature release
- 7. Error handling and retries in the multi agent workflow
- 8. Observability: logging across multiple agents
- 9. Single agent versus multi agent workflow compared
- 10. Summary
- 11. FAQ
1. What a multi agent workflow is and why a single agent hits limits
A multi agent workflow describes a software architecture in which several AI agents with different roles work on a shared task, instead of a single agent processing all steps one after another. With Claude Code this shows up concretely as an interplay between a coordinating main process and several subagents, each receiving a clearly scoped subtask. The difference from a classic single agent is not model quality, but task distribution and how context is handled.
In practice, the need for a multi agent workflow becomes visible whenever a task contains several substeps from different domains that each need their own context. An agent that simultaneously analyzes requirements, writes code, designs tests and maintains documentation accumulates information in its context window that becomes increasingly irrelevant to the current substep. This leads to longer response times, higher costs and, in some cases, lower quality, because relevant details get diluted in the growing context.
A well designed multi agent workflow solves this problem by giving each agent only the context it actually needs for its subtask. This not only reduces the token volume per request, it also improves traceability: a reviewer agent that only sees the diff and the project conventions delivers more focused feedback than an agent that is still simultaneously occupied with the original requirements discussion.
2. Base architecture patterns: orchestrator, worker and reviewer
Most production implementations of a multi agent workflow follow one of three recurring base patterns. In the orchestrator worker pattern, a central agent takes over decomposing the overall task into subtasks, distributes them to specialized worker agents and then merges the results. This pattern works particularly well when subtasks are clearly separated from each other and have little interdependency, for example analyzing several modules of a codebase in parallel.
In the pipeline pattern, agents work sequentially, with the output of one agent forming the input of the next. A multi agent workflow of this type suits tasks with a clear order, for example analyzing a requirement, designing an implementation, writing code, generating tests. The third pattern, the reviewer pattern, extends an existing workflow with an independent checking instance: a separate agent evaluates the result of another agent without knowing its reasoning process, delivering a more unbiased assessment as a result.
In practice, many teams combine all three patterns within a single multi agent workflow: an orchestrator distributes subtasks to workers, the results then go through a pipeline stage for consolidation, and a final reviewer agent checks the overall result before it goes back to a human. This combination significantly increases reliability, because errors can be caught at multiple points.
{
"workflow": "feature-release-multi-agent",
"orchestrator": {
"role": "coordinator",
"receives": ["feature_spec", "repo_context"],
"delegates_to": ["analysis_agent", "implementation_agent", "test_agent", "review_agent"]
},
"agents": [
{
"id": "analysis_agent",
"role": "worker",
"tools": ["read_file", "grep", "list_directory"],
"context_scope": "affected_modules_only"
},
{
"id": "implementation_agent",
"role": "worker",
"tools": ["read_file", "write_file", "run_linter"],
"context_scope": "analysis_agent.output"
},
{
"id": "test_agent",
"role": "worker",
"tools": ["read_file", "write_file", "run_tests"],
"context_scope": "implementation_agent.output"
},
{
"id": "review_agent",
"role": "reviewer",
"tools": ["read_file", "run_static_analysis"],
"context_scope": "diff_only"
}
]
}
3. Role distribution: how tasks are cleanly separated
Clean role distribution is the most important design decision in every multi agent workflow. A good rule of thumb: an agent should carry exactly one functional responsibility and carry it fully, rather than several responsibilities partially at once. An analysis agent reads and understands code, an implementation agent writes code, a test agent writes and checks tests, a review agent evaluates the result. This separation prevents an agent from being both author and reviewer of its own work at the same time, which systematically degrades the quality of feedback.
A common design mistake in a multi agent workflow is overlapping responsibilities, for example when both the implementation agent and the test agent are allowed to independently make assumptions about the requirement. This leads to contradictory interpretations that only surface late. The solution is to record assumptions and decisions centrally in the orchestrator or in a dedicated requirements artifact that all downstream agents access as the binding source.
4. Sharing context and state between agents
Passing context is the technically most demanding part of a multi agent workflow. The obvious but inefficient approach is to hand every downstream agent the complete history of all previous agents. This quickly leads to overloaded context windows and high costs. The better approach is for each agent to produce a clearly structured result artifact, for example a JSON object with the relevant findings, which the next agent consumes in a targeted way.
For longer running multi agent workflows, a shared state store has proven effective, for example a file in the repository or a simple key value store where intermediate results are placed. Each agent reads only the entries relevant to it and writes its own results back. This approach decouples the agents in time, since not every agent has to wait synchronously for the previous one's answer, and makes the state inspectable at any point, which is decisive when debugging.
# Simplified orchestrator for a multi agent workflow
# Each agent receives only its scoped context, not the full history
import json
from pathlib import Path
STATE_FILE = Path(".claude/workflow-state.json")
def load_state() -> dict:
if STATE_FILE.exists():
return json.loads(STATE_FILE.read_text())
return {}
def save_state(state: dict) -> None:
STATE_FILE.write_text(json.dumps(state, indent=2))
def run_agent(agent_id: str, scoped_context: dict) -> dict:
"""Placeholder: invokes the Claude API with a narrow, agent-specific context."""
# In practice this calls client.messages.create(...) with a system
# prompt tailored to agent_id and only scoped_context as input.
raise NotImplementedError
def orchestrate(feature_spec: str) -> dict:
state = load_state()
state["analysis"] = run_agent("analysis_agent", {"spec": feature_spec})
save_state(state)
state["implementation"] = run_agent(
"implementation_agent", {"analysis": state["analysis"]}
)
save_state(state)
state["tests"] = run_agent(
"test_agent", {"implementation": state["implementation"]}
)
save_state(state)
state["review"] = run_agent(
"review_agent", {"diff": state["implementation"]["diff"]}
)
save_state(state)
return state
5. Limiting tools and permissions per agent
A multi agent workflow gains extra safety when each agent only receives access to the tools necessary for its role. An analysis agent needs read file access and search tools, but no write access. An implementation agent needs write access, but no access to production systems. This limitation follows the principle of least privilege and reduces the possible damage if an agent performs an unexpected or faulty action.
In Claude Code, this limitation can be implemented via per subagent permission configuration, so that a test agent may run test commands but may not trigger deployment scripts. For a production multi agent workflow, it is also advisable to tie critical tools such as deleting files or running shell commands with destructive potential to a human approval step, regardless of which agent requests them.
{
"permission_profile": {
"analysis_agent": { "allowed": ["read_file", "grep"], "requires_approval": [] },
"implementation_agent": { "allowed": ["read_file", "write_file"], "requires_approval": ["delete_file"] },
"test_agent": { "allowed": ["read_file", "run_tests"], "requires_approval": [] },
"review_agent": { "allowed": ["read_file"], "requires_approval": [] }
},
"always_require_human_approval": ["delete_file", "run_shell_destructive", "deploy"]
}
6. Practical example: a multi agent workflow for a feature release
A concrete example illustrates the interplay: for introducing a new filter in the product catalog of a Magento shop, the orchestrator first takes over decomposing the requirement. An analysis agent reads the affected modules, identifies relevant classes and configuration files and delivers a structured summary. An implementation agent receives only this summary, not the full repository context, and implements the change.
A test agent then generates PHPUnit tests based on the resulting diff, without knowing the original requirements discussion, which forces it to orient itself purely on the actual code. A final review agent evaluates diff and tests together and flags deviations from the project conventions in CLAUDE.md. This multi agent workflow noticeably reduces the time from ticket to review ready pull request, because the substeps can be prepared in parallel while the human only needs to check the overall result.
#!/usr/bin/env bash
# Kick off a multi agent workflow run for a given ticket
set -euo pipefail
TICKET_ID="${1:?Usage: run-workflow.sh TICKET-123}"
WORKFLOW_DIR=".claude/workflows/feature-release"
echo "[orchestrator] Loading feature spec for ${TICKET_ID}"
claude --agent-config "${WORKFLOW_DIR}/analysis.json" \
--input "tickets/${TICKET_ID}.md" \
--output "state/analysis-${TICKET_ID}.json"
echo "[orchestrator] Dispatching implementation agent"
claude --agent-config "${WORKFLOW_DIR}/implementation.json" \
--input "state/analysis-${TICKET_ID}.json" \
--output "state/implementation-${TICKET_ID}.json"
echo "[orchestrator] Dispatching test agent"
claude --agent-config "${WORKFLOW_DIR}/test.json" \
--input "state/implementation-${TICKET_ID}.json" \
--output "state/tests-${TICKET_ID}.json"
echo "[orchestrator] Dispatching review agent"
claude --agent-config "${WORKFLOW_DIR}/review.json" \
--input "state/implementation-${TICKET_ID}.json" \
--output "state/review-${TICKET_ID}.json"
echo "[orchestrator] Multi agent workflow complete for ${TICKET_ID}"
7. Error handling and retries in the multi agent workflow
Errors in a multi agent workflow differ from errors in a single agent call in that they can propagate across multiple stages. If the analysis agent delivers an incomplete summary, the implementation agent builds a faulty solution on top of it, which then gets confirmed by the test agent with fitting but irrelevant tests. Without countermeasures, errors in such a workflow confirm each other rather than surfacing.
An effective countermeasure is introducing validation points between stages: after analysis, a simple rule or a second, independent agent checks whether the summary is plausible and complete before it is passed on. For retries, a limited number of attempts per stage with a clearly defined abort criterion is recommended, so that a failing agent is not retried endlessly but escalates to a human after a fixed number of attempts.
# Retry with bounded attempts and escalation to a human after the limit
MAX_RETRIES = 3
def run_stage_with_retry(stage_id: str, stage_input: dict) -> dict:
for attempt in range(1, MAX_RETRIES + 1):
result = run_agent(stage_id, stage_input)
if validate_result(stage_id, result):
return result
print(f"[workflow] {stage_id} failed validation, attempt {attempt}/{MAX_RETRIES}")
escalate_to_human(stage_id, stage_input, reason="max_retries_exceeded")
raise RuntimeError(f"Stage {stage_id} failed after {MAX_RETRIES} attempts")
8. Observability: logging across multiple agents
Without structured logging, a multi agent workflow quickly becomes a black box in which no one can trace which agent made which decision. Every agent call should therefore be logged with a unique workflow id, a timestamp, the role used, and the inputs and outputs. These logs allow a faulty run to be reconstructed step by step afterward, instead of only seeing the final result.
For teams running a multi agent workflow in production, it is also worth building a dashboard that aggregates runtime, token consumption and success rate per agent role. This makes it possible to notice early when, for example, the review agent rejects above average often, which can point to a problem in the upstream implementation stage rather than a problem in the review stage itself.
9. Single agent versus multi agent workflow compared
The following overview summarizes when a single agent is sufficient and when a multi agent workflow is the better choice. The decision depends less on the complexity of the task itself and more on how clearly it can be decomposed into independent subtasks.
| Criterion | Single Agent | Multi Agent Workflow |
|---|---|---|
| Task scope | Small to medium, one topic area | Large, multiple domains |
| Context consumption | Grows with every substep | Small and focused per agent |
| Parallelizability | Not possible | Worker agents run in parallel |
| Setup effort | Low, one prompt is enough | Higher, needs roles and state |
| Error traceability | A single conversation history | Clear attribution per role |
This comparison does not lead to a blanket recommendation for a multi agent workflow, but to a clear condition: as soon as a task can be decomposed into independent, functionally different substeps, the advantages of splitting it up outweigh the added complexity. If the task remains tightly coupled and consistently requires the same context, a single agent remains the more efficient choice.
Mironsoft
Multi agent workflows for Magento and Hyvä development with Claude
Want to orchestrate several Claude agents for your project?
We design multi agent workflows for analysis, implementation, tests and review, tailored to your existing codebase, with clear roles, limited permissions and traceable state.
Architecture design
Roles, state and tool boundaries for your multi agent workflow
Implementation
Orchestrator and subagents implemented in production Claude Code
Monitoring
Logging and dashboards for runtime, cost and success rate
10. Summary
A multi agent workflow solves a real problem precisely when a task contains too many functionally different substeps to be handled efficiently by a single agent. Orchestrator, worker and reviewer are the three recurring roles found in almost every production implementation. Quality hinges on clear role distribution, lean, deliberately passed context, and limited tool permissions per agent.
Error handling and observability must not be treated as an afterthought, they belong in the design of a multi agent workflow from the very start. Whoever builds validation points between stages and logs every agent call in a structured way catches errors early and can improve the workflow in a targeted way, instead of starting over with every problem.
Multi agent workflows with Claude, the key takeaways
Base pattern
Orchestrator distributes subtasks, workers execute them, reviewer independently checks the overall result.
Context
Each agent gets only the slice it needs for its role, not the complete history.
Tools
Limit permissions per role, tie destructive actions to human approval.
Operations
Validation points and structured logging prevent errors from propagating unnoticed.