# Diagrams — DD-12: CrewAI (Role-Based Multi-Agent, Emergent Coordination)

**Course**: Master Course · **Deep-Dive**: DD-12
**Subject**: Multi-agent framework — role-based crews, emergent coordination, the emergent-coordination pole paired with LangGraph (DD-10)
**Diagram count**: 6

---

## Diagram 1 — Role-Based Sequential Crew (the three primitives)

```mermaid
flowchart LR
    TASKS["Task list (with context refs)"]
    TASKS --> RESEARCHER
    subgraph CREW["CREW (orchestration unit)"]
        direction LR
        RESEARCHER["Agent: Researcher<br/>role + goal + backstory<br/>tools: [search, read]"]
        RESEARCHER -->|"task output (untrusted boundary)"| WRITER["Agent: Writer<br/>role + goal + backstory<br/>tools: [write]"]
        WRITER -->|"task output (untrusted boundary)"| REVIEWER["Agent: Reviewer<br/>role + goal + backstory<br/>tools: [read]"]
        REVIEWER -->|"final output"| DONE["Crew complete"]
    end
    MEMORY["Crew-scoped shared memory<br/>(short-term / long-term / entity)"]
    MEMORY -.->|"all agents read/write (NO write isolation)"| RESEARCHER
    MEMORY -.-> WRITER
    MEMORY -.-> REVIEWER
    style CREW fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style RESEARCHER fill:#14141f,stroke:#5eead4,color:#e4e4e8
    style WRITER fill:#14141f,stroke:#5eead4,color:#e4e4e8
    style REVIEWER fill:#14141f,stroke:#5eead4,color:#e4e4e8
    style MEMORY fill:#2a1810,stroke:#a04000,color:#f0a868
```

- **Type**: Architecture / reference.
- **Purpose**: The defining diagram. Shows the three primitives (`Crew`, `Agent`, `Task`) and how a sequential crew runs: tasks flow agent to agent, each output becoming the next agent's input. Also shows the crew-scoped shared memory that all agents read/write — the security-relevant design choice.
- **Reading**: Each agent is its system prompt, assembled from role + goal + backstory (Module 12 applied at agent granularity). Tasks run in list order (sequential process); each task output is appended to shared context the next agent reads. The dashed lines to memory are the security concern: all agents share one memory store, so a compromised agent can poison memory every other agent later reads (Module 4.3 write-gating unavailable by default). The task-output arrows marked "untrusted boundary" are the indirect-prompt-injection surface — each handoff is an untrusted-content boundary (Module 2.4 Vector 1).

---

## Diagram 2 — Emergent vs Declared Coordination (the load-bearing axis)

```mermaid
flowchart TB
    subgraph CREW["CREWAI — emergent coordination"]
        direction TB
        C1["Define roles + tasks"]
        C2["Graph EMERGES from context refs + process type"]
        C3["Simpler · faster setup · less auditable"]
        C1 --> C2 --> C3
    end
    subgraph GRAPH["LANGGRAPH (DD-10) — declared coordination"]
        direction TB
        G1["Draw nodes + edges"]
        G2["Graph IS a first-class object"]
        G3["More ceremony · fully auditable · checkpointable"]
        G1 --> G2 --> G3
    end
    CREW <-->|"the multi-agent coordination axis<br/>load-bearing for Course 4 E09"| GRAPH
    style CREW fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style GRAPH fill:#2a1810,stroke:#a04000,color:#f0a868
```

- **Type**: Conceptual / cross-reference.
- **Purpose**: The load-bearing diagram of the deep-dive. Establishes the multi-agent coordination axis: CrewAI (emergent — the graph emerges from task context references and process type) vs LangGraph (declared — the graph is a first-class object you draw). This axis is the organizing principle of Course 4's E09 module.
- **Reading**: CrewAI (teal) asks you to describe the team; the coordination graph emerges implicitly. LangGraph (warn) asks you to draw the graph; the coordination is fully explicit. The tradeoff is simplicity vs auditability. The diagnostic question: *do you need to prove properties about the coordination graph?* If yes (compliance, security audit, reproducibility), declared coordination earns its ceremony. If no (prototyping, internal tools), emergent coordination earns its speed. Every multi-agent framework in the roster sits between these two poles.

---

## Diagram 3 — Two Orchestration Modes (sequential vs concurrent/hierarchical)

