Introduction

Multi-agent AI systems represent the next evolution in AI automation. Instead of a single AI handling everything, specialized agents collaborate — each with distinct roles, goals, and tools — to solve complex tasks more effectively.

CrewAI is a Python framework that makes building these systems straightforward. In this tutorial, you'll build a research crew that automatically investigates a technology topic, analyzes market trends, and produces a professional report.

What You'll Learn

  • Set up a CrewAI project from scratch
  • Define agents with specialized roles and tools
  • Create tasks with dependencies and expected outputs
  • Orchestrate multi-agent workflows
  • Integrate web search and custom tools
  • Prerequisites

  • Python 3.10+
  • OpenAI API key
  • Basic Python knowledge
  • ---

    Step 1: Environment Setup

    Create a new project and install dependencies:

    mkdir tech-research-crew && cd tech-research-crew
    

    python -m venv venv

    source venv/bin/activate # Windows: venv\Scripts\activate

    pip install crewai crewai-tools langchain-openai python-dotenv

    Create a .env file for your API keys:

    # .env
    

    OPENAI_API_KEY=sk-your-api-key-here

    SERPER_API_KEY=your-serper-key-here # For web search

    ---

    Step 2: Define Your Agents

    Create agents.py — each agent has a role, goal, and backstory that guides its behavior:

    # agents.py
    

    from crewai import Agent

    from crewai_tools import SerperDevTool, WebsiteSearchTool

    # Tools

    search_tool = SerperDevTool()

    web_tool = WebsiteSearchTool()

    # Agent 1: Research Specialist

    researcher = Agent(

    role="Senior Technology Researcher",

    goal="Find comprehensive, accurate information about emerging technologies",

    backstory="""You are a veteran technology researcher with 15 years of

    experience at top consulting firms. You excel at finding reliable sources,

    identifying key trends, and separating hype from substance.""",

    tools=[search_tool, web_tool],

    verbose=True,

    allow_delegation=False,

    max_iter=5,

    )

    # Agent 2: Data Analyst

    analyst = Agent(

    role="Technology Market Analyst",

    goal="Analyze technology trends and provide data-driven insights",

    backstory="""You are a data-driven analyst who specializes in technology

    market analysis. You transform raw research into actionable insights,

    identify patterns, and make evidence-based predictions.""",

    verbose=True,

    allow_delegation=False,

    )

    # Agent 3: Technical Writer

    writer = Agent(

    role="Senior Technical Writer",

    goal="Create clear, engaging, and well-structured technical reports",

    backstory="""You are an award-winning technical writer known for making

    complex topics accessible. You create reports that executives and

    engineers alike find valuable.""",

    verbose=True,

    allow_delegation=False,

    )

    ---

    Step 3: Create Tasks

    Create tasks.py — tasks define what each agent should accomplish:

    # tasks.py
    

    from crewai import Task

    from agents import researcher, analyst, writer

    def create_research_tasks(topic: str):

    """Create a sequence of research tasks for the given topic."""

    # Task 1: Research

    research_task = Task(

    description=f"""Conduct thorough research on: {topic}

    Your research should cover:

    1. Current state of the technology

    2. Key players and companies

    3. Recent developments (last 6 months)

    4. Use cases and real-world applications

    5. Technical challenges and limitations

    Provide URLs for all sources.""",

    expected_output="""A detailed research document with:

    - Executive summary (2-3 sentences)

    - Key findings (5-7 bullet points)

    - Detailed sections for each research area

    - Source URLs for verification""",

    agent=researcher,

    )

    # Task 2: Analysis (depends on research)

    analysis_task = Task(

    description=f"""Analyze the research findings on: {topic}

    Based on the research provided, create an analysis that includes:

    1. SWOT analysis of the technology

    2. Market adoption timeline prediction

    3. Comparison with competing technologies

    4. Risk assessment for enterprise adoption

    5. ROI potential for early adopters""",

    expected_output="""A structured analysis document with:

    - SWOT matrix

    - Adoption timeline (with phases)

    - Competitive comparison table

    - Risk matrix (likelihood vs impact)

    - ROI projections with assumptions""",

    agent=analyst,

    context=[research_task], # This task depends on research

    )

    # Task 3: Report Writing (depends on both)

    writing_task = Task(

    description=f"""Write a professional technical report on: {topic}

    Using the research and analysis provided, create a report that:

    1. Opens with an executive summary

    2. Presents findings in a logical flow

    3. Includes the analytical frameworks

    4. Provides actionable recommendations

    5. Concludes with next steps

    Format: Markdown with clear headers, bullet points, and tables.""",

    expected_output="""A polished markdown report (2000-3000 words) with:

    - Title and date

    - Executive summary

    - Research findings

    - Analysis and insights

    - Recommendations (prioritized)

    - Appendix with sources""",

    agent=writer,

    context=[research_task, analysis_task],

    output_file="output/report.md", # Auto-save to file

    )

    return [research_task, analysis_task, writing_task]

    ---

    Step 4: Assemble the Crew

    Create main.py — the orchestration layer:

    # main.py
    

    import os

    from dotenv import load_dotenv

    from crewai import Crew, Process

    from agents import researcher, analyst, writer

    from tasks import create_research_tasks

    load_dotenv()

    os.makedirs("output", exist_ok=True)

    def run_research_crew(topic: str):

    """Run the research crew on a given topic."""

    # Create tasks

    tasks = create_research_tasks(topic)

    # Assemble the crew

    crew = Crew(

    agents=[researcher, analyst, writer],

    tasks=tasks,

    process=Process.sequential, # Tasks run in order

    verbose=True,

    memory=True, # Enable memory between tasks

    max_rpm=10, # Rate limit API calls

    share_crew=False,

    )

    # Execute

    result = crew.kickoff()

    print("\n" + "=" * 60)

    print("CREW EXECUTION COMPLETE")

    print("=" * 60)

    print(f"\nReport saved to: output/report.md")

    print(f"\nTokens used: {crew.usage_metrics}")

    return result

    if __name__ == "__main__":

    topic = input("Enter research topic: ") or "AI Agents in Enterprise"

    result = run_research_crew(topic)

    print(f"\nFinal Output:\n{result}")

    ---

    Step 5: Add Custom Tools

    Extend your agents with custom tools. Create tools.py:

    # tools.py
    

    from crewai_tools import tool

    import json

    from datetime import datetime

    @tool("Save JSON Report")

    def save_json_report(content: str, filename: str) -> str:

    """Save structured data as a JSON report file.

    Args:

    content: The report content as a JSON string

    filename: Output filename (without extension)

    """

    try:

    data = json.loads(content)

    except json.JSONDecodeError:

    data = {"raw_content": content}

    report = {

    "generated_at": datetime.now().isoformat(),

    "data": data,

    }

    filepath = f"output/{filename}.json"

    with open(filepath, "w") as f:

    json.dump(report, f, indent=2)

    return f"Report saved to {filepath}"

    @tool("GitHub Trending")

    def get_github_trending(language: str = "python") -> str:

    """Fetch trending repositories from GitHub for a given language.

    Args:

    language: Programming language to filter by

    """

    import urllib.request

    url = f"https://api.github.com/search/repositories?q=language:{language}&sort=stars&order=desc&per_page=5"

    req = urllib.request.Request(url, headers={"Accept": "application/vnd.github.v3+json"})

    with urllib.request.urlopen(req) as response:

    data = json.loads(response.read())

    repos = []

    for repo in data.get("items", [])[:5]:

    repos.append({

    "name": repo["full_name"],

    "stars": repo["stargazers_count"],

    "description": repo["description"],

    "url": repo["html_url"],

    })

    return json.dumps(repos, indent=2)

    Then add tools to your agents:

    # In agents.py, add:
    

    from tools import save_json_report, get_github_trending

    researcher = Agent(

    ...

    tools=[search_tool, web_tool, get_github_trending],

    )

    writer = Agent(

    ...

    tools=[save_json_report],

    )

    ---

    Step 6: Advanced — Hierarchical Process

    For complex workflows, use a manager agent that delegates:

    # hierarchical_crew.py
    

    from crewai import Crew, Process, Agent

    from langchain_openai import ChatOpenAI

    # Manager LLM (uses a more capable model)

    manager_llm = ChatOpenAI(model="gpt-4o", temperature=0.1)

    crew = Crew(

    agents=[researcher, analyst, writer],

    tasks=tasks,

    process=Process.hierarchical, # Manager delegates

    manager_llm=manager_llm,

    verbose=True,

    )

    result = crew.kickoff()

    In hierarchical mode, CrewAI creates a manager agent that:

  • Decides which agent handles each task
  • Can reassign work if results are unsatisfactory
  • Coordinates information flow between agents
  • ---

    Step 7: Run and Test

    # Run the crew
    

    python main.py

    # Example output:

    # > Agent: Senior Technology Researcher

    # > Task: Conducting research on AI Agents in Enterprise...

    # > Using tool: Search the internet

    # > ...

    # > Agent: Technology Market Analyst

    # > Task: Analyzing research findings...

    # > ...

    # > Agent: Senior Technical Writer

    # > Task: Writing professional report...

    # > ...

    # CREW EXECUTION COMPLETE

    # Report saved to: output/report.md

    ---

    Project Structure

    tech-research-crew/
    

    ├── .env # API keys

    ├── agents.py # Agent definitions

    ├── tasks.py # Task definitions

    ├── tools.py # Custom tools

    ├── main.py # Entry point

    ├── hierarchical_crew.py # Advanced example

    ├── output/

    │ └── report.md # Generated report

    └── requirements.txt

    requirements.txt:

    crewai>=0.28.0
    

    crewai-tools>=0.1.0

    langchain-openai>=0.0.5

    python-dotenv>=1.0.0

    ---

    Key Concepts Recap

    | Concept | Description |

    |---------|-------------|

    | Agent | An autonomous AI entity with a role, goal, and tools |

    | Task | A specific assignment with expected output and context |

    | Crew | A group of agents working together on tasks |

    | Process | Execution strategy (sequential or hierarchical) |

    | Tools | Functions agents can use to interact with the world |

    | Memory | Shared context that persists across task execution |

    | Delegation | Agents can request help from other agents |

    ---

    Best Practices

    1. Specific roles — Give agents narrow, well-defined roles rather than broad ones

    2. Clear expectations — Define expected_output precisely so agents know what success looks like

    3. Task dependencies — Use context to chain tasks and pass information

    4. Rate limiting — Set max_rpm to avoid hitting API rate limits

    5. Error handling — Set max_iter to prevent infinite loops

    6. Model selection — Use GPT-4o for complex reasoning, GPT-3.5 for simple tasks

    ---

    Next Steps

  • Add a QA reviewer agent to check report quality
  • Integrate Slack/email to deliver reports automatically
  • Build a FastAPI endpoint to trigger research via API
  • Add vector memory for persistent knowledge across runs
  • Explore LangGraph for more complex agent orchestration patterns
  • ---

    Resources

  • CrewAI Documentation
  • CrewAI GitHub Repository
  • CrewAI Examples
  • LangChain Integration Guide

Published by Techsfree — Your partner in technology innovation.