AutoGen消息转发:register_reply用法详解及多Agent协作方案
2025-03-11 02:24:22
AutoGen 中如何将消息转发给另一个 Agent? (register_reply 的使用)
在开发多智能体系统时,常常需要一个智能体将对话转发给另一个智能体。像你遇到的情况:需要项目经理先制定计划,然后用户审核,审核通过后再把消息转发给一组其他智能体。你尝试使用 register_reply
,但似乎没起作用。别担心,咱来一起捋一捋。
问题根源:对 register_reply
的误解
从你的代码和看, 你对register_reply
的功能和用法可能有些偏差. register_reply
确实用于注册一个回复函数,但其主要目的是允许一个 agent 基于 其他 agent 的回复, 或环境(如工具函数的调用等),触发 自身 的回复逻辑 ,而不是直接将消息“转发”到另一个 agent. 在你这儿 project_manager.register_reply(user_proxy,add_data_reply)
会把user_proxy
的答复传给 project_manager
触发 add_data_reply
, 然而并不会执行 comedian.generate_reply
. comedian.generate_reply
需要的 messages
也并不是原先你想的.
咱们需要更灵活的方式来控制对话流程,实现“转发”的效果。
解决方案:多种姿势搞定消息转发
下面,我将提供几种可行的方案,帮你解决这个问题。各有优缺点,你可以根据自己的实际需求选择。
方案一:直接调用,简单粗暴
最简单的方法是在用户审核通过后,直接调用目标 agent 的 send
和 receive
方法。
原理:
- 在用户代理 (
UserProxyAgent
) 确认计划后, 不使用register_reply
, 直接让它主动给执行 agent 发送消息 - 触发
comedian
Agent, 使用initiate_chat
orsend
&receive
.
代码示例:
import autogen
config_list = autogen.config_list_from_json(
"OAI_CONFIG_LIST",
filter_dict={
"model": ["gpt-4"],
},
)
llm_config = {
"config_list": config_list,
"cache_seed": 42,
"request_timeout":600
}
project_manager = autogen.AssistantAgent(
name="project_manager",
system_message="""You are responsible for coming up with a plan to estimate the cost.""",
llm_config=llm_config,
)
comedian = autogen.AssistantAgent(
name= "comedian",
system_message="""Your job is to make a joke about the plan shared.
""",
llm_config=llm_config,)
user_proxy = autogen.UserProxyAgent(
name="User_proxy",
system_message="A human admin.",
code_execution_config={"last_n_messages": 2, "work_dir": "groupchat"},
human_input_mode="ALWAYS"
)
# 第一次对话:项目经理制定计划并等待用户确认
user_proxy.initiate_chat(
project_manager,
message="""I would like you to comeup with a plan to build a model rocket""",
)
# 获取用户对计划的反馈。 假设这是来自用户界面或某种输入机制
user_feedback = input("Do you approve the plan? (yes/no): ")
if user_feedback.lower() == 'yes':
# 获取 project_manager 的最后一条消息(即计划)
plan_message = project_manager.last_message()["content"]
# 将计划作为消息发送给 comedian, 可以开始新的对话,或这把消息转发给另一个group
user_proxy.send(
recipient=comedian,
message=plan_message
)
user_proxy.receive(
sender=comedian,
)
说明:
user_proxy.initiate_chat
启动与project_manager
的对话,制定计划。- 通过
input()
模拟用户审核 (实际应用中, 可能是前端界面的操作)。 - 如果用户批准,通过
project_manager.last_message()
获取计划内容。 user_proxy.send
和user_proxy.receive
用于实现user_proxy
和comedian
交流.- 可以进一步拓展, 把comedian 换成group chat manager, 开始群聊.
方案二:使用 GroupChat,灵活可控
如果后续涉及多个智能体的交互,使用 GroupChat
会更方便管理。
原理:
- 创建一个包含
project_manager
、comedian
和其他需要参与的智能体的GroupChat
。 project_manager
先跟user_proxy
制定计划, 计划获得批准后。- 创建一个新的
GroupChat
对象,用于启动新的讨论. 将原先对话加入新的GroupChat。
代码示例:
import autogen
config_list = autogen.config_list_from_json(
"OAI_CONFIG_LIST",
filter_dict={
"model": ["gpt-4"],
},
)
llm_config = {
"config_list": config_list,
"cache_seed": 42,
"request_timeout":600
}
project_manager = autogen.AssistantAgent(
name="project_manager",
system_message="""You are responsible for coming up with a plan to estimate the cost.""",
llm_config=llm_config,
)
comedian = autogen.AssistantAgent(
name= "comedian",
system_message="""Your job is to make a joke about the plan shared.
""",
llm_config=llm_config,)
engineer = autogen.AssistantAgent(
name="engineer",
system_message="""Your job is to review the plan, and provide constructive feedback.
""",
llm_config=llm_config,
)
user_proxy = autogen.UserProxyAgent(
name="User_proxy",
system_message="A human admin.",
code_execution_config={"last_n_messages": 2, "work_dir": "groupchat"},
human_input_mode="ALWAYS"
)
# 第一次对话:项目经理制定计划并等待用户确认
user_proxy.initiate_chat(
project_manager,
message="""I would like you to comeup with a plan to build a model rocket""",
)
# 获取用户对计划的反馈。 假设这是来自用户界面或某种输入机制
user_feedback = input("Do you approve the plan? (yes/no): ")
if user_feedback.lower() == 'yes':
# 获取 project_manager 的最后一条消息(即计划)
plan_message = project_manager.last_message()
groupchat = autogen.GroupChat(agents=[user_proxy, comedian, engineer], messages=[], max_round=12)
manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=llm_config)
user_proxy.send(
recipient=manager,
message=plan_message["content"] #把上一个对话的内容总结发给下一个groupchat
)
说明:
- 前期准备工作与方案一致。
- 当计划审核通过后,用新的agents创建
GroupChat
- 注意: 使用
plan_message["content"]
, 或者更好的做法是,在project_manager
完成计划时就要求其总结内容, 并把内容发送到下一个GroupChat
。
方案三:自定义 register_reply
,精细控制(进阶)
如果你坚持使用 register_reply
,想实现更复杂的逻辑(例如,根据用户反馈的不同,转发给不同的 agent),可以这样改进。
原理:
- 定义一个更通用、灵活的回复函数。
- 在这个函数里,根据具体情况(如用户输入、消息内容等)决定下一步操作。
- 不依赖
sender
做消息转发。
代码示例:
import autogen
config_list = autogen.config_list_from_json(
"OAI_CONFIG_LIST",
filter_dict={
"model": ["gpt-4"],
},
)
llm_config = {
"config_list": config_list,
"cache_seed": 42,
"request_timeout":600
}
project_manager = autogen.AssistantAgent(
name="project_manager",
system_message="""You are responsible for coming up with a plan to estimate the cost.""",
llm_config=llm_config,
)
comedian = autogen.AssistantAgent(
name= "comedian",
system_message="""Your job is to make a joke about the plan shared.
""",
llm_config=llm_config,)
user_proxy = autogen.UserProxyAgent(
name="User_proxy",
system_message="A human admin.",
code_execution_config={"last_n_messages": 2, "work_dir": "groupchat"},
human_input_mode="ALWAYS",
)
async def custom_reply(
recipient,
messages,
sender,
config,
):
if messages is None or len(messages) == 0:
return False, None
last_message = messages[-1]
if "APPROVED" in last_message["content"].upper():
plan = [msg for msg in reversed(messages) if msg["role"] == "assistant"][0]["content"]
user_proxy.send(recipient=comedian, message=plan)
return True, None #stop on this turn
return False, None
# 让 user_proxy 触发事件
user_proxy.register_reply(
trigger=autogen.Agent, #监听任何agent
reply_func=custom_reply,
config=None,
)
# 启动与 project_manager 的对话
user_proxy.initiate_chat(
project_manager,
message="""I would like you to comeup with a plan to build a model rocket""",
)
# 模拟用户批准
user_proxy.send(project_manager, "APPROVED")
user_proxy.receive(comedian) #user_proxy 会先触发 register_reply 的function.
说明:
custom_reply
接收参数的意义和之前的不同.messages
指的是触发agent之前的对话, 包括触发Agent所发出的.- 内部逻辑:判断 messages, 如果有 “APPROVED”,则提取之前的计划, 再转发消息给
comedian
。 - 使用
user_proxy.register_reply
将其注册到user_proxy
上, 触发任何 Agent都可以 (包括project_manager
). - 用
user_proxy.send(project_manager, "APPROVED")
模拟用户的批准操作(实际中应根据实际用户输入来决定)。 - 通过返回
(True, None)
终止默认的循环.
这种写法避免了直接转发, 更清晰.
总结和建议
选择哪种方案取决于你的具体需求:
- 如果只是简单的转发,方案一最直接。
- 如果后续交互复杂,方案二更易于管理。
- 如果需要根据用户反馈做更精细的控制,方案三更灵活, 但是有一定上手难度。
记住,register_reply
的核心是基于其他人的回复触发自身的逻辑 ,而不是直接的消息转发。掌握了这一点,你就能更好地运用 AutoGen 构建复杂的多智能体系统了!