1 快速开始
1.1 框架介绍
01.框架定位
a.核心理念
a.功能说明
CrewAI是一个专为编排和自动化多智能体协作而设计的开源框架。其核心理念是通过结合两大核心抽象——Flows(流程)和Crews(团队),来构建能够处理复杂任务、具备生产级别稳定性的AI应用。Flows作为应用程序的结构化骨干,负责定义事件驱动的工作流、管理状态和控制执行逻辑;而Crews则作为工作单元,由多个自主的AI智能体组成,负责在Flow的指导下协同完成具体、复杂的任务。
b.代码示例
---
# 概念示例:Flows定义工作流程,Crews执行具体任务
from crewai import Flow, Crew
# 1. 定义一个工作流 (Flow)
financial_analysis_flow = Flow(
name="季度财报分析流程",
description="自动完成季度财报的数据提取、分析和报告生成。"
)
# 2. 在Flow中定义一个步骤,该步骤委派给一个Crew执行
@financial_analysis_flow.task
def analyze_earnings_call(company: str):
"""分析公司的财报电话会议记录。"""
# 创建并启动一个专门用于分析的Crew
analysis_crew = Crew(...)
result = analysis_crew.kickoff(inputs={"company": company})
return result
---
b.技术架构
a.功能说明
CrewAI的架构设计旨在实现自主性与控制之间的平衡。Flows作为顶层控制器,如同应用程序的“经理”,定义了任务的步骤、逻辑分支以及数据如何在系统中流转。Crews则是执行层,是完成具体工作的“团队”。当Flow遇到一个需要创造性协作和深度分析的复杂问题时,便会将该任务委派给一个专门的Crew。Crew内部的智能体通过角色扮演、自主协作和任务委派来共同解决问题,并将最终结果返回给Flow,由Flow决定下一步的走向。
b.代码示例
---
# 架构协同工作的概念示例
# Flow层面:管理状态和控制流程
class ApplicationFlow:
def handle_request(self, user_request):
# 1. Flow接收请求并管理状态
state = self.manage_state(user_request)
# 2. Flow将复杂任务委派给Crew
if state["needs_deep_analysis"]:
research_crew = self.create_research_crew()
analysis_result = research_crew.kickoff(inputs={"topic": state["topic"]})
state["analysis"] = analysis_result
# 3. Flow根据Crew的结果继续执行
final_report = self.generate_report(state)
return final_report
---
02.核心特性
a.自主运行
a.功能说明
CrewAI的智能体被设计为能够根据其角色、目标和可用工具自主做出决策。它们可以独立地规划行动、执行任务,并在需要时与其他智能体进行交互,而无需持续的人工干预。这种自主性是实现复杂任务自动化的关键。
b.代码示例
---
# Agent自主决策的概念示例
# 在一个研究任务中,研究员Agent可能会自主决定:
# 1. 使用搜索工具查找初始资料
# 2. 分析搜索结果,识别关键信息
# 3. 发现信息不足时,再次使用搜索工具进行更精确的查询
# 4. 整理所有信息,形成初步报告
---
b.自然交互
a.功能说明
智能体之间的协作通过类似人类团队成员的自然语言进行沟通。它们可以分享信息、委派子任务、请求帮助或提供反馈。这种基于对话的交互模式使得整个协作过程更加透明和易于理解。
b.代码示例
---
# 智能体交互对话示例
# Researcher Agent: "我已经收集了关于AI市场规模的初步数据,但需要更详细的财务分析。@Financial_Analyst,你能帮忙分析一下这些数据吗?"
# Financial_Analyst Agent: "收到。正在分析数据... 分析完成。数据显示,AI市场预计在未来五年内复合年增长率为25%。"
---
c.可扩展设计
a.功能说明
CrewAI的框架设计具有高度的可扩展性。开发者可以轻松地创建和集成自定义的工具(Tools),为智能体赋予新的能力。此外,也可以方便地定义新的智能体角色和任务类型,以适应各种不同的应用场景。
b.代码示例
---
from crewai_tools import BaseTool
# 创建一个自定义工具:读取本地文件
class MyFileReadTool(BaseTool):
name: str = "文件读取工具"
description: str = "读取指定路径的本地文件内容。"
def _run(self, file_path: str) -> str:
with open(file_path, 'r') as f:
return f.read()
# 在创建Agent时,将这个自定义工具加入其工具列表
custom_agent = Agent(
...,
tools=[MyFileReadTool()]
)
---
1.2 安装配置
01.环境准备
a.安装CrewAI
a.功能说明
安装CrewAI及其相关依赖是开始使用的第一步。官方推荐使用`pip`进行安装。为了使用CrewAI提供的命令行工具(CLI),例如快速创建项目脚手架,需要一并安装`crewai[tools]`。这个工具包包含了运行CLI所需的所有依赖。
b.代码示例
---
# 推荐使用虚拟环境以避免包冲突
python -m venv crewai-env
source crewai-env/bin/activate # Linux/macOS
# .\crewai-env\Scripts\activate # Windows
# 使用pip安装CrewAI和其工具包
pip install 'crewai[tools]'
# 验证安装
crewai --version
---
b.设置环境变量
a.功能说明
CrewAI的智能体通常需要与大型语言模型(LLM)进行交互,并且可能需要使用外部工具(如搜索引擎)。因此,必须在环境中配置相关的API密钥。这些密钥应保存在项目根目录下的`.env`文件中,CrewAI会自动加载这些变量。最基础的配置是LLM的API密钥,例如OpenAI。如果使用了需要认证的工具(如SerperDevTool),也需要一并设置。
b.代码示例
---
# 在项目根目录下创建 .env 文件
# .env 文件内容示例
# OpenAI API 密钥
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# 如果使用Serper进行网络搜索,需要Serper API密钥
SERPER_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# 如果使用其他LLM提供商,如Google Gemini
# GEMINI_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
---
02.项目结构
a.使用CLI创建项目
a.功能说明
CrewAI CLI提供了一个便捷的命令`crewai create`来快速生成一个结构化的项目模板。这个模板包含了预设的目录结构、配置文件(`agents.yaml`, `tasks.yaml`)和主程序入口,极大地简化了新项目的启动过程。开发者可以直接在这些模板文件的基础上进行修改,以适应自己的业务需求。
b.代码示例
---
# 在终端中运行以下命令创建一个名为 market-analysis-crew 的新项目
crewai create market-analysis-crew
# 命令执行后会生成如下目录结构:
# market-analysis-crew/
# ├── src/
# │ └── market_analysis_crew/
# │ ├── __init__.py
# │ ├── agents.py
# │ ├── crew.py
# │ ├── main.py
# │ └── tasks.py
# ├── config/
# │ ├── agents.yaml
# │ └── tasks.yaml
# └── .env
---
b.手动创建项目
a.功能说明
如果不使用CLI,也可以手动创建项目结构。核心是创建一个主Python文件(例如`main.py`),在其中定义Agent、Task和Crew。这种方式更加灵活,适合快速原型验证或集成到现有项目中。所有定义都在一个文件中,便于理解和调试。
b.代码示例
---
# 手动创建的项目结构可以非常简单
# my-simple-crew/
# ├── main.py
# └── .env
# main.py 文件内容
from crewai import Agent, Task, Crew, Process
import os
# os.environ['OPENAI_API_KEY'] = "YOUR_API_KEY"
# ... 在此处定义Agent, Task, Crew ...
# result = crew.kickoff()
# print(result)
---
1.3 快速开始
01.定义Agent
a.创建研究员Agent
a.功能说明
首先,我们定义一个“研究员”智能体。这个智能体的目标是围绕特定主题进行深入研究。我们为其分配“高级研究分析师”的角色,并提供一个背景故事来强化其专家身份。为了让它能够获取外部信息,我们为其配备了`SerperDevTool`,这是一个用于网络搜索的工具。
b.代码示例
---
from crewai import Agent
from crewai_tools import SerperDevTool
# 创建一个搜索工具实例
search_tool = SerperDevTool()
# 创建一个研究员智能体
researcher = Agent(
role=\'高级研究分析师\',
goal=\'发现关于 {topic} 的突破性见解\',
backstory=(
"作为一名传奇的研究分析师,你以能够从海量数据中挖掘出隐藏的叙事和趋势而闻名。"
"你擅长拆解复杂的数据,并以清晰、可操作的方式呈现出来。"
),
verbose=True,
allow_delegation=False, # 该Agent不委派任务给其他Agent
tools=[search_tool]
)
---
b.创建作家Agent
a.功能说明
接下来,我们定义一个“技术内容策略师”智能体。它的任务是基于研究员找到的资料,撰写一篇引人入胜的博客文章。我们为其设定的目标是创作有趣、易于理解且吸引人的内容。
b.代码示例
---
# 创建一个作家智能体
writer = Agent(
role=\'技术内容策略师\',
goal=\'撰写关于 {topic} 的引人入胜的博客文章\',
backstory=(
"作为一名著名的内容策略师,你以能够将复杂的技术概念转化为引人入胜的故事而闻名。"
"你拥有将复杂思想提炼为简单、引人入胜的格式的天赋。"
),
verbose=True,
allow_delegation=True # 该Agent可以委派任务
)
---
02.定义Task
a.创建研究任务
a.功能说明
现在,我们为研究员智能体创建一个具体的任务。任务描述清晰地说明了需要做什么——识别关于特定主题的最新AI趋势。期望输出则为任务的成功标准——一份包含5个要点的总结报告。我们将这个任务明确地分配给之前创建的`researcher`智能体。
b.代码示例
---
from crewai import Task
# 为researcher创建一个研究任务
task1 = Task(
description=(
"识别‘AI在2024年的应用’这一主题下的最新趋势。"
"重点关注主要的技术突破、行业应用和潜在的社会影响。"
),
expected_output="一份包含5个要点的项目符号列表总结,详细说明每个趋势及其重要性。",
agent=researcher
)
---
b.创建写作任务
a.功能说明
然后,我们为作家智能体创建一个写作任务。这个任务的目标是基于研究任务的结果,撰写一篇完整的博客文章。任务描述要求文章的格式为Markdown,并强调了内容的吸引力。
b.代码示例
---
# 为writer创建一个写作任务
task2 = Task(
description=(
"利用研究分析师提供的见解,撰写一篇关于‘AI在2024年的应用’的引人入胜的博客文章。"
"文章应突出最重要的趋势,并以引人入胜、信息丰富的方式呈现。"
),
expected_output="一篇格式完整的博客文章,采用Markdown格式,准备好发布。",
agent=writer
)
---
03.组建并运行Crew
a.实例化Crew
a.功能说明
最后一步是将我们创建的智能体和任务组建成一个`Crew`。我们将`researcher`和`writer`放入`agents`列表,将`task1`和`task2`放入`tasks`列表。我们选择`Process.sequential`作为执行流程,这意味着任务将按照它们在列表中的顺序依次执行。设置`verbose=2`可以让我们在运行时看到详细的执行日志。
b.代码示例
---
from crewai import Crew, Process
# 实例化你的Crew
crew = Crew(
agents=[researcher, writer],
tasks=[task1, task2],
process=Process.sequential, # 顺序执行
verbose=2, # 可以设置为1或2,查看不同详细程度的日志
)
---
b.启动任务
a.功能说明
通过调用`crew.kickoff()`方法,我们正式启动整个团队开始工作。我们可以在`inputs`字典中传入在任务和智能体定义中使用的动态占位符(如`{topic}`)。Crew会返回所有任务完成后的最终结果。
b.代码示例
---
# 启动Crew并获取结果
result = crew.kickoff(inputs={\'topic\': \'AI在2024年的应用\'})
print("######################")
print(result)
---
2 核心组件
2.1 核心组件:Agent详解
01.Agent基本构成
a.角色与目标 (Role & Goal)
a.功能说明
`role`和`goal`是定义一个Agent身份和使命的核心参数。`role`(角色)为其提供了一个行为框架和身份定位,例如“资深软件工程师”或“市场分析专家”。`goal`(目标)则清晰地指明了该Agent需要完成的具体任务。这两个参数共同作用,引导LLM在执行任务时产生更符合预期的行为和输出。
b.代码示例
---
# 定义一个具有明确角色和目标的Agent
data_analyst_agent = Agent(
role="数据分析师",
goal="分析用户行为数据并找出关键增长点",
# ... 其他参数
)
---
b.背景故事 (Backstory)
a.功能说明
`backstory`(背景故事)为Agent提供了更丰富的上下文和个性。一段精心编写的背景故事,可以使其行为更具深度和一致性,仿佛一个拥有真实经验和知识的专家。这有助于LLM更好地进行角色扮演,从而提高任务完成的质量。
b.代码示例
---
# 为数据分析师Agent添加背景故事
data_analyst_agent = Agent(
role="数据分析师",
goal="分析用户行为数据并找出关键增长点",
backstory=(
"你曾在多家顶尖科技公司担任数据分析主管,"
"擅长从复杂的数据集中洞察商业机会,并为产品决策提供数据支持。"
),
# ... 其他参数
)
---
02.Agent高级配置
a.任务委派 (Delegation)
a.功能说明
`allow_delegation`参数控制Agent是否能够将任务或子任务委派给其他Agent。当一个Agent认为某项任务超出了其能力范围,或者由另一个Agent处理更高效时,如果`allow_delegation`设置为`True`,它就可以主动发起委派。这使得Crew能够动态地、自主地进行任务分工和协作,极大地提高了灵活性和效率。
b.代码示例
---
# 创建一个可以委派任务的项目经理Agent
project_manager_agent = Agent(
role="项目经理",
goal="协调团队完成一个新功能的开发",
allow_delegation=True # 允许委派
)
# 创建一个不允许委派任务的初级开发Agent
junior_dev_agent = Agent(
role="初级开发者",
goal="根据分配的任务编写代码",
allow_delegation=False # 不允许委派
)
---
b.内存管理 (Memory)
a.功能说明
`memory`参数决定Agent是否在执行任务时拥有记忆能力。当设置为`True`时,Agent能够记住之前的对话历史、行动和结果,从而在后续的决策中利用这些信息。这对于需要长期上下文理解和连贯执行的复杂任务至关重要。CrewAI会利用记忆来提高后续步骤的质量和相关性。
b.代码示例
---
# 创建一个具有记忆能力的客服Agent
support_agent_with_memory = Agent(
role="高级客服代表",
goal="解决客户的复杂问题,并提供个性化支持",
memory=True, # 启用记忆功能
# ... 其他参数
)
---
c.详细日志 (Verbose)
a.功能说明
`verbose`参数用于控制Agent在执行过程中的日志输出详细程度。设置为`True`或具体的数字(如1或2)可以让你实时看到Agent的思考过程、工具使用情况、与其他智能体的交互等信息。这对于调试和理解Crew的工作流程非常有帮助。
b.代码示例
---
# 创建一个开启详细日志的Agent
debugging_agent = Agent(
role="调试助手",
goal="复现并定位一个软件缺陷",
verbose=True, # 开启详细日志
# ... 其他参数
)
---
d.语言模型配置 (LLM)
a.功能说明
`llm`参数允许为单个Agent指定特定的语言模型。默认情况下,Agent会使用在Crew层面定义的LLM。通过这个参数,可以为不同的Agent配置不同的模型,例如,为需要强大推理能力的研究员Agent配置GPT-4,而为执行简单文本处理任务的Agent配置更经济的模型。这有助于在性能和成本之间取得平衡。
b.代码示例
---
from langchain_openai import ChatOpenAI
# 为不同的Agent配置不同的LLM
gpt4_llm = ChatOpenAI(model_name="gpt-4-turbo")
gpt3_5_llm = ChatOpenAI(model_name="gpt-3.5-turbo")
# 研究员使用GPT-4
researcher = Agent(
role="研究员",
goal="进行深度研究",
llm=gpt4_llm,
# ...
)
# 总结员使用GPT-3.5
summarizer = Agent(
role="总结员",
goal="总结研究报告",
llm=gpt3_5_llm,
# ...
)
---
2.2 核心组件:Task详解
01.Task基本构成
a.描述与期望输出 (Description & Expected Output)
a.功能说明
`description`和`expected_output`是定义一个Task的核心。`description`清晰地阐述了该任务需要完成的具体工作内容,为Agent提供了明确的行动指令。`expected_output`则定义了任务成功的标准和交付物的格式,使得Agent的目标更加聚焦,也便于后续步骤或人工对结果进行评估。
b.代码示例
---
# 定义一个具有清晰描述和期望输出的任务
market_research_task = Task(
description=(
"对2024年第二季度全球智能手机市场进行全面分析。"
"需要涵盖主要厂商的市场份额、出货量变化以及关键增长区域。"
),
expected_output=(
"一份详细的市场分析报告,包含:"
"1. 各厂商市场份额的饼状图数据。"
"2. 出货量同比和环比变化的表格。"
"3. 对亚洲、欧洲、北美三大市场的增长趋势分析。"
),
# ... 其他参数
)
---
b.分配Agent (Agent)
a.功能说明
`agent`参数用于将一个任务明确地分配给一个或多个特定的Agent来执行。如果只分配给一个Agent,则该Agent会独立完成此任务。如果分配给一个Agent列表,则这些Agent会协同完成该任务,但具体的协作方式取决于Crew的流程设置。这个参数是连接任务和执行者的桥梁。
b.代码示例
---
# 假设已创建 market_analyst 和 data_visualizer 两个Agent
# 将任务分配给单个Agent
analysis_task = Task(
description="分析销售数据",
expected_output="一份销售趋势报告",
agent=market_analyst
)
# 将任务分配给多个Agent协同完成(不常用,通常在Crew层面定义协作)
# visualization_task = Task(
# description="将分析报告可视化",
# expected_output="一组数据图表",
# agent=[market_analyst, data_visualizer]
# )
---
02.Task高级配置
a.任务上下文 (Context)
a.功能说明
`context`参数允许将其他任务的输出作为当前任务的输入。这使得任务之间可以形成依赖关系和数据流。例如,一个写作任务可以利用一个研究任务的输出作为其写作素材。通过在任务列表中按顺序组织,前一个任务的结果会自动传递给后一个任务,无需手动指定`context`。只有在需要使用非直接前驱任务的结果时,才需要手动配置。
b.代码示例
---
# research_task 和 writing_task 顺序执行
# writing_task 会自动接收 research_task 的输出作为上下文
writing_task = Task(
description="根据研究报告撰写一篇博客文章。",
expected_output="一篇完整的博客文章。",
agent=writer_agent
)
# 手动指定上下文的场景(较少见)
# translation_task = Task(
# description="将最终的博客文章翻译成西班牙语。",
# expected_output="西班牙语版本的博客文章。",
# context=[writing_task], # 明确指定使用writing_task的输出
# agent=translator_agent
# )
# crew = Crew(tasks=[research_task, writing_task, translation_task])
---
b.异步执行 (Async Execution)
a.功能说明
`async_execution`参数允许任务以异步方式执行。当设置为`True`时,Crew在启动该任务后不会等待其完成,而是会立即开始执行下一个可以执行的任务。这对于执行可以并行处理的、互不依赖的任务非常有用,可以显著缩短整个Crew的运行时间。
b.代码示例
---
# 创建两个可以并行执行的异步任务
# 任务1:从API获取天气数据
fetch_weather_task = Task(
description="获取纽约市今天的天气数据。",
expected_output="包含温度和天气的字符串。",
agent=api_agent,
async_execution=True
)
# 任务2:从API获取股票数据
fetch_stock_task = Task(
description="获取苹果公司今天的股价。",
expected_output="包含股价的字符串。",
agent=api_agent,
async_execution=True
)
# 汇总任务,它会等待前两个异步任务完成
summary_task = Task(
description="总结天气和股票信息。",
expected_output="一段总结性文字。",
agent=summary_agent,
context=[fetch_weather_task, fetch_stock_task]
)
---
c.输出文件 (Output File)
a.功能说明
`output_file`参数允许将任务的最终输出直接保存到一个文件中。这对于需要生成报告、代码、配置文件等产物的任务非常方便。只需提供一个文件路径,CrewAI会在任务成功完成后自动将结果写入该文件。
b.代码示例
---
# 创建一个将结果保存到文件的代码生成任务
code_generation_task = Task(
description="编写一个Python函数,用于计算斐波那契数列。",
expected_output="一个名为 fibonacci.py 的文件,包含完整的Python代码。",
agent=coder_agent,
output_file="fibonacci.py"
)
---
2.3 核心组件:Crew详解
01.Crew基本构成
a.智能体与任务列表 (Agents & Tasks)
a.功能说明
`agents`和`tasks`是组建一个Crew最核心的两个列表。`agents`列表包含了所有参与该Crew工作的智能体实例,定义了“谁来做”。`tasks`列表则包含了所有需要完成的任务实例,定义了“做什么”。Crew会根据这两个列表以及设定的流程来管理和执行整个工作流。
b.代码示例
---
# 假设已创建 researcher, writer 两个Agent
# 以及 research_task, write_task 两个Task
# 创建一个包含Agent和Task列表的Crew
blog_crew = Crew(
agents=[researcher, writer], # 定义团队成员
tasks=[research_task, write_task], # 定义待办任务
# ... 其他参数
)
---
02.流程控制 (Process)
a.顺序流程 (Sequential)
a.功能说明
`Process.sequential`是Crew最常用也是默认的执行流程。当设置为顺序流程时,Crew会严格按照`tasks`列表中定义的顺序,一个接一个地执行任务。前一个任务的输出会自动成为后一个任务的上下文,形成一条清晰的任务链。这种模式简单、可预测,适用于大多数线性工作流。
b.代码示例
---
from crewai import Crew, Process
# 创建一个使用顺序流程的Crew
sequential_crew = Crew(
agents=[...],
tasks=[task1, task2, task3],
process=Process.sequential # 设置为顺序执行
)
# 任务执行顺序: task1 -> task2 -> task3
---
b.层级流程 (Hierarchical)
a.功能说明
`Process.hierarchical`提供了一种更复杂的、由管理者驱动的协作模式。在这种模式下,你需要指定一个`manager_llm`。Crew会动态地决定任务的执行顺序,而不是严格遵循列表顺序。管理者(由`manager_llm`驱动)会评估所有任务和智能体的状态,决定下一步应该执行哪个任务,或者是否需要委派新任务。这种模式更加灵活和智能,适用于需要动态规划和决策的复杂场景。
b.代码示例
---
from langchain_openai import ChatOpenAI
# 创建一个使用层级流程的Crew
hierarchical_crew = Crew(
agents=[...],
tasks=[...],
process=Process.hierarchical, # 设置为层级执行
manager_llm=ChatOpenAI(model="gpt-4-turbo") # 必须指定一个管理者LLM
)
# 任务执行顺序由manager_llm动态决定
---
03.Crew高级配置
a.共享工具 (Share Crew)
a.功能说明
`share_crew`参数允许一个Crew将其自身作为一个工具,提供给另一个Crew使用。这是一种强大的组合模式,可以将一个专门负责某项复杂任务(如“深度市场分析”)的Crew,封装成一个单一的工具,供一个更高层次的“决策”Crew调用。这极大地促进了模块化和代码复用。
b.代码示例
---
# 1. 创建一个专门用于分析的子Crew
financial_analysis_crew = Crew(
agents=[analyst, researcher],
tasks=[analysis_task, research_task],
share_crew=True # 允许该Crew被共享
)
# 2. 创建一个使用子Crew作为工具的决策者Agent
ceo_agent = Agent(
role="CEO",
goal="根据市场分析做出战略决策",
tools=[financial_analysis_crew] # 将子Crew作为工具
)
# 3. 在更高层次的Crew中使用该Agent
strategy_crew = Crew(
agents=[ceo_agent],
tasks=[decision_task]
)
---
b.完整输出 (Full Output)
a.功能说明
默认情况下,`kickoff()`方法只返回最后一个任务的输出。当`full_output`设置为`True`时,`kickoff()`将返回一个包含所有任务执行细节的完整对象,包括每个任务的输入、输出、使用的工具、时间戳等。这对于需要详细审计、日志记录或对中间结果进行分析的场景非常有用。
b.代码示例
---
# 创建一个需要完整输出的Crew
audited_crew = Crew(
agents=[...],
tasks=[...],
full_output=True # 启用完整输出
)
# 启动Crew并获取详细结果
detailed_result = audited_crew.kickoff()
# detailed_result 将是一个包含所有执行信息的对象
# print(detailed_result.tasks_outputs)
---
3 相关信息
3.1 Flows工作流
01.Flows核心概念
a.事件驱动架构
a.功能说明
Flows是CrewAI中用于构建生产级AI应用的核心抽象,它采用事件驱动的架构。与线性的、以任务为中心的Crews不同,Flows将应用程序构建为一系列由事件触发的、相互连接的步骤。每个步骤都可以是一个简单的函数、一个复杂的逻辑块,或者是一个完整的Crew。这种架构使得应用能够响应外部事件(如用户输入、API回调、定时器),并以灵活、可扩展的方式处理它们。
b.代码示例
---
from crewai import Flow
# 创建一个Flow实例
customer_support_flow = Flow(
name="客户支持流程",
description="处理来自用户的支持请求。"
)
# 定义一个由事件触发的入口点
@customer_support_flow.on_event("user_request")
def handle_user_request(data):
# ... 处理用户请求的逻辑 ...
if data["is_complex"]:
# 触发另一个事件,将任务委派给Crew
customer_support_flow.trigger("escalate_to_crew", data)
else:
# 执行简单的回复逻辑
return {"reply": "这是一个简单的回复。"}
---
b.状态管理
a.功能说明
Flows内置了强大的状态管理能力。它可以在整个工作流的生命周期内维护一个状态对象,每个步骤都可以读取和更新这个状态。这使得在不同步骤之间传递数据和上下文变得非常简单和可靠。状态管理是构建能够处理多轮交互和复杂逻辑的应用的关键。
b.代码示例
---
# 在Flow的步骤中访问和更新状态
@customer_support_flow.task
def categorize_request(state):
# 读取状态
user_query = state["user_query"]
# 更新状态
category = classify_query(user_query) # 假设这是一个分类函数
state["category"] = category
return state
@customer_support_flow.task
def route_request(state):
# 根据状态中的分类来路由请求
if state["category"] == "billing":
# ... 处理账单问题 ...
else:
# ... 处理技术问题 ...
---
02.Flows与Crews的协同
a.委派复杂任务
a.功能说明
Flows和Crews的设计初衷是协同工作。Flows作为应用程序的“大脑”或“控制器”,负责处理高层逻辑、路由和状态管理。当Flow遇到一个需要深度分析、创造性协作或复杂工具使用的任务时,它就会将这个任务“委派”给一个专门的Crew。Crew作为“专家团队”,负责解决这个复杂问题,并将结果返回给Flow,由Flow决定下一步的行动。这种模式实现了控制与自主的完美结合。
b.代码示例
---
# 在Flow中定义一个委派给Crew的任务
@customer_support_flow.task
def complex_issue_analysis(state):
# 创建并配置一个专门用于分析复杂问题的Crew
analysis_crew = Crew(
agents=[expert_agent, researcher_agent],
tasks=[deep_dive_task]
)
# 启动Crew并传入所需数据
result = analysis_crew.kickoff(inputs={"query": state["user_query"]})
# 将Crew的结果更新到Flow的状态中
state["analysis_result"] = result
return state
---
b.构建生产级应用
a.功能说明
通过结合Flows和Crews,开发者可以构建出健壮、可维护且可扩展的生产级AI应用。Flows提供了清晰的结构和控制流,使得应用逻辑易于理解和修改。Crews则封装了复杂的多智能体协作,使得核心的“智能”部分可以被模块化和复用。这种分层架构使得应用既能处理结构化的业务流程,又能应对开放式的复杂问题。
b.代码示例
---
# 一个完整的生产级应用流程示例
# 1. Flow的入口点接收到一个API请求
@app.post("/support")
def start_support_flow(request: Request):
customer_support_flow.trigger("user_request", request.json())
# 2. Flow的第一个任务对请求进行初步处理和分类
# @customer_support_flow.task
# def categorize_request(state): ...
# 3. 如果是复杂问题,Flow将任务委派给一个Crew
# @customer_support_flow.task
# def complex_issue_analysis(state): ...
# 4. Flow的最后一个任务根据Crew的结果生成最终回复,并通过API返回
# @customer_support_flow.task
# def generate_final_response(state): ...
---
3.2 工具集成
01.使用内置工具
a.官方工具库 (crewai_tools)
a.功能说明
CrewAI提供了一个名为`crewai_tools`的官方工具库,其中包含了大量预置的、可以直接使用的工具。这些工具涵盖了网页搜索、文件读写、代码执行、网站内容抓取等多种常用功能。通过简单地导入和实例化,就可以为Agent配备强大的能力。
b.代码示例
---
from crewai import Agent
from crewai_tools import (
SerperDevTool,
FileReadTool,
ScrapeWebsiteTool,
DirectoryReadTool
)
# 创建工具实例
search_tool = SerperDevTool()
file_read_tool = FileReadTool()
scrape_tool = ScrapeWebsiteTool()
directory_read_tool = DirectoryReadTool()
# 在创建Agent时,将工具列表传入
research_agent = Agent(
role="研究员",
goal="进行全面的信息收集",
tools=[
search_tool,
file_read_tool,
scrape_tool,
directory_read_tool
]
)
---
b.工具使用示例
a.功能说明
Agent在执行任务时,会根据其目标和当前上下文,自主决定何时以及如何使用其配备的工具。例如,一个研究员Agent在接到研究任务后,可能会首先使用`SerperDevTool`进行网络搜索,然后使用`ScrapeWebsiteTool`抓取关键网页的内容,最后使用`FileReadTool`读取本地的参考资料,以完成其研究报告。
b.代码示例
---
# 任务描述
research_task = Task(
description=(
"研究LangChain的最新发展。首先,在网上搜索\'LangChain v0.2 release notes\',"
"然后抓取官方发布说明页面的内容,并结合本地文件\'my_notes.md\'进行总结。"
),
expected_output="一份详细的LangChain v0.2更新总结报告。",
agent=research_agent
)
# 在执行过程中,Agent会依次调用 search_tool, scrape_tool, file_read_tool
---
02.创建自定义工具
a.继承BaseTool类
a.功能说明
当内置工具无法满足特定需求时,可以轻松创建自定义工具。只需创建一个继承自`crewai_tools.BaseTool`的类,并实现`name`、`description`和`_run`方法即可。`name`和`description`用于告诉Agent这个工具的用途,而`_run`方法则包含了工具的具体执行逻辑。
b.代码示例
---
from crewai_tools import BaseTool
# 创建一个用于计算两个数之和的自定义工具
class CalculatorTool(BaseTool):
name: str = "计算器工具"
description: str = "计算两个整数的和。"
def _run(self, a: int, b: int) -> str:
"""执行计算并返回结果。"""
return str(a + b)
# 创建Agent时使用这个自定义工具
math_agent = Agent(
role="数学家",
goal="解决数学问题",
tools=[CalculatorTool()]
)
---
b.使用函数工具
a.功能说明
对于更简单的场景,CrewAI提供了`FunctionTool`,可以将任何一个普通的Python函数快速封装成一个工具,而无需创建完整的类。只需将函数本身和其描述传递给`FunctionTool`即可。这对于快速集成现有函数或进行原型设计非常方便。
b.代码示例
---
from crewai_tools import FunctionTool
# 定义一个普通的Python函数
def get_weather(city: str) -> str:
"""获取指定城市的天气信息。"""
# 实际应用中会调用天气API
if city.lower() == "beijing":
return "北京今天晴天,气温25摄氏度。"
else:
return f"无法获取{city}的天气信息。"
# 将函数封装成工具
weather_tool = FunctionTool.from_function(
func=get_weather,
description="获取指定城市的实时天气信息。"
)
# 在Agent中使用该工具
travel_agent = Agent(
role="旅行规划师",
goal="为用户规划行程",
tools=[weather_tool]
)
---
3.3 高级特性
01.协作模式
a.任务委派 (Delegation)
a.功能说明
任务委派是CrewAI中实现动态协作的核心机制。当一个Agent在其`allow_delegation`参数被设置为`True`时,它可以在执行任务的过程中,判断是否需要将部分工作或整个任务委派给另一个更适合的Agent。这种决策是自主的,基于Agent对任务的理解和对团队中其他成员能力的认知。这使得Crew能够像一个真正的人类团队一样,灵活地分配工作,而不是死板地遵循预设流程。
b.代码示例
---
# 假设有一个项目经理Agent和一个开发Agent
project_manager = Agent(
role="项目经理",
goal="确保项目按时交付",
allow_delegation=True # 允许委派
)
developer = Agent(
role="软件工程师",
goal="编写高质量的代码",
allow_delegation=False # 通常执行者不委派
)
# 任务:规划并执行一个新功能的开发
planning_task = Task(
description="规划新功能的开发,并将其分解为具体的编码任务。",
expected_output="一份详细的开发计划和已委派的编码任务列表。",
agent=project_manager
)
# 在执行planning_task时,project_manager会自主地创建新的编码任务,并委派给developer
---
02.记忆功能 (Memory)
a.短期记忆
a.功能说明
CrewAI的Agent默认拥有短期记忆,即在同一个任务执行过程中,能够记住之前的思考和行动。这使得Agent可以进行连贯的、多步骤的推理和操作。例如,一个Agent可以先搜索信息,然后基于搜索结果进行分析,再根据分析结果做出决策。
b.代码示例
---
# Agent的短期记忆是内置的,无需特殊配置
# 在一个任务中,Agent的思考过程展示了其短期记忆:
# Thought: 我需要先搜索X公司的财报。
# Action: search(query="X公司最新财报")
# ... (得到结果)
# Thought: 财报显示利润增长了20%。现在我需要分析其原因。
# Action: search(query="X公司利润增长原因")
---
b.长期记忆 (RAG)
a.功能说明
为了让Crew拥有跨任务、跨会话的长期记忆,CrewAI集成了先进的检索增强生成(RAG)技术。通过在Crew层面配置`memory=True`,可以为整个团队启用长期记忆。Crew会将关键的对话历史、任务结果和学习到的知识存储在一个向量数据库中。在未来的任务中,Agent可以查询这个记忆库,以获取相关的上下文信息,从而做出更明智的决策,避免重复工作。
b.代码示例
---
# 在Crew层面启用长期记忆
crew_with_memory = Crew(
agents=[...],
tasks=[...],
memory=True, # 启用RAG长期记忆
verbose=2
)
# 第一次运行后,Crew会将关键信息存入记忆库
# result1 = crew_with_memory.kickoff(inputs={"customer_id": "123"})
# 第二次为同一客户服务时,Crew可以从记忆库中检索历史信息
# result2 = crew_with_memory.kickoff(inputs={"customer_id": "123"})
---
03.规划能力 (Planning)
a.任务分解
a.功能说明
CrewAI的Agent具备初步的任务规划和分解能力。当面对一个复杂的任务时,Agent可以将其分解为一系列更小、更易于管理的子任务。这种能力通常通过Agent的`backstory`和`goal`来引导,并结合其可用的工具来实现。例如,一个“旅行规划师”Agent可能会将“规划一次巴黎之旅”分解为“预订机票”、“预订酒店”、“规划每日行程”等子任务。
b.代码示例
---
# Agent的思考过程展示了其任务分解能力
# Thought: 我需要规划一次巴黎之旅。这个任务可以分解为几个步骤:
# 1. 查找并预订往返机票。
# 2. 根据预算和位置选择并预订酒店。
# 3. 规划每天的观光路线和活动。
# 我将首先开始第一步:查找机票。
# Action: search_flights(origin="NYC", destination="CDG", date="2024-10-10")
---
3.4 实战案例
01.市场分析报告
a.案例描述
a.功能说明
这是一个典型的研究与写作案例。目标是创建一个能够自动生成关于特定行业(如“AI行业”)市场分析报告的Crew。这个Crew由一个研究员Agent和一个作家Agent组成。研究员负责收集数据和趋势,作家负责将研究结果整理成一篇结构完整、语言流畅的报告。
b.代码示例
---
# 完整代码结构
# 1. 定义Agents: researcher, writer
# - researcher配备搜索工具
# 2. 定义Tasks: research_task, write_task
# - research_task分配给researcher
# - write_task分配给writer
# 3. 组建Crew:
# - agents=[researcher, writer]
# - tasks=[research_task, write_task]
# - process=Process.sequential
# 4. 启动Crew:
# - crew.kickoff(inputs={\'topic\': \'AI行业最新发展\'})
---
02.客户支持自动化
a.案例描述
a.功能说明
这个案例旨在构建一个多层次的客户支持系统。Crew由三个Agent组成:一个“分类员”Agent,一个“初级支持”Agent,和一个“高级工程师”Agent。当收到客户请求时,分类员首先判断问题的类型和紧急程度。简单问题由初级支持Agent使用知识库工具直接回答。复杂的技术问题则被委派给高级工程师Agent,该Agent可以使用更专业的诊断工具来解决问题。
b.代码示例
---
# 概念代码结构
# 1. Agents: classifier, junior_support, senior_engineer
# - classifier: 无特殊工具
# - junior_support: 配备知识库搜索工具
# - senior_engineer: 配备日志分析、数据库查询等高级工具
# 2. Tasks: classify_task, simple_support_task, complex_support_task
# 3. Crew:
# - 使用层级流程(Process.hierarchical)和管理者LLM来动态决定任务流转
# - 或者通过Agent的任务委派能力实现
---
03.自动化代码生成与审查
a.案例描述
a.功能说明
这个案例模拟了一个软件开发的迷你流程。Crew包含一个“产品经理”Agent,一个“程序员”Agent,和一个“代码审查员”Agent。产品经理负责将需求转化为具体的开发任务。程序员根据任务编写代码。代码完成后,审查员Agent会自动对代码进行分析,检查其是否符合编码规范、是否存在潜在的bug,并提出修改建议。整个流程实现了从需求到代码产出的自动化闭环。
b.代码示例
---
# 概念代码结构
# 1. Agents: product_manager, programmer, code_reviewer
# - programmer: 配备文件读写工具
# - code_reviewer: 配备静态代码分析工具
# 2. Tasks: define_spec_task, coding_task, review_task
# 3. Crew:
# - 使用顺序流程(Process.sequential)
# - coding_task的输出(代码文件路径)作为review_task的输入
---
3.5 生产部署
01.API服务封装
a.使用FastAPI
a.功能说明
将CrewAI应用部署为生产级服务的最常见方式是使用Web框架(如FastAPI)将其封装为API。你可以创建一个FastAPI应用,定义一个或多个API端点(例如`/run-crew`)。当这个端点被调用时,它会接收输入参数,启动Crew,并以HTTP响应的形式返回最终结果。这种方式使得Crew可以被任何客户端(网页、移动应用、其他后端服务)轻松集成。
b.代码示例
---
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
from my_crew import MyCrew # 假设你的Crew在my_crew.py中定义
app = FastAPI()
class CrewInput(BaseModel):
topic: str
@app.post("/run-crew")
def run_crew_endpoint(crew_input: CrewInput):
inputs = {"topic": crew_input.topic}
result = MyCrew().crew().kickoff(inputs=inputs)
return {"result": result}
# 运行服务: uvicorn main:app --reload
---
02.Docker化部署
a.创建Dockerfile
a.功能说明
为了实现环境一致性和便捷部署,强烈建议使用Docker将你的CrewAI应用容器化。你需要创建一个`Dockerfile`,在其中定义应用的基础环境(如Python版本)、安装所有依赖项、复制项目文件,并指定启动命令(如`uvicorn`)。
b.代码示例
---
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
# 复制依赖文件并安装
COPY requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# 复制所有项目文件
COPY . .
# 暴露端口并设置启动命令
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
---
b.构建与运行容器
a.功能说明
有了`Dockerfile`之后,你可以使用`docker build`命令构建镜像,并使用`docker run`命令启动容器。记得通过`-p`参数将容器的端口映射到主机的端口,并通过`--env-file`参数传入包含API密钥的`.env`文件。
b.代码示例
---
# 1. 构建Docker镜像
docker build -t my-crew-app .
# 2. 运行Docker容器
docker run -d -p 8000:8000 --env-file .env --name crew-container my-crew-app
---
03.部署到云平台
a.选择云服务
a.功能说明
容器化的CrewAI应用可以轻松部署到任何支持Docker的云平台,例如Amazon ECS, Google Cloud Run, Microsoft Azure App Service, 或者 Heroku。这些平台提供了自动扩缩容、负载均衡、日志监控等生产级功能,可以确保你的服务高可用和可扩展。
b.代码示例
---
# 以Google Cloud Run为例的部署命令
# 1. 将Docker镜像推送到Google Artifact Registry
gcloud auth configure-docker
docker tag my-crew-app gcr.io/YOUR_PROJECT_ID/my-crew-app
docker push gcr.io/YOUR_PROJECT_ID/my-crew-app
# 2. 部署到Cloud Run
gcloud run deploy my-crew-service \
--image gcr.io/YOUR_PROJECT_ID/my-crew-app \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars="OPENAI_API_KEY=your_key"
---