AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


6. 关于AI应用开发的一些想法
发布日期:2024-05-06 16:14:15 浏览次数: 1691


1. Autogen是什么?

AutoGen是微软公司开源的多智能体(Mutiple Agents)应用开发框架,多智能体应用让不同的Agent之间相互交流沟通来解决问题。
更大白话一些,在公司里,老板如果有一个事情要办,通常会让秘书组织一个会议,把相关的人拉到会议室里,然后告诉他们自己的目标,比如要半年实现一百倍的增长,下面的人就会相互扯皮讨论,但是最终还是琢磨出一个不靠谱的方法把事儿给办了。

你可能不是老板,但是可以通过AutoGen创建几个Agent,一起玩Cosplay。你扮演老板,给Agent分配不同的角色,比如项目经理,程序员,或者主管等。把你的目标告诉它们,让们任意去想办法,你只要在一旁听汇报,如果觉得有意见或者它们做得不对的地方,就让它们改,直到满意为止。
如果要提供一个开发框架,让开发人员能够在这个框架的基础上开发出不同的应用,那么这个框架要实现哪些能力呢?把"大象放进冰箱"分三步:

  1. 能够创建一个Agent,就是单独创建不同的Agent,让他们担任不同的角色,分配必要的工具,负责具体的任务;

  2. 提供多个Agent对话的环境,将多个Agent放到一个"小黑屋"里,让他们之间能够相互对话,把对话记录下来;

  3. 对对话进行管理,比如发言顺序,什么时候会议结束,对话过程是不是跑偏。

基本上AutoGen就是预先把这些功能都实现了,开发人员要做的只是明确任务,创建Agent,把Agent拉到聊天室里,让他们开聊。

2. 为什么需要Multi-Agent框架

现在一大堆开发框架都已经实现了单Agent的能力,比如AutoGPT, Langchain Agent等,为什么会需要一个Multi-Agent框架?实际上Multi-Agent框架还不止AutoGen一家,BabyAGI、CAMEL、MetaGPT、ChatDev等等都是。业界这么热心投入Multi-Agent研究肯定是有一些道理的。
简单的说,人们的直觉是模仿人类分工协同的模式,能够更有效的解决问题。更底层的逻辑是为了突破单Agent的一些限制。例如上下文窗口大小
Long Context是很多LLM追求的特性之一,单一的Agent也会受到Context 的限制,因为Agent一般都通过XoT (CoT、ToT、GoT) + React等方法来规划和思考,上下文会不断的加长,迟早会突破窗口限制。因此拆分Agent的功能避免超过上下文窗口限制是一个很有效的方法。
而且,Prompt是Agent工作的中很关键的因素,单一的Agent如果维护的大量的上下文,难免"脑子"会乱。如果只执行特定的任务,掌握特定技能,当然理论上表现会更好。
具体到开发应用的过程里,也需要不同的开发团队分工协同,那么势必要对应用功能进行拆分,每个开发团队负责一个Agent的模式也更有效。

3. AutoGen的基本原理

跟Langchain等框架比起来,AutoGen还是相对比较简单的框架。前面已经提过,AutoGen所做的就是如下几件事情:
  1. 能够创建一个Agent,AutoGen定义了一些Agent的类,用于定义和实例化特定的Agent。这些Agent具有基本的对话能力,能够根据接收到的消息,生成回复。最简单的,创建两个Agent,就能够让他们一对一的闲聊起来。
  2. 提供多个Agent对话的环境,通过GroupChat类来管理一个具有多个Agent参与的群聊环境,在这个GroupChat中来维护管理聊天记录、发言者选择/转换规则、谁是下一个发言者、什么时候群聊终止等;
  3. 对群聊进行管理,群聊的实际管理是由一个GroupChatManager来实现的,GroupChatManager也是一个Agent,GroupChat提供了一个环境,交给GroupChatManager来实际管理这个环境。

3.1 单个Agent

一个最简单的AutoGen helloworld 应用就是下面的样子:

from autogen import UserProxyAgent, ConversableAgent, config_list_from_json

def main():
# Load LLM inference endpoints from an env variable or a file
# 从文件或者环境变量中加载LLM的推理端点
# 具体参看https://microsoft.github.io/autogen/docs/FAQ#set-your-api-endpoints
# 以及 OAI_CONFIG_LIST_sample.
# 例如,如果你在当前工作目录下创建了一个 OAI_CONFIG_LIST 的文件,那么这个文件就会被用来作为配置文件
config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")

#利用LLM来创建一个Assistant Agent,这个LLM是在上面的配置文件里指定的。
assistant = ConversableAgent("agent", llm_config={"config_list": config_list})

#创建一个用户代理,这个用户代理就代表你,你可以随时加入对话中
user_proxy = UserProxyAgent("user", code_execution_config=False)

#让assistant来开始这个对话,如果用户输入 exit,那么对话就会被终止。
assistant.initiate_chat(user_proxy, message="How can I help you today?")

if __name__ == "__main__":
main()

