Course: Master Course · Deep-Dive: DD-12 · Duration: 45 min · Prerequisites: Modules 0–12, DD-01–11
45,900+ stars. Most accessible multi-agent framework. Role-based sequential/parallel crews. 1.8s avg latency. Large community.
CrewAI is the role-based multi-agent framework — the most accessible entry point into multi-agent orchestration. Where LangGraph (DD-10) makes you draw explicit nodes and edges, and the Agents SDK (DD-11) hands you handoffs and agents-as-tools as primitives, CrewAI asks you to do something far more intuitive: describe the team you wish you had, and it runs.
| Metric | Value |
|---|---|
| Stars | 45,900+ |
| Language | Python |
| Typical latency | ~1.8s avg per crew kickoff |
| Orchestration model | Role-driven (sequential or concurrent processes) |
| Core abstractions | Crew, Agent, Task |
| Tool sharing | Per-agent; tools attach to agents, not the crew |
| Memory | Short-term (crew-scoped), long-term, entity memory (opt-in) |
| Sandbox | None (you bring your own — Docker, E2B, etc.) |
A Crew is a set of Agents (each defined by role, goal, backstory, and an optional llm) and a list of Tasks (each assigned to an agent, with expected output and optional context dependencies). crewai kickoff reads the process type (sequential or concurrent) and dispatches. That is the entire mental model — and the entire reason it has 45k stars.
Agent — the unit of role. An agent is its system prompt assembled from role ("Senior Researcher"), goal ("find the most relevant sources"), backstory ("20 years at the New York Times, ruthless about provenance"), plus the tool set it's allowed to call. Role is the system prompt. This is the load-bearing insight: CrewAI does not give you a raw system-prompt string; it gives you a templated one whose fields are role/goal/backstory. The template is the framework's opinion.Task — the unit of work. A task has a description, an assigned_agent, an expected_output, and optional context (other tasks whose output feeds this one). Tasks carry the dependency graph implicitly: if Task B lists Task A in context, A runs first and its result is injected into B's prompt.Crew — the unit of orchestration. The crew holds the agents, the tasks, and the process strategy. It owns the loop, the memory, and the kickoff entry point.sequential: concurrent (hierarchical):
Task1 → Task2 → Task3 Manager agent decomposes, dispatches
(output chains forward) workers run, manager synthesizes
The crucial contrast: LangGraph makes the graph a first-class object you can visualize, checkpoint, and edit. CrewAI's graph emerges from task context references and the process type — easier to declare, harder to audit. For a 3-agent crew this is a feature; for a 15-agent crew it becomes a liability (the implicit dependency graph is invisible).
CrewAI's role-to-prompt mapping is opinionated and worth reading in source. Each agent's system prompt is assembled roughly as:
You are {role}.
Your personal goal is: {goal}
Your backstory: {backstory}
You have access to the following tools: {tool_names_and_schemas}
...
This is Module 12 (Prompt Assembly) applied at the agent granularity rather than the harness granularity. The framework's value proposition is that you never hand-author a system prompt — you fill in three fields and the template does the rest. The risk is the inverse: when the template is wrong for your use case, you are fighting the framework's opinion rather than editing a string.
Tools attach to agents (Agent(tools=[...])), not to the crew. This means each agent's capability surface is scoped at declaration time — which is, structurally, a form of Module 2.4 per-agent capability scoping. The catch: there is no enforcement that two agents can't share the same dangerous tool, and no built-in mechanism to prevent an agent from passing instructions to a downstream agent that would cause it to call a tool the upstream agent doesn't have. Per-agent scoping exists by construction; per-agent capability isolation does not.
CrewAI offers three opt-in memory tiers:
This maps cleanly to Module 4's memory tiers. The notable design choice is that memory is crew-scoped, not agent-scoped — all agents in a crew share the same memory store. That is convenient for collaboration but eliminates the per-agent memory isolation that Module 4.3 (write-gating) would want. A compromised agent can write into shared memory that every other agent later reads.
Right: work that genuinely decomposes along role lines — research-then-write, draft-then-review, plan-then-execute. When the subtasks have clean handoffs and each benefits from a distinct persona/policy, the role abstraction earns its keep. The classic example is "research a topic, then write a blog post, then edit it" — three roles, three skill profiles, sequential dependencies. CrewAI's mental model fits this almost perfectly.
Wrong: work that is really a single reasoning thread wearing different hats. If Task 2 needs everything Task 1 produced plus the ability to revise it, you don't have two agents — you have one agent with a checkpoint. Spinning it into a crew adds latency, token cost (each agent re-reads context), and a new injection surface (the task-output handoff) without adding capability. The temptation in CrewAI is to role-ify everything because the abstraction is so pleasant; the cost shows up in the bill and in the attack surface.
The diagnostic question: could one agent with one system prompt and a subtask list do this? If yes, you don't need a crew. If the roles genuinely carry different policies, tool sets, or verification duties, the crew earns its overhead.
| Module | Pattern | Tradeoff accepted |
|---|---|---|
| 1 Execution Loop | Conversation-driven, role-per-turn | Each agent re-reads shared context; token cost scales with crew size |
| 1.3 Subagents | Sequential crews + hierarchical manager | Emergent graph is hard to audit at scale |
| 2 Tools | Per-agent attachment | No capability isolation between agents |
| 4 Memory | Crew-scoped shared store | No per-agent write isolation (Module 4.3) |
| 5 Sandboxing | None | You bring Docker/E2B |
| 8 State | Limited checkpointing | Long crews don't resume cleanly |
| 10 Observability | Crew run logs | Below the structured-event bar of DD-21/Mastra |
Three decisions I agree with:
Three decisions I would make differently:
| Module | Score | Notes |
|---|---|---|
| M1 Loop | 3/5 | Role-per-turn is clean but token-heavy; no steering mid-crew |
| M1.3 Subagents | 4/5 | Sequential crews are a textbook multi-agent pattern; hierarchical is shallower than DD-06 |
| M2 Tools | 3/5 | Per-agent attachment is good; no isolation enforcement |
| M3 Context | 2/5 | Relies on each agent re-reading shared context; no compaction |
| M4 Memory | 3/5 | Three tiers exist; crew-scoping forfeits write isolation |
| M5 Sandbox | 1/5 | None. Bring your own |
| M6 Permission | 2/5 | No per-action gates |
| M7 Errors | 2/5 | Basic; a failing task can sink a crew |
| M8 State | 2/5 | Limited checkpointing; long crews don't resume |
| M9 Verification | 1/5 | None built-in |
| M10 Observability | 2/5 | Run logs, not structured events |
| M11 Security | 1/5 | No SECURITY model; shared memory is an attack surface |
CrewAI optimizes for accessibility — the fastest way to stand up a multi-agent crew with role-based task assignment, and the most legible mental model ("describe the team") in the multi-agent category. It sacrifices production-readiness: no sandboxing, crew-scoped shared memory with no write isolation, limited state, and run logs below the structured-event floor. Build on CrewAI to prototype multi-agent patterns and to teach orchestration; move to LangGraph (DD-10) when the dependency graph needs to be explicit and auditable, or to the Agents SDK (DD-11) when you need sandboxing and handoffs as primitives.
Role-based crews inherit all agents' combined permissions: a compromised agent can influence downstream agents via task outputs (indirect prompt injection across the handoff boundary) and can poison the crew-scoped shared memory every other agent later reads. Per-agent capability scoping (Module 2.4) exists by construction but per-agent isolation does not; the shared memory tier makes Module 4.3's write-gating defense unavailable by default. Treat every task-output handoff as an untrusted-content boundary (Module 2.4 Vector 1).
context references is invisible past ~5 tasks; offer a LangGraph-style visualization/checkpoint path.# Deep-Dive DD-12 — CrewAI: Role-Based Multi-Agent
**Course**: Master Course · **Deep-Dive**: DD-12 · **Duration**: 45 min · **Prerequisites**: Modules 0–12, DD-01–11
> *45,900+ stars. Most accessible multi-agent framework. Role-based sequential/parallel crews. 1.8s avg latency. Large community.*
---
## The Subject
CrewAI is the **role-based multi-agent framework** — the most accessible entry point into multi-agent orchestration. Where LangGraph (DD-10) makes you draw explicit nodes and edges, and the Agents SDK (DD-11) hands you handoffs and agents-as-tools as primitives, CrewAI asks you to do something far more intuitive: *describe the team you wish you had, and it runs.*
| Metric | Value |
| --- | --- |
| Stars | 45,900+ |
| Language | Python |
| Typical latency | ~1.8s avg per crew kickoff |
| Orchestration model | Role-driven (sequential or concurrent processes) |
| Core abstractions | `Crew`, `Agent`, `Task` |
| Tool sharing | Per-agent; tools attach to agents, not the crew |
| Memory | Short-term (crew-scoped), long-term, entity memory (opt-in) |
| Sandbox | None (you bring your own — Docker, E2B, etc.) |
A `Crew` is a set of `Agent`s (each defined by `role`, `goal`, `backstory`, and an optional `llm`) and a list of `Task`s (each assigned to an agent, with expected output and optional context dependencies). `crewai kickoff` reads the process type (`sequential` or `concurrent`) and dispatches. That is the entire mental model — and the entire reason it has 45k stars.
## Architecture
### The three primitives
1. **`Agent`** — the unit of role. An agent is its system prompt assembled from `role` ("Senior Researcher"), `goal` ("find the most relevant sources"), `backstory` ("20 years at the New York Times, ruthless about provenance"), plus the tool set it's allowed to call. *Role is the system prompt.* This is the load-bearing insight: CrewAI does not give you a raw system-prompt string; it gives you a templated one whose fields are role/goal/backstory. The template is the framework's opinion.
2. **`Task`** — the unit of work. A task has a `description`, an `assigned_agent`, an `expected_output`, and optional `context` (other tasks whose output feeds this one). Tasks carry the dependency graph implicitly: if Task B lists Task A in `context`, A runs first and its result is injected into B's prompt.
3. **`Crew`** — the unit of orchestration. The crew holds the agents, the tasks, and the `process` strategy. It owns the loop, the memory, and the kickoff entry point.
### Two orchestration modes
```
sequential: concurrent (hierarchical):
Task1 → Task2 → Task3 Manager agent decomposes, dispatches
(output chains forward) workers run, manager synthesizes
```
- **Sequential** is the default and the well-trodden path. Tasks run in list order; each task's output is appended to a shared context the next agent reads. This is a linear ReAct chain stretched across multiple roles — conceptually close to Module 1's conversation-driven loop, except each turn is owned by a different role-shaped system prompt.
- **Concurrent (hierarchical)** adds a manager agent that decomposes the goal, assigns subtasks to the worker agents, runs them, and synthesizes results. This is closer to the meta-hierarchy in DD-06 (oh-my-opencode's Sisyphus/Prometheus/Atlas/Junior taxonomy) — except CrewAI's manager is implicit and the hierarchy is one level deep, whereas DD-06's is a deliberate multi-tier design.
The crucial contrast: LangGraph makes the graph a first-class object you can visualize, checkpoint, and edit. CrewAI's graph *emerges* from task context references and the process type — easier to declare, harder to audit. For a 3-agent crew this is a feature; for a 15-agent crew it becomes a liability (the implicit dependency graph is invisible).
### How roles map to system prompts
CrewAI's role-to-prompt mapping is opinionated and worth reading in source. Each agent's system prompt is assembled roughly as:
```
You are {role}.
Your personal goal is: {goal}
Your backstory: {backstory}
You have access to the following tools: {tool_names_and_schemas}
...
```
This is Module 12 (Prompt Assembly) applied at the *agent* granularity rather than the harness granularity. The framework's value proposition is that you never hand-author a system prompt — you fill in three fields and the template does the rest. The risk is the inverse: when the template is wrong for your use case, you are fighting the framework's opinion rather than editing a string.
### Tool sharing and the crew boundary
Tools attach to agents (`Agent(tools=[...])`), not to the crew. This means each agent's capability surface is scoped at declaration time — which is, structurally, a form of Module 2.4 per-agent capability scoping. The catch: there is no enforcement that two agents can't share the same dangerous tool, and no built-in mechanism to *prevent* an agent from passing instructions to a downstream agent that would cause it to call a tool the upstream agent doesn't have. Per-agent scoping exists by construction; per-agent *capability isolation* does not.
### Memory model
CrewAI offers three opt-in memory tiers:
- **Short-term** — crew-scoped; recent task outputs are retained for the crew's run.
- **Long-term** — persists across crew runs (backed by a local or remote store).
- **Entity memory** — keyed by named entities (people, orgs, codebases) so an agent can recall facts about a specific subject.
This maps cleanly to Module 4's memory tiers. The notable design choice is that memory is **crew-scoped, not agent-scoped** — all agents in a crew share the same memory store. That is convenient for collaboration but eliminates the per-agent memory isolation that Module 4.3 (write-gating) would want. A compromised agent can write into shared memory that every other agent later reads.
## When role-based multi-agent is right (and wrong)
**Right:** work that genuinely decomposes along role lines — research-then-write, draft-then-review, plan-then-execute. When the subtasks have clean handoffs and each benefits from a distinct persona/policy, the role abstraction earns its keep. The classic example is "research a topic, then write a blog post, then edit it" — three roles, three skill profiles, sequential dependencies. CrewAI's mental model fits this almost perfectly.
**Wrong:** work that is really a single reasoning thread wearing different hats. If Task 2 needs everything Task 1 produced plus the ability to revise it, you don't have two agents — you have one agent with a checkpoint. Spinning it into a crew adds latency, token cost (each agent re-reads context), and a new injection surface (the task-output handoff) without adding capability. The temptation in CrewAI is to role-ify everything because the abstraction is so pleasant; the cost shows up in the bill and in the attack surface.
The diagnostic question: *could one agent with one system prompt and a subtask list do this?* If yes, you don't need a crew. If the roles genuinely carry different policies, tool sets, or verification duties, the crew earns its overhead.
## Phase 3 — Design Decision Audit (selected)
| Module | Pattern | Tradeoff accepted |
| --- | --- | --- |
| 1 Execution Loop | Conversation-driven, role-per-turn | Each agent re-reads shared context; token cost scales with crew size |
| 1.3 Subagents | Sequential crews + hierarchical manager | Emergent graph is hard to audit at scale |
| 2 Tools | Per-agent attachment | No capability isolation between agents |
| 4 Memory | Crew-scoped shared store | No per-agent write isolation (Module 4.3) |
| 5 Sandboxing | None | You bring Docker/E2B |
| 8 State | Limited checkpointing | Long crews don't resume cleanly |
| 10 Observability | Crew run logs | Below the structured-event bar of DD-21/Mastra |
**Three decisions I agree with:**
1. Role as the system-prompt abstraction — the most legible multi-agent mental model in the roster.
2. Sequential as the default — it's the pattern that actually composes for most real workloads.
3. Tools attached to agents, not the crew — structurally gives you per-agent capability scoping for free.
**Three decisions I would make differently:**
1. Make the dependency graph explicit (a la LangGraph) once a crew exceeds ~5 tasks — the emergent graph stops being a convenience and starts being a debugging hazard.
2. Offer agent-scoped memory as an option — crew-scoped shared memory forfeits the Module 4.3 write-gating defense by default.
3. Emit a structured per-agent event stream — CrewAI's run logs are below the observability floor set by DD-14 (Mastra) and DD-21 (Tau).
## Score: 33/60
| Module | Score | Notes |
|---|---|---|
| M1 Loop | 3/5 | Role-per-turn is clean but token-heavy; no steering mid-crew |
| M1.3 Subagents | 4/5 | Sequential crews are a textbook multi-agent pattern; hierarchical is shallower than DD-06 |
| M2 Tools | 3/5 | Per-agent attachment is good; no isolation enforcement |
| M3 Context | 2/5 | Relies on each agent re-reading shared context; no compaction |
| M4 Memory | 3/5 | Three tiers exist; crew-scoping forfeits write isolation |
| M5 Sandbox | 1/5 | None. Bring your own |
| M6 Permission | 2/5 | No per-action gates |
| M7 Errors | 2/5 | Basic; a failing task can sink a crew |
| M8 State | 2/5 | Limited checkpointing; long crews don't resume |
| M9 Verification | 1/5 | None built-in |
| M10 Observability | 2/5 | Run logs, not structured events |
| M11 Security | 1/5 | No SECURITY model; shared memory is an attack surface |
### Architect's Verdict
> *CrewAI optimizes for accessibility — the fastest way to stand up a multi-agent crew with role-based task assignment, and the most legible mental model ("describe the team") in the multi-agent category. It sacrifices production-readiness: no sandboxing, crew-scoped shared memory with no write isolation, limited state, and run logs below the structured-event floor. Build on CrewAI to prototype multi-agent patterns and to teach orchestration; move to LangGraph (DD-10) when the dependency graph needs to be explicit and auditable, or to the Agents SDK (DD-11) when you need sandboxing and handoffs as primitives.*
### MLSecOps Relevance
> *Role-based crews inherit all agents' combined permissions: a compromised agent can influence downstream agents via task outputs (indirect prompt injection across the handoff boundary) and can poison the crew-scoped shared memory every other agent later reads. Per-agent capability scoping (Module 2.4) exists by construction but per-agent isolation does not; the shared memory tier makes Module 4.3's write-gating defense unavailable by default. Treat every task-output handoff as an untrusted-content boundary (Module 2.4 Vector 1).*
### 3 things CrewAI does better
1. **Role-based mental model**: the most accessible entry point into multi-agent orchestration in the roster. "Describe the team" beats "draw the graph" for first-time builders.
2. **Sequential crews as a clean pattern**: the default process type composes well for research-then-write, draft-then-review, plan-then-execute workloads.
3. **Per-agent tool attachment**: structurally gives you per-agent capability scoping at declaration time — closer to Module 2.4 than most frameworks that attach tools at the harness level.
### 3 things to fix
1. **Make the dependency graph explicit at scale** — the emergent graph from task `context` references is invisible past ~5 tasks; offer a LangGraph-style visualization/checkpoint path.
2. **Offer agent-scoped memory** — crew-scoped shared memory forfeits the Module 4.3 write-gating defense by default; let memory isolation be opt-in.
3. **Emit structured per-agent events** — the run logs are below the observability floor; adopt an event union (DD-21, DD-14) so a crew run produces a trace, not a log.
---
## References
1. **CrewAI source** — the role-based multi-agent reference.
2. **Module 1** — conversation-driven loop architectures; CrewAI's role-per-turn is a multi-agent instance.
3. **Module 1.3** — subagents; sequential crews and the hierarchical manager.
4. **Module 2.4** — per-agent capability scoping (exists by construction) and the untrusted-content boundary at each task handoff.
5. **Module 4 / 4.3** — memory tiers; crew-scoped shared memory and the absent write-gating defense.
6. **DD-06 (oh-my-opencode)** — the meta-hierarchy comparison; CrewAI's hierarchical manager is a shallower instance of Sisyphus/Prometheus/Atlas/Junior.
7. **DD-10 (LangGraph)** — the explicit-graph alternative when the crew grows past legibility.
8. **DD-11 (Agents SDK)** — handoffs + agents-as-tools as primitives; the production path with sandboxing.
9. **DD-14 (Mastra)** — the observability floor CrewAI's run logs sit below.
10. **DD-21 (Tau)** — the typed event union CrewAI lacks.