介绍
大家好,这次给大家分享的内容是微软AutoGen框架的高级功能Selector Group Chat(选择器群聊),"选择器群聊"我在给大家分享的这篇博文的代码中有所体现微软AutoGen介绍——Custom Agents创建自己的Agents-CSDN博客,但是并没有详细的去介绍该功能(因为那篇博文的重点是讲解Custom Agents😊)。今天通过这次分享,我详细的给大家讲解一下该功能,那么我们直接进入正题。
Selector Group Chat
“SelectorGroupChat”(选择器群组聊天)实现了这样一种团队模式:参与者轮流向所有其他成员广播消息。一个生成式模型(例如,一个大语言模型)会基于共享的上下文信息来选择下一位发言者,从而实现动态的、具备上下文感知能力的协作。
它的主要特点包括:
- 基于模型的发言者选择
- 可配置的参与者角色和描述
- (可选)防止同一位发言者连续发言
- 可定制的选择提示
- 可定制的选择函数,用以覆盖默认的基于模型的选择方式
它如何运作
SelectorGroupChat是一种类似于 “轮询式群组聊天”(RoundRobinGroupChat)的群组聊天模式,但它采用了基于模型的下一位发言者选择机制。当团队通过 “run()” 或 “run_stream ()” 接收到一项任务时,会执行以下步骤:
- 团队会分析当前的对话上下文,包括对话记录以及参与者的姓名和描述属性,以便使用一个模型来确定下一位发言者。默认情况下,团队不会连续选择同一位发言者,除非该发言者是唯一可用的智能体。这一设定可以通过将“allow_repeated_speaker”设置为“True”来更改。我们也可以通过提供一个自定义的选择函数来替代默认模型。
- 团队会促使被选中的发言智能体给出回复,然后该回复会被广播给所有其他参与者。
- 接着检查终止条件,以确定对话是否应该结束。如果不结束,就从步骤1开始重复该过程。
- 当对话结束时,团队会返回包含本次任务对话记录的“TaskResult”(任务结果)。
一旦团队完成任务,对话上下文会保留在团队及所有参与者之中,这样下一个任务就可以在上一次的对话上下文基础上继续进行。我们可以通过调用“reset()”函数来重置对话上下文。
下面我们将通过一个针对网络搜索和数据分析任务的简单示例,来演示如何使用SelectorGroupChat。
智能体流程图
我们使用了三个专用的智能体:
- 规划智能体:作为战略协调者,它将复杂的任务分解为易于处理的子任务。
- 网络搜索智能体:这是一位信息检索专家,负责与网络搜索工具进行交互。
- 数据分析智能体:这是一位擅长执行计算的智能体,配备了百分比变化工具。
search_web_tool和percentage_change_tool是外部工具,智能体可以利用它们来执行各自的任务。
代码演示
# 注意:为了便于演示,本示例使用的是模拟工具,而非真实的应用程序编程接口(API)。
def search_web_tool(query: str) -> str:
if "2006-2007" in query:
return """Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
"""
elif "2007-2008" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214."
elif "2008-2009" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398."
return "No data found."
def percentage_change_tool(start: float, end: float) -> float:
return ((end - start) / start) * 100
让我们使用“AssistantAgent”类来创建这些专门的智能体。需要重点注意的是,模型会利用智能体的名称和描述属性来确定下一位发言者,所以建议提供有实际意义的名称和描述。
代码演示
model_client = OpenAIChatCompletionClient(model="gpt-4o")
planning_agent = AssistantAgent(
"PlanningAgent",
description="An agent for planning tasks, this agent should be the first to engage when given a new task.",
model_client=model_client,
system_message="""
You are a planning agent.
Your job is to break down complex tasks into smaller, manageable subtasks.
Your team members are:
WebSearchAgent: Searches for information
DataAnalystAgent: Performs calculations
You only plan and delegate tasks - you do not execute them yourself.
When assigning tasks, use this format:
1. <agent> : <task>
After all tasks are complete, summarize the findings and end with "TERMINATE".
""",
)
web_search_agent = AssistantAgent(
"WebSearchAgent",
description="An agent for searching information on the web.",
tools=[search_web_tool],
model_client=model_client,
system_message="""
You are a web search agent.
Your only tool is search_tool - use it to find information.
You make only one search call at a time.
Once you have the results, you never do calculations based on them.
""",
)
data_analyst_agent = AssistantAgent(
"DataAnalystAgent",
description="An agent for performing calculations.",
model_client=model_client,
tools=[percentage_change_tool],
system_message="""
You are a data analyst.
Given the tasks you have been assigned, you should analyze the data and provide results using the tools provided.
If you have not seen the data, ask for it.
""",
)
博主笔记:默认情况下,助手智能体将工具的输出作为回复返回。如果我们的工具没有以自然语言格式返回格式规范的字符串,我们可能需要在创建智能体时通过将 reflect_on_tool_use设置为True,在智能体内部添加一个反思步骤。这将使智能体能够对工具的输出进行反思,并提供自然语言形式的回复。
工作流程
1. 任务由选择器群组聊天接收,它会依据智能体的描述,挑选出最适合处理初始任务的智能体(一般是规划智能体)。
2. 规划智能体对任务进行分析,并将其拆解为多个子任务,然后按照<agent>:<task>的格式,把每个子任务分配给最合适的智能体。
3. 根据对话的上下文以及智能体的描述,选择器群组聊天管理器会动态地挑选出下一个智能体来处理分配给它的子任务。
4. 网络搜索智能体每次执行一次搜索操作,并将结果存储在共享的对话记录中。
5. 当被选中时,数据分析师会使用可用的计算工具来处理收集到的信息。
6. 工作流程会继续动态选择智能体,直到出现以下两种情况之一:
· 规划智能体判定所有子任务都已完成,然后发送“TERMINATE”指令。
· 满足了另一个终止条件(例如,达到了消息数量的上限)。
在定义我们的智能体时,请务必包含一个有用的描述(这点非常重要),因为这将被用于决定接下来选择哪个智能体。
终止条件
让我们使用两种终止条件:当规划智能体发送“终止”指令时,使用“文本提及终止(TextMentionTermination)”来结束对话;使用 “最大消息数终止(MaxMessageTermination)” 将对话限制为25条消息,以避免出现无限循环。
代码演示
text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_termination
运行团队
让我们使用这些智能体、终止条件以及自定义的选择器提示来创建这个团队。
代码演示
team = SelectorGroupChat(
[planning_agent, web_search_agent, data_analyst_agent],
model_client=model_client,
termination_condition=termination,
selector_prompt=selector_prompt,
allow_repeated_speaker=True, # 允许一个智能体连续进行多轮发言。
)
现在,我们让这个团队执行一项任务,去查找关于一位 NBA 球员的信息。
完整代码
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
# 注意:为了便于演示,本示例使用的是模拟工具,而非真实的应用程序编程接口(API)。
def search_web_tool(query: str) -> str:
if "2006-2007" in query:
return """Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
"""
elif "2007-2008" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214."
elif "2008-2009" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398."
return "No data found."
def percentage_change_tool(start: float, end: float) -> float:
return ((end - start) / start) * 100
model_client = OpenAIChatCompletionClient(model="gpt-4o")
planning_agent = AssistantAgent(
"PlanningAgent",
description="An agent for planning tasks, this agent should be the first to engage when given a new task.",
model_client=model_client,
system_message="""
You are a planning agent.
Your job is to break down complex tasks into smaller, manageable subtasks.
Your team members are:
WebSearchAgent: Searches for information
DataAnalystAgent: Performs calculations
You only plan and delegate tasks - you do not execute them yourself.
When assigning tasks, use this format:
1. <agent> : <task>
After all tasks are complete, summarize the findings and end with "TERMINATE".
""",
)
web_search_agent = AssistantAgent(
"WebSearchAgent",
description="An agent for searching information on the web.",
tools=[search_web_tool],
model_client=model_client,
system_message="""
You are a web search agent.
Your only tool is search_tool - use it to find information.
You make only one search call at a time.
Once you have the results, you never do calculations based on them.
""",
)
data_analyst_agent = AssistantAgent(
"DataAnalystAgent",
description="An agent for performing calculations.",
model_client=model_client,
tools=[percentage_change_tool],
system_message="""
You are a data analyst.
Given the tasks you have been assigned, you should analyze the data and provide results using the tools provided.
If you have not seen the data, ask for it.
""",
)
text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_termination
selector_prompt = """(Select) an agent to perform task.
{roles}
Current conversation context:
{history}
Read the above conversation, then select an agent from {participants} to perform the next task.
Make sure the planner agent has assigned tasks before other agents start working.
Only select one agent.
"""
team = SelectorGroupChat(
[planning_agent, web_search_agent, data_analyst_agent],
model_client=model_client,
termination_condition=termination,
selector_prompt=selector_prompt,
allow_repeated_speaker=True, # 允许一个智能体连续进行多轮发言。
)
task = "Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?"
async def main() -> None:
await Console(team.run_stream(task=task))
asyncio.run(main())
运行结果
---------- user ----------
Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?
---------- PlanningAgent ----------
To answer this question, we'll need to break it down into the following tasks:
1. WebSearchAgent: Investigate who was the Miami Heat player with the highest points scored in the 2006-2007 NBA season.
2. WebSearchAgent: Gather statistics for the player's total rebounds during the 2007-2008 NBA season.
3. WebSearchAgent: Collect statistics for the same player's total rebounds during the 2008-2009 NBA season.
4. DataAnalystAgent: Calculate the percentage change in total rebounds for the player between the 2007-2008 and 2008-2009 seasons.
Let's begin by gathering the necessary data.
1. WebSearchAgent: Investigate who was the Miami Heat player with the highest points scored in the 2006-2007 NBA season.
---------- WebSearchAgent ----------
[FunctionCall(id='call_knPrF0edlVal8opo7AMMU8Z0', arguments='{"query":"Miami Heat highest points scorer 2006-2007 NBA season"}', name='search_web_tool')]
---------- WebSearchAgent ----------
[FunctionExecutionResult(content='Here are the total points scored by Miami Heat players in the 2006-2007 season:\n Udonis Haslem: 844 points\n Dwayne Wade: 1397 points\n James Posey: 550 points\n ...\n ', call_id='call_knPrF0edlVal8opo7AMMU8Z0')]
---------- WebSearchAgent ----------
Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
---------- WebSearchAgent ----------
[FunctionCall(id='call_KOP1aR8O2kLGIeAkaUa8dE8u', arguments='{"query": "Dwyane Wade total rebounds 2007-2008 season"}', name='search_web_tool'), FunctionCall(id='call_Hk9j3wvryEhlKpe0YOUgXO46', arguments='{"query": "Dwyane Wade total rebounds 2008-2009 season"}', name='search_web_tool')]
---------- WebSearchAgent ----------
[FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.', call_id='call_KOP1aR8O2kLGIeAkaUa8dE8u'), FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.', call_id='call_Hk9j3wvryEhlKpe0YOUgXO46')]
---------- WebSearchAgent ----------
The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.
The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.
---------- DataAnalystAgent ----------
[FunctionCall(id='call_By2X8HJjd7K0B3qKSOti1vJ8', arguments='{"start":214,"end":398}', name='percentage_change_tool')]
---------- DataAnalystAgent ----------
[FunctionExecutionResult(content='85.98130841121495', call_id='call_By2X8HJjd7K0B3qKSOti1vJ8')]
---------- DataAnalystAgent ----------
85.98130841121495
---------- PlanningAgent ----------
To summarize:
- The Miami Heat player with the highest points in the 2006-2007 season was Dwyane Wade, with a total of 1,397 points.
- The percentage change in Dwyane Wade's total rebounds from the 2007-2008 season to the 2008-2009 season is approximately 85.98%.
TERMINATE
进程已结束,退出代码为 0
正如我们所见,在网络搜索智能体进行了必要的搜索,且数据分析智能体完成了必要的计算之后,我们发现德怀恩・韦德是迈阿密热火队在2006-2007赛季得分最高的球员,并且他在2007-2008赛季和2008-2009赛季的总篮板数变化百分比为85.98%!
自定义选择器方法
很多时候,我们希望能更好地控制选择过程。为此,我们可以使用一个自定义的选择器函数来设置selector_func参数,从而覆盖默认的基于模型的选择方式。例如,我们希望规划智能体在任何一个专业智能体发言之后立即发言,以便检查进度。
博主笔记:从自定义选择器函数中返回None将采用默认的基于模型的选择方式。
完整代码
import asyncio
from typing import Sequence
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_agentchat.messages import AgentEvent, ChatMessage
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
# 注意:为了便于演示,本示例使用的是模拟工具,而非真实的应用程序编程接口(API)。
def search_web_tool(query: str) -> str:
if "2006-2007" in query:
return """Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
"""
elif "2007-2008" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214."
elif "2008-2009" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398."
return "No data found."
def percentage_change_tool(start: float, end: float) -> float:
return ((end - start) / start) * 100
model_client = OpenAIChatCompletionClient(model="gpt-4o")
planning_agent = AssistantAgent(
"PlanningAgent",
description="An agent for planning tasks, this agent should be the first to engage when given a new task.",
model_client=model_client,
system_message="""
You are a planning agent.
Your job is to break down complex tasks into smaller, manageable subtasks.
Your team members are:
WebSearchAgent: Searches for information
DataAnalystAgent: Performs calculations
You only plan and delegate tasks - you do not execute them yourself.
When assigning tasks, use this format:
1. <agent> : <task>
After all tasks are complete, summarize the findings and end with "TERMINATE".
""",
)
web_search_agent = AssistantAgent(
"WebSearchAgent",
description="An agent for searching information on the web.",
tools=[search_web_tool],
model_client=model_client,
system_message="""
You are a web search agent.
Your only tool is search_tool - use it to find information.
You make only one search call at a time.
Once you have the results, you never do calculations based on them.
""",
)
data_analyst_agent = AssistantAgent(
"DataAnalystAgent",
description="An agent for performing calculations.",
model_client=model_client,
tools=[percentage_change_tool],
system_message="""
You are a data analyst.
Given the tasks you have been assigned, you should analyze the data and provide results using the tools provided.
If you have not seen the data, ask for it.
""",
)
text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_termination
selector_prompt = """(Select) an agent to perform task.
{roles}
Current conversation context:
{history}
Read the above conversation, then select an agent from {participants} to perform the next task.
Make sure the planner agent has assigned tasks before other agents start working.
Only select one agent.
"""
def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:
if messages[-1].source != planning_agent.name:
return planning_agent.name
return None
async def main() -> None:
team = SelectorGroupChat(
[planning_agent, web_search_agent, data_analyst_agent],
model_client=model_client,
termination_condition=termination,
selector_prompt=selector_prompt,
allow_repeated_speaker=True, # 允许一个智能体连续进行多轮发言。
)
task = "Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?"
await Console(team.run_stream(task=task))
# 重置之前的团队,然后使用该选择器函数再次运行聊天程序。
await team.reset()
team = SelectorGroupChat(
[planning_agent, web_search_agent, data_analyst_agent],
model_client=model_client,
termination_condition=termination,
selector_prompt=selector_prompt,
allow_repeated_speaker=True,
selector_func=selector_func,
)
await Console(team.run_stream(task=task))
asyncio.run(main())
运行结果
---------- user ----------
Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?
---------- PlanningAgent ----------
To answer this question, we need to follow these steps:
1. Identify the Miami Heat player with the highest points in the 2006-2007 season.
2. Retrieve the total rebounds of that player for the 2007-2008 and 2008-2009 seasons.
3. Calculate the percentage change in his total rebounds between the two seasons.
Let's delegate these tasks:
1. WebSearchAgent: Find the Miami Heat player with the highest points in the 2006-2007 NBA season.
2. WebSearchAgent: Retrieve the total rebounds for the identified player during the 2007-2008 NBA season.
3. WebSearchAgent: Retrieve the total rebounds for the identified player during the 2008-2009 NBA season.
4. DataAnalystAgent: Calculate the percentage change in total rebounds between the 2007-2008 and 2008-2009 seasons for the player found.
---------- WebSearchAgent ----------
[FunctionCall(id='call_Pz82ndNLSV4cH0Sg6g7ArP4L', arguments='{"query":"Miami Heat player highest points 2006-2007 season"}', name='search_web_tool')]
---------- WebSearchAgent ----------
[FunctionExecutionResult(content='Here are the total points scored by Miami Heat players in the 2006-2007 season:\n Udonis Haslem: 844 points\n Dwayne Wade: 1397 points\n James Posey: 550 points\n ...\n ', call_id='call_Pz82ndNLSV4cH0Sg6g7ArP4L')]
---------- WebSearchAgent ----------
Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
---------- PlanningAgent ----------
Great! Dwyane Wade was the Miami Heat player with the highest points in the 2006-2007 season. Now, let's continue with the next tasks:
2. WebSearchAgent: Retrieve the total rebounds for Dwyane Wade during the 2007-2008 NBA season.
3. WebSearchAgent: Retrieve the total rebounds for Dwyane Wade during the 2008-2009 NBA season.
---------- WebSearchAgent ----------
[FunctionCall(id='call_3qv9so2DXFZIHtzqDIfXoFID', arguments='{"query": "Dwyane Wade total rebounds 2007-2008 season"}', name='search_web_tool'), FunctionCall(id='call_Vh7zzzWUeiUAvaYjP0If0k1k', arguments='{"query": "Dwyane Wade total rebounds 2008-2009 season"}', name='search_web_tool')]
---------- WebSearchAgent ----------
[FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.', call_id='call_3qv9so2DXFZIHtzqDIfXoFID'), FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.', call_id='call_Vh7zzzWUeiUAvaYjP0If0k1k')]
---------- WebSearchAgent ----------
The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.
The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.
---------- PlanningAgent ----------
Now let's calculate the percentage change in total rebounds between the 2007-2008 and 2008-2009 seasons for Dwyane Wade.
4. DataAnalystAgent: Calculate the percentage change in total rebounds for Dwyane Wade between the 2007-2008 and 2008-2009 seasons.
---------- DataAnalystAgent ----------
[FunctionCall(id='call_FXnPSr6JVGfAWs3StIizbt2V', arguments='{"start":214,"end":398}', name='percentage_change_tool')]
---------- DataAnalystAgent ----------
[FunctionExecutionResult(content='85.98130841121495', call_id='call_FXnPSr6JVGfAWs3StIizbt2V')]
---------- DataAnalystAgent ----------
85.98130841121495
---------- PlanningAgent ----------
Dwyane Wade was the Miami Heat player with the highest points in the 2006-2007 season, scoring a total of 1397 points. The percentage change in his total rebounds from the 2007-2008 season (214 rebounds) to the 2008-2009 season (398 rebounds) is approximately 86.0%.
TERMINATE
进程已结束,退出代码为 0
从对话记录中你可以看到,PlanningAgent总是在WebSearchAgent和DataAnalystAgent智能体发言后立刻发言。
添加用户反馈功能
我们可以将用户代理智能体(UserProxyAgent)添加到团队中,以便在运行过程中收集用户反馈。
要在网络搜索示例中使用用户代理智能体(UserProxyAgent),我们只需将其添加到团队中,并更新选择器函数,使其在规划智能体发言后始终检查是否有用户反馈。如果用户回复“APPROVE”(批准),对话将继续进行;否则,规划智能体将再次尝试,直到用户批准为止。
完整代码
import asyncio
from typing import Sequence
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_agentchat.messages import AgentEvent, ChatMessage
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
# 注意:为了便于演示,本示例使用的是模拟工具,而非真实的应用程序编程接口(API)。
def search_web_tool(query: str) -> str:
if "2006-2007" in query:
return """Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
"""
elif "2007-2008" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214."
elif "2008-2009" in query:
return "The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398."
return "No data found."
def percentage_change_tool(start: float, end: float) -> float:
return ((end - start) / start) * 100
model_client = OpenAIChatCompletionClient(model="gpt-3.5-turbo-0125")
planning_agent = AssistantAgent(
"PlanningAgent",
description="An agent for planning tasks, this agent should be the first to engage when given a new task.",
model_client=model_client,
system_message="""
You are a planning agent.
Your job is to break down complex tasks into smaller, manageable subtasks.
Your team members are:
WebSearchAgent: Searches for information
DataAnalystAgent: Performs calculations
You only plan and delegate tasks - you do not execute them yourself.
When assigning tasks, use this format:
1. <agent> : <task>
After all tasks are complete, summarize the findings and end with "TERMINATE".
""",
)
web_search_agent = AssistantAgent(
"WebSearchAgent",
description="An agent for searching information on the web.",
tools=[search_web_tool],
model_client=model_client,
system_message="""
You are a web search agent.
Your only tool is search_tool - use it to find information.
You make only one search call at a time.
Once you have the results, you never do calculations based on them.
""",
)
data_analyst_agent = AssistantAgent(
"DataAnalystAgent",
description="An agent for performing calculations.",
model_client=model_client,
tools=[percentage_change_tool],
system_message="""
You are a data analyst.
Given the tasks you have been assigned, you should analyze the data and provide results using the tools provided.
If you have not seen the data, ask for it.
""",
)
text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_termination
selector_prompt = """(Select) an agent to perform task.
{roles}
Current conversation context:
{history}
Read the above conversation, then select an agent from {participants} to perform the next task.
Make sure the planner agent has assigned tasks before other agents start working.
Only select one agent.
"""
user_proxy_agent = UserProxyAgent("UserProxyAgent", description="A proxy for the user to approve or disapprove tasks.")
def selector_func_with_user_proxy(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:
if messages[-1].source != planning_agent.name and messages[-1].source != user_proxy_agent.name:
# 当接到新任务时,或者要检查进度时,规划智能体应该率先参与进来。
return planning_agent.name
if messages[-1].source == planning_agent.name:
if messages[-2].source == user_proxy_agent.name and "APPROVE" in messages[-1].content.upper(): # type: ignore
# 用户已批准该计划,继续让下一个智能体进行操作。
return None
# 使用用户代理智能体来获取用户的批准以便继续进行。
return user_proxy_agent.name
if messages[-1].source == user_proxy_agent.name:
# 如果用户不批准,就回到让PlanningAgent来处理。
if "APPROVE" not in messages[-1].content.upper(): # 类型:忽略
return planning_agent.name
return None
async def main() -> None:
team = SelectorGroupChat(
[planning_agent, web_search_agent, data_analyst_agent],
model_client=model_client,
termination_condition=termination,
selector_prompt=selector_prompt,
allow_repeated_speaker=True, # 允许一个智能体连续进行多轮发言。
)
task = "Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?"
await Console(team.run_stream(task=task))
# 重置之前的智能体,然后结合用户代理智能体和选择器函数再次运行聊天程序。
await team.reset()
team = SelectorGroupChat(
[planning_agent, web_search_agent, data_analyst_agent, user_proxy_agent],
model_client=model_client,
termination_condition=termination,
selector_prompt=selector_prompt,
selector_func=selector_func_with_user_proxy,
allow_repeated_speaker=True,
)
await Console(team.run_stream(task=task))
asyncio.run(main())
运行结果
---------- user ----------
Who was the Miami Heat player with the highest points in the 2006-2007 season, and what was the percentage change in his total rebounds between the 2007-2008 and 2008-2009 seasons?
---------- PlanningAgent ----------
To address the user's query, we will need to perform the following tasks:
1. Identify the Miami Heat player with the highest points in the 2006-2007 season.
2. Find the total rebounds for that player in the 2007-2008 season.
3. Find the total rebounds for that player in the 2008-2009 season.
4. Calculate the percentage change in the total rebounds between the 2007-2008 and 2008-2009 seasons.
Let's assign these tasks:
1. **WebSearchAgent**: Identify the Miami Heat player with the highest points in the 2006-2007 season.
(Task 2 and 3 depend on the result of Task 1. We'll proceed with Tasks 2 and 3 once Task 1 is complete.)
---------- UserProxyAgent ----------
approve
---------- WebSearchAgent ----------
[FunctionCall(id='call_0prr3fUnG5CtisUG7QeygW0w', arguments='{"query":"Miami Heat highest points scorer 2006-2007 NBA season"}', name='search_web_tool')]
---------- WebSearchAgent ----------
[FunctionExecutionResult(content='Here are the total points scored by Miami Heat players in the 2006-2007 season:\n Udonis Haslem: 844 points\n Dwayne Wade: 1397 points\n James Posey: 550 points\n ...\n ', call_id='call_0prr3fUnG5CtisUG7QeygW0w')]
---------- WebSearchAgent ----------
Here are the total points scored by Miami Heat players in the 2006-2007 season:
Udonis Haslem: 844 points
Dwayne Wade: 1397 points
James Posey: 550 points
...
---------- PlanningAgent ----------
Dwyane Wade was the Miami Heat player with the highest points in the 2006-2007 season, scoring 1397 points.
Next, we need to find Dwyane Wade's total rebounds for the 2007-2008 and 2008-2009 seasons:
2. **WebSearchAgent**: Find Dwyane Wade's total rebounds for the 2007-2008 season.
3. **WebSearchAgent**: Find Dwyane Wade's total rebounds for the 2008-2009 season.
---------- UserProxyAgent ----------
approve
---------- WebSearchAgent ----------
[FunctionCall(id='call_fBZe80NaBfruOVGwRWbhXyRm', arguments='{"query": "Dwyane Wade total rebounds 2007-2008 NBA season"}', name='search_web_tool'), FunctionCall(id='call_cURYibna4fGxySiL7IYt0c3s', arguments='{"query": "Dwyane Wade total rebounds 2008-2009 NBA season"}', name='search_web_tool')]
---------- WebSearchAgent ----------
[FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.', call_id='call_fBZe80NaBfruOVGwRWbhXyRm'), FunctionExecutionResult(content='The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.', call_id='call_cURYibna4fGxySiL7IYt0c3s')]
---------- WebSearchAgent ----------
The number of total rebounds for Dwayne Wade in the Miami Heat season 2007-2008 is 214.
The number of total rebounds for Dwayne Wade in the Miami Heat season 2008-2009 is 398.
---------- PlanningAgent ----------
Now that we have Dwyane Wade's total rebounds for both seasons, we can calculate the percentage change:
4. **DataAnalystAgent**: Calculate the percentage change in Dwyane Wade's total rebounds from the 2007-2008 season (214 rebounds) to the 2008-2009 season (398 rebounds).
---------- UserProxyAgent ----------
approve
---------- DataAnalystAgent ----------
[FunctionCall(id='call_z3uog7t2x0z1Suzl5hACF9hY', arguments='{"start":214,"end":398}', name='percentage_change_tool')]
---------- DataAnalystAgent ----------
[FunctionExecutionResult(content='85.98130841121495', call_id='call_z3uog7t2x0z1Suzl5hACF9hY')]
---------- DataAnalystAgent ----------
85.98130841121495
---------- PlanningAgent ----------
Dwyane Wade was the Miami Heat player with the highest points in the 2006-2007 season, scoring 1397 points. His total rebounds increased from 214 in the 2007-2008 season to 398 in the 2008-2009 season, which is a percentage change of approximately 85.98%.
TERMINATE
进程已结束,退出代码为 0
通过上述演示我们看到,用户的反馈已融入到对话流程中,用户可以批准或否决规划智能体所做出的决策。
说明
如果大家在运行上述代码的时候有AutoGen相关的提示或报错(例如:该参数不存在,没有此类方法等),请尝试更新一下AutoGen,博主在分享这篇博文的时候,AutoGen的版本是0.4.6稳定版。
安装或更新命令
pip install -U "autogen-agentchat" "autogen-ext[openai,azure]"
另外大家要根据业务需求,设置使用的LLM,不一定要按照我给大家分享代码中的设置来,如果只是为了测试并看运行结果可直接复制粘贴代码(完整代码)。
结束
好了,以上就是本次分享的全部内容了,今天的代码量有点多,请大家耐心看完和耐心在本地电脑调试,我相信大家肯定会有所收获,或者脱口而出来一句“哦~原来是这么回事”(哈哈)。为了让大家加深一下今天的分享内容,博主再次帮助大家整理下SelectorGroupChat(类)。
在微软AutoGen中,SelectorGroupChat主要用于在多智能体(multi-agent)的聊天场景中,根据特定的逻辑和条件来选择合适的智能体进行发言,以更好地管理和协调智能体之间的交互过程。具体来说,它有以下几个关键作用:
- 自定义选择逻辑:允许用户通过设置自定义的选择器函数(selector function)来覆盖默认的智能体选择方式。用户可以根据自己的需求和业务逻辑,决定在特定情况下哪个智能体应该发言。例如,规定某个规划智能体在其他专业智能体完成特定任务后立刻发言,以检查进度。
- 融入用户反馈:可以与用户代理智能体(UserProxyAgent)结合使用,将用户反馈纳入到智能体的选择和对话流程中。根据用户的批准或拒绝等反馈信息,决定后续由哪个智能体继续参与对话,从而实现“人机交互”(Human-in-the-Loop)的交互模式,使整个对话过程更加灵活和符合实际需求。
- 协调智能体交互:在多智能体协作的场景中,管理不同智能体之间的发言顺序和时机,确保对话能够有序进行,避免混乱和不必要的重复交流,提高多智能体系统的协作效率和交互效果。
总之,SelectorGroupChat为微软AutoGen中的多智能体聊天场景提供了更灵活、可定制的智能体选择和交互管理机制。
大家明白了吧?博主这次分享的内容首先让大家知道微软AutoGen框架中有这样一个功能,另外使用SelectorGroupChat的程度取决于具体的应用场景和用户需求。例如在需要多个智能体紧密协作完成复杂任务的场景中,如多领域专家协同解决复杂问题、大型项目的多角色团队协作等,SelectorGroupChat是非常常用的。还比如,在智能客服、智能助手等需要与用户进行多轮交互的系统中,如果希望根据用户输入和对话状态,灵活调配不同功能的智能体来提供服务,SelectorGroupChat也会经常被用到。请大家根据自己的项目类型和所涉及到的行业来选择去使用。博主还是那句话,请大家多去大胆的尝试和使用。如果大家对博主分享的内容感兴趣或有帮助,请点赞和关注,大家的点赞和关注是博主持续分享的动力🤭。