# How to Build a Multi-Agent System

- Tool: Any LLM or framework
- Difficulty: Advanced
- Time required: 50-65 min
- Compatibility: Python 3.10+, crewai 1.x, Claude or OpenAI API key, any OS
- Last updated: November 2026

## TL;DR

A multi-agent system splits one task across several specialized agents instead of giving one agent every tool and hoping it manages the complexity. This guide builds a three-agent crew with CrewAI, a Researcher that looks up competitor pricing, a Writer that drafts a comparison post, and an Editor that fact-checks it against the research, chained with task context so each stage builds on the last. Budget 50-65 minutes and roughly triple the token cost of a single agent.

## What you'll build

You'll build a three-agent crew that produces a competitor pricing comparison post. A Researcher agent looks up a competitor's current pricing with a search tool, a Writer agent turns that research into a draft, and an Editor agent checks every claim and price in the draft against what the Researcher actually found, flagging anything it can't trace back.

That last agent is the point of this example. A single agent writing and fact-checking its own work tends to rubber-stamp itself; a separate Editor agent whose only job is catching unsupported claims catches mistakes a combined agent would wave through. CrewAI models this as agents (a role, a goal, a backstory, and the tools that role needs), tasks (what to do and what a correct result looks like), and a Crew that runs the tasks in order, passing each task's output forward as context to the ones after it.

Reach for multiple agents when a task has genuinely distinct phases that benefit from distinct instructions, tools, or review, not just because the single-agent prompt got long. If one well-scoped agent with two or three tools can already do the job (see the pillar guide), adding agents only adds tokens and failure surface. For orchestration that isn't strictly sequential, several branches running in parallel or a central router deciding which specialist to call, see the architecture guide and LangGraph's supervisor pattern instead of a CrewAI crew.

## Before you start

- Python 3.10+ and a terminal
- An Anthropic or OpenAI API key with available credits
- pip install crewai
- Comfort with the idea of three agents each only seeing part of the task

## Step-by-step guide

### 1. Decide you actually need more than one agent

Before building a crew, write down the phases of the task and ask whether each one needs different tools, different instructions, or independent review. This example splits cleanly: research needs a search tool and factual grounding, writing needs tone and structure, editing needs to distrust the writer. If your task doesn't split that cleanly, a single agent with more tools is almost always less code and fewer tokens.

**Expected result:** A short list of 2-4 genuinely distinct phases, each with its own reason to be a separate agent.

### 2. Install CrewAI and define a shared tool

Install crewai, then define a custom tool with the @tool decorator from crewai.tools, the same pattern as a single-agent tool, just handed only to the agent that needs it. search_competitor_pricing is the only tool in this crew, and only the Researcher gets it.

```
pip install crewai

from crewai.tools import tool

PRICING = {"Acme Rival Co": "Starter $29/mo, Growth $99/mo, Enterprise custom"}

@tool("Search competitor pricing")
def search_competitor_pricing(competitor: str) -> str:
    """Look up the current public pricing tiers for a named competitor."""
    return PRICING.get(competitor, "No public pricing found")
```

**Expected result:** A tool function you could call directly with a competitor name and get pricing text back, no agent involved yet.

### 3. Define the three agents

Each Agent gets a role, a goal, a backstory that sets its judgment and tone, and only the tools that role actually needs. The Researcher gets search_competitor_pricing; the Writer and Editor get none, they work from what the Researcher already found, passed in as task context in the next step.

```
from crewai import Agent

researcher = Agent(
    role="Competitive Pricing Researcher",
    goal="Find accurate, current pricing for the named competitor",
    backstory="You are a meticulous analyst who never states a number you haven't looked up.",
    tools=[search_competitor_pricing],
)

writer = Agent(
    role="Content Writer",
    goal="Turn pricing research into a clear, honest comparison post",
    backstory="You write tight B2B comparison content and never invent a figure.",
)

editor = Agent(
    role="Fact-Check Editor",
    goal="Catch unsupported claims and pricing errors before anything publishes",
    backstory="You reject any claim in the draft that isn't traceable to the research.",
)
```