在上面的简单的程序里,定义了两个Agent,一个叫assistant,一个是user_proxy,然后让assistant初始化了一个对话,这个对话的对象是user_proxy,初始的消息是"How can I help you today?"。运行代码后,你会接收到这条消息,然后可以任意输入回复,直到你输入exit,对话结束。
所以单个Agent的行为模式很简单,就是收发消息而已,输入输出都是文本。和人一样,有人跟你说话,你可以回复,或者选择不回复。
在上面的代码示例中,assistant这个Agent实例是一个ConversableAgent,而user_proxy是一个UserProxyAgent的实例。实际上在AutoGen中,Agent是如下图构造的:

AutoGen的Agent类继承关系

AutoGen先声明了一个Agent的protocol,规定了作为一个Agent基本属性和行为:
  • name属性:每个Agent必须有一个属性。
  • description属性:每个Agent必须有个自我介绍,描述自己的能干啥和一些行为模式。
  • send方法:发送消息给另一个Agent。
  • receive方法:接收来自另一个代理的消息Agent。
  • generate_reply方法:基于接收到的消息生成回复,也可以同步或异步执行。
只要具有这些能力,那么在AutoGen中就会被认为是一个Agent。
如果你定义了一个Agent,无论其他人说什么它都固定回复"好的",也可以认为是一个Agent,并不需要有LLM。这也是为什么在Agent之后又定义了一个LLMAgent的封装,它在Agent的基础上增加给LLM用的system message。
然后在ConversableAgent中具体实现了Agent规定的各种方法。核心是receive,当ConversableAgent收到一个消息之后,它会调用generate_reply去生成回复,然后调用send把消息回复给指定的接收方。同时ConversableAgent还负责实现对话消息的记录,一般都记录在ChatResult里,还可以生成摘要等。
最后,AutoGen在ConversableAgent的基础上实现了AssistantAgent,UserProxyAgent和GroupChatAgent三个比较常用的Agent类,这三个类在ConversableAgent的基础上添加了特定的system_message和description。其实就是添加了一些基本的prompt而已。
你可能也留意到了,好像这些Agent没有工具,那么它是如何使用工具呢?其实具体的实现是在ConversableAgent中。你可以通过类似如下的方法来给Agent提供工具:
def my_tool_function(param1, param2):
# 实现工具的功能
return result

agent = ConversableAgent(...)
agent.register_function({"my_tool_function": my_tool_function})

那么决定Agent的行为模式就有几点关键:
  1. 提示词,system_message,就是这个Agent的基本提示词
  2. 能调用的工具,取决于给Agent提供了哪些工具,在AssistantAgent默认没有配置任何工具,但是提示它可以生成python代码,交给UserProxyAgent来执行获得返回,相当于变相的拥有了工具
  3. 回复逻辑,如果你希望在过程中掺入一点私货而不是完全交给LLM来决定,那么可以在generate_reply的方法中加入一点其他逻辑来控制Agent返回回复的逻辑,例如在生成回复前去查询知识库,参考知识库的内容来生成回复。

3.2 两个Agent之间对话

你可以创建两个Agent,然后让它们进行对话。这是比较简单的一种方式。
如下图所示:

两个Agent对话的场景


实际的代码是:

import os
from autogen import ConversableAgent

#构造student_agent实例
student_agent = ConversableAgent(
name="Student_Agent",
system_message="You are a student willing to learn.",
llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
)

#构造teacher_agent实例
teacher_agent = ConversableAgent(
name="Teacher_Agent",
system_message="You are a math teacher.",
llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
)

#初始化一个聊天,由student_agent发出,接收方式teacher_agent
chat_result = student_agent.initiate_chat(
teacher_agent,
message="What is triangle inequality?",
summary_method="reflection_with_llm",
max_turns=2,
)

由student_agent通过调用initiate_chat()的方法,问teacher_agent()什么是三角不等式,并且规定了最大对话轮次为两轮,最后的对话摘要是通过reflection_with_llm的方法生成。整个对话结果保存在chat_result中。
如果一个对话需要跟多个Agent一对一顺序交流完成,可以通过下面的方法将对话串在一起。上一次对话的摘要会被作为参数一起传递到下一个对话环节。

顺序实现多次两个Agent对话


代码是:

# Start a sequence of two-agent chats.
# Each element in the list is a dictionary that specifies the arguments
# for the initiate_chat method.
chat_results = AgentA.initiate_chats(
[
{
"recipient": AgentB,
"message": "初始的message",
"max_turns": 2,
"summary_method": "last_msg",
},
{
"recipient": AgentC,
"message": "需要给AgentC的message",
"max_turns": 2,
"summary_method": "last_msg",
},
{
"recipient": AgentD,
"message": "需要给AgentD的message",
"max_turns": 2,
"summary_method": "last_msg",
},
{
"recipient": AgentE,
"message": "需要给AgentE的message",
"max_turns": 2,
"summary_method": "last_msg",
},
]
)

3.3 多个Agent的群聊