```mermaid
flowchart TB
    subgraph SEQ["SEQUENTIAL (default)"]
        direction LR
        S1["Task 1<br/>Agent A"] -->|"output"| S2["Task 2<br/>Agent B"]
        S2 -->|"output"| S3["Task 3<br/>Agent C"]
        S3 -->|"final"| SOUT["Complete"]
    end
    subgraph CON["CONCURRENT / HIERARCHICAL"]
        direction TB
        MGR["Manager agent<br/>decomposes + synthesizes"]
        MGR -->|"assigns"| W1["Worker 1"]
        MGR -->|"assigns"| W2["Worker 2"]
        MGR -->|"assigns"| W3["Worker 3"]
        W1 & W2 & W3 -->|"results"| MGR
        MGR --> COUT["Complete"]
    end
    style SEQ fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style CON fill:#14141f,stroke:#5eead4,color:#e4e4e8
    style MGR fill:#152d15,stroke:#208a20,color:#a0d0a0
```

- **Type**: Architecture / pattern.
- **Purpose**: Shows the two process types. Sequential is the default and the well-trodden path — a linear chain across roles. Concurrent/hierarchical adds a manager agent that decomposes, dispatches, and synthesizes — closer to DD-06's meta-hierarchy but one level deep.
- **Reading**: Sequential (teal) is a linear ReAct chain stretched across multiple roles — each turn owned by a different role-shaped system prompt. This is where CrewAI earns its 4/5 on Module 1.3: it is a textbook multi-agent pattern that composes well for research-then-write, draft-then-review, plan-then-execute. Concurrent/hierarchical (accent) is shallower than DD-06's deliberate multi-tier design (Sisyphus/Prometheus/Atlas/Junior) — CrewAI's manager is implicit and the hierarchy is one level. Use sequential for clean role decomposition; use hierarchical when a manager's synthesis adds value the sequential chain cannot.

---

## Diagram 4 — Role-to-Prompt Mapping (Module 12 at agent granularity)

```mermaid
flowchart LR
    ROLE["role: 'Senior Researcher'"]
    GOAL["goal: 'find key facts'"]
    BS["backstory: '20yr NYT, ruthless on provenance'"]
    TOOLS["tools: [search, read]"]
    ROLE & GOAL & BS & TOOLS --> TEMPLATE["CrewAI system prompt template"]
    TEMPLATE --> PROMPT["Assembled system prompt<br/>'You are {role}. Your goal is {goal}...'"]
    PROMPT --> AGENT["Agent runs with this prompt"]
    style TEMPLATE fill:#14141f,stroke:#5eead4,color:#e4e4e8
    style PROMPT fill:#0d2818,stroke:#1e8449,color:#82e0aa
```

- **Type**: Pattern / reference.
- **Purpose**: Shows CrewAI's defining opinion: role is the system prompt. You never hand-author a system prompt — you fill in three fields (role, goal, backstory) plus tools, and the template assembles the prompt. This is Module 12 (Prompt Assembly) applied at agent granularity rather than harness granularity.
- **Reading**: The template (accent border) is the framework's opinion. Its value: you get a well-structured system prompt without writing one, which is why CrewAI is the most accessible multi-agent framework. Its risk: when the template is wrong for your use case, you are fighting the framework's opinion rather than editing a string. The assembled prompt (teal) is what the agent actually runs with. This design choice is load-bearing for the "describe the team" mental model — the template is what makes role/goal/backstory sufficient.

---

## Diagram 5 — The Security Surface (handoff injection + shared memory poisoning)

```mermaid
flowchart TB
    ATTACK["Compromised upstream agent<br/>(or injected task output)"]
    ATTACK -->|"task output contains hidden instructions"| HANDOFF["Task-output handoff<br/>(UNTRUSTED boundary — Module 2.4 V1)"]
    HANDOFF -->|"downstream agent reads + acts"| DOWN["Downstream agent<br/>executes injected instructions"]
    ATTACK -->|"writes poisoned entry"| SHARED["Crew-scoped shared memory<br/>(NO write isolation — Module 4.3 unavailable)"]
    SHARED -.->|"every other agent reads"| ALL["All agents in crew<br/>read poisoned memory"]
    style ATTACK fill:#2d1010,stroke:#a00000,color:#f08080
    style HANDOFF fill:#2a1810,stroke:#a04000,color:#f0a868
    style SHARED fill:#2a1810,stroke:#a04000,color:#f0a868
    style DOWN fill:#2d1010,stroke:#a00000,color:#f08080
    style ALL fill:#2d1010,stroke:#a00000,color:#f08080
```

- **Type**: Security / threat model.
- **Purpose**: Shows the two attack surfaces CrewAI's architecture creates: (1) indirect prompt injection propagating through task-output handoffs, and (2) shared-memory poisoning compounding across all agents in the crew. Both are consequences of the role-based, crew-scoped design.
- **Reading**: The compromised upstream agent (danger red) attacks along two paths. Path 1 (warn): the task-output handoff is an untrusted-content boundary — if the output contains hidden instructions, the downstream agent reads and acts on them (indirect prompt injection). Cure: treat every handoff as untrusted input; validate task outputs before injection. Path 2 (warn): the crew-scoped shared memory has no write isolation — a poisoned entry written by one agent is read by every other agent in the crew. This is the same compounding-poisoning argument as Hermes (DD-08), except here the compounding is across agents within a single crew run, not across sessions. Cure: opt for agent-scoped memory (not available by default — one of the "three things to fix").

