How to Build CrewAI Agents: Complete Tutorial
CrewAI gives you a Python framework for assembling multi-agent systems where each agent has a defined role, goal, and set of tools. This tutorial walks through every step: installing the CLI, configuring agents in YAML, defining tasks, wiring up a crew, adding built-in and custom tools, and orchestrating complex pipelines with Flows. By the end, you will have a working multi-agent application that you can extend for research, content generation, or data analysis workflows.
What you will build: A two-agent research crew that searches the web, analyzes results, and produces a structured report, all running from the CrewAI CLI.
Prerequisites
Before installing CrewAI, confirm that your environment meets these requirements. CrewAI enforces strict Python version bounds and depends on compiled C extensions, so skipping any prerequisite will cause installation failures.
Install CrewAI
CrewAI uses uv as its default package manager. Install uv first, then install the CrewAI CLI as a global tool.
Step 1: Install uv
Step 2: Install CrewAI CLI
Step 3: Scaffold a new crew project
This generates the full project structure: src/my_research_crew/config/agents.yaml, tasks.yaml, crew.py, main.py, a .env file for API keys, and directories for custom tools and knowledge files.
Step 4: Install dependencies and run
Alternative install: If you prefer pip over uv, run pip install 'crewai[a2a]' to get CrewAI with all optional dependencies.
Define Agents
An Agent in CrewAI represents a single autonomous worker with a specific role. Each agent gets three required personality parameters (essentially prompt engineering via YAML) that shape how the LLM responds: role, goal, and backstory.
The YAML-first approach keeps agent definitions separate from your Python logic. Edit src/my_research_crew/config/agents.yaml:
Delegation behavior: By default, allow_delegation is True when a crew has multiple agents. Set it to false on worker agents (like the writer above) to prevent infinite delegation loops where agents keep passing tasks back and forth.
Agentic AI Compliance Assessment
Compliance checklist for autonomous agent deployments
Download Free →Define Tasks
A Task tells an agent exactly what to do and what output format to produce. Each task needs a description, an expected_output, and an assigned agent. In sequential mode, every task must have an agent assigned.
Edit src/my_research_crew/config/tasks.yaml:
| Parameter | Required | Purpose |
|---|---|---|
| description | Yes | What the agent should accomplish |
| expected_output | Yes | Format and structure of the result |
| agent | Sequential: Yes | Which agent handles this task |
| output_file | No | Save result to disk automatically |
| output_json | No | Parse output as JSON (Pydantic model) |
| context | No | Reference outputs from other tasks |
| guardrail | No | Validation function that can reject and retry |
Assemble a Crew
The Crew object brings agents and tasks together, selects the execution process, and provides the kickoff() method that runs everything. Edit crew.py:
Sequential vs. Hierarchical: Process.sequential (the default) runs tasks in the order listed, passing each output to the next. Process.hierarchical uses a manager agent (or manager_llm) to dynamically delegate tasks across agents.
The kickoff() method accepts an inputs dictionary. Any {placeholder} in agent goals or task descriptions gets replaced with the corresponding value from this dictionary. The return value is a CrewOutput object with properties for .raw, .json, .pydantic, and .token_usage.
Add Tools
Tools give agents the ability to interact with the outside world. CrewAI ships with built-in tools for web search, scraping, file operations, and code execution. You can also write custom tools by inheriting from BaseTool.
Built-in tools
| Tool | What It Does | Requires |
|---|---|---|
| SerperDevTool | Google Search via Serper.dev API, returns structured JSON | SERPER_API_KEY |
| ScrapeWebsiteTool | Extracts content from web pages | None |
| FileReadTool | Reads and extracts data from local files | None |
| CodeInterpreterTool | Runs Python in a sandboxed environment | None |
Custom tools
Place custom tools in the tools/ directory. Each tool must inherit from BaseTool, define a name and description, and implement the _run method:
Then assign the tool to an agent: tools=[SentimentAnalysisTool()]. The agent reads the tool's description and _run method signature to decide when and how to call it, so detailed docstrings and type hints are important for accurate tool invocation.
Orchestrate with Flows
Flows provide a deterministic, event-driven orchestration layer for situations where a single crew is not enough. This is where CrewAI transitions from a framework into a full agentic AI platform. Use Flows when you need to chain multiple crews, add conditional routing, or maintain structured state across pipeline stages.
A Flow class uses three decorators to control execution:
- @start() marks the entry point that runs first
- @listen() triggers a method when a previous method completes
- @router() sends execution down different paths based on conditions
State management uses Pydantic BaseModel classes, giving you typed attributes with validation. Each flow method can read and update self.state to pass data between stages without relying on LLM memory.
Limitations and Gotchas
CrewAI handles a lot of orchestration automatically, but there are tradeoffs worth knowing before you commit to a production deployment.
Troubleshooting
These are the most common issues encountered during CrewAI setup and their fixes.
Video Resources
Go Deeper
Resources from across Tech Jacks Solutions
Agent Frameworks Compared
Side-by-side analysis of LangChain, CrewAI, AutoGen, and more
Agent Threat Landscape
Security risks specific to autonomous AI agents
FREEAgentic AI Compliance Assessment
Compliance checklist for autonomous agent deployments
PREMIUMPre-Deployment Safety Gate
27-point checklist before any AI tool goes live
IAPP AIGP Certification
The AI governance certification for privacy professionals