版本:v1.14.3(2026年4月)|语言:Python ≥3.10|License:MIT
1. 你为什么需要 CrewAI?
单个 LLM 的天花板
你可能已经用过 ChatGPT 或者直接调用 OpenAI API。单个大模型很厉害,但它有个根本局限:一次对话只有一个"大脑"在工作。当任务变得复杂,比如"帮我做一份完整的竞品分析报告",单个模型需要同时扮演研究员、分析师、报告撰写者……注意力被分散,质量会明显下降。
现实世界是这样解决问题的:
❌ 一个全能大脑独自处理所有事
✅ 专业分工 + 团队协作
CrewAI 就是把这种人类团队协作模式映射到 AI 上的框架。
CrewAI 的核心价值
┌─────────────────────────────────────────────────────────────┐
│ CrewAI 解决的问题 │
├─────────────────┬───────────────────────────────────────────┤
│ 问题 │ 解决方案 │
├─────────────────┼───────────────────────────────────────────┤
│ 单模型注意力分散 │ 专业 Agent 各司其职 │
│ 复杂任务协调难 │ Crew 编排 + 任务依赖链 │
│ 工作流不可控 │ Flow 事件驱动精确控制 │
│ 无上下文记忆 │ 统一 Memory 系统 │
│ 外部数据割裂 │ Knowledge RAG 知识库 │
│ 框架依赖重 │ 完全独立,不依赖 LangChain │
└─────────────────┴───────────────────────────────────────────┘
生态现状
- 🌟 GitHub Stars:~35K+(快速增长)
- 👨💻 认证开发者:100,000+(通过 learn.crewai.com)
- 📦 独立构建:零 LangChain 依赖,比 LangGraph 快 5.76x(官方实测)
- 🏢 企业级:配套 CrewAI AMP Suite(可观测性、控制平面、企业安全)
2. 核心概念全景图
在写任何代码之前,先建立一张完整的心智地图。
2.1 整体架构鸟瞰
╔══════════════════════════════════════════════════════════════════╗
║ CrewAI 框架全景 ║
╠══════════════╦═══════════════════════════════════════════════════╣
║ ║ ║
║ CREWS ║ FLOWS ║
║ (自治协作) ║ (精确控制) ║
║ ║ ║
║ ┌─────────┐ ║ ┌─────────────────────────────────────┐ ║
║ │ Agent A │ ║ │ @start → @listen → @router → ... │ ║
║ │ Agent B │◄║──┤ 状态管理 | 事件驱动 | 条件分支 │ ║
║ │ Agent C │ ║ │ 可内嵌 Crew 作为步骤 │ ║
║ └────┬────┘ ║ └─────────────────────────────────────┘ ║
║ │ ║ ║
║ ┌────▼────┐ ║ ║
║ │ Tasks │ ║ ║
║ └─────────┘ ║ ║
╠══════════════╩═══════════════════════════════════════════════════╣
║ 支撑层 ║
║ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ ║
║ │ Memory │ │Knowledge │ │ Tools │ │ LLM 适配层 │ ║
║ │ 统一记忆 │ │ RAG知识库 │ │ 工具注册 │ │ OpenAI/Claude/ │ ║
║ └──────────┘ └──────────┘ └──────────┘ │ Gemini/Ollama │ ║
║ └────────────────┘ ║
╠══════════════════════════════════════════════════════════════════╣
║ 基础设施层 ║
║ Events 事件总线 | Hooks 钩子 | Telemetry 遥测 | MCP 协议 ║
║ A2A Agent通信 | Checkpoint 断点续跑 | Security 安全 ║
╚══════════════════════════════════════════════════════════════════╝
2.2 两大范式:Crews vs Flows
这是理解 CrewAI 最关键的一个区分:
┌─────────────────────────────────┐
│ 你有什么需求? │
└───────────────┬─────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────────┐
│ CREWS │ │ FLOWS │
│ "我需要智能协作" │ │ "我需要精确掌控" │
├──────────────────────┤ ├──────────────────────────┤
│ ✅ 需要多角色分工 │ │ ✅ 工作流路径需精确控制 │
│ ✅ 任务之间需要委托传递 │ │ ✅ 需要条件分支逻辑 │
│ ✅ 希望 AI 自主决策 │ │ ✅ 需要状态持久化 │
│ ✅ 复杂的研究/写作任务 │ │ ✅ 企业级生产部署 │
│ │ │ ✅ 可以在步骤中嵌入 Crew │
└──────────────────────┘ └──────────────────────────┘
2.3 仓库目录结构
这是阅读源码的索引图:
crewAI/
├── lib/
│ ├── crewai/ # 核心包
│ │ └── src/crewai/
│ │ ├── agent/ # Agent 定义(新版核心实现)
│ │ ├── agents/ # Agent 执行器、构建器
│ │ ├── crew.py # Crew 入口类
│ │ ├── task.py # Task 定义
│ │ ├── flow/ # Flow 事件驱动引擎
│ │ ├── memory/ # 统一记忆系统
│ │ ├── knowledge/ # RAG 知识库
│ │ ├── tools/ # 工具基类
│ │ ├── llm.py / llms/ # LLM 适配层
│ │ ├── mcp/ # Model Context Protocol
│ │ ├── a2a/ # Agent-to-Agent 通信
│ │ ├── events/ # 事件总线
│ │ ├── state/ # 运行时状态 & Checkpoint
│ │ ├── hooks/ # LLM 调用钩子
│ │ ├── skills/ # Agent 技能系统
│ │ └── project/ # @CrewBase 等装饰器
│ ├── crewai-tools/ # 官方工具集
│ ├── crewai-files/ # 文件处理
│ └── devtools/ # 开发调试工具
└── pyproject.toml # monorepo 配置(uv workspace)
3. 5分钟快速上手
3.1 安装
# 推荐:使用 uv(比 pip 快 10-100x)
uv pip install crewai
# 安装官方工具集(含搜索、文件读取等常用工具)
uv pip install 'crewai[tools]'
# 或者 pip
pip install crewai
pip install 'crewai[tools]'
3.2 脚手架创建项目
# 创建标准项目(推荐方式)
crewai create crew my_research_team
cd my_research_team
# 项目结构自动生成:
# my_research_team/
# ├── .env # 存放 API Key
# ├── pyproject.toml
# └── src/my_research_team/
# ├── main.py # 入口
# ├── crew.py # Crew 定义
# ├── config/
# │ ├── agents.yaml # Agent 配置
# │ └── tasks.yaml # Task 配置
# └── tools/
# └── custom_tool.py
# 安装依赖并运行
crewai install
crewai run
3.3 最简单的入门示例
【初学者示例】一个研究员+一个撰写者
# 最简版本,不用 YAML,全 Python 定义
from crewai import Agent, Task, Crew, Process, LLM
import os
# 配置 LLM(也可直接用环境变量 OPENAI_API_KEY)
llm = LLM(model="gpt-4o-mini")
# ① 定义 Agent
researcher = Agent(
role="科技研究员",
goal="深入研究 {topic},找出最新的进展和关键信息",
backstory="你是一位经验丰富的科技记者,擅长快速定位关键信息并提炼要点。",
llm=llm,
verbose=True, # 打印执行过程,学习时建议开启
)
writer = Agent(
role="内容撰写者",
goal="将研究结果整理成一篇清晰易读的中文文章",
backstory="你是一位专业的科技博主,文风简洁,善于用通俗的语言解释复杂概念。",
llm=llm,
verbose=True,
)
# ② 定义 Task
research_task = Task(
description="对 {topic} 进行深入调研,总结 5 个最重要的技术要点。",
expected_output="包含 5 个关键技术要点的结构化摘要,每条 2-3 句话说明。",
agent=researcher,
)
write_task = Task(
description="基于研究员的调研结果,撰写一篇 500 字以内的中文科普文章。",
expected_output="一篇结构清晰、语言通俗的科普文章,包含引言、正文和结语。",
agent=writer,
context=[research_task], # 依赖研究任务的输出
output_file="article.md", # 自动保存到文件
)
# ③ 组建 Crew 并执行
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
process=Process.sequential, # 顺序执行
verbose=True,
)
result = crew.kickoff(inputs={"topic": "AI Agent 框架"})
print(result)
执行流程可视化:
用户调用 crew.kickoff(inputs)
│
▼
┌────────────────────┐
│ Task 1: 调研任务 │ ← researcher 执行
│ "研究 AI Agent 框架" │
└─────────┬──────────┘
│ 输出传递给下一个任务
▼
┌────────────────────┐
│ Task 2: 写作任务 │ ← writer 执行(拿到 Task1 的上下文)
│ "写一篇科普文章" │
└─────────┬──────────┘
│
▼
结果 + article.md 文件
4. Agent:你的 AI 员工
Agent 是 CrewAI 的灵魂。每个 Agent 就像一个有专业背景、个人目标、工作习惯的虚拟员工。
4.1 Agent 的完整参数
from crewai import Agent, LLM
from crewai.agent.planning_config import PlanningConfig
agent = Agent(
# ── 身份三要素(最重要!)──
role="高级数据分析师", # 角色定名,影响 LLM 的"人格"
goal="从数据中发现可操作的商业洞察", # 驱动目标
backstory="""你在金融行业有 10 年数据分析经验,
擅长用统计学方法发现隐藏规律,曾帮助多家上市公司优化运营策略。""",
# ── LLM 配置 ──
llm=LLM(model="gpt-4o"), # 默认用 OPENAI_API_KEY
# 也可以:llm="gpt-4o" 直接传字符串
# ── 工具配置 ──
tools=[], # 见第 7 章
# ── 执行控制 ──
max_iter=20, # ReAct 循环最大步数(默认 20)
max_retry_limit=2, # 出错最大重试次数
respect_context_window=True, # 超出 context 时自动摘要
# ── 记忆与委托 ──
memory=True, # 启用记忆(跨任务记住信息)
allow_delegation=False, # 是否允许委托给其他 Agent
# ── 规划能力(高级)──
planning=True, # 启用任务规划
planning_config=PlanningConfig(
reasoning_effort="medium", # low / medium / high
),
# ── 调试 ──
verbose=True, # 打印每一步的思考过程
)
4.2 Agent 内部执行机制(ReAct 循环)
这是理解 Agent 行为的关键。CrewAI Agent 用的是 ReAct(Reasoning + Acting) 模式:
┌─────────────────────────────────────────────────────────┐
│ Agent 的一次任务执行 │
└─────────────────────────────────────────────────────────┘
接收 Task
│
▼
┌───────────┐
│ Thought │ ← LLM 思考:"要完成这个任务,我需要..."
└─────┬─────┘
│
▼
┌───────────┐
│ Action │ ← 决定调用哪个工具,传入什么参数
└─────┬─────┘
│
▼
┌───────────┐
│Observation│ ← 工具返回结果
└─────┬─────┘
│
▼
还没完成?───► 循环回 Thought(最多 max_iter 次)
│
▼(任务完成)
┌───────────────┐
│ Final Answer │ ← 生成最终回答
└───────────────┘
│
▼
(可选)Memory 系统保存结果
│
▼
TaskOutput 返回
4.3 三种"身份"配置技巧
role / goal / backstory 是 Agent 最重要的三个参数,它们共同构成了给 LLM 的 System Prompt。
# ❌ 模糊的配置 → 产出质量差
bad_agent = Agent(
role="助手",
goal="帮忙做事",
backstory="我是一个 AI。",
)
# ✅ 具体的配置 → 产出质量高
good_agent = Agent(
role="法律合同审查专家",
goal="识别合同中的法律风险条款,保护委托方利益,特别关注违约责任、管辖权和知识产权归属",
backstory="""你有 15 年律师事务所经验,专注于商业合同领域。
你见过无数坑人的合同条款,养成了极度谨慎的阅读习惯。
你会优先识别"不平等条款"和"模糊措辞",用通俗语言向客户说明风险。""",
)
4.4 PlanningConfig 深度解析
从源码 planning_config.py 中可以看到,reasoning_effort 控制 Agent 的深度思考行为:
from crewai.agent.planning_config import PlanningConfig
# Low:最快,只验证步骤是否成功,不重新规划
agent_fast = Agent(
role="快速执行者",
planning_config=PlanningConfig(reasoning_effort="low"),
# ...
)
# Medium:失败时触发重规划(推荐的均衡选项)
agent_balanced = Agent(
role="均衡分析师",
planning_config=PlanningConfig(reasoning_effort="medium"),
# ...
)
# High:每步都进行深度观察和优化(最慢但最精准)
agent_deep = Agent(
role="深度研究员",
planning_config=PlanningConfig(
reasoning_effort="high",
llm=LLM(model="o1"), # 可为规划单独配置更强的模型
),
# ...
)
5. Task:分配给员工的工作
Task 定义了 Agent 需要完成什么,以及对输出的期望。
5.1 Task 完整参数
from crewai import Task
from pydantic import BaseModel
# 定义结构化输出(推荐!)
class AnalysisReport(BaseModel):
summary: str
risk_level: str # "low" | "medium" | "high"
recommendations: list[str]
confidence_score: float
task = Task(
# ── 核心配置 ──
description="""
分析以下股票 {ticker} 在过去 30 天的走势。
重点关注:
1. 价格波动率
2. 成交量异常
3. 与大盘的相关性
当前日期:{current_date}
""",
expected_output="一份包含风险评级和投资建议的分析报告",
agent=analyst_agent,
# ── 上下文依赖 ──
context=[data_collection_task], # 使用前序任务的输出
# ── 输出格式 ──
output_pydantic=AnalysisReport, # 结构化 Pydantic 输出
# output_json=AnalysisReport, # JSON 格式
# output_file="report.md", # 保存到文件
# ── 质量控制 ──
guardrail=validate_output, # 函数或字符串,用于校验输出
# ── 人机协作 ──
human_input=False, # True 则执行前请求人工确认
# ── 并行执行 ──
async_execution=False, # True 则异步并行
# ── Markdown 输出 ──
markdown=True, # 提示 Agent 用 Markdown 格式输出
)
5.2 Task 之间的数据流
Task A (数据收集) Task B (分析)
┌─────────────────┐ ┌─────────────────┐
│ description: │ context │ description: │
│ "收集股价数据" │────────────►│ "分析股票走势" │
│ │ │ │
│ output: │ │ 自动获得 Task A │
│ TaskOutput { │ │ 的输出作为背景 │
│ raw: "...", │ │ │
│ pydantic: ... │ │ output: │
│ } │ │ AnalysisReport │
└─────────────────┘ └─────────────────┘
5.3 ConditionalTask:按条件执行
from crewai.tasks.conditional_task import ConditionalTask
def should_deep_analyze(output):
"""只有风险等级为 high 时才做深度分析"""
if hasattr(output, 'pydantic') and output.pydantic:
return output.pydantic.risk_level == "high"
return False
# 普通任务
quick_analysis = Task(
description="快速评估风险等级",
expected_output="风险等级:low/medium/high",
agent=analyst,
output_pydantic=AnalysisReport,
)
# 条件任务:只有条件满足才执行
deep_analysis = ConditionalTask(
description="进行深度风险分析,详细拆解每个风险点",
expected_output="详细的风险分析报告,每个风险点含成因和应对措施",
agent=senior_analyst,
condition=should_deep_analyze, # 传入判断函数
)
5.4 Guardrail:输出质量守门员
from crewai.tasks.llm_guardrail import LLMGuardrail
# 方式1:函数式 Guardrail
def check_word_count(output):
"""确保输出不少于 200 字"""
if len(output.raw) < 200:
return (False, "输出太短,请补充更多细节,至少 200 字")
return (True, None) # (通过, 错误信息)
task = Task(
description="写一篇产品介绍",
expected_output="详细的产品介绍文章",
agent=writer,
guardrail=check_word_count,
)
# 方式2:LLM 智能审核(基于自然语言描述)
task_with_llm_guardrail = Task(
description="生成营销文案",
expected_output="吸引人的营销文案",
agent=copywriter,
guardrail=LLMGuardrail(
description="确保文案:1.不含夸大宣传 2.有明确行动呼吁 3.语气积极正面",
),
)
6. Crew:让员工组成团队
Crew 是 Agent 和 Task 的容器,负责协调整个执行过程。
6.1 两种执行模式
┌─────────────────────────────────────────────────────────────┐
│ Process.sequential(顺序模式) │
└─────────────────────────────────────────────────────────────┘
Task1 ──► Task2 ──► Task3 ──► Task4
(研究) (分析) (撰写) (校对)
↑ ↑ ↑ ↑
Agent1 Agent2 Agent3 Agent4
(收到 Task1 的输出)
适用:步骤明确、前后依赖的任务
┌─────────────────────────────────────────────────────────────┐
│ Process.hierarchical(层级模式) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ Manager Agent │ ← 自动生成,负责分配和审核
│ (CrewAI 创建) │
└────────┬────────┘
┌────────────┼────────────┐
▼ ▼ ▼
Task1 Task2 Task3
Agent1 Agent2 Agent3
适用:任务复杂,需要动态委托和审核,希望 AI 自主规划
6.2 YAML 配置方式(生产推荐)
# config/agents.yaml
senior_researcher:
role: >
{topic} 领域高级研究员
goal: >
深入研究 {topic} 的最新动态,找到关键突破和行业趋势
backstory: >
你是一位在 {topic} 领域有 10 年研究经验的专家学者,
发表过多篇高引用论文,善于从海量信息中提炼关键洞察。
data_analyst:
role: >
数据分析专家
goal: >
将研究数据可视化分析,发现隐藏的规律和异常
backstory: >
你精通统计学和数据可视化,能将复杂数据转化为清晰的商业洞察。
# config/tasks.yaml
research_task:
description: >
对 {topic} 进行全面调研。
重点:最新技术突破、主要参与者、市场趋势。
时间范围:最近 6 个月。
expected_output: >
包含以下结构的调研报告:
1. 执行摘要(200字)
2. 关键发现(5-8条)
3. 主要参与者分析
4. 趋势预测
agent: senior_researcher
analysis_task:
description: >
基于研究员的调研报告,进行深度数据分析,
量化关键指标,识别统计显著的趋势。
expected_output: >
数据分析报告,包含图表描述和统计结论
agent: data_analyst
context:
- research_task
output_file: analysis_report.md
# crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task, before_kickoff, after_kickoff
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew:
"""研究分析团队"""
agents: List[BaseAgent]
tasks: List[Task]
@before_kickoff
def setup(self, inputs):
"""执行前的准备工作"""
print(f"🚀 开始研究:{inputs.get('topic', '未知主题')}")
return inputs
@agent
def senior_researcher(self) -> Agent:
return Agent(
config=self.agents_config['senior_researcher'],
verbose=True,
tools=[SerperDevTool()], # 给研究员配搜索工具
)
@agent
def data_analyst(self) -> Agent:
return Agent(
config=self.agents_config['data_analyst'],
verbose=True,
)
@task
def research_task(self) -> Task:
return Task(config=self.tasks_config['research_task'])
@task
def analysis_task(self) -> Task:
return Task(config=self.tasks_config['analysis_task'])
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
memory=True, # 启用全局记忆
)
@after_kickoff
def cleanup(self, output):
"""执行后的收尾工作"""
print(f"✅ 研究完成!输出已保存。")
return output
6.3 并行执行加速
# 并行 Task:多个不相互依赖的任务同时执行
from crewai import Task
# 这三个任务可以同时进行
task_market = Task(
description="分析市场规模",
agent=market_analyst,
async_execution=True, # ← 关键
)
task_tech = Task(
description="分析技术可行性",
agent=tech_expert,
async_execution=True,
)
task_legal = Task(
description="分析法规合规性",
agent=legal_advisor,
async_execution=True,
)
# 汇总任务:等待所有并行任务完成
task_summary = Task(
description="综合以上三个分析,生成投资决策报告",
agent=senior_partner,
context=[task_market, task_tech, task_legal], # 依赖三个并行任务
)
并行执行示意图:
时间轴 ──────────────────────────────────────►
task_market ████████████████████ 完成
task_tech ████████████████ 完成
task_legal ██████████████████████ 完成
↓ 全部完成后
task_summary █████████ 汇总
7. Tools:给 Agent 配备武器
工具是 Agent 与外部世界交互的唯一途径。没有工具的 Agent 只能靠"脑中的知识"回答,有了工具才能真正"做事"。
7.1 官方内置工具(crewai-tools)
from crewai_tools import (
SerperDevTool, # Google 搜索
ScrapeWebsiteTool, # 网页抓取
FileReadTool, # 读取文件
FileWriterTool, # 写入文件
CSVSearchTool, # CSV 数据搜索
PDFSearchTool, # PDF 文档搜索
CodeInterpreterTool,# 代码执行(已废弃,建议用沙箱服务)
BrowserbaseTool, # 浏览器自动化
EXASearchTool, # 语义搜索
)
# 使用示例
search_tool = SerperDevTool() # 需要 SERPER_API_KEY 环境变量
web_tool = ScrapeWebsiteTool()
agent = Agent(
role="网络研究员",
goal="通过网络搜索获取最新信息",
backstory="...",
tools=[search_tool, web_tool],
)
7.2 自定义工具(两种方式)
方式一:装饰器(简单快速)
from crewai.tools import tool
@tool("天气查询工具")
def get_weather(city: str) -> str:
"""
查询指定城市的实时天气信息。
Args:
city: 城市名称,例如 "北京"、"上海"
Returns:
天气信息字符串
"""
# 实际项目中调用天气 API
import requests
# response = requests.get(f"https://api.weather.com/{city}")
return f"{city}:晴,25°C,湿度 60%,微风"
# 直接给 Agent 使用
agent = Agent(
role="旅行规划师",
tools=[get_weather],
# ...
)
方式二:继承 BaseTool(功能完整)
from crewai.tools.base_tool import BaseTool
from pydantic import BaseModel, Field
import requests
class DatabaseQueryInput(BaseModel):
"""工具输入参数的 Schema(Pydantic 验证)"""
sql: str = Field(description="要执行的 SQL 查询语句")
limit: int = Field(default=100, description="返回记录数上限")
class DatabaseQueryTool(BaseTool):
name: str = "数据库查询工具"
description: str = "执行 SQL 查询,从公司数据库中检索业务数据"
args_schema: type[BaseModel] = DatabaseQueryInput
# 工具的私有配置
connection_string: str = "postgresql://..."
def _run(self, sql: str, limit: int = 100) -> str:
"""同步执行"""
try:
# 实际的数据库查询逻辑
results = self._execute_query(sql, limit)
return f"查询成功,返回 {len(results)} 条记录:\n{results}"
except Exception as e:
return f"查询失败:{str(e)}"
async def _arun(self, sql: str, limit: int = 100) -> str:
"""异步执行(可选,用于高性能场景)"""
# 异步版本的实现
pass
def _execute_query(self, sql, limit):
# 实际查询逻辑...
pass
# 实例化并使用
db_tool = DatabaseQueryTool()
data_agent = Agent(
role="数据库分析师",
tools=[db_tool],
# ...
)
7.3 MCP 工具(现代标准)
MCP(Model Context Protocol)是 Anthropic 主导的工具调用标准,CrewAI 原生支持:
from crewai.mcp import MCPClient, MCPServerStdio, MCPServerHTTP
# ① 连接本地 MCP 服务(Stdio 传输 —— 本地子进程)
mcp_client = MCPClient(
servers={
"filesystem": MCPServerStdio(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp/workspace"],
),
"git": MCPServerStdio(
command="uvx",
args=["mcp-server-git"],
),
}
)
# ② 连接远程 MCP 服务(HTTP 传输)
remote_mcp = MCPClient(
servers={
"company_tools": MCPServerHTTP(
url="https://mcp.yourcompany.com/v1",
headers={"Authorization": "Bearer YOUR_TOKEN"},
)
}
)
# ③ 将 MCP 工具注入 Agent
with mcp_client:
tools = mcp_client.get_tools() # 自动发现服务端暴露的所有工具
dev_agent = Agent(
role="全栈开发工程师",
goal="使用文件系统和 Git 工具完成代码任务",
backstory="你是一位经验丰富的工程师,熟练使用各种开发工具。",
tools=tools,
)
MCP 工具的优势对比:
传统自定义工具 MCP 工具
┌─────────────────────┐ ┌─────────────────────────┐
│ • 每个工具写 Python │ │ • 标准协议,跨语言可复用 │
│ • 紧耦合,难复用 │ │ • 工具服务可独立部署 │
│ • 无服务发现 │ │ • 自动发现,即插即用 │
│ • 维护成本高 │ │ • 社区生态丰富(数百个服务)│
└─────────────────────┘ └─────────────────────────┘
8. Flow:精确掌控执行流程
Flow 是 CrewAI 的另一个核心范式,适合需要精确控制执行路径的生产场景。
8.1 Flow 的四大装饰器
Flow 装饰器体系:
@start() ──► 流程入口,Flow 执行时第一个被调用
@listen(fn) ──► 监听某函数完成后触发
@router(fn) ──► 路由器,根据返回字符串决定下一步走哪条路
@listen(or_(...)) ──► 任意一个完成就触发(OR 逻辑)
@listen(and_(...))──► 全部完成才触发(AND 逻辑)
8.2 Flow 状态管理
Flow 最强大的特性之一是结构化状态管理。状态在所有方法间共享,Pydantic 保证类型安全:
from crewai.flow.flow import Flow, listen, start, router, or_, and_
from pydantic import BaseModel
from typing import Literal
# ── 定义状态 Schema ──
class OrderState(BaseModel):
order_id: str = ""
customer_name: str = ""
items: list[str] = []
total_amount: float = 0.0
payment_status: Literal["pending", "paid", "failed"] = "pending"
inventory_ok: bool = False
shipping_address: str = ""
tracking_number: str = ""
# ── 定义 Flow ──
class OrderProcessingFlow(Flow[OrderState]):
@start()
def receive_order(self):
"""入口:接收订单"""
# self.state 就是 OrderState 实例,类型安全!
self.state.order_id = "ORD-2026-001"
self.state.customer_name = "张三"
self.state.items = ["iPhone 16", "AirPods Pro"]
self.state.total_amount = 9999.0
print(f"📦 收到订单 {self.state.order_id}")
return self.state.order_id # 返回值会传给监听者
@listen(receive_order)
def check_inventory(self, order_id: str):
"""监听订单接收,检查库存"""
print(f"🔍 检查库存,订单: {order_id}")
# 模拟库存检查
self.state.inventory_ok = True
return "inventory_checked"
@listen(receive_order)
def process_payment(self, order_id: str):
"""与库存检查并行:处理支付"""
print(f"💳 处理支付,订单: {order_id}")
self.state.payment_status = "paid"
return "payment_done"
@listen(and_(check_inventory, process_payment))
def arrange_shipping(self):
"""库存 AND 支付都完成后才安排发货"""
if self.state.inventory_ok and self.state.payment_status == "paid":
self.state.tracking_number = "SF1234567890"
print(f"🚚 安排发货,单号: {self.state.tracking_number}")
return "shipped"
return "hold"
@router(arrange_shipping)
def notify_customer(self):
"""路由:根据结果决定通知内容"""
if self.state.payment_status == "paid" and self.state.tracking_number:
return "success"
return "problem"
@listen("success")
def send_success_notification(self):
print(f"✅ 发货成功!通知 {self.state.customer_name},快递单号: {self.state.tracking_number}")
@listen("problem")
def send_problem_notification(self):
print(f"❌ 订单异常!通知客服处理订单 {self.state.order_id}")
# 执行
flow = OrderProcessingFlow()
result = flow.kickoff()
print(f"\n最终状态: {flow.state}")
执行流程图:
┌──────────────────┐
│ receive_order │ @start
└────────┬─────────┘
│ order_id
┌──────────────┴──────────────┐
▼ ▼
┌──────────────────┐ ┌────────────────────┐
│ check_inventory │ │ process_payment │
│ @listen │ │ @listen │
└────────┬─────────┘ └─────────┬──────────┘
│ │
└──────────┬──────────────────┘
│ and_() — 全部完成才触发
▼
┌──────────────────┐
│ arrange_shipping │ @listen(and_(...))
└────────┬─────────┘
│
▼
┌──────────────────┐
│ notify_customer │ @router — 返回路由字符串
└────────┬─────────┘
┌───────┴───────┐
▼ ▼
"success" "problem"
│ │
▼ ▼
send_success_ send_problem_
notification notification
8.3 Flow 中嵌入 Crew(终极组合)
这是 CrewAI 最强大的用法——在 Flow 的精确控制下,在关键步骤调用自治的 Crew:
from crewai.flow.flow import Flow, listen, start, router
from crewai import Crew, Agent, Task, Process
from pydantic import BaseModel
class ContentState(BaseModel):
topic: str = ""
research_result: str = ""
draft: str = ""
review_passed: bool = False
final_article: str = ""
publish_platform: str = ""
class ContentPipelineFlow(Flow[ContentState]):
@start()
def select_topic(self):
"""Flow 直接执行 Python 逻辑(无需 LLM)"""
import datetime
# 根据当天日期选题
today = datetime.date.today().weekday()
topics = ["AI进展", "开源工具", "工程实践", "架构设计", "职场成长"]
self.state.topic = topics[today]
print(f"📝 今日选题:{self.state.topic}")
@listen(select_topic)
def research_and_draft(self):
"""调用 Crew 完成研究和起草(多 Agent 协作)"""
# 在 Flow 内部按需创建 Crew
researcher = Agent(
role="内容研究员",
goal=f"研究 {self.state.topic} 的最新内容",
backstory="你是一位快速研究员,擅长在30分钟内找到核心信息。",
)
writer = Agent(
role="科技博主",
goal="将研究成果写成吸引人的博客文章",
backstory="你写过 200+ 篇科技文章,了解读者喜欢什么样的内容。",
)
research = Task(
description=f"研究 {self.state.topic},找出 5 个关键点",
expected_output="5个关键技术要点,每条附简短说明",
agent=researcher,
)
draft = Task(
description="基于研究结果写一篇 800 字博客,包含引言/正文/结语",
expected_output="完整的博客文章草稿",
agent=writer,
context=[research],
)
crew = Crew(
agents=[researcher, writer],
tasks=[research, draft],
process=Process.sequential,
)
result = crew.kickoff(inputs={"topic": self.state.topic})
self.state.draft = result.raw
print(f"✍️ 草稿完成,共 {len(self.state.draft)} 字")
@listen(research_and_draft)
def review_quality(self):
"""Flow 直接做质量检验(Python 逻辑,不消耗 LLM Token)"""
word_count = len(self.state.draft)
has_intro = "引言" in self.state.draft or "背景" in self.state.draft
self.state.review_passed = word_count >= 400 and has_intro
print(f"🔍 质量审核:{'通过' if self.state.review_passed else '不通过'} (字数: {word_count})")
@router(review_quality)
def route_after_review(self):
"""路由:通过则发布,否则修改"""
return "publish" if self.state.review_passed else "revise"
@listen("publish")
def publish_article(self):
self.state.final_article = self.state.draft
self.state.publish_platform = "微信公众号"
print(f"🚀 发布到 {self.state.publish_platform}!")
@listen("revise")
def request_revision(self):
"""修改后重新进入 research_and_draft(也可递归调用)"""
print("🔄 质量不达标,返回修改...")
self.state.draft = self.state.draft + "\n\n[已补充更多内容...]"
self.state.review_passed = True # 修改后直接通过
# 运行
flow = ContentPipelineFlow()
flow.kickoff()
Crew + Flow 组合优势图:
┌─────────────────────────────────────────────────────────────┐
│ Flow 精确控制层 │
│ │
│ Python逻辑 ──► Crew协作 ──► Python校验 ──► 路由分发 │
│ (零Token消耗) (自治协作) (零Token消耗) (精确控制) │
│ │
│ ✅ 用 Python 做能做的事(便宜、快速、可靠) │
│ ✅ 只在真正需要 AI 的步骤调用 Crew │
│ ✅ 全程状态可见、可序列化、可恢复 │
└─────────────────────────────────────────────────────────────┘
9. Memory:让 Agent 拥有记忆
没有记忆的 Agent 每次执行都是"失忆状态"。CrewAI 的统一记忆系统让 Agent 能跨任务、跨 Crew 甚至跨次运行保留信息。
9.1 记忆架构
┌──────────────────────────────────────────────────────────────┐
│ CrewAI 统一记忆系统 │
├──────────────────────────────────────────────────────────────┤
│ │
│ Agent 执行完任务 │
│ │ │
│ ▼ │
│ ┌─────────────────┐ LLM 分析提取 ┌──────────────────┐ │
│ │ 原始输出内容 │ ──────────────► │ MemoryRecord │ │
│ └─────────────────┘ │ content: "..." │ │
│ │ scope: "/crew/ │ │
│ │ agent_id/..." │ │
│ │ category: "fact"│ │
│ │ embedding: [...] │ │
│ └────────┬─────────┘ │
│ │ 向量化存储 │
│ ▼ │
│ ┌─────────────────────────────┐ │
│ │ StorageBackend │ │
│ │ │ │
│ │ LanceDB(默认,本地) │ │
│ │ Qdrant(云端生产) │ │
│ │ 自定义(实现 Protocol) │ │
│ └────────────┬────────────────┘ │
│ │ │
│ 下次任务执行时 │ 相似度搜索 │
│ │ │ │
│ ▼ ▼ │
│ Task 描述 → 生成 embedding → 查询相关记忆 → 注入上下文 │
└──────────────────────────────────────────────────────────────┘
9.2 记忆的作用域(Scope)
从源码 memory/types.py 可以看到,记忆用层级路径组织作用域,类似文件系统:
/ ← 全局共享
├── /crew/{crew_id}/ ← Crew 级别(同 Crew 内 Agent 共享)
│ ├── /agent/{agent_id}/ ← Agent 私有记忆
│ └── /task/{task_id}/ ← 任务级别记忆
└── /flow/{flow_id}/ ← Flow 级别
from crewai import Agent, Crew, Task, Process, Memory
# 最简单:给 Crew 开启记忆(推荐起步配置)
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
process=Process.sequential,
memory=True, # ← 启用记忆,使用默认 LanceDB
verbose=True,
)
# 进阶:自定义记忆配置
from crewai import Memory
from crewai.memory.storage.lancedb_storage import LanceDBStorage
memory = Memory(
storage=LanceDBStorage(
path="./my_memory_db", # 自定义存储路径(跨次运行持久化)
),
embedder={
"provider": "openai",
"config": {"model": "text-embedding-3-small"},
},
)
crew_with_memory = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
memory=memory,
)
9.3 三种记忆类型(对应不同场景)
记忆类型 作用域 典型用途
─────────────────────────────────────────────────────
短期记忆(Short-term) 当次任务执行 任务内的工具调用结果
内部自动管理 Agent 思考链
─────────────────────────────────────────────────────
长期记忆(Long-term) 跨次运行持久化 用户偏好、历史决策
存入向量数据库 过往项目经验
─────────────────────────────────────────────────────
实体记忆(Entity) 全局命名实体 "张三"是谁?
自动识别提取 "A公司"的业务是什么?
─────────────────────────────────────────────────────
# Crew 级别控制各类记忆
crew = Crew(
agents=[...],
tasks=[...],
memory=True, # 全部开启(推荐)
# 或精细控制:
# short_term_memory=..., # 自定义短期记忆配置
# long_term_memory=..., # 自定义长期记忆配置
# entity_memory=..., # 自定义实体记忆配置
)
9.4 记忆的实际效果
第1次运行:
Agent 研究"GPT-5发布" ──► 记忆保存:{"content": "GPT-5于2025年发布,支持1M token"}
第2次运行(不同任务):
Agent 收到问题"OpenAI最新模型是什么"
│
▼ 记忆检索(向量相似度)
找到相关记忆:{"content": "GPT-5于2025年发布,支持1M token"}
│
▼ 注入上下文
Agent 回答时已知道 GPT-5 的信息,无需重新查询!
10. Knowledge:注入领域知识
Memory 是 Agent 运行后积累的,而 Knowledge 是运行前就注入的先验知识库。
10.1 Knowledge 架构
┌──────────────────────────────────────────────────────────────┐
│ Knowledge 知识库系统 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 数据源(Sources) 处理 向量存储 │
│ ┌───────────────┐ │
│ │ PDF 文件 │──► 分块(Chunk) │
│ │ Word 文档 │──► 清洗(Clean) ──► Embeddings │
│ │ CSV 表格 │──► 索引(Index) │ │
│ │ Excel │ ▼ │
│ │ JSON 数据 │ KnowledgeStorage │
│ │ 网页 URL │ (ChromaDB / Qdrant) │
│ │ 纯文本 │ │ │
│ │ Docling文档 │ │ RAG检索 │
│ └───────────────┘ ▼ │
│ Agent 获得相关知识片段 │
└──────────────────────────────────────────────────────────────┘
10.2 使用示例
from crewai import Agent, Crew, Task, Knowledge
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from crewai.knowledge.source.text_knowledge_source import TextKnowledgeSource
from crewai.knowledge.source.csv_knowledge_source import CSVKnowledgeSource
from crewai.knowledge.source.json_knowledge_source import JSONKnowledgeSource
# ── 方式1:PDF 知识库 ──
pdf_source = PDFKnowledgeSource(
file_paths=["company_handbook.pdf", "product_manual.pdf"],
chunk_size=1000, # 每块 1000 字符
chunk_overlap=200, # 块间重叠 200 字符(保持上下文)
)
# ── 方式2:结构化数据(CSV/JSON)──
csv_source = CSVKnowledgeSource(
file_paths=["sales_data.csv"],
)
json_source = JSONKnowledgeSource(
file_paths=["product_catalog.json"],
)
# ── 方式3:直接文本 ──
text_source = TextKnowledgeSource(
content="""
公司政策摘要:
1. 差旅报销上限:经济舱 5000元/次,商务舱需总监审批
2. 请假制度:年假15天,需提前3天申请
3. 绩效考核:每季度一次,采用 OKR 体系
""",
)
# ── 创建知识库 ──
company_knowledge = Knowledge(
sources=[pdf_source, csv_source, text_source],
embedder={
"provider": "openai",
"config": {"model": "text-embedding-3-small"},
},
collection_name="company_docs", # 同名则复用已有索引,避免重复向量化
)
# ── 注入到 Agent ──
hr_agent = Agent(
role="HR 助手",
goal="准确回答员工关于公司政策和福利的问题",
backstory="你熟悉公司的各项规章制度,能准确引用政策条款。",
knowledge=company_knowledge, # Agent 级别知识库
)
# ── 也可以给整个 Crew 注入 ──
crew = Crew(
agents=[hr_agent, ...],
tasks=[...],
knowledge=company_knowledge, # Crew 级别知识库(所有 Agent 共享)
)
11. 进阶特性大全
11.1 Human-in-the-Loop(人机协作)
在关键节点暂停,等待人工确认或修改:
# 方式1:Task 级别(执行前询问)
risky_task = Task(
description="删除所有过期用户数据",
expected_output="删除操作的执行报告",
agent=data_engineer,
human_input=True, # ← 执行前会暂停,等待人工确认
)
# 方式2:Agent 级别(每次迭代都可以介入)
cautious_agent = Agent(
role="财务审计师",
goal="审计财务报表",
backstory="...",
# 通过 Crew 的 step_callback 实现细粒度控制
)
def my_step_callback(agent_output):
"""每个 Agent 步骤完成后回调"""
print(f"Agent 完成了一步:{agent_output}")
# 可以在这里记录日志、触发告警等
crew = Crew(
agents=[cautious_agent],
tasks=[...],
step_callback=my_step_callback,
task_callback=lambda output: print(f"Task 完成:{output.description}"),
)
11.2 Checkpoint 断点续跑(生产必备)
这是 2026 年 CrewAI 最重要的新特性之一。长任务中途失败不再需要从头来过:
from crewai import Crew, Agent, Task, Process
from crewai.state.checkpoint_config import CheckpointConfig
# 开启 Checkpoint
crew = Crew(
agents=[researcher, analyst, writer],
tasks=[task1, task2, task3, task4, task5],
process=Process.sequential,
checkpoint_config=CheckpointConfig(
enabled=True,
storage_path="./checkpoints", # 检查点存储目录
auto_save=True, # 每个 Task 完成后自动保存
),
)
# 正常执行(会在每个 Task 完成后保存断点)
result = crew.kickoff(inputs={"topic": "AI 市场分析"})
Checkpoint 工作原理:
任务执行序列:
Task1 ──► [CHECKPOINT] ──► Task2 ──► [CHECKPOINT] ──► Task3 ──► 💥FAIL
✅已完成 ✅已完成 ❌失败
修复 Bug 后恢复:
▼ 从 Task3 断点恢复
Task3 ──► Task4 ──► Task5
✅ ✅ ✅
无需重新执行 Task1 和 Task2!节省时间和费用!
# 从检查点恢复(CLI 命令)
# crewai replay -n 2 (从第2个task开始重跑)
# 代码中恢复
from crewai import Crew
# 重新创建相同 Crew,框架会自动检测并加载最近的 checkpoint
crew = Crew(
agents=[researcher, analyst, writer],
tasks=[task1, task2, task3, task4, task5],
checkpoint_config=CheckpointConfig(
enabled=True,
storage_path="./checkpoints",
),
)
result = crew.kickoff(inputs={"topic": "AI 市场分析"}) # 自动从断点继续
11.3 LLM Hooks:拦截和修改 LLM 调用
Hooks 允许你在 LLM 调用的前后插入自定义逻辑——日志、成本控制、内容过滤等:
from crewai.hooks.llm_hooks import (
LLMCallHookContext,
register_before_llm_call_hook,
register_after_llm_call_hook,
)
# ── Before Hook:调用前拦截 ──
def cost_guard_hook(ctx: LLMCallHookContext) -> None:
"""预算守卫:Token 超限则截断消息"""
total_chars = sum(len(str(m)) for m in ctx.messages)
if total_chars > 50000:
# 截断最早的消息,保留系统消息
ctx.messages = [ctx.messages[0]] + ctx.messages[-5:]
print("⚠️ 消息过长,已自动截断")
def audit_log_hook(ctx: LLMCallHookContext) -> None:
"""审计日志:记录所有 LLM 调用"""
import json, datetime
log = {
"timestamp": datetime.datetime.now().isoformat(),
"agent_role": getattr(ctx.executor, 'role', 'unknown') if ctx.executor else 'direct',
"message_count": len(ctx.messages),
}
with open("llm_audit.jsonl", "a") as f:
f.write(json.dumps(log, ensure_ascii=False) + "\n")
# ── After Hook:响应后处理 ──
def token_tracker_hook(ctx: LLMCallHookContext) -> None:
"""Token 追踪:统计成本"""
if ctx.response:
# ctx.response 是 LLM 返回的完整响应对象
print(f"本次调用消耗 Token:{getattr(ctx.response, 'usage', 'N/A')}")
# 注册为全局 Hook(对所有 Agent 生效)
register_before_llm_call_hook(cost_guard_hook)
register_before_llm_call_hook(audit_log_hook)
register_after_llm_call_hook(token_tracker_hook)
# 之后创建的所有 Crew/Agent 都会自动应用这些 Hook
11.4 Event Bus:监听框架内部事件
CrewAI 有一个完整的事件系统,你可以监听任何内部事件:
from crewai.events.event_bus import crewai_event_bus
from crewai.events.event_listener import event_listener
from crewai.events.types.agent_events import (
AgentExecutionStartedEvent,
AgentExecutionCompletedEvent,
)
from crewai.events.types.task_events import (
TaskStartedEvent,
TaskCompletedEvent,
)
from crewai.events.types.crew_events import (
CrewKickoffStartedEvent,
CrewKickoffCompletedEvent,
)
# 创建自定义事件监听器
class MyMonitor:
@event_listener.on(CrewKickoffStartedEvent)
def on_crew_start(self, event: CrewKickoffStartedEvent):
print(f"🚀 Crew 开始执行:{event.crew_name}")
@event_listener.on(TaskStartedEvent)
def on_task_start(self, event: TaskStartedEvent):
print(f"▶️ 任务开始:{event.task_description[:50]}...")
@event_listener.on(TaskCompletedEvent)
def on_task_done(self, event: TaskCompletedEvent):
print(f"✅ 任务完成,输出:{event.output.raw[:100]}...")
@event_listener.on(AgentExecutionCompletedEvent)
def on_agent_done(self, event: AgentExecutionCompletedEvent):
print(f"🤖 [{event.agent_role}] 完成执行")
monitor = MyMonitor()
CrewAI 完整事件类型图:
事件类别 事件(Started / Completed / Failed)
────────────────────────────────────────────────────────────
Crew 事件 CrewKickoff*, CrewTrain*, CrewTest*
Task 事件 TaskStarted, TaskCompleted, TaskFailed
Agent 事件 AgentExecution*, LiteAgentExecution*
LLM 事件 LLMCallStarted/Completed/Failed, LLMStreamChunk
Tool 事件 ToolUsageStarted/Finished/Error
Memory 事件 MemorySave*, MemoryQuery*, MemoryRetrieval*
Knowledge 事件 KnowledgeQuery*, KnowledgeRetrieval*
MCP 事件 MCPConnection*, MCPToolExecution*
A2A 事件 A2ADelegation*, A2AConversation*, A2AStreaming*
11.5 A2A:Agent 间网络通信
A2A(Agent-to-Agent)是 CrewAI 最新的分布式特性,允许不同机器上的 Agent 互相调用:
from crewai import Agent, Crew
from crewai.a2a.config import A2AServerConfig, A2AClientConfig
# ── 服务端:暴露一个 Agent 为远程可调用服务 ──
expert_agent = Agent(
role="法律专家",
goal="提供准确的法律建议",
backstory="你是一位有20年经验的律师。",
# 通过 A2AServerConfig 让此 Agent 可被远程调用
)
server_crew = Crew(
agents=[expert_agent],
tasks=[...],
a2a=A2AServerConfig(
host="0.0.0.0",
port=8080,
# auth=... 可配置认证
),
)
# ── 客户端:像调用本地 Agent 一样调用远程 Agent ──
remote_legal_agent = Agent(
role="法律顾问(远程)",
goal="通过远程服务获取法律意见",
backstory="...",
a2a=A2AClientConfig(
url="http://legal-service.company.com:8080",
),
)
# 在本地 Crew 中使用远程 Agent,无需关心底层通信
local_crew = Crew(
agents=[local_agent, remote_legal_agent],
tasks=[...],
)
A2A 通信架构:
服务器 A(法律服务) 服务器 B(业务系统)
┌─────────────────┐ ┌─────────────────────┐
│ LegalCrew │ │ BusinessCrew │
│ ┌───────────┐ │ HTTP/SSE │ ┌───────────────┐ │
│ │LegalAgent │◄─┼─────────────┼──│RemoteLegalAgent│ │
│ └───────────┘ │ │ └───────────────┘ │
│ A2AServer:8080 │ │ BusinessAgent │
└─────────────────┘ └─────────────────────┘
12. 高级架构:生产级实战
12.1 完整企业级示例:智能客服系统
这个例子综合运用了 Flow、Crew、Memory、Knowledge、Guardrail 等核心特性:
# ============================================================
# 企业级智能客服系统
# 支持:意图识别 → 知识检索 → 多 Agent 协同回答 → 质量控制
# ============================================================
from crewai import Agent, Crew, Task, Process, Knowledge, Memory, LLM
from crewai.flow.flow import Flow, listen, start, router
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from crewai.knowledge.source.text_knowledge_source import TextKnowledgeSource
from crewai.tasks.llm_guardrail import LLMGuardrail
from crewai.hooks.llm_hooks import register_before_llm_call_hook
from pydantic import BaseModel
from typing import Literal
import json
# ── 1. 成本控制 Hook ──
def token_limiter(ctx):
"""全局 Token 守卫,避免超出预算"""
if len(ctx.messages) > 20:
# 保留系统消息 + 最近 10 条
ctx.messages = ctx.messages[:1] + ctx.messages[-10:]
register_before_llm_call_hook(token_limiter)
# ── 2. 知识库配置 ──
product_knowledge = Knowledge(
sources=[
PDFKnowledgeSource(file_paths=["product_manual.pdf"]),
TextKnowledgeSource(content="""
常见问题解答:
Q: 退款政策?A: 7天无理由退款,15天内质量问题换货
Q: 发货时间?A: 付款后24小时内发货,3-5个工作日到达
Q: 会员权益?A: 黄金会员享受9折优惠,白金会员享受85折
"""),
],
collection_name="customer_service_kb",
)
# ── 3. Flow 状态 ──
class ServiceState(BaseModel):
user_query: str = ""
intent: Literal["product", "order", "complaint", "other"] = "other"
response: str = ""
satisfaction_score: float = 0.0
escalate_to_human: bool = False
# ── 4. 专业 Agent 定义 ──
llm_fast = LLM(model="gpt-4o-mini") # 低成本模型用于简单任务
llm_strong = LLM(model="gpt-4o") # 强
intent_agent = Agent(
role="用户意图识别专家",
goal="精准判断用户咨询属于哪个类别",
backstory="你是电商客服系统的意图分析模块,能在一句话内准确分类用户问题。",
llm=llm_fast, # 简单分类任务用便宜的模型
)
product_agent = Agent(
role="产品咨询专员",
goal="基于知识库准确回答产品问题",
backstory="你熟记公司所有产品的参数、规格和常见问题,回答专业且友好。",
llm=llm_strong,
knowledge=product_knowledge, # 注入产品知识库
)
order_agent = Agent(
role="订单服务专员",
goal="处理订单查询、退换货等售后问题",
backstory="你精通公司的订单系统,能快速查询订单状态并给出解决方案。",
llm=llm_fast,
)
complaint_agent = Agent(
role="投诉处理专员",
goal="安抚客户情绪,妥善处理投诉,保留客户",
backstory="你有丰富的危机处理经验,善于在解决问题的同时维护客户关系。",
llm=llm_strong, # 投诉处理用更强的模型
)
# ── 5. 主 Flow ──
class CustomerServiceFlow(Flow[ServiceState]):
@start()
def receive_query(self):
"""入口:接收用户咨询(实际场景从请求/队列读取)"""
self.state.user_query = "我买的手机壳三天就掉色了,太差了!"
print(f"📨 收到咨询:{self.state.user_query}")
@listen(receive_query)
def classify_intent(self):
"""Step 1:意图分类(单 Agent 快速执行)"""
classify_task = Task(
description=f"""
将以下用户咨询分类为:product/order/complaint/other
咨询内容:"{self.state.user_query}"
只返回类别英文单词,不要其他内容。
""",
expected_output="product 或 order 或 complaint 或 other",
agent=intent_agent,
)
crew = Crew(agents=[intent_agent], tasks=[classify_task])
result = crew.kickoff()
intent_raw = result.raw.strip().lower()
# 防御性解析
if intent_raw in ["product", "order", "complaint", "other"]:
self.state.intent = intent_raw
else:
self.state.intent = "other"
print(f"🏷️ 意图识别:{self.state.intent}")
@router(classify_intent)
def route_to_department(self):
"""Step 2:路由到对应部门"""
return self.state.intent
@listen("product")
def handle_product_query(self):
task = Task(
description=f"回答用户关于产品的问题:{self.state.user_query}",
expected_output="专业、友好、完整的产品咨询回答,不超过200字",
agent=product_agent,
guardrail=LLMGuardrail(description="回答必须基于事实,不得承诺不存在的功能"),
)
crew = Crew(agents=[product_agent], tasks=[task], memory=True)
self.state.response = crew.kickoff().raw
@listen("order")
def handle_order_query(self):
task = Task(
description=f"处理用户订单问题:{self.state.user_query}",
expected_output="清晰说明处理方案和预计时间",
agent=order_agent,
)
crew = Crew(agents=[order_agent], tasks=[task])
self.state.response = crew.kickoff().raw
@listen("complaint")
def handle_complaint(self):
task = Task(
description=f"""
处理以下用户投诉:"{self.state.user_query}"
要求:1.先表达歉意 2.承诺解决方案 3.给出补偿(如优惠券)
""",
expected_output="安抚投诉的完整回复,包含具体解决方案",
agent=complaint_agent,
)
crew = Crew(agents=[complaint_agent], tasks=[task])
self.state.response = crew.kickoff().raw
# 投诉触发升级评估
self.state.escalate_to_human = "严重" in self.state.user_query
@listen("other")
def handle_other(self):
self.state.response = "感谢您的咨询!您的问题已转交人工客服,预计3分钟内回复。"
@listen(or_("product", "order", "complaint", "other"))
def finalize_response(self):
"""所有分支汇合后统一后处理"""
if self.state.escalate_to_human:
print("🔴 升级人工处理!")
print(f"\n💬 最终回复:\n{self.state.response}")
# 执行
flow = CustomerServiceFlow()
flow.kickoff()
12.2 批量处理:kickoff_for_each
当你有大量相似任务要并行处理时,kickoff_for_each 是最优解:
from crewai import Crew, Agent, Task, Process
# 定义一个通用的报告生成 Crew
analyst = Agent(
role="财务分析师",
goal="分析企业财务数据并生成简报",
backstory="你是一位擅长快速解读财务报表的分析师。",
)
analysis_task = Task(
description="分析 {company} 的 {year} 年财务数据,重点关注营收、利润和现金流",
expected_output="一份 300 字以内的财务简报",
agent=analyst,
output_file="{company}_{year}_report.md", # 动态文件名
)
report_crew = Crew(
agents=[analyst],
tasks=[analysis_task],
process=Process.sequential,
)
# 批量处理多个公司
companies_data = [
{"company": "阿里巴巴", "year": "2025"},
{"company": "腾讯", "year": "2025"},
{"company": "字节跳动", "year": "2025"},
{"company": "华为", "year": "2025"},
{"company": "小米", "year": "2025"},
]
# 串行版本
results = report_crew.kickoff_for_each(inputs=companies_data)
# 并行版本(async,更快)
import asyncio
async def run_parallel():
results = await report_crew.kickoff_for_each_async(inputs=companies_data)
return results
results = asyncio.run(run_parallel())
for i, result in enumerate(results):
company = companies_data[i]["company"]
print(f"\n{'='*40}")
print(f"📊 {company} 财务简报")
print(f"{'='*40}")
print(result.raw)
print(f"Token 消耗:{result.token_usage.total_tokens}")
12.3 流式输出(Streaming)
生产环境中实时展示 Agent 思考过程:
from crewai import Crew, Agent, Task
from crewai.crews.crew_output import CrewStreamingOutput
async def stream_crew_output():
writer = Agent(
role="创意写手",
goal="写出引人入胜的故事",
backstory="你是一位才华横溢的故事作家。",
)
write_task = Task(
description="写一个关于 AI 觉醒的短篇科幻故事,500 字以内",
expected_output="完整的科幻短篇故事",
agent=writer,
)
crew = Crew(agents=[writer], tasks=[write_task])
# 流式执行
async for chunk in await crew.kickoff_async(stream=True):
if isinstance(chunk, CrewStreamingOutput):
# 实时打印每个 Token
print(chunk.content, end="", flush=True)
else:
# 最终完整结果
print(f"\n\n✅ 完成!总 Token:{chunk.token_usage.total_tokens}")
import asyncio
asyncio.run(stream_crew_output())
12.4 输出数据追踪
每次 kickoff() 都返回 CrewOutput,包含完整的执行数据:
result = crew.kickoff(inputs={"topic": "量子计算"})
# ── 访问结果 ──
print(result.raw) # 最终输出文本
print(result.json_dict) # JSON 格式(如果任务配置了 output_json)
print(result.pydantic) # Pydantic 对象(如果任务配置了 output_pydantic)
# ── 每个任务的输出 ──
for task_output in result.tasks_output:
print(f"任务:{task_output.description[:50]}")
print(f"输出:{task_output.raw[:200]}")
print(f"Agent:{task_output.agent}")
# ── Token 用量统计(成本控制必备)──
usage = result.token_usage
print(f"""
Token 用量统计:
总 Token: {usage.total_tokens:,}
Prompt Token:{usage.prompt_tokens:,}
缓存命中: {usage.cached_prompt_tokens:,}
输出 Token: {usage.completion_tokens:,}
成功请求数: {usage.successful_requests}
预估成本(GPT-4o):${usage.prompt_tokens/1e6*2.5 + usage.completion_tokens/1e6*10:.4f}
""")
13. 与其他框架对比
13.1 全面对比矩阵
维度 CrewAI LangGraph AutoGen ChatDev
─────────────────────────────────────────────────────────────────────────
独立性 ✅ 完全独立 ❌ 依赖 LangChain ✅ 独立 ✅ 独立
学习曲线 ⭐⭐⭐ 中等 ⭐⭐⭐⭐⭐ 陡峭 ⭐⭐⭐ 中等 ⭐⭐ 简单
角色扮演 ✅ 原生支持 ⚠️ 需手动实现 ✅ 支持 ✅ 支持
执行速度 ✅ 极快 ⚠️ 中等 ✅ 快 ⚠️ 中等
工作流控制 ✅ Flow 精确控制 ✅ 图结构强控制 ❌ 复杂时混乱 ❌ 固化流程
生产部署 ✅ 企业级特性 ⚠️ 需自建 ⚠️ 需要工作 ❌ 不适合
并行执行 ✅ async_exec ✅ 支持 ⚠️ 有限 ❌ 串行
记忆系统 ✅ 统一记忆 ⚠️ 需集成 ⚠️ 需集成 ❌ 无
RAG 知识库 ✅ 原生 Knowledge ⚠️ 需集成 ⚠️ 需集成 ❌ 无
Checkpoint ✅ 原生支持 ⚠️ 需自建 ❌ 无 ❌ 无
MCP 支持 ✅ 原生支持 ⚠️ 需插件 ❌ 无 ❌ 无
社区活跃度 ✅ 10万+认证 ⭐⭐⭐⭐ 活跃 ⭐⭐⭐ 活跃 ⭐⭐ 一般
13.2 选型建议
你的场景 推荐框架
────────────────────────────────────────────────────────
快速验证 AI 多 Agent 想法 CrewAI(最快上手)
需要与 LangChain 生态深度集成 LangGraph
学术研究、对话式多 Agent AutoGen
构建企业级生产 AI 自动化系统 CrewAI(Flows + Crews)
需要极致精细的图状态机控制 LangGraph
附录 A:完整速查手册
A.1 常用 LLM 模型配置
from crewai import LLM
# OpenAI(默认,需 OPENAI_API_KEY)
llm = LLM(
model="gpt-4o",
temperature=0.7, # 0=确定性,1=创意性
max_tokens=4096,
top_p=0.9,
timeout=120, # 超时秒数
max_retries=3,
)
# Anthropic Claude(需 ANTHROPIC_API_KEY)
llm_claude = LLM(
model="claude-sonnet-4-20250514",
temperature=0.5,
)
# Google Gemini(需 GEMINI_API_KEY)
llm_gemini = LLM(
model="gemini/gemini-2.0-flash",
temperature=0.3,
)
# 本地模型(Ollama,无需 API Key)
llm_local = LLM(
model="ollama/llama3.2",
base_url="http://localhost:11434",
)
# Azure OpenAI(需 AZURE_API_KEY 等环境变量)
llm_azure = LLM(
model="azure/gpt-4o",
base_url="https://YOUR_RESOURCE.openai.azure.com/",
api_version="2024-02-01",
)
# AWS Bedrock(需 AWS 凭证)
llm_bedrock = LLM(
model="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
)
A.2 环境变量速查
# .env 文件配置示例
# ── LLM API Keys ──
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=...
AZURE_API_KEY=...
# ── 工具 API Keys ──
SERPER_API_KEY=... # Google 搜索(SerperDevTool)
EXA_API_KEY=... # 语义搜索(EXASearchTool)
BROWSERBASE_API_KEY=... # 浏览器工具
# ── CrewAI 配置 ──
OTEL_SDK_DISABLED=true # 禁用遥测
CREWAI_STORAGE_DIR=./storage # 自定义存储路径
# ── 向量数据库(Memory/Knowledge)──
# LanceDB(默认,本地文件,无需配置)
# Qdrant(云端)
QDRANT_URL=https://...
QDRANT_API_KEY=...
A.3 调试技巧
# ① verbose=True:打印 Agent 每一步的思考和行动
agent = Agent(role="...", verbose=True)
crew = Crew(agents=[...], tasks=[...], verbose=True)
# ② 事件监听:精细追踪执行状态
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallStartedEvent, LLMCallCompletedEvent
@crewai_event_bus.on(LLMCallStartedEvent)
def log_llm_call(event):
print(f"[LLM] 开始调用,消息数:{len(event.messages)}")
@crewai_event_bus.on(LLMCallCompletedEvent)
def log_llm_done(event):
print(f"[LLM] 调用完成,Token:{event.usage}")
# ③ Token 成本预算
from crewai.hooks.llm_hooks import register_after_llm_call_hook
total_cost = {"value": 0.0}
def track_cost(ctx):
if ctx.response and hasattr(ctx.response, 'usage'):
usage = ctx.response.usage
# GPT-4o 定价(每百万 Token)
cost = (usage.prompt_tokens / 1e6 * 2.5 +
usage.completion_tokens / 1e6 * 10)
total_cost["value"] += cost
if total_cost["value"] > 1.0: # 超过 1 美元警告
print(f"⚠️ 累计成本:${total_cost['value']:.4f},请注意预算!")
register_after_llm_call_hook(track_cost)
# ④ 打印系统 Prompt(了解 Agent 实际收到了什么)
import os
os.environ["CREWAI_LOG_LEVEL"] = "DEBUG" # 开启 DEBUG 日志
A.4 项目结构最佳实践
my_ai_project/
├── .env # API Keys(不提交 Git!)
├── .gitignore
├── pyproject.toml
├── README.md
│
├── src/my_ai_project/
│ ├── __init__.py
│ ├── main.py # 入口,只做参数解析和调用
│ │
│ ├── crews/ # 按功能划分的 Crew 定义
│ │ ├── research_crew.py
│ │ ├── analysis_crew.py
│ │ └── report_crew.py
│ │
│ ├── flows/ # Flow 定义
│ │ └── main_pipeline.py
│ │
│ ├── tools/ # 自定义工具
│ │ ├── __init__.py
│ │ ├── database_tool.py
│ │ └── api_client_tool.py
│ │
│ ├── config/ # YAML 配置
│ │ ├── agents.yaml
│ │ └── tasks.yaml
│ │
│ └── knowledge/ # 知识库文件
│ ├── company_docs/
│ └── product_manuals/
│
├── checkpoints/ # Checkpoint 存储
├── outputs/ # 任务输出文件
└── tests/ # 测试
├── test_tools.py
└── test_crews.py
附录 B:学习路线图
┌─────────────────────────────────────────────────────────────────┐
│ CrewAI 学习路线图 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 第一阶段:入门(1-2天) │
│ ① 安装并跑通 "Hello World" 示例 │
│ ② 理解 Agent / Task / Crew 三角关系 │
│ ③ 用脚手架创建项目,修改 YAML 配置 │
│ │
│ 第二阶段:基础(1周) │
│ ④ 学习自定义工具开发(@tool 装饰器) │
│ ⑤ 掌握顺序 vs 层级两种 Process │
│ ⑥ 接入不同 LLM(Claude / Gemini / Ollama) │
│ ⑦ 理解 context 任务依赖和并行执行 │
│ │
│ 第三阶段:进阶(2周) │
│ ⑧ 掌握 Flow 的四大装饰器,构建事件驱动流程 │
│ ⑨ 学习 Memory 和 Knowledge,让 Agent 更"聪明" │
│ ⑩ 使用 Guardrail 保障输出质量 │
│ ⑪ 实现 Human-in-the-Loop │
│ │
│ 第四阶段:高级(持续) │
│ ⑫ Checkpoint 断点续跑 │
│ ⑬ LLM Hooks + Events 监控 │
│ ⑭ MCP 协议工具集成 │
│ ⑮ A2A 分布式 Agent 网络 │
│ ⑯ 生产部署 + CrewAI AMP 监控平台 │
│ │
└─────────────────────────────────────────────────────────────────┘
推荐学习资源:
📚 官方文档: docs.crewai.com
🎓 认证课程: learn.crewai.com(免费)
💻 示例代码: github.com/crewAIInc/crewAI-examples
💬 社区论坛: community.crewai.com
🤖 DeepLearning.AI 合作课程(中文字幕版在 B 站可搜到)
结语
CrewAI 不是一个玩具,它是目前多 Agent 编排领域工程成熟度最高的开源框架之一。从本文梳理的源码和特性来看,它在以下几个方向已经达到生产级水准:
一是双范式架构的设计非常务实——Crews 给你自治协作能力,Flows 给你精确控制能力,二者能自由组合,解决了"灵活性 vs 可控性"这个多 Agent 框架的核心矛盾。
二是工程基础设施完整:统一记忆系统、RAG 知识库、Checkpoint 断点续跑、事件总线、LLM Hooks、MCP 协议支持……这些都是真实生产环境需要的能力,不是玩具级别的拼凑。
三是近期的技术演进方向非常前沿:Checkpoint/Fork 机制、A2A Agent 网络、Skills 系统……说明团队在往"Agent 操作系统"的方向演进,而不只是一个简单的提示词框架。
对于刚接触的同学,建议的心态是:不要试图一次学完所有特性,先把一个真实问题用 CrewAI 解决掉,学习效果会远好于看教程。从一个你工作中真实存在的重复性脑力劳动开始——比如每周写的报告、每天整理的竞品信息——把它变成一个 CrewAI 项目,这才是最快的入门方式。