---

## Diagram 6 — Sequential Crew (n8n state-machine workflow)

```json
{
  "name": "CrewAI Sequential Crew — DD-12",
  "nodes": [
    { "parameters": { "assignments": { "assignments": [{ "id": "topic", "name": "topic", "value": "={{ $json.body.topic || 'harness engineering' }}", "type": "string" }]}, "options": {} }, "id": "task", "name": "Task: Write Article", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [160, 300] },
    { "parameters": { "model": "gpt-4o-mini", "messages": "={{ [{role:'system',content:'You are a Researcher. Role: find key facts. Goal: comprehensive research. Backstory: 20yr NYT, ruthless on provenance.'},{role:'user',content:'Research: ' + $json.topic}] }}", "options": {} }, "id": "researcher", "name": "Agent: Researcher", "type": "@n8n/n8n-nodes-langchain.toolExecuteTool", "typeVersion": 1.1, "position": [400, 300], "notesInFlow": true, "notes": "Role-based: role + goal + backstory = system prompt (Module 12 at agent granularity). Sequential: output feeds next agent. Task-output handoff is an UNTRUSTED boundary (Module 2.4 V1)." },
    { "parameters": { "model": "gpt-4o-mini", "messages": "={{ [{role:'system',content:'You are a Writer. Role: draft article. Goal: engaging prose. Backstory: 10yr novelist.'},{role:'user',content:'Write based on this research: ' + $('Agent: Researcher').item.json.choices[0].message.content}] }}", "options": {} }, "id": "writer", "name": "Agent: Writer", "type": "@n8n/n8n-nodes-langchain.toolExecuteTool", "typeVersion": 1.1, "position": [640, 300], "notesInFlow": true, "notes": "Receives Researcher's output (untrusted). Writes the draft. Sequential crew: task flows agent to agent. Emergent coordination — the graph is not drawn, it emerges from context refs." },
    { "parameters": { "model": "gpt-4o-mini", "messages": "={{ [{role:'system',content:'You are a Reviewer. Role: quality check. Goal: publication-ready. Backstory: 15yr editor.'},{role:'user',content:'Review: ' + $('Agent: Writer').item.json.choices[0].message.content}] }}", "options": {} }, "id": "reviewer", "name": "Agent: Reviewer", "type": "@n8n/n8n-nodes-langchain.toolExecuteTool", "typeVersion": 1.1, "position": [880, 300], "notesInFlow": true, "notes": "Receives Writer's draft (untrusted). Reviews for quality. Final output = the crew's deliverable. Crew-scoped shared memory: all 3 agents read/write the same store (NO write isolation — Module 4.3 unavailable by default)." },
    { "parameters": { "content": "={{ JSON.stringify({ article: $('Agent: Reviewer').item.json.choices[0].message.content, crew: 'Researcher to Writer to Reviewer (sequential)', pattern: 'role-based multi-agent — emergent coordination', pole: 'emergent-coordination pole (vs LangGraph DD-10 declared)', score: '33/60 — Module 1.3 Subagents 4/5' }) }}", "options": {} }, "id": "out", "name": "Crew Output", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [1120, 300] }
  ],
  "connections": { "Task: Write Article": { "main": [ [ { "node": "Agent: Researcher", "type": "main", "index": 0 } ] ] }, "Agent: Researcher": { "main": [ [ { "node": "Agent: Writer", "type": "main", "index": 0 } ] ] }, "Agent: Writer": { "main": [ [ { "node": "Agent: Reviewer", "type": "main", "index": 0 } ] ] }, "Agent: Reviewer": { "main": [ [ { "node": "Crew Output", "type": "main", "index": 0 } ] ] } },
  "settings": { "executionOrder": "v1" }, "meta": { "templateCreatedBy": "Harness Engineering Master Course — DD-12 CrewAI" }
}
```

- **Type**: n8n state-machine workflow (importable).
- **Purpose**: An executable diagram you can import into n8n to see a sequential crew concretely. Each agent node shows the role/goal/backstory-assembled system prompt and the task-output handoff to the next agent.
- **Reading**: Import into n8n (or read top-to-bottom). The Researcher node's system prompt shows the role/goal/backstory template in action. The handoff from Researcher to Writer is the untrusted-content boundary. The final output confirms the architectural properties: emergent coordination, the role-based pattern, and the 33/60 score with Module 1.3 at 4/5. This is the lab flow the `07-lab-spec.md` simulates in pure Python.