如果有超过两个Agent,那么就需要把它们加入一个聊天室(GroupChat)。然后考虑这个聊天室怎么管理和控制。例如谁应该在什么时候发言,哪些Agent之间才可以相互对话。
聊天室的管理是由GroupChatManager来进行的,GroupChatManager也是一个Agent。它首选择一个发言的Agent,然后发言Agent会返回它的响应,然后GroupChatManager会把收到的响应广播给聊天室内的其他Agent,然后再选择下一个发言者。直到对话终止的条件被满足。GroupChatManager选择下一个发言者的方法有:
  1. 自动选择: "auto"下一个发言者由LLM来自动选择;
  2. 手动选择:"manual"由用户输入来决定下一个发言者;
  3. 随机选择:"random"随机选择下一个发言者;
  4. 顺序发言:"round_robin" :根据Agent顺序轮流发言
  5. 自定义的函数:通过调用函数来决定下一个发言者;

多Agent群聊

如果聊天室里Agent比较多,还可以通过设置GroupChat类中设置allowed_or_disallowed_speaker_transitions参数来规定当特定的Agent发言时,下一个候选的Agent都有哪些。例如可以规定AgentB发言时,只有AgentC才可以响应。
通过这些发言控制的方法,可以将Agent组成各种不同的拓扑。例如层级化、扁平化。甚至可以通过传入一个图(Graph)来控制发言的顺序。

3.4 群聊嵌套

AutoGen允许在一个群聊中,调用另外一个Agent群聊来执行对话(嵌套对话Nested Chats)。这样做可以把一个群聊封装成单一的Agent,从而实现更加复杂的工作流。
具体实现方法是先利用上面的方法定义一个群聊,然后将这个群聊在另外一个群聊中,注册成为nested chat,并且设定一个trigger的表达式,当trigger表达式为"真"时,就会调用nested chat包装好的群聊来解决问题,将结果返回。

群聊嵌套

4. AutoGen能做什么

4.1 基本的场景

AutoGen的论文里举了6种场景。

AutoGen的应用场景

分别是解决数学问题,检索增强(RAG),决策制定,多Agent编程,动态群聊,下国际象棋。具体可以参见官网描述,这里不详细说明。

4.2 更高阶一点的玩法

可能已经有人会想到,前面无论是单个Agent或者是多个Agent,都是人类预先创建好的。针对某个具体的问题,又怎么知道应该创建多少个Agent?什么样的Agent才合适呢?在特定的任务里,是不是可以临时创建一个Agent?能不能只给一个"第一推动力",后面的事儿全交给AI去干了?
这个也有人想过了,两位中国留学生Linxin Song和Jieyu Zhang搞了一个Agent AutoBuild的项目,就是解决这个问题。他们的方法是:设计一个名为AgentBuilder的类,它将在用户提供构建任务和执行任务的描述后,自动完成参与者专家Agent的生成和群聊的构建。
大概的代码如下:
from autogen.agentchat.contrib.agent_builder import AgentBuilder

#步骤1,创建AgentBuilder的实例
builder = AgentBuilder(config_file_or_env=config_file_or_env, builder_model='gpt-4-1106-preview', agent_model='gpt-4-1106-preview')

#步骤2,指定任务
building_task = "Find a paper on arxiv by programming, and analyze its application in some domain. For example, find a latest paper about gpt-4 on arxiv and find its potential applications in software."

#步骤3,创建群聊的Agent,这一步会返回一个agent_list和agent的配置
agent_list, agent_configs = builder.build(building_task, default_llm_config, coding=True)

#步骤4,利用返回的agent_list和agent_configs构建群聊,并且将任务交给群聊去执行。

这就将Agent的构建也交给AI去决策了,你需要的只是指定任务而已。
在官网的Blog还有一些其他也挺有的意思的试验性项目,例如让Agent更新自己的技能等等。可以自己参阅。

5. AutoGen的可视化界面AutoGen Studio

AutoGen也提供了一个可视化的界面,让你无需编码也可以进行构建多Agent系统。按照官方的说明就可以安装。

AutoGen Studio界面

当然,目前这界面还比较简单,很多高阶功能还是需要编码实现。

6. 关于AI应用开发的一些想法

Agent和过去程序代码不一样的地方就是它或多或少是有一些智能的,和传统一个函数或者应用写好之后就处于不可改动的情况不同。也就是意味着,利用Agent或者Multi-Agent实现的应用程序是有可能实现进化的。传统的应用程序不过是为Agent提供了一个基本的"环境",Agent可以通过与人("用户")的交互以及环境的互动过程中,通过数据和反馈来感知外部,并且不断生成代码和使用工具来优化应用。例如,过去人们购买的应用软件都需要等待厂家的升级来进行版本的改动和调整,但是基于Agent的应用程序就有可能通过自然语言来构筑新的功能,而无需等待版本的更新。也就是说,应用应该是"成长"出来。
如果将来LLM能够收集数据来更新自己,那么人类就真的变成了超级智能的引导程序。



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询