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
- Python 3.10+
- OpenAI API key
- Basic Python knowledge
Prerequisites
---
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:
---
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
---
Resources
Published by Techsfree — Your partner in technology innovation.