Build Multi-Agent Systems with CrewAI: Roles, Tasks & Workflows

Learn how to build multi-agent AI systems with CrewAI. Define agent roles, delegate tasks, and orchestrate collaborative workflows with practical Python examples.

a group of men sitting next to each other
Photo by Herlambang Tinasih Gusti on Unsplash
white and black number 3
Photo by Glen Carrie on Unsplash

Build Multi-Agent Systems with CrewAI: Roles, Tasks & Workflows

CrewAI makes it easy to build teams of specialized AI agents that collaborate to complete complex tasks. Instead of one agent doing everything, you define agents with specific roles and let them work together β€” like a real team. In this tutorial, you'll build a multi-agent research and writing crew.

What You'll Learn#

  • Core CrewAI concepts: agents, tasks, crews, and processes
  • How to define specialized agent roles with clear backstories
  • Task delegation and agent collaboration patterns
  • Building a complete research + writing workflow
  • Real-world tips for production CrewAI deployments

Prerequisites#

CrewAI Core Concepts#

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    CREW                         β”‚
β”‚                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚ Agent 1  β”‚  β”‚ Agent 2  β”‚  β”‚ Agent 3  β”‚     β”‚
β”‚  β”‚Researcherβ”‚  β”‚ Writer   β”‚  β”‚ Editor   β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜     β”‚
β”‚       β”‚              β”‚              β”‚           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚ Task 1   β”‚  β”‚ Task 2   β”‚  β”‚ Task 3   β”‚     β”‚
β”‚  β”‚ Research β”‚  β”‚ Draft    β”‚  β”‚ Review   β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                 β”‚
β”‚  Process: Sequential | Hierarchical             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

| Concept | What it is | |---------|-----------| | Agent | A specialized AI worker with a role, goal, and backstory | | Task | A specific assignment for an agent to complete | | Crew | A team of agents working together | | Process | How agents collaborate (sequential or hierarchical) | | Tool | External capabilities agents can use |

Step 1: Setup#

mkdir crewai-project && cd crewai-project
python -m venv venv
source venv/bin/activate

pip install crewai crewai-tools python-dotenv

Create .env:

OPENAI_API_KEY=your-api-key-here

Step 2: Define Your Agents#

Each agent needs a clear role, goal, and backstory. The backstory is crucial β€” it shapes the agent's personality and expertise.

# crew.py
import os
from dotenv import load_dotenv

load_dotenv()

from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool, WebsiteSearchTool

# Tools
search_tool = SerperDevTool()
web_tool = WebsiteSearchTool()

# Agent 1: Researcher
researcher = Agent(
    role="Senior Research Analyst",
    goal="Discover comprehensive, accurate information about "
         "the given topic from multiple authoritative sources",
    backstory="""You are a veteran research analyst with 15 years
    of experience in technology research. You're known for your
    thorough, unbiased analysis and your ability to synthesize
    complex information from multiple sources. You never rely on
    a single source and always cross-reference your findings.""",
    tools=[search_tool, web_tool],
    verbose=True,
    allow_delegation=False,  # Researcher works independently
    max_iter=5
)

# Agent 2: Writer
writer = Agent(
    role="Content Strategist & Writer",
    goal="Transform research findings into engaging, well-structured "
         "content that is accessible to a general audience",
    backstory="""You are an award-winning technology writer who
    excels at making complex topics understandable. You have a
    talent for finding compelling angles and telling stories that
    resonate with readers. You always cite your sources and focus
    on actionable insights.""",
    verbose=True,
    allow_delegation=False,
    max_iter=5
)

# Agent 3: Editor
editor = Agent(
    role="Senior Editor & Fact Checker",
    goal="Ensure content is accurate, well-structured, free of "
         "errors, and meets our quality standards",
    backstory="""You are a meticulous editor with a keen eye for
    detail. You verify facts, check for logical consistency,
    improve clarity, and ensure the content flows naturally.
    You're never afraid to push back on claims that lack evidence
    or writing that lacks clarity.""",
    verbose=True,
    allow_delegation=True,  # Can ask researcher for clarification
    max_iter=3
)

Agent Design Tips#

| Tip | Why | |-----|-----| | Give specific roles, not generic ones | "Senior Research Analyst" > "Researcher" | | Write detailed backstories | They shape the agent's behavior significantly | | Set clear goals | The agent optimizes toward this objective | | Limit delegation | Only enable it when collaboration is needed | | Set max_iter | Prevents agents from looping endlessly |

Step 3: Define Tasks#

Tasks define what each agent should accomplish:

# Task 1: Research
research_task = Task(
    description="""Research the topic: {topic}

    Your research should cover:
    1. Current state and recent developments (last 6 months)
    2. Key players and their approaches
    3. Benefits, risks, and limitations
    4. Real-world examples and case studies
    5. Expert opinions and predictions

    Find at least 5 authoritative sources.
    Cross-reference all major claims across sources.""",
    expected_output="""A comprehensive research brief with:
    - Executive summary (3-4 sentences)
    - Key findings organized by theme
    - Source list with URLs
    - Data points and statistics
    - Identified knowledge gaps""",
    agent=researcher
)

# Task 2: Write article
writing_task = Task(
    description="""Using the research brief provided, write a
    comprehensive article about {topic}.

    Requirements:
    - Engaging introduction with a hook
    - Clear section headings
    - Practical examples and actionable advice
    - Data and statistics to support claims
    - Conclusion with key takeaways
    - 1500-2000 words""",
    expected_output="""A polished article in markdown format with:
    - Title and subtitle
    - Introduction, body sections, conclusion
    - Inline citations referencing the research
    - Practical takeaways for the reader""",
    agent=writer,
    context=[research_task]  # Writer receives researcher's output
)