**Expected result:** Three Agent objects, none runnable alone yet without a Task.

### 4. Define the three tasks and chain them with context

Each Task names what to do, what a correct result looks like (expected_output), and which agent does it. context=[...] is what makes this a pipeline instead of three independent jobs: the writing_task sees the research_task's output, and the editing_task sees both. Without context, the Writer and Editor would only see the original request, not the Researcher's actual findings.

```
from crewai import Task

research_task = Task(
    description="Research {competitor}'s current pricing tiers using the search tool.",
    expected_output="A list of pricing tiers with exact dollar amounts and what each includes.",
    agent=researcher,
)

writing_task = Task(
    description="Write a 300-word comparison post using only the pricing from the research task.",
    expected_output="A markdown blog post comparing our pricing to the competitor's.",
    agent=writer,
    context=[research_task],
)

editing_task = Task(
    description="Check every price and claim in the draft against the research task's output. Flag anything unsupported.",
    expected_output="The approved post, or a specific list of corrections needed.",
    agent=editor,
    context=[research_task, writing_task],
)
```

**Expected result:** Three Task objects where editing_task can see both the raw research and the Writer's draft.

### 5. Assemble the Crew and run it

Crew takes the agents, the tasks in the order they should run, and a process. Process.sequential runs each task in order, passing context forward exactly as wired above. kickoff() takes an inputs dict that fills in the {competitor} placeholder in research_task's description.

```
from crewai import Crew, Process

crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    process=Process.sequential,
)

result = crew.kickoff(inputs={"competitor": "Acme Rival Co"})
print(result.raw)
```

**Expected result:** A final result.raw containing either the Editor's approved post or a specific list of corrections, never a draft that skipped review.

### 6. Harden it: cost, process choice, and failure modes

Three agents roughly triple your token cost versus one agent doing all three jobs, since each agent's prompt, tools, and context all cost tokens independently. If tasks don't actually depend on each other in sequence, for example researching two competitors in parallel, switch to Process.hierarchical with a manager agent coordinating instead of forcing a strict sequential order. Log every task's output during development; a crew failing silently usually means context was missing, not that an agent is broken.

```
# Parallel-friendly alternative when tasks are independent, not sequential:
# crew = Crew(agents=[...], tasks=[...], process=Process.hierarchical, manager_llm="anthropic/claude-sonnet-5.5")
```

**Expected result:** A documented decision on sequential versus hierarchical, and a rough cost estimate before this runs against real traffic.

## Complete code example

File: `pricing_comparison_crew.py`

```python
"""Three-agent crew: researches competitor pricing, drafts a post, fact-checks it.
Run: python pricing_comparison_crew.py (pip install crewai; set ANTHROPIC_API_KEY)
"""
from crewai import Agent, Crew, Process, Task
from crewai.tools import tool

PRICING = {
    "Acme Rival Co": "Starter $29/mo, Growth $99/mo, Enterprise custom",
}


@tool("Search competitor pricing")
def search_competitor_pricing(competitor: str) -> str:
    """Look up the current public pricing tiers for a named competitor."""
    return PRICING.get(competitor, "No public pricing found")


researcher = Agent(
    role="Competitive Pricing Researcher",
    goal="Find accurate, current pricing for the named competitor",
    backstory="You are a meticulous analyst who never states a number you haven't looked up.",
    tools=[search_competitor_pricing],
)

writer = Agent(
    role="Content Writer",
    goal="Turn pricing research into a clear, honest comparison post",
    backstory="You write tight B2B comparison content and never invent a figure.",
)

editor = Agent(
    role="Fact-Check Editor",
    goal="Catch unsupported claims and pricing errors before anything publishes",
    backstory="You reject any claim in the draft that isn't traceable to the research.",
)

research_task = Task(
    description="Research {competitor}'s current pricing tiers using the search tool.",
    expected_output="A list of pricing tiers with exact dollar amounts and what each includes.",
    agent=researcher,
)

writing_task = Task(
    description="Write a 300-word comparison post using only the pricing from the research task.",
    expected_output="A markdown blog post comparing our pricing to the competitor's.",
    agent=writer,
    context=[research_task],
)

editing_task = Task(
    description=(
        "Check every price and claim in the draft against the research task's "
        "output. Flag anything unsupported instead of approving it."
    ),
    expected_output="The approved post, or a specific list of corrections needed.",
    agent=editor,
    context=[research_task, writing_task],
)

crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    process=Process.sequential,
)

if __name__ == "__main__":
    result = crew.kickoff(inputs={"competitor": "Acme Rival Co"})
    print(result.raw)
```

