基于LLM构建的Agent中有一个明显的现象就是多智能体体系结构的表现要超越单智能体,即使单智能体使用无可挑剔的提示策略。本文将探索另一个有趣的多智能体框架——CrewAI。
一、CrewAI整体优势
CrewAI可以应用在生成环境中。它在发言人的反应和编排上牺牲了一点灵活性和随机性,但在代理人的能力、任务和发言转向上获得了更多的确定性。到目前为止,唯一的编排策略是“sequential”,未来的发布计划是“consensual”和“hierarchical”。
当我们在下一章中深入研究这个框架及其代码时,我们会发现确保任务由相关代理并按定义的顺序处理非常容易。你肯定不会在CrewAI中看到智能体之间的任何生动互动,比如一个智能体纠正另一个智能体,一个智能体的多次讲话。这些交互有利于实验或演示,但对需要高效、确定性和成本效益高的任务完成的真实LLM产品用处不大。因此,CrewAI优先考虑精简和可靠的方法,在一个强大的群聊中,每个人工智能代理都准确地知道该做什么以及他们的目标。
在我看来,另一个也是最关键的优势是它蓬勃发展的工具和支持丰富的资源,可以用来构建代理和任务,这源于它是基于LangChain设计的智能体。LangChain是一个成熟的LLM框架,已经为LLM应用程序开发人员提供了丰富的工具和外围设备来增强语言模型的功能。
CrewAI被证明适合熟悉LangChain的LLM应用程序开发人员,或者已经在其上构建应用程序的开发人员。对他们来说,将现有的单独代理集成到CrewAI框架中可以相对容易地实现。相比之下,AutoGen的学习曲线可能更陡峭,需要更多的时间来了解其用法并有效地集成代理。
二、CrewAI代码实战
现在让我们深入了解如何在代码中实践这些优势。
2.1 CrewAI业务流程
为了证明Agent顺序任务的易用性,我将使用之前AutoGen演示相同的任务,可以参考之前的博文LLM之Agent(九)| 通过API集成赋能Autogen Multi-Agent系统,该演示要求人工智能代理根据天气条件和所附的保险项目列表,生成一个包含适当活动的旅行计划。
构建一套群聊人工智能代理,需要以下角色:
- Weather reporter:根据地点和日期提供天气状况。
- Activity agent:根据地点和天气条件为旅行活动提供建议。
- Travel advisor:生成包括每天活动在内的旅行行程。
- Insurance agent:根据计划活动和潜在风险量身定制保险方案。
为了详细说明,沟通应按顺序操作,如天气记者->活动代理人->旅行顾问->保险代理人。
下面看一下如何实现:
a)步骤1-首先安装CrewAI软件包
pip install crewai
b)步骤2-导入包,并进行相关设置
由于底层实现依赖于LangChain库,因此除了CrewAI之外,我们还必须导入相关的LangChain包
import os
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4-1106-preview")
c)步骤3-构建代理
实施过程主要是为每个代理商设置系统提示。CrewAI将系统提示(可能还有代理描述)分为多个部分。看看天气预报员的代码:
Weather_reporter = Agent(
role='Weather_reporter',
goal="""provide historical weather
overall status based on the dates and location user provided.""",
backstory="""You are a weather reporter who provides weather
overall status based on the dates and location user provided.
You are using historical data from your own experience. Make your response short.""",
verbose=True,
allow_delegation=False,
llm=llm,
)
通常情况下,你应该填写role、goal和backstory来构建一个代理。这三个部分的名称很容易理解,其中role指的是代理的名称,goal指的是创建该代理的原因,以及代理能力的backstory。allow_delegation是为将任务传递给下一个代理(如果该代理无法处理)时的情况定义的。
按照相同的方法,让我们构造其余三个代理。
from langchain.agents import load_tools
human_tools = load_tools(["human"])
activity_agent = Agent(
role='activity_agent',
goal="""responsible for activities
recommendation considering the weather situation from weather_reporter.""",
backstory="""You are an activity agent who recommends
activities considering the weather situation from weather_reporter.
Don't ask questions. Make your response short.""",
verbose=True,
allow_delegation=False,
llm=llm,
)
travel_advisor = Agent(
role='travel_advisor',
goal="""responsible for making a travel plan by consolidating
the activities and require human input for approval.""",
backstory="""After activities recommendation generated
by activity_agent, You generate a concise travel plan
by consolidating the activities.""",
verbose=True,
allow_delegation=False,
tools=human_tools,
llm=llm,
)
Insure_agent = Agent(
role='Insure_agent',
goal="""responsible for listing the travel plan from advisor and giving the short
insurance items based on the travel plan""",
backstory="""You are an Insure agent who gives
the short insurance items based on the travel plan.
Don't ask questions. Make your response short.""",
verbose=True,
allow_delegation=False,
llm=llm,
)
人机交互是多智能体应用程序治理的基本组成部分,以确保人工智能代理在适当的监督下发言。与需要开发人员构建用户代理以结合人类交互的AutoGen框架不同,集成LangChain的CrewAI提供了一种简化的方法,通过将名为“human”的工具加载到tools参数中,然后在代理travel_advisor的定义中加入tools=human_tools即可无缝地集成人工输入。我们接下来应该做的是将这个人工提示写入我们将在下一步中介绍的Task对象的描述中。
d)步骤4-构建任务
在CrewAI中,没有针对整个组的“整体”任务,而是应该通过Task()方法为每个代理分配单独的任务。
task_weather = Task(
description="""Provide weather
overall status in Bohol Island in Sept.""",
agent=Weather_reporter
)
task_activity = Task(
description="""Make an activity list
recommendation considering the weather situation""",
agent=activity_agent
)
task_insure = Task(
description="""1. Copy and list the travel plan from task_advisor. 2. giving the short
insurance items based on the travel plan considering its activities type and intensity.""",
agent=Insure_agent
)
task_advisor = Task(
description="""Make a travel plan which includes all the recommended activities, and weather,
Make sure to check with the human if the draft is good
before returning your Final Answer.
.""",
agent=travel_advisor
)
必须使用agent=…为每个任务显式分配一个代理…。
如果你更喜欢评论旅行计划人际互动,你可以试着附加这样的文字“Make sure to check with the human if the draft is good before returning your final answer”。
e)步骤5-组建团队并开始
现在,是时候用编排策略将他们组成一支有能力的团队了。
crew = Crew(
agents=[Weather_reporter, activity_agent, travel_advisor, Insure_agent, ],
tasks=[task_weather, task_activity, task_advisor, task_insure, ],
verbose=2
)
result = crew.kickoff()
在目前唯一的选择顺序策略中,会严格按照agents列表和tasks列表中的顺序执行。根据我的测试,你必须确保两个顺序都是一致的,但我认为设计需要改进,以保持tasks列表是任务执行顺序的唯一参考。将verbose设置为2将使系统打印[Info]和[Debug]信息。
当一切就绪时,只需调用kickoff()函数就可以开始群聊生成。
从正在进行的打印中,您将看到LangChain的ReAct流程为每个任务提供的熟悉输出。
最后,最后的答案显示了预期的旅行计划:
2.2 带Tools的代理
当我们通过AutoGen框架开发AI群聊时,使用OpenAI的函数调用功能来调用外部API或自定义函数以扩展代理的知识是非常方便的。不幸的是,函数调用仅适用于GPT模型,很少有经过微调的开源模型。通过使用LangChain框架,该工具界面自然支持在现实世界中与CrewAI代理交互,并可用于所有兼容的模型。尽管工具的可靠性低于函数调用,但当工具的函数不需要复杂的输入参数时,它非常适用于开源模型。
让我们看看如何在我们的旅行计划应用程序中使用它。
a.预置工具
首先,我们希望Activity_agent提供来自互联网搜索的旅行活动,而不是自行生产。像大多数LangChain示例一样,我们使用DuckDuckGo作为搜索工具,该工具已内置到LangChain库中了。
安装DuckDuckGo软件包:
pip install duckduckgo_search
定义搜索工具:
from langchain_community.tools import DuckDuckGoSearchRun
search_tool = DuckDuckGoSearchRun()
将search_tool插入activity_agent。
activity_agent = Agent(
role='activity_agent',
goal="""responsible for actitivies
recommendation considering the weather situation from weather_reporter.""",
backstory="""You are an activity agent who recommends
activities considering the weather situation from weather_reporter.
Don't ask questions. Make your response short.""",
verbose=True,
allow_delegation=False,
tools=[search_tool],
llm=llm,
)
在最后一步中,不要忘记通知代理使用Task定义中的最新数据。
task2 = Task(
description="""Make a research for suitable and up-to-date activities
recommendation considering the weather situation""",
agent=activity_agent
)
现有的各种工具可以从LangChain集成中选择。
b.自定义工具
有时用户会调用自定义函数或API,也可以通过LangChain的装饰器@tool或StructuredTool方法创建自定义工具。
假设我们希望weather_reporter能够通过自定义API搜索在线天气数据。让我们快速模拟一个。
from langchain.tools import BaseTool, StructuredTool, tool
from langchain.pydantic_v1 import BaseModel, Field
class WeatherInput(BaseModel):
search_string: str = Field(description="the search string for the weather status")
def get_weather(search_string:str) -> str:
"""Look up the weather status"""
return "It's raining season with typhoons."
weather_search = StructuredTool.from_function(
func=get_weather,
name="weather_search",
description="search for the weather status",
args_schema=WeatherInput,
return_direct=True,
)
现在创建了新工具weather_search,用于接受查询字符串以返回虚拟天气状态“It’s raining season with typhoons”。然后,我们更新代理以配备此工具:
Weather_reporter = Agent(
role='Weather_reporter',
goal="""providing weather
overall status based on the dates and location the user provided.""",
backstory="""You are a weather reporter who provides weather
overall status based on the dates and location the user provided.
Make your response short.""",
verbose=True,
allow_delegation=False,
tools=[weather_search],
llm=llm,
)
并更新任务:
task1 = Task(
description="""providing weather
overall status in Bohol Island in September.""",
agent=Weather_reporter
)
在应用程序重新运行后,根据结果,weather_reporter和activity_agent都将开始使用该工具来支持它们的响应生成(蓝色句子)。
2.3 开源模型
由于该框架与OpenAI API的推理结构没有紧密绑定,因此在CrewAI中使用开源模型的局限性比AutoGen小得多。一个快速的方法是通过安装Ollama来部署一个本地模型。
步骤1-安装Ollama
按照Ollama官方[2]页面上的说明将软件包安装到您的本地机器上,并确保您有足够的本地计算资源来运行模型。
步骤2——创建LLM实例
要为代理创建Ollama模型的推理,只需要使用LangChain中的Ollama()方法定义一个新的llm。
from langchain.llms import Ollama
llm_ollama = Ollama(model="YOUR_MODEL_NAME")
支持的型号列表可以参考:[3]
然后,将llm_ollama提供给代理,例如:
Insure_agent = Agent(
role='Insure_agent',
goal="""responsible for listing the travel plan from advisor and giving the short
insurance items based on the travel plan""",
backstory="""You are an Insure agent who gives
the short insurance items based on the travel plan.
Don't ask questions. Make your response short.""",
verbose=True,
allow_delegation=False,
llm=llm_ollama,
)
现在,Insure_agent将通过本地语言模型生成文本。
三、结论
CrewAI在提供LangChain引入的可扩展功能方面具有明显优势,包括工具集成和对开源大型语言模型的支持。它的顺序编排能力有利于多智能体应用程序的生产。尽管有这些优势,但缺乏某些功能可能会阻碍其广泛采用——与OpenAI的助手和更复杂的编排相关的功能明显缺乏。CrewAI团队必须尽快解决这些差距并部署增强功能,以满足LLM应用程序开发的需求。
参考文献:
[1] https://levelup.gitconnected.com/for-a-multi-agent-framework-crewai-has-its-advantages-compared-to-autogen-a1df3ff66ed3
[2] https://ollama.ai/
[3] https://ollama.ai/library