1. 引言
在人工智能领域,Multi Agent 系统正逐渐成为解决复杂问题、实现高效协作的关键技术。CrewAI 作为一款强大的多 Agent 协作工具,为开发者提供了便捷的方式来构建智能协作系统。本文将详细介绍如何基于 CrewAI 构建 Multi Agent 系统。
2. CrewAI 核心概念详解
2.1 代理(Agent)
2.1.1 Agent 的定义与功能
Agent 是 CrewAI 中的自主单元,具备执行任务、做出决策和与其他代理通信的能力。它们如同团队中的成员,各自承担特定角色,如研究员、作家或客户支持等,共同为实现团队目标贡献力量。
2.1.2 代理属性
- 角色(Role) :明确代理在团队中的功能定位,决定其最适合执行的任务类型。例如,研究员角色的代理擅长收集和分析信息,而作家角色的代理则专注于创作内容。
- 目标(Goal) :指导代理的决策过程,是代理努力实现的个体目标。比如,数据分析师代理的目标可能是提取可操作的见解,以支持业务决策。
- 背景故事(Backstory) :为代理的角色和目标提供丰富背景信息,增强互动和协作的动态性。以数据分析师为例,其背景故事可以是 "您是一家大公司的数据分析师。您负责分析数据并为业务提供见解。您目前正在进行一个项目,分析我们营销活动的表现。"
- LLM(可选) :表示运行代理的语言模型。若未指定,默认从
OPENAI_MODEL_NAME
环境变量中获取模型名称,否则默认为 "gpt-4"。开发者可以根据需求选择合适的语言模型,以满足不同任务的处理要求。 - 工具(可选) :代理可使用的一组能力或功能集,通常是与执行环境兼容的自定义类实例,默认值为空列表。这些工具能够扩展代理的能力,使其能够执行诸如网页搜索、数据分析等操作。
- 调用功能的 LLM(可选) :指定处理该代理工具调用的语言模型,若传递则覆盖团队功能调用 LLM,默认值为
None
。通过灵活配置此属性,开发者可以更精准地控制代理的工具调用行为。 - 最大迭代次数(可选) :代理在被强制给出最佳答案前可执行的最大迭代次数,默认值为 25。合理设置该参数有助于控制任务执行的深度和效率。
- 最大请求次数(可选) :代理每分钟可执行的最大请求数,用于避免速率限制,默认值为
None
。开发者可根据实际情况进行设置,以确保系统稳定运行。 - 最大执行时间(可选) :代理执行任务的最大时长,默认值为
None
,表示无最大执行时间限制。此属性可用于控制任务的执行周期,防止任务长时间占用资源。 - 详细模式(可选) :将其设置为
True
可配置内部记录器提供详细执行日志,便于调试和监控,默认值为False
。在开发和优化过程中,开启详细模式有助于快速定位问题。 - 允许委托(可选) :代理之间可相互委托任务或问题,确保任务由最合适的代理处理,默认值为
True
。这一特性促进了团队内部的灵活协作,提高了任务处理的准确性和效率。 - 步骤回调(可选) :在代理每个步骤后调用的函数,可用于记录操作或执行其他操作,会覆盖团队
step_callback
。开发者可以利用此回调函数实现自定义的监控和处理逻辑。 - 缓存(可选) :指示代理是否使用工具使用缓存,默认值为
True
。缓存机制有助于提高任务执行效率,减少重复计算。
2.1.3 创建代理
代理可以使用 CrewAI 内置的委托和通信机制相互交互。这允许在团队内进行动态任务管理和问题解决。
要创建代理,通常会使用所需属性初始化 Agent
类的实例。以下是一个包含所有属性的概念示例:
from crewai import Agent
agent = Agent(
role="数据分析师",
goal="提取可操作的见解",
backstory="""您是一家大公司的数据分析师。
您负责分析数据并为业务提供见解。
您目前正在进行一个项目,分析我们营销活动的表现。""",
tools=[my_tool1, my_tool2], # 可选,默认为空列表
llm=my_llm, # 可选
function_calling_llm=my_llm, # 可选
max_iter=15, # 可选
max_rpm=None, # 可选
verbose=True, # 可选
allow_delegation=True, # 可选
step_callback=my_intermediate_step_callback, # 可选
cache=True # 可选
)
2.2 任务(Task)
2.2.1 任务定义与协作
在 CrewAI 框架中,任务是代理需要完成的具体工作,包含执行所需的各种细节,如清晰的描述、负责执行的代理、所需工具等。任务可以是协作性的,通过属性管理和流程编排,实现多个代理的协同工作,提升团队合作效率。
2.2.2 任务的属性
- 描述(Description) :对任务内容的清晰简明陈述,让代理明确知道需要做什么。例如 "查找并总结有关人工智能的最新和最相关新闻"。
- 代理(Agent) :负责任务执行的代理,可以直接指定,也可由 Crew 的流程根据角色、可用性等因素分配。这确保了任务能够找到合适的执行者。
- 预期输出(Expected Output) :对任务完成后的详细描述,使代理清楚任务的目标和期望结果。比如 "对前 5 条最重要的人工智能新闻进行项目符号列表总结"。
- 工具(可选) :代理执行任务时使用的功能或能力,可增强任务性能和代理交互。通过选择合适的工具,代理能够更高效地完成任务。
- 异步执行(可选) :设置后任务将异步执行,允许在不等待完成的情况下继续推进其他任务,适用于耗时较长或对后续任务执行影响不大的任务。
- 上下文(可选) :指定输出用作此任务上下文的任务,明确任务之间的依赖关系,实现任务输出的有效传递和利用。
- 配置(可选) :用于执行任务的代理的附加配置细节,提供了进一步定制任务执行的灵活性。
- 输出 JSON(可选) :输出 JSON 对象,需要 OpenAI API,且只能设置一种输出格式。此属性方便与其他系统进行数据交互和集成。
- 输出 Pydantic(可选) :输出 Pydantic 模型对象,同样需要 OpenAI API,且只能设置一种输出格式。开发者可根据实际需求选择合适的输出格式。
- 输出文件(可选) :将任务输出保存到文件,若与
输出 JSON
或输出 Pydantic
一起使用,可指定输出保存方式。这有助于数据的持久化和后续分析。 - 回调(可选) :任务完成后执行的 Python 可调用函数,可用于根据任务结果触发操作或通知,如发送邮件等。
- 人工输入(可选) :指示任务是否需要最终人工反馈,对于需要人工监督的任务非常有用,确保任务结果的准确性和可靠性。
2.2.3 使用工具创建任务
在了解任务的基本属性后,我们进一步探讨如何使用工具创建任务。以下是一个示例:
import os
os.environ["OPENAI_API_KEY"] = "Your Key"
os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API key
from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool
research_agent = Agent(
role="研究员",
goal="查找并总结最新的人工智能新闻",
backstory="""您是一家大公司的研究员。
您负责分析数据并为业务提供见解。""",
verbose=True
)
search_tool = SerperDevTool()
task = Task(
description="查找并总结最新的人工智能新闻",
expected_output="对前 5 条最重要的人工智能新闻进行项目符号列表总结",
agent=research_agent,
tools=[search_tool]
)
crew = Crew(
agents=[research_agent],
tasks=[task],
verbose=2
)
result = crew.kickoff()
print(result)
2.2.4 创建任务
创建任务涉及定义其范围、负责代理以及任何额外属性以实现灵活性:
from crewai import Task
task = Task(
description="查找并总结有关人工智能的最新和最相关新闻",
agent=sales_agent
)
任务分配可以直接为分配指定一个 代理
,或者让 分层
的 CrewAI 流程根据角色、可用性等决定。
2.2.5 任务依赖
在 CrewAI 中,一个任务的输出会自动传递到下一个任务,当有一个任务依赖于另一个任务的输出,但并非立即在其后执行时,这将非常有用。这通过任务的 上下文
属性完成:
research_ai_task = Task(
description="查找并总结最新的人工智能新闻",
expected_output="对前 5 条最重要的人工智能新闻进行项目符号列表总结",
async_execution=True,
agent=research_agent,
tools=[search_tool]
)
research_ops_task = Task(
description="查找并总结最新的人工智能运营新闻",
expected_output="对前 5 条最重要的人工智能运营新闻进行项目符号列表总结",
async_execution=True,
agent=research_agent,
tools=[search_tool]
)
write_blog_task = Task(
description="撰写一篇关于人工智能重要性及其最新新闻的完整博客文章",
expected_output="4 段长的完整博客文章",
agent=writer_agent,
context=[research_ai_task, research_ops_task]
)
2.2.6 异步执行
任务以异步方式执行,意味着 Crew 不会等待其完成才继续下一个任务。这对于需要很长时间完成的任务或对下一个任务执行不是至关重要的任务非常有用。可以使用 上下文
属性在将来的任务中定义,它应等待异步任务的输出完成。
list_ideas = Task(
description="探索有关人工智能文章的 5 个有趣想法。",
expected_output="一份包含 5 个文章想法的项目符号列表。",
agent=researcher,
async_execution=True # 将以异步方式执行
)
list_important_history = Task(
description="研究人工智能的历史,并告诉我 5 个最重要的事件。",
expected_output="包含 5 个重要事件的项目符号列表。",
agent=researcher,
async_execution=True # 将以异步方式执行
)
write_article = Task(
description="撰写一篇关于人工智能、其历史和有趣想法的文章。",
expected_output="一篇关于人工智能的 4 段文章。",
agent=writer,
context=[list_ideas, list_important_history] # 将等待两个任务的输出完成
)
2.2.7 回调机制
在任务完成后执行回调函数,允许根据任务结果触发操作或通知。
def callback_function(output: TaskOutput):
# 任务完成后执行某些操作
# 例如:向经理发送电子邮件
print(f"""
任务完成!
任务:{output.description}
输出:{output.raw_output}
""")
research_task = Task(
description="查找并总结最新的人工智能新闻",
expected_output="对前 5 条最重要的人工智能新闻进行项目符号列表总结",
agent=research_agent,
tools=[search_tool],
callback=callback_function
)
2.2.8 访问特定任务输出
一组 Crew 运行完成后,可以通过使用任务对象的 output
属性访问特定任务的输出:
task1 = Task(
description="查找并总结最新的人工智能新闻",
expected_output="对前 5 条最重要的人工智能新闻进行项目符号列表总结",
agent=research_agent,
tools=[search_tool]
)
crew = Crew(
agents=[research_agent],
tasks=[task1, task2, task3],
verbose=2
)
result = crew.kickoff()
print(f"""
任务完成!
任务:{task1.output.description}
输出:{task1.output.raw_output}
""")
2.2.9 工具覆盖机制
在任务中指定工具允许动态调整代理能力,突出了 CrewAI 的灵活性。
2.2.10 错误处理和验证机制
在创建和执行任务时,存在验证机制,以确保任务属性的健壮性和可靠性。这些验证包括但不限于:
- 确保每个任务仅设置一种输出类型,以保持清晰的输出期望。
- 防止手动分配
id
属性,以维护唯一标识符系统的完整性。
这些验证有助于在 CrewAI 框架内维护任务执行的一致性和可靠性。
2.3 工具(Tool)
2.3.1 工具的作用与类型
CrewAI 工具赋予代理多种能力,包括网页搜索、数据分析、内容生成和任务委派等,使代理能够执行各种复杂操作,实现从简单搜索到复杂互动以及有效团队合作的跨越。
2.3.2 工具的关键特征
- 实用性(Utility) :专为任务设计,涵盖了多个领域的功能需求,如网页搜索、数据分析、内容生成等,满足代理在不同场景下的工作需求。
- 集成性(Integration) :能够无缝集成到工作流程中,与代理和任务紧密配合,提升代理的整体能力,实现高效协作。
- 可定制性(Customizability) :提供了灵活性,开发者既可以开发定制工具满足特定需求,也可以利用现有工具,根据代理的实际需求进行个性化配置。
- 错误处理(Error Handling) :具备强大的错误处理机制,确保工具在运行过程中遇到异常时能够优雅地处理,保证系统的平稳运行。
- 缓存机制(Caching Mechanism) :具有智能缓存功能,可优化性能,减少冗余操作。开发者还可以通过
cache_function
属性对缓存机制进行更精细的控制,进一步提高效率。
2.3.3 使用 CrewAI 工具
要通过 CrewAI 工具增强代理的能力,需要先安装额外工具包:
pip install 'crewai[tools]'
下面是使用案例:
import os
from crewai import Agent, Task, Crew
# 导入 CrewAI 工具
from crewai_tools import (
DirectoryReadTool,
FileReadTool,
SerperDevTool,
WebsiteSearchTool
)
# 设置 API 密钥
os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API 密钥
os.environ["OPENAI_API_KEY"] = "Your Key"
# 实例化工具
docs_tool = DirectoryReadTool(directory='./blog-posts')
file_tool = FileReadTool()
search_tool = SerperDevTool()
web_rag_tool = WebsiteSearchTool()
# 创建代理
researcher = Agent(
role="市场研究分析师",
goal="提供关于人工智能行业最新市场分析",
backstory="一位对市场趋势敏锐的专家分析师。",
tools=[search_tool, web_rag_tool],
verbose=True
)
writer = Agent(
role="内容撰写人员",
goal="撰写有关人工智能行业的引人入胜的博客文章",
backstory="一位对技术充满激情的熟练撰稿人。",
tools=[docs_tool, file_tool],
verbose=True
)
# 定义任务
research = Task(
description="研究人工智能行业的最新趋势并提供摘要。",
expected_output="关于人工智能行业前三个热门发展的摘要,并对其重要性提供独特视角。",
agent=researcher
)
write = Task(
description="根据研究分析师的摘要撰写一篇引人入胜的博客文章。从目录中最新的博客文章中汲取灵感。",
expected_output="一篇以 markdown 格式排版的四段博客文章,内容引人入胜、信息丰富且易懂,避免使用复杂术语。",
agent=writer,
output_file='blog-posts/new_post.md' # 最终的博客文章将保存在此处
)
# 组建团队
crew = Crew(
agents=[researcher, writer],
tasks=[research, write],
verbose=2
)
# 执行任务
crew.kickoff()
2.3.4 创建自己的工具
需要先安装工具包:
pip install 'crewai[tools]'
- 子类化
BaseTool
:通过继承BaseTool
类,开发者可以创建自定义工具。需要定义工具的名称、描述,并实现_run
方法来定义工具的具体功能逻辑。例如:
from crewai_tools import BaseTool
class MyCustomTool(BaseTool):
name: str = "我的工具名称"
description: str = "清晰描述此工具用于什么,您的代理将需要这些信息来使用它。"
def _run(self, argument: str) -> str:
# 实现在这里
return "自定义工具的结果"
- 利用
tool
装饰器 :使用tool
装饰器可以更简洁地创建自定义工具。只需定义函数,在函数上方添加@tool
装饰器,并提供工具名称和描述即可。例如:
from crewai_tools import tool
@tool("我的工具名称")
def my_tool(question: str) -> str:
"""清晰描述此工具用于什么,您的代理将需要这些信息来使用它。"""
# 函数逻辑在这里
return "您的自定义工具的结果"
- 自定义缓存机制 :工具可以选择实现
cache_function
来微调缓存行为。根据特定条件确定何时缓存结果,提供对缓存逻辑的细粒度控制。例如:
from crewai_tools import tool
@tool
def multiplication_tool(first_number: int, second_number: int) -> str:
"""当您需要将两个数字相乘时有用。"""
return first_number * second_number
def cache_func(args, result):
# 在这种情况下,仅在结果是 2 的倍数时才缓存结果
cache = result % 2 == 0
return cache
multiplication_tool.cache_function = cache_func
2.3.5 使用 LangChain 工具
CrewAI 与 LangChain 的工具包无缝集成,开发者可以利用 LangChain 提供的内置工具,如 GoogleSerperAPIWrapper
等,通过简单的配置将其集成到 CrewAI 系统中,扩展代理的能力。例如:
from crewai import Agent
from langchain.agents import Tool
from langchain.utilities import GoogleSerperAPIWrapper
# 设置 API 密钥
os.environ["SERPER_API_KEY"] = "Your Key"
search = GoogleSerperAPIWrapper()
# 创建并将搜索工具分配给代理
serper_tool = Tool(
name="中级答案",
func=search.run,
description="用于基于搜索的查询的工具"
)
agent = Agent(
role="研究分析师",
goal="提供最新的市场分析",
backstory="一位对市场趋势敏锐的专家分析师。",
tools=[serper_tool]
)
2.4 流程(Process)
2.4.1 流程实现方式
- 顺序执行(Sequential) :任务按照预先定义的顺序依次执行,一个任务的输出作为下一个任务的上下文,确保任务执行的有序性和连贯性。
- 分级(Hierarchical) :将任务组织在管理层级中,通过指定管理语言模型(
manager_llm
)启用该流程。管理者代理负责监督任务执行,包括规划、委派和验证任务,任务根据代理能力分配,而非预分配。 - 共识流程(计划中) :旨在实现代理之间在任务执行上的协作决策,引入民主的任务管理方式,目前尚未在代码库中实施,但体现了 CrewAI 对持续发展和创新的追求。
2.4.2 流程在团队合作中的作用
流程使个体代理能够作为一个有凝聚力的整体运作,简化协作努力,以高效、协调的方式实现共同目标。通过合理的流程设计,团队能够更好地应对复杂任务,提高整体工作效率。
2.4.3 将流程分配给 Manager
在创建 Manager 时,开发者可以指定流程类型来设置执行策略。对于分级流程,必须为管理者代理定义 manager_llm
。例如:
from crewai import Crew, Process
from langchain_openai import ChatOpenAI
# 顺序流程
crew = Crew(
agents=my_agents,
tasks=my_tasks,
process=Process.sequential
)
# 分级流程,确保提供 manager_llm
crew = Crew(
agents=my_agents,
tasks=my_tasks,
process=Process.hierarchical,
manager_llm=ChatOpenAI(model="gpt-4")
)
2.4.4 附加任务特性
- 异步执行(Asynchronous Execution) :允许任务异步执行,实现并行处理,提高团队整体生产力。开发者可以根据任务特点灵活选择同步或异步执行方式。
- 人工输入审查(Human Input Review) :提供可选的人工审查任务输出功能,在最终确定任务结果前确保质量和准确性,引入了额外的监督层,保障任务执行的可靠性。
- 输出定制(Output Customization) :任务支持多种输出格式,如 JSON(
output_json
)、Pydantic 模型(output_pydantic
)和文件输出(output_file
),满足不同需求,方便数据的处理和利用。
2.5 团队(Crews)
2.5.1 团队属性
- 任务(Tasks) :分配给团队的任务列表,明确团队需要完成的工作内容。
- 代理(Agents) :属于团队的代理列表,确定团队成员构成,每个代理都有其独特的角色和能力。
- 流程(可选) :团队遵循的流程类型,如顺序或分层流程,决定任务执行的顺序和方式。
- 详细程度(可选) :执行过程中日志记录的详细程度,便于开发者在调试和监控时获取足够信息。
- 经理 LLM(可选,分层流程必需) :分层流程中经理代理使用的语言模型,用于管理任务执行过程。
- 功能调用 LLM(可选) :若传递,团队将使用此 LLM 为所有代理进行工具的功能调用,开发者可根据需求灵活配置。
- 配置(可选) :团队的可选配置设置,以
Json
或Dict[str, Any]
格式提供,用于进一步定制团队行为。 - 最大 RPM(可选) :团队执行过程中每分钟可执行的最大请求数,避免速率限制,可覆盖个别代理的
max_rpm
设置。 - 语言(可选) :团队使用的语言,默认为英语,可根据实际需求进行调整。
- 语言文件(可选) :用于团队的语言文件路径,方便进行多语言支持。
- 内存(可选) :用于存储执行记忆(短期、长期、实体记忆),增强团队的执行能力和学习能力。
- 缓存(可选) :指定是否使用缓存存储工具执行结果,提高流程效率。
- 嵌入器(可选) :团队使用的嵌入器配置,主要用于内存功能,影响数据的嵌入和检索方式。
- 完整输出(可选) :决定团队是否返回包含所有任务输出的完整输出或仅最终输出,满足不同的结果获取需求。
- 步骤回调(可选) :在每个代理的每个步骤后调用的函数,用于记录操作或执行其他操作,不覆盖特定于代理的
step_callback
。 - 任务回调(可选) :在每个任务完成后调用的函数,用于监控或执行任务后的其他操作。
- 共享团队(可选) :是否与 CrewAI 团队共享完整的团队信息和执行情况,以改进库并允许训练模型。
- 输出日志文件(可选) :是否创建包含完整团队输出和执行情况的文件,可指定文件路径和名称。
2.5.2 创建团队示例
以下是一个组建团队的示例,展示如何将具有互补角色和工具的代理结合在一起,分配任务并选择流程:
from crewai import Crew, Agent, Task, Process
from langchain_community.tools import DuckDuckGoSearchRun
# 定义具有特定角色和工具的代理
researcher = Agent(
role="高级研究分析师",
goal="发现创新的人工智能技术",
tools=[DuckDuckGoSearchRun()]
)
writer = Agent(
role="内容撰稿人",
goal="撰写有关人工智能发现的引人入胜的文章",
verbose=True
)
# 为代理创建任务
research_task = Task(
description="识别突破性人工智能技术",
agent=researcher
)
write_article_task = Task(
description="撰写关于最新人工智能技术的文章",
agent=writer
)
# 使用顺序流程组装团队
my_crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_article_task],
process=Process.sequential,
full_output=True,
verbose=True,
)
2.5.3 团队执行流程
- 顺序流程(Sequential) :任务依次执行,工作线性流动,简单直观,适用于任务之间有明确先后顺序的场景。
- 分层流程(Hierarchical) :经理代理协调团队,委派任务并在继续之前验证结果。此流程需要
manager_llm
,适用于复杂任务的管理和分配,确保任务的高效执行和质量控制。 - 启动团队 :使用
kickoff()
方法启动团队工作流程,根据定义的流程开始执行任务,获取任务执行结果。例如:
# 启动团队的任务执行
result = my_crew.kickoff()
print(result)
2.6 记忆(Memory)
2.6.1 记忆系统组成部分
- 短期记忆(Short-term Memory) :暂时存储最近的互动和结果,使代理能够迅速回忆和利用与当前情境紧密相关的信息,从而在对话或任务序列中保持连贯性,做出更贴合实际情况的决策和回应。
- 长期记忆(Long-term Memory) :犹如一个知识宝库,保留从过往执行中积累的宝贵见解和学习成果。随着时间的推移,代理能够不断从中汲取经验,逐步构建和完善自身的知识体系,进而提升未来决策和问题解决的能力,以更好地应对复杂多变的任务场景。
- 实体记忆(Entity Memory) :专注于捕获和组织在任务执行过程中遇到的各类实体信息,涵盖人、地点、概念等。这有助于代理深入理解复杂信息之间的内在联系,通过对实体关系的精准映射,更高效地处理和整合相关知识,为解决问题提供更全面、深入的视角。
- 上下文记忆(Context Memory) :致力于维护互动过程中的上下文信息,确保代理在一系列任务或连续对话中,能够始终保持响应的连贯性和相关性。即使在长时间的交互过程中,也能准确理解任务背景和意图,避免出现信息断层或误解,从而提供更加准确、合理的输出。
2.6.2 记忆系统如何赋能代理
- 上下文意识增强 :借助短期记忆和上下文记忆的协同作用,代理能够在对话或任务的演进过程中,牢牢把握上下文脉络。无论是多轮对话中的信息关联,还是任务序列中的逻辑延续,代理都能依据存储的上下文信息,生成更加连贯、一致且符合情境的回应,极大地提升了交互体验的流畅性和逻辑性。
- 经验积累与学习加速 :长期记忆为代理提供了一个不断成长和进化的平台。通过存储和回顾过去的行动及结果,代理能够从中总结经验教训,发现规律和模式,进而不断优化自身的决策策略和问题解决方法。这种经验积累的过程使得代理在面对类似问题时,能够迅速做出更明智、更高效的决策,显著提高工作效率和质量。
- 实体理解与信息处理优化 :实体记忆赋予代理识别和记忆关键实体的能力,使其在处理复杂信息时能够快速聚焦核心要点,理清信息之间的相互关系。这不仅有助于代理更准确地理解任务需求,还能在面对海量信息时,迅速筛选出有价值的内容,提高信息处理的速度和精度,从而更有效地应对复杂任务和多样化的问题场景。
2.6.3 在团队中实施记忆
在配置团队时,开发者可以根据团队目标和任务性质,灵活启用和定制每个记忆组件。默认情况下,记忆系统处于关闭状态,通过在团队配置中设置 memory=True
,即可激活记忆功能,为团队注入强大的记忆能力。记忆默认使用 OpenAI Embeddings,但开发者也可以通过调整 embedder
参数,将其设置为其他模型,如 Google AI、Azure OpenAI、GPT4ALL、Vertex AI 或 Cohere 等,以满足不同场景下的需求。例如:
from crewai import Crew, Agent, Task, Process
# 使用具有记忆功能的团队,采用默认的 OpenAI Embeddings
my_crew = Crew(
agents=[...],
tasks=[...],
process=Process.sequential,
memory=True,
verbose=True
)
# 使用具有记忆功能的团队,切换为 Google AI 嵌入
my_crew = Crew(
agents=[...],
tasks=[...],
process=Process.sequential,
memory=True,
verbose=True,
embedder={
"provider": "google",
"config": {
"model": "models/embedding-001",
"task_type": "retrieval_document",
"title": "Embeddings for Embedchain"
}
}
)
2.6.4 使用 CrewAI 记忆系统的好处
- 自适应学习与持续优化 :随着时间的推移和任务的不断执行,团队能够逐渐适应新的信息和任务要求,不断完善处理任务的方法和策略。记忆系统使代理能够从过往经验中学习,自动调整行为模式,从而在面对新情况时更加从容,团队整体效率也会随着经验的积累而不断提升。
- 个性化体验提升 :记忆功能使代理能够记录和识别用户的偏好、历史互动等信息,从而为用户提供更加个性化的服务和体验。无论是在内容推荐、问题解答还是交互方式上,代理都能够根据用户的个性化特征进行精准回应,满足用户的特定需求,增强用户与系统之间的粘性和满意度。
- 问题解决能力强化 :丰富的记忆存储库为代理提供了强大的知识后盾,使其在解决问题时能够充分借鉴过去的学习成果和上下文信息。通过快速检索和利用相关经验,代理能够更全面地分析问题,发现潜在的解决方案,做出更明智、更准确的决策,从而有效提升解决复杂问题的能力,为团队的成功运作提供有力支持。
3. 基于 CrewAI 构建 Multi Agent 系统的实践步骤
3.1 准备工作
3.1.1 环境配置
确保系统满足 CrewAI 和相关依赖项的安装要求。根据不同的操作系统,可能需要安装特定的软件包或配置环境变量。例如,在某些系统上可能需要安装 Python 环境、相关的库以及配置 API 密钥等。
3.1.2 安装 CrewAI 和 Ollama(可选)
按照官方文档的指导,依次安装 CrewAI 和 Ollama(如果需要使用 Ollama)。安装过程中可能需要注意版本兼容性、依赖关系等问题,确保安装顺利完成。例如,使用 pip 命令安装 CrewAI 及其工具包:pip install crewai[tools]
,并根据 Ollama 的安装指南进行相应操作。
3.1.3 设置模型
在 CrewAI 的配置文件中,将语言模型(LLM)设置为所需的模型,如 Llama3 等。这一步骤确保代理在执行任务时能够使用合适的语言模型进行推理和决策。
3.2 创建代理
3.2.1 定义代理角色和目标
根据任务需求,明确每个代理的角色和目标。例如,创建一个负责信息收集的代理,其角色可以定义为 "信息采集员",目标为 "收集特定领域的相关信息";再如,创建一个专注于数据分析的代理,角色为 "数据分析师",目标是 "对收集到的数据进行深入分析,提取有价值的见解"。
3.2.2 配置代理属性
根据代理的角色和任务特点,合理配置代理的属性,如选择合适的语言模型、添加必要的工具、设置最大迭代次数、缓存策略等。以信息采集员代理为例,可以为其配置网页搜索工具,设置较大的最大请求次数以提高信息获取效率,同时开启缓存以减少重复搜索;而数据分析师代理可能需要连接到特定的数据库工具,根据分析任务的复杂程度调整最大迭代次数等属性。
3.2.3 编写代理背景故事(可选但推荐)
为代理编写详细的背景故事,虽然这是可选步骤,但可以为代理的行为和决策提供更丰富的上下文,增强代理的拟人化特征,有助于提升系统的交互性和可解释性。例如,为信息采集员编写背景故事:"您是一名专业的信息采集员,擅长在海量的网络信息中快速筛选出有价值的内容。您长期从事数据收集工作,对各种信息源了如指掌,并且熟练掌握多种搜索技巧和工具。此次任务是为了帮助团队获取关于 [具体领域] 的最新信息,为后续的分析和决策提供有力支持。"
3.3 定义任务
3.3.1 明确任务描述
对每个任务进行清晰、准确的描述,确保代理能够明确理解任务的具体要求。例如,"分析过去一个月内社交媒体上关于 [产品名称] 的用户反馈,提取主要的意见和建议"、"根据市场数据预测未来三个月内 [行业名称] 的发展趋势" 等。
3.3.2 分配任务代理
根据代理的角色和能力,将任务合理分配给相应的代理。可以直接指定负责执行任务的代理,也可以利用 CrewAI 的流程机制,让系统根据代理的可用性、专业技能等因素自动分配任务。例如,将信息收集任务分配给信息采集员代理,将数据分析任务分配给数据分析师代理。
3.3.3 配置任务属性
根据任务需求,设置任务的其他属性,如预期输出格式(JSON、Pydantic 模型或文件等)、是否需要异步执行、是否需要人工输入审查、设置任务上下文等。例如,对于实时性要求较高的任务,可以设置为异步执行,以提高系统的整体响应速度;对于重要的决策性任务,可以开启人工输入审查,确保结果的准确性。
3.4 集成工具
3.4.1 选择合适的工具
从 CrewAI 提供的丰富工具库中选择适合任务的工具,如用于网页搜索的 WebsiteSearchTool
、用于文件读取的 FileReadTool
、用于数据分析的 CSVSearchTool
等。也可以根据需要创建自定义工具,以满足特定任务的独特需求。
3.4.2 将工具与代理和任务集成
将选定的工具分配给相应的代理,使代理能够在执行任务时调用这些工具。在定义任务时,明确指定任务所需使用的工具,确保工具与任务紧密结合,协同工作。例如,在信息收集任务中,为信息采集员代理配备 WebsiteSearchTool
和 DirectorySearchTool
,以便其能够从网页和本地目录中获取信息。
3.5 组建团队
3.5.1 组合代理
将具有不同角色和能力的代理组合在一起,形成一个协同工作的团队。确保团队成员之间的角色互补,能够共同完成复杂的任务。例如,一个团队可以包括信息采集员、数据分析师、内容创作者等不同角色的代理,各自发挥专长,共同实现项目目标。
3.5.2 定义团队流程
根据任务的特点和要求,选择合适的团队流程,如顺序流程或分级流程。顺序流程适用于任务之间具有明确先后顺序的场景,代理按照预定顺序依次执行任务;分级流程则适用于需要管理和协调的复杂任务,通过经理代理进行任务分配和监督。
3.5.3 配置团队属性
根据团队的需求,设置团队的各种属性,如日志记录详细程度、最大请求速率、语言设置、内存和缓存配置、是否共享团队信息等。合理的团队属性配置能够优化团队的运行效率,满足不同场景下的需求。
3.6 执行任务与监控
3.6.1 启动团队任务执行
使用 kickoff()
方法启动团队的任务执行流程,系统将根据定义的流程和任务分配,驱动代理开始工作。在任务执行过程中,可以通过日志记录、控制台输出等方式实时监控任务的进展情况。
3.6.2 监控任务执行过程
利用 CrewAI 提供的日志记录功能和相关监控工具,密切关注任务的执行状态、代理的操作步骤、输出结果等信息。通过详细的监控,及时发现任务执行过程中可能出现的问题,如代理执行错误、任务超时、资源占用过高等。
3.6.3 处理任务执行结果
任务执行完成后,获取并处理任务的输出结果。根据任务的预期输出格式,对结果进行解析和分析,将有价值的信息提取出来,用于后续的决策或进一步的处理。同时,根据任务执行的结果和监控过程中发现的问题,对代理、任务或团队配置进行必要的调整和优化,以提高系统的性能和准确性。
4. 案例分析:CrewAI 在实际项目中的应用
4.1 智能客服系统
4.1.1 系统架构与代理角色
在智能客服系统中,构建了多个代理来模拟人类客服的工作流程。其中包括用户问题接收代理、问题分类代理、信息查询代理、回答生成代理和回答审核代理等。用户问题接收代理负责接收用户的咨询问题,并将其传递给问题分类代理;问题分类代理根据问题的类型,将其分配给相应的信息查询代理;信息查询代理利用各种工具(如知识库查询工具、数据库搜索工具等)查找相关信息;回答生成代理根据查询到的信息生成初步回答;回答审核代理对生成的回答进行审核和优化,确保回答的准确性和质量。
4.1.2 任务流程与协作
当用户提出问题时,用户问题接收代理将问题记录并传递给问题分类代理。问题分类代理通过对问题的关键词分析、语义理解等技术,将问题分类为常见问题、技术问题、售后问题等不同类型。然后,根据分类结果,将问题分配给对应的信息查询代理。信息查询代理根据问题类型,在知识库、数据库或外部资源中查找相关信息。例如,对于常见问题,直接从知识库中检索答案;对于技术问题,可能需要查询技术文档或与技术专家系统进行交互。回答生成代理根据查询到的信息,运用自然语言生成技术,将信息转化为清晰、易懂的回答。最后,回答审核代理对回答进行语法检查、逻辑审核和礼貌性评估,如有必要,进行进一步的优化和修改。整个过程中,各个代理通过 CrewAI 的通信机制和任务编排功能,实现了高效的协作,为用户提供了快速、准确的回答。
4.2 智能内容创作助手
4.2.1 代理功能与分工
智能内容创作助手由多个代理协同工作,包括主题策划代理、素材收集代理、内容生成代理和内容润色代理等。主题策划代理负责根据用户需求或市场趋势确定创作主题;素材收集代理利用网络搜索工具、数据库查询工具等收集相关的素材,如文章、图片、数据等;内容生成代理根据主题和素材,运用自然语言生成算法创作初稿;内容润色代理则对初稿进行语法优化、风格调整和逻辑梳理,使其更符合用户的要求和预期。
4.2.2 创作过程与协同机制
当用户提出创作需求(如撰写一篇关于 [特定主题] 的文章)时,主题策划代理首先进行主题分析和策划,确定文章的大致框架和重点内容。然后,素材收集代理根据主题,在互联网上搜索相关的文章、研究报告、案例等素材,并将其整理后传递给内容生成代理。内容生成代理根据主题框架和收集到的素材,运用深度学习模型生成文章初稿。例如,它可以根据素材中的观点、数据等生成段落内容,组织文章结构。最后,内容润色代理对初稿进行全面的润色,检查语法错误、优化词汇选择、调整句子结构,使文章更加通顺、流畅、有吸引力。在整个创作过程中,代理之间通过 CrewAI 的通信和协作机制,实时共享信息和反馈,确保创作工作的顺利进行。
4.3 智能投资决策系统
4.3.1 系统组成与代理职责
智能投资决策系统由市场数据采集代理、数据分析代理、风险评估代理、投资策略推荐代理和投资组合优化代理等组成。市场数据采集代理负责从各种金融数据源(如股票交易所、财经新闻网站、金融数据库等)实时采集市场数据,包括股票价格、成交量、宏观经济指标等;数据分析代理对采集到的数据进行清洗、整理和分析,提取有价值的信息,如市场趋势、行业动态、公司财务状况等;风险评估代理根据数据分析结果,运用风险评估模型评估投资标的的风险水平;投资策略推荐代理根据市场情况和投资者的风险偏好,推荐合适的投资策略,如长期投资、短期投机、分散投资等;投资组合优化代理则根据推荐的投资策略,对投资组合进行优化,确定最佳的资产配置比例。
4.3.2 决策流程与协作模式
市场数据采集代理持续不断地收集最新的市场数据,并将其传递给数据分析代理。数据分析代理对数据进行深度分析,例如通过技术分析方法预测股票价格走势,通过基本面分析评估公司的内在价值。风险评估代理根据数据分析结果,结合历史数据和风险模型,评估不同投资标的的风险程度。投资策略推荐代理综合考虑市场趋势、风险评估结果和投资者的风险偏好,为投资者推荐个性化的投资策略。例如,对于风险偏好较高的投资者,可能推荐更多的股票投资比例;对于保守型投资者,则推荐更稳健的债券和基金投资组合。最后,投资组合优化代理根据推荐的投资策略,运用数学优化算法,确定最优的投资组合配置,以实现收益最大化和风险最小化。在整个决策过程中,各个代理紧密协作,通过 CrewAI 的流程编排和通信机制,实现数据的高效流转和决策的科学化。