Files
2026-09-22 15:42:25 +08:00

201 lines
14 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阶段三 · 小点 4:CrewAI(多智能体快速开发·上手快)
> 所属:阶段三 主流 Agent 开发框架
> 定位:CrewAI 是"最快能跑起来的多智能体"框架。它把 Agent 建模成**一支真实团队**:每个成员有职位、目标、性格,任务逐个派发,团队按流程推进。上手快是它的卖点,但**行为表达力弱**是它的天花板——这一讲既要让你能一天写出来,也要让你清楚"什么情况该换回 LangGraph"。
## 精简大纲
1. 核心理念:角色化多智能体
2. 三要素:Agent(船员)/ Task(任务)/ Crew(团队)
3. Process:顺序 vs 分层
4. 工程提醒与适用边界
## 学习内容详情
> 安装:`pip install crewai crewai-tools`,运行前设置 OPENAI_API_KEY(或支持的其他模型)。
### 1. 核心理念
- 像组建一个真实团队:每个成员(Agent)有明确职位(角色 / 目标 / 背景故事),任务(Task)逐个派发,团队(Crew)按流程推进。
- 上手速度是四个框架里最快的。
```mermaid
graph LR
A[Agent 船员: 角色/目标/背景/工具] --> D[Crew 团队打包]
B[Task 任务: 描述/交付物/归属] --> D
C[Process 流程: sequential/hierarchical] --> D
D --> E[kickoff 启动执行]
```
### 2. 三要素
- **Agent(船员):** 四要素——`role`(职位,如「资深撰稿人」)、`goal`(目标)、`backstory`(背景故事,塑造行为风格的软提示)、`tools`(专属工具集)。**背景故事不是摆设,能显著改变行为风格。**
> 🔬 **深度理解 · 角色分工(role / goal / backstory)的本质**:
> 1. **本质**:CrewAI 的"角色"不是真正的隔离进程,而是给同一个 LLM 提供不同「系统提示 + 任务说明 + 行为风格约束」,让它在不同 Agent 上下文下表现出不同专业性。
> 2. **机制**:每个 Agent 实例化时,role / goal / backstory 会被拼进它的 system prompt;调用 LLM 时只带上「该角色的设定 + 分派给它的任务 + context 注入的上游产出」,而不是全量对话。backstory 以软提示方式影响措辞、语气、抓重点的偏好。
> 3. **为什么重要**:它用极低成本实现"专业化分工与自行隔离"——不用手写一套提示词拼接逻辑,只需声明角色,框架负责组装。也正因如此,换角色 / 换团队的边际成本很低。
> 4. **易错点**:把 backstory 当可有可无——它直接决定行为风格;也误以为多个 Agent 会共享记忆——实际默认隔离,协作靠 `context` 显式传参,靠"共享全局上下文"协作是不成立的。
```python
from crewai import Agent, Task, Crew, Process
# ① 定义船员: 角色 + 目标 + 背景故事 + 工具
researcher = Agent(
role="资深行业研究员", # 职位
goal="搜集最新AI行业趋势并提炼要点", # 目标
backstory="你在一线科技媒体深耕5年, 擅长抓重点、去噪音", # 背景故事(塑造风格)
verbose=True, # 打印每步执行, 学习神器和排查帮手
)
writer = Agent(
role="资深内容撰稿人",
goal="把研究要点写成吸引人的营销推文",
backstory="你是短视频文案专家, 擅长用一句话抓住读者",
verbose=True,
)
```
- **Task(任务):** `description`(做什么)+ **`expected_output`(交付物长什么样——必须写,否则输出质量差)** + `agent`(交给谁)+ `context`(依赖哪些前置任务的产出,等于把上游结果注入本任务上下文)。
> 🔬 **深度理解 · Task 与 context 依赖注入**:
> 1. **本质**:Task 是「派给某个角色的一段工作 + 明确交付物」,`context` 是它获得上游产出的「输入管道」,`expected_output` 是它交给下游 / 终端的「验收标准」。
> 2. **机制**:sequential 模式下任务串行,`context=[前置Task]` 把前置任务的最终产出注入当前任务的 prompt 上下文;`expected_output` 作为输出约束写进任务提示,引导模型产出结构化、可度量的结果。任务间通过 `context` 显式声明依赖,而非共享可变全局状态。
> 3. **为什么重要**:`expected_output` 是质量生命线——写含糊时模型不知道交付什么,会反复自我修改直到 token 耗尽;`context` 让链式协作显式化、可追踪,避免"全员共享记忆"的污染。
> 4. **易错点**:`expected_output` 只写"一段文字"等于没写,要具体到「几条、带什么结构、每条多长」;只声明 agent 归属却忘了 `context` 声明数据依赖,下游拿不到上游产出。
```python
trade_research = Task(
description="研究2025年AI Agent市场, 提炼3条关键趋势",
expected_output="3条带具体数字依据的趋势要点, 每条不超过50字", # 必须写!影响质量
agent=researcher,
)
write_post = Task(
description="根据研究结果写一篇200字营销推文",
expected_output="一段完整的中文营销推文", # 精确描述交付物
agent=writer,
context=[trade_research], # 依赖研究员产出 → 注入本任务上下文
)
```
- **Crew(团队):** 把成员和任务打包成执行体,`kickoff()` 启动。
```python
crew = Crew(
agents=[researcher, writer], # 团队里的所有船员
tasks=[trade_research, write_post], # 要执行的所有任务
process=Process.sequential, # 执行流程: 顺序
verbose=True,
)
result = crew.kickoff({"topic": "AI Agent"}) # 启动! 传入全局输入
print(result.raw) # 最终交付物文本
```
> 注:`crew.kickoff({...})` 传全局输入、`result.raw` 取最终文本,属**较新 CrewAI** 的形态;旧版 `kickoff` 返回 `dict`,取值方式不同(请以你安装的版本为准)。
> ⏳ **短期可不深究**:CrewAI 版本迭代节奏偏快,这一遍只要掌握 `Agent / Task / Crew / Process` 这套核心对象与"声明式组队"的心智模型即可,`kickoff` 返回值、构造参数等 API 细节以你安装的版本为准,不必背死具体的版本差异。
### 3. Process(执行流程)
#### 3.1 两种流程对比
```mermaid
graph TD
subgraph sequential[顺序模式]
s1[任务1] --> s2[任务2] --> s3[任务3]
end
subgraph hierarchical[分层模式]
m[Manager主管: 自动生成, 统筹派活] --> h1[任务A]
m --> h2[任务B]
m --> h3[审稿]
end
```
- `sequential`:顺序流水线,任务按列表顺序执行,最常用。
- `hierarchical`:分层模式,自动生成 Manager Agent 统筹派活、审稿,适合复杂任务、成本更高。
```python
# 切换流程只需改一个参数
complex_crew = Crew(
agents=[researcher, writer],
tasks=[trade_research, write_post],
process=Process.hierarchical, # 换成分层: 自动有Manager统筹
manager_llm="gpt-4o", # 分层模式需指定主管用的模型
)
```
> ⏳ **短期可不深究**:`hierarchical` 属于进阶用法——自动生成的 Manager 怎么派活、怎么判定完工,底层调度细节偏复杂且成本更高;这一遍以 `sequential` 跑通为准,等真要做复杂多角色协作时再回来补分层模式。
> 🔬 **深度理解 · Process(sequential / hierarchical)编排机制**:
> 1. **本质**:Process 定义了 Crew 里「任务以什么顺序、由谁派发」的编排规则——它是把"一群人"组织成"一条流水线或一次会议"的调度协议。
> 2. **机制**:`sequential` 下任务按传入列表顺序执行,每个 Task 由指定 agent 完成,产出通过 `context` 注入依赖它的后续任务;`hierarchical` 下框架自动创建一个 Manager Agent,由它(用 `manager_llm` 驱动)决定下一步派给哪个船员、何时收尾,相当于多了个"调度大脑"。
> 3. **为什么重要**:它决定了多智能体的协作形态与成本——顺序模式可预期、易排查;分层模式灵活但引入额外 LLM 调用(更贵、输出更难复现)。
> 4. **易错点**:以为 hierarchical 自动搞定一切、不用管依赖——其实 Manager 也可能派错导致链路发散,所以简单 / 可预期任务优先 sequential;分层模式需要提供 `manager_llm`,缺默认模型时无法启动。
### 4. Agent 之间隔离
- 每个 Agent 只看到「自己的角色设定 + 分派给它的任务 + context 指定的上游产出」,**不共享全量对话**——避免互相污染,但信息传递要靠 Task 的 `context` 显式声明。
```mermaid
graph LR
A[研究Agent] -.context注入.-> B[撰稿Agent]
C[其他无关任务] -.默认隔离.-> B
style C stroke-dasharray: 5 5
```
### 5. 工程提醒
1. `verbose=True` 是最好的学习方式:能看到每个 Agent 实际收到的 prompt 与产出。
2. **任务失败常见原因**:`expected_output` 写得含糊 → 模型不知道交付什么 → 迭代到 token 耗尽。
3. **深度定制弱**:想精确控制「第 3 步失败回滚到第 1 步」这类状态流转,CrewAI 表达力不足 → 复杂流程回到 LangGraph(等价但可控性完全不同)。
4. **生产前必须二次封装**:日志、重试、成本统计 CrewAI 都要自己补。
| 场景 | 用 CrewAI | 用 LangGraph |
|-|-|-|
| 快速搭多角色流水线(研究→写稿→校对) | ✅ 首选 | 也能做但繁琐 |
| 需要断点续跑 / 精确状态回滚 | ❌ 表达力不足 | ✅ |
| 复杂分支 + 人工审批流 | ❌ | ✅ |
## 本节自检
- [ ] 能定义一个三船员团队并跑通一次顺序任务链
- [ ] 能说清 CrewAI 与 LangGraph 的适用边界
## 本节配套思考题(快速入门的检验)
1. 为什么 `expected_output` 必须写清楚?写含糊时模型会怎样(结合"迭代到 token 耗尽"回答)?
2. `Process.hierarchical` 自动生成 Manager 统筹,这种"自动派活"相比 sequential 各有什么代价和收益?
3. 三个船员之间为什么默认不共享全量对话?`context` 字段解决的又是什么?这和"防记忆污染"有什么关系?
4. 假如你要做一个"第 3 步失败回滚到第 1 步重来"的流程,CrewAI 能轻松做吗?你会怎么选型?
## 本节常见面试题(深度解析)
> 针对本节核心知识的面试高频点,配合"本质+机制"式理解,能让你答得既有深度又有广度。
### 面试题 1:CrewAI 里"角色"的本质是什么?多个 Agent 之间是如何"隔离"又"协作"的?
- **面试官想考察**:是否理解"角色 = 系统提示 + 任务 + 风格约束",以及协作不是靠共享记忆。
- **专业作答(含深度)**:
1. 角色本质是为同一个 LLM 准备的不同上下文(role / goal / backstory 拼进 system prompt),让它在不同 Agent 下表现出不同专业性,而不是真的隔离进程。
2. 隔离:每个 Agent 只看到自己的角色设定 + 分派任务 + `context` 注入的上游产出,不共享全量对话,避免相互污染。
3. 协作:通过 Task 的 `context` 显式声明依赖,把前置任务的产出注入后续任务;数据依赖是显式的,不是"黑盒共享"。
4. 意义:隔离 + 显式注入让多角色流水线可控、可追踪;这也是它与 LangGraph"共享 State"模型的差异点。
- **加分亮点 / 深度追问**:对比 LangGraph 的 State 共享 vs CrewAI 的 context 注入两种协作模型;追问常是"backstory 有什么用"——答:是塑造行为风格的软提示,直接影响措辞与抓重点。
### 面试题 2:为什么 `expected_output` 必须写清楚?`context` 字段解决的是什么问题?
- **面试官想考察**:对"任务交付物约束"和"依赖注入"这两个协作质量关键点的理解。
- **专业作答(含深度)**:
1. `expected_output` 是给模型的「验收标准」:写清楚(几条、什么结构、多长)能让模型目标明确、一次到位。
2. 写含糊时模型不知道交付什么,会"自说自话地反复修改"直到 token 耗尽——这正是任务失败的常见原因。
3. `context` 是任务获得上游产出的输入管道:只声明了任务归属却忘了 context,下游就"看不到"上游结果。
4. 归因:expected_output 管"产出的形"、context 管"产出的源",两者共同决定多任务链能否高质量衔接。
- **加分亮点 / 深度追问**:主动讲"写 expected_output 类似给子函数写返回值契约";追问常是"如何避免 context 过长"——答:对超长产出先做摘要再注入。
### 面试题 3:`Process.sequential` 和 `Process.hierarchical` 各自代价与收益是什么?如何据此选型?
- **面试官想考察**:对多智能体"编排协议"和成本/可控性权衡的理解。
- **专业作答(含深度)**:
1. sequential:任务按序执行、由显式 context 串联,可预期、易排查、成本可控,适合"研究→写稿→校对"这类固定流水线。
2. hierarchical:自动生成 Manager,由 LLM 动态派活、审稿,更灵活、改写复杂任务,但多一次调度 LLM 调用、输出更难复现、Manager 也可能派错。
3. 选型:默认优先 sequential;任务间分工需动态决策时再上 hierarchical。
4. 边界:CrewAI 表达力仍偏弱——需要精确状态回滚 / 人工审批中断时,应切回 LangGraph 这类"图编排"框架,而不是硬用 CrewAI。
- **加分亮点 / 深度追问**:补充"多智能体要慎重——单 Agent + 多工具通常更简单可靠";追问常是"CrewAI 何时该换 LangGraph"——答:需要断点续跑 / 精确状态回滚 / 人工审批流时。