CrewAI's sweet spot: a planner + worker + reviewer trio that collaborates on a brief.
Agents Module 5 CrewAI Multi-Agent
context=[...].topic_lookup; the worker and reviewer work from artefacts alone.Hits every condition on L09 Slide 11's “Pick it when” list.
Given a topic, produce a short structured brief: 1 outline (from the planner), 1 draft (from the worker), 1 review with any concerns (from the reviewer).
Real example topic: “What changed in Linux kernel 6.14's networking stack?”
Three agents, three artefacts, one sequential process — the canonical CrewAI shape.
| Agent | Role | Goal | Backstory in one phrase |
|---|---|---|---|
| Planner | “Brief Planner” | “Produce an outline of the brief — 3 sections, 1 line each” | “structured thinker, refuses fluff” |
| Worker | “Brief Writer” | “Draft the brief following the planner's outline exactly” | “concise writer, follows instructions” |
| Reviewer | “Skeptical Reviewer” | “Flag unsupported claims or unclear sentences in the draft” | “rigorous, friendly, paid to find issues” |
topic
│
▼
[Planner] ──outline──► [Worker] ──draft──► [Reviewer] ──review──► final
│
└──outline-also visible via context─┐
Sequential process; each downstream task context=[...] the upstream ones it needs.
topic_lookup (a mocked PKB-style tool). Worker and reviewer have no tools — they work from artefacts alone.plan_task = Task(
description="Plan a brief on {topic}. Output 3 section headings, one line each.",
expected_output="3 lines, each a section heading.",
agent=planner,
)
draft_task = Task(
description="Draft a brief on {topic} following the planner's outline EXACTLY.",
expected_output="A 150-250 word brief with the 3 sections from the outline.",
agent=worker,
context=[plan_task],
)
review_task = Task(
description="Review the draft for unsupported claims or unclear sentences.",
expected_output="A short review: list 0-3 issues, or write 'no issues found'.",
agent=reviewer,
context=[plan_task, draft_task],
)
context=[plan_task, draft_task] on the reviewer means the reviewer sees both — useful for catching cases where the draft diverged from the plan.
crew = Crew(
agents=[planner, worker, reviewer],
tasks=[plan_task, draft_task, review_task],
process=Process.sequential,
verbose=True,
)
result = crew.kickoff(inputs={"topic": question})
~6 lines of glue. The collaboration is in the agent + task definitions above — the Crew just runs them.
topic_lookup tool@tool
def topic_lookup(topic: str) -> str:
"""Look up a topic in the in-process knowledge base."""
return KB.get(topic.lower(), "no entry found in KB")
Small dict of pre-seeded entries so the planner has something to ground the outline on. Same shape as M2's L04 mocked tools. The crew runs deterministically.
[Planner ] Section 1: io_uring zero-copy TX
Section 2: BIG TCP default for IPv4
Section 3: tc-bpf flow-tracking kfuncs
[Worker ] (draft of ~200 words following the outline)
[Reviewer ] 1 issue: section 3 mentions "kfunc family"
without naming any. Consider citing.
Three LLM calls (one per agent) plus any tool calls by the planner. Total: ~$0.04–$0.08 with Sonnet across the team.
output_json= / output_pydantic= on Task for typed outputs.output_pydantic=BriefDraft on draft_task so the worker's output is a BriefDraft(title, sections) object.write_report final-answer-tool pattern: a tax of one Pydantic model definition per typed task, in exchange for structured outputs.topic_lookup multiple times.Plan F wires this exact agent.py into agents/_eval/run_all.py as the CrewAI row of the cross-framework scorecard.
The scorecard's runner calls from agents.lesson10_multi_agent_crew.agent import run_brief_crew and records cost/latency/LoC/output-quality.
Module 6 finally answers “which framework should I pick?” with real numbers, not editorial scoring. Today's agent.py is the canonical CrewAI entry.
context=[...] is the artefact flow primitive. Each downstream task declares which upstream artefacts it can see; the framework wires them in.