## Common mistakes

- **Giving every agent in the crew every tool, just in case** — undefined Fix: Scope tools to the agent that actually needs them. An Editor with a search tool will go verify things itself instead of checking the Researcher's actual work, defeating the point of the role.
- **Forgetting context=[...] on a dependent task** — undefined Fix: Without it, a later task only sees the original kickoff inputs, not an earlier task's output. The Writer would draft from nothing and the Editor would have nothing to check against.
- **Forcing Process.sequential on tasks that don't actually depend on each other** — undefined Fix: If two research tasks are independent, Process.hierarchical with a manager agent can run them more efficiently than an artificial sequential order.
- **Not budgeting for the token cost of N agents each carrying their own prompt and context** — undefined Fix: A three-agent crew roughly triples the token cost of one agent doing the same job. Estimate this before committing to a crew over a single well-scoped agent.
- **Skipping a review or fact-check agent entirely** — undefined Fix: A crew with no agent whose job is to doubt the others tends to compound small errors across stages instead of catching them. Add the equivalent of this guide's Editor to any crew that produces external-facing output.

## Best practices

- Scope each agent's tools to exactly what its role needs; least privilege applies to agents as much as to API keys.
- Use context=[...] explicitly on every task that depends on another, don't assume the crew infers it.
- Add a review or fact-check agent to any crew producing output a customer or the public will see.
- Budget tokens as roughly (number of agents) times a single agent's cost, then measure the real number on a test run.
- Default to Process.sequential when tasks genuinely depend on each other; reach for Process.hierarchical when they don't.
- Log every task's output, not just the crew's final result, so a bad final answer is traceable to the stage that caused it.

## Use cases

### undefined



### undefined



### undefined



## Frequently asked questions

### What is a multi-agent system, exactly?

Several AI agents, each with a distinct role, tools, and instructions, working on parts of the same task instead of one agent trying to do everything. This guide's crew has a Researcher, a Writer, and an Editor, each only able to do its own job.

### When should I use a multi-agent system instead of one agent with more tools?

When the task has genuinely distinct phases that benefit from separate instructions, separate tools, or independent review, like a writer that shouldn't also be grading its own work. If one agent with two or three tools already covers it, adding agents mostly adds cost.

### How is CrewAI different from LangGraph for multi-agent systems?

CrewAI models roles, tasks, and a process (sequential or hierarchical) at a higher level, good for crews where the phases are clear. LangGraph gives you an explicit state graph you control node by node, better when routing between agents needs custom logic the role/process model doesn't capture.

### Does a multi-agent system cost more to run than a single agent?

Yes, roughly in proportion to how many agents are involved, since each one carries its own prompt, tools, and context. A three-agent crew like this one costs roughly three times what one well-scoped agent doing the same job would.

### How do agents in a CrewAI crew share information?

Through a Task's context parameter, a list of earlier tasks whose output gets passed into the current task. Without it, an agent only sees the original kickoff inputs, not what an earlier agent actually found or wrote.

### Can someone build this for me instead of doing it myself?

Yes. RapidDev builds multi-agent systems on CrewAI and LangGraph, including the review and cost-control patterns this guide introduces. A free 30-minute consultation is the fastest way to scope your version.

---

Source: https://www.rapidevelopers.com/build-ai-agent/how-to-build-a-multi-agent-system
© RapidDev — https://www.rapidevelopers.com/build-ai-agent/how-to-build-a-multi-agent-system