# Task 3: Edit
editing_task = Task(
    description="""Review and improve the article draft.

    Check for:
    1. Factual accuracy β€” verify claims against the research
    2. Logical flow β€” ensure sections connect naturally
    3. Clarity β€” simplify complex sentences
    4. Grammar and style β€” professional tone, active voice
    5. Completeness β€” all research findings are covered

    Make direct edits, not suggestions.""",
    expected_output="""The final, publication-ready article with:
    - All factual errors corrected
    - Improved clarity and flow
    - Professional formatting
    - Editor notes on any major changes""",
    agent=editor,
    context=[research_task, writing_task]  # Editor sees both
)

Context Flow#

context is how information flows between tasks. In this example:

Research Task β†’ (output feeds into) β†’ Writing Task
Research Task + Writing Task β†’ (both feed into) β†’ Editing Task

Step 4: Assemble and Run the Crew#

# Create the crew
crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    process=Process.sequential,  # Tasks run in order
    verbose=True
)

# Run the crew
result = crew.kickoff(
    inputs={"topic": "AI agents in enterprise customer service"}
)

print("=" * 50)
print("FINAL OUTPUT:")
print("=" * 50)
print(result)

Process Types#

| Process | How it works | Best for | |---------|-------------|----------| | sequential | Tasks run one after another | Linear workflows | | hierarchical | A manager agent delegates tasks | Complex, dynamic workflows |

Hierarchical Process Example#

from crewai import Crew, Process

# Manager-driven crew
crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    process=Process.hierarchical,
    manager_llm=ChatOpenAI(model="gpt-4o", temperature=0),
    verbose=True
)

In hierarchical mode, a manager agent decides task order and reassigns work if quality is insufficient.

Step 5: Add Custom Tools#

Create domain-specific tools for your agents:

from crewai_tools import BaseTool

class CompanyDatabaseTool(BaseTool):
    name: str = "Company Database Lookup"
    description: str = (
        "Search our internal company database for information "
        "about products, policies, and case studies. Input should "
        "be a search query string."
    )

    def _run(self, query: str) -> str:
        # In production, this queries your actual database
        database = {
            "case studies": [
                "Acme Corp reduced support tickets by 40% with "
                "AI agents",
                "TechStart improved response time from 4h to "
                "15min using CrewAI"
            ],
            "products": [
                "AgentHub: Enterprise AI agent platform",
                "CrewDeploy: Production deployment for CrewAI"
            ]
        }

        results = []
        for key, values in database.items():
            if key in query.lower():
                results.extend(values)

        return "\n".join(results) if results else "No results found."

# Attach to agent
researcher_with_db = Agent(
    role="Senior Research Analyst",
    goal="Discover comprehensive information using both web "
         "search and internal databases",
    backstory="...",
    tools=[search_tool, CompanyDatabaseTool()],
    verbose=True
)

Step 6: Production Configuration#

Environment Configuration#

import os

crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    process=Process.sequential,
    verbose=os.getenv("CREWAI_VERBOSE", "false").lower() == "true",
    memory=True,  # Enable crew memory across runs
    cache=True,   # Cache tool results to reduce API calls
    max_rpm=30,   # Rate limit: max 30 requests per minute
)

Output Handling#

# Save output to file
result = crew.kickoff(inputs={"topic": "AI agents in sales"})

with open("output/article.md", "w") as f:
    f.write(str(result))

# Access individual task outputs
for task_output in crew.tasks:
    print(f"Task: {task_output.description[:50]}...")
    print(f"Output: {task_output.output}")
    print("---")

Real-World Use Cases for CrewAI#

| Use Case | Agents | Flow | |----------|--------|------| | Content pipeline | Researcher β†’ Writer β†’ Editor | Sequential | | Lead qualification | Enricher β†’ Scorer β†’ Router | Sequential | | Customer support | Triager β†’ Specialist β†’ QA | Hierarchical | | Code review | Analyzer β†’ Reviewer β†’ Reporter | Sequential | | Market research | Searcher β†’ Analyst β†’ Strategist | Hierarchical |

Common Mistakes to Avoid#

  1. Agents with overlapping roles: Each agent should have a clear, distinct responsibility
  2. Vague task descriptions: Be specific about inputs, outputs, and quality criteria
  3. Missing context links: Ensure each task receives the outputs it needs
  4. No iteration limits: Always set max_iter to prevent runaway agents
  5. Over-delegation: Start with sequential processes; move to hierarchical only when necessary

Next Steps#


Frequently Asked Questions#

CrewAI vs. LangChain β€” which should I choose?#

Use LangChain for single-agent workflows with tool access. Use CrewAI when you need multiple specialized agents collaborating on a task. They're complementary β€” CrewAI can even use LangChain tools internally. See our LangChain tutorial for comparison.

How much does CrewAI cost to run?#

CrewAI itself is open source and free. Costs come from LLM API calls. A 3-agent sequential crew typically makes 6-15 LLM calls per run. With GPT-4o, expect $0.10-0.50 per crew execution depending on task complexity. Use caching and rate limiting to optimize costs.

Can I use local LLMs with CrewAI?#

Yes. CrewAI supports any LLM provider compatible with LiteLLM, including Ollama for local models. Set the model in your agent configuration. Be aware that smaller models may struggle with complex reasoning and delegation tasks.

How do I handle failures in a crew?#

CrewAI has built-in retry logic. For custom error handling, wrap crew.kickoff() in try/except blocks and use human_input=True on critical tasks to request human review when the agent is uncertain. You can also set up fallback agents for critical tasks.