Enterprise DNA

Omni by Enterprise DNA

Enterprise DNA Resources

Step-by-step how-tos. Practical AI operating-system thinking for owners, operators, and teams doing real work.

220k+

Data professionals

Omni

AI agents and apps

Audit

Map the manual work

Guide Intermediate General

CrewAI Tutorial Build a Working Multi-Agent Workflow

Practical CrewAI walkthrough covering setup, a multi-agent example, key settings, and where the framework helps or breaks down in production.

Sam McKay |
CrewAI Tutorial Build a Working Multi-Agent Workflow

What CrewAI actually is

CrewAI is a Python framework that orchestrates multiple LLM-powered agents to work on a shared task. The marketing copy frames it as AI teams or collaborative intelligence, but the technical reality is more grounded. It is a task routing layer on top of a language model, where each agent is a separate LLM call wrapped in a ReAct-style loop, with role-based system prompts and optional tool access.

There are four primitives you work with. An Agent has a role, a goal, a backstory, an LLM, and a list of tools. A Task is a unit of work with a description, an expected output, and the agent assigned to it. A Crew is a container that holds agents and tasks plus a Process. A Process describes how tasks flow between agents, either sequentially, hierarchically with a manager agent, or via a consensus mechanism in newer versions.

Each agent is not a separate model. It is the same underlying LLM called with different system prompts and different tool sets. The framework manages the conversation context between agents and handles the tool execution loop. That distinction matters because it tells you where the real cost lives, in token consumption, and where the real failure modes live, in prompt drift and context bloat.

CrewAI is open source under the MIT license and ships as a pip-installable package. The current version runs against OpenAI, Anthropic, Google, and any OpenAI-compatible endpoint including local models served through Ollama or vLLM.

Setup and authentication

The starting point is straightforward. You need Python 3.10 or higher, an API key for at least one model provider, and a clean virtual environment. The package itself is small and pulls in only what it needs.

Install it with pip install crewai. If you plan to use the optional CLI scaffolding, install CrewAI with the tools extra, which gives you the crewai command. Set your model API key in your shell environment or a .env file. CrewAI reads OPENAI_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_BASE for custom endpoints automatically through its config layer.

The quickest path to a working project is crewai create crew my_project. This generates a folder with a main.py, a crew definition file, a tasks file, an agents file, a pyproject.toml, and a .env template. You fill in your API key, edit the agents and tasks to match your use case, and run python main.py from the project root. The scaffold is opinionated but it removes a lot of boilerplate you would otherwise write by hand.

For local model support, point OPENAI_API_BASE to your local server and set OPENAI_MODEL_NAME to whatever your local endpoint exposes. A typical setup pairs CrewAI with Ollama running llama3 or qwen2.5 on a developer laptop, and works without rate limits but with noticeably slower agent loops.

First working example

The simplest meaningful crew has two agents in a sequential process. A research agent gathers information, and a writer agent produces a final summary. Each agent has a tight role and one clear job.

Define a researcher agent with the goal of finding the three most important facts about a given topic and a backstory framing it as an experienced analyst. Give it a search tool, the built-in SerperDevTool or SerpAPI tool, plus a web scraper if you need page content. Define a writer agent with the goal of turning the research output into a 300-word briefing, and a backstory that emphasizes clarity and structure.

Define two tasks. The research task tells the agent to produce a structured list of findings. The writing task takes the research output as context and produces the final brief. The expected_output field on each task is what the framework uses to validate completion, so write it as a concrete schema or a clear format description rather than a vague instruction.

When you run the crew, the researcher runs first, finishes, and its output is appended to the shared context. The writer then receives that context and produces the briefing. The whole run is a synchronous Python call that returns a CrewOutput object. You can print it, write it to a file, or pipe it into the next step of a larger pipeline.

A minimal main.py looks roughly like this. You import Agent, Task, Crew, and Process, instantiate the two agents, instantiate the two tasks, and pass them into a Crew with process=Process.sequential. Calling crew.kickoff(inputs={“topic”: “your topic here”}) returns the final result. The verbose flag, when set to True, prints every LLM call and tool invocation to the console, which is what you want during development.

This example is small but it captures the core pattern. You compose roles, you compose tasks, you set a process, and the framework does the orchestration. Everything else in this guide is variation on that loop.

Key settings that matter

The dials most people miss are the ones that determine whether a crew runs in 20 seconds or burns through 5 dollars of API spend. Verbose mode is the first. Setting verbose=True logs every LLM call, tool invocation, and intermediate thought. It is essential for debugging and ruinous for production logs. Use verbose=True when developing and verbose=False in any scheduled or batch context.

Memory is the second big dial. CrewAI supports short-term memory, which is conversation context within a run, long-term memory persisted across runs through a vector store, and entity memory that builds a structured knowledge graph of people, places, and concepts the crew encounters. Short-term memory is on by default. Long-term memory is opt-in and requires you to configure a storage backend, typically Chroma, Qdrant, or any other vector store supported by the underlying memory library. Entity memory adds cost and latency but produces noticeably better continuity in long-running workflows.

The process type changes behavior more than most settings. Sequential is predictable and easy to debug. Hierarchical introduces a manager agent that decides task assignment and can re-delegate work, which sounds powerful but in practice adds latency and one more place for the LLM to go off-script. The consensus process is newer and works well for tasks where multiple agents should vote on an answer, though it roughly triples the token cost per decision.

Max iterations per task controls the ReAct loop termination. The default is around 15, which is usually too high for well-defined tasks. Set it to 3 or 5 for deterministic tools, and reserve higher values for tasks where the agent genuinely needs to retry on tool errors. There is also a step callback hook you can wire into the process to inspect or transform intermediate outputs without modifying the agent prompts.

Delegation is enabled per agent through allow_delegation=True. When on, the agent can hand off work to other agents in the same crew. This is the mechanism that makes hierarchical process actually work, and it is also the mechanism that produces the longest, hardest-to-trace execution paths. Default to off unless you have a specific reason for one agent to route work to another.

Where it shines

CrewAI is at its best on tasks that benefit from role specialization and structured handoffs. A research and writing pipeline is the canonical example because the two roles genuinely require different prompts, different tools, and different output formats. The same pattern works for data enrichment, where a finder agent locates records and a validator agent checks them, or for code review, where a writer agent drafts a fix and a reviewer agent critiques it.

It also works well for content workflows with explicit review stages. A draft agent produces a blog post, an editor agent tightens the prose, and a fact-checker agent flags anything unsupported. Sequential process handles this cleanly. Each stage has a verifiable output and the boundaries between roles map to real human workflows.

For batch jobs that