顺德大良营销网站建设百度指数分析报告
这篇文章瞄的是AutoGen官方教学文档 Advanced
章节中的 Selector Group Chat
篇章,介绍了SelectorGroupChat
对象如何从一个Team中选择其中一个Agent与LLM进行对话,并且在得到结果后进行二次规划,同时你也可以自定义选择函数。本质上还是对Team的流程控制。
- 官网链接:https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/selector-group-chat.html# ;
Selector Group Chat
官方展示了一个名为 SelectorGroupChat
的对象,是一个Team对象也就是由多个Agent组成的对象,和我们之前使用的 RoundRobinGroupChat
是同一类型。它的作用在于内部的每一个Agent都会轮流向其他Agent进行广播消息,然后由LLM根据整个Team的上下文环境选择与这个Team中的哪一个Agent进行对话。
SelectorGroupChat
对象的关键特性有以下几点:
- 依靠LLM选择合适的Agent;
- 可以配置参与对象于描述;
- 防止同一个Agent持续性对话(可选);
- 可自定义的prompt;
- 可自定义选择函数
selection function
,即你也可以不让LLM进行选择而是根据你的选择函数给LLM一个Agent进行对话;
相当于之前使用的RoundRobinGroupChat
是内部Agent自发向LLM进行对话;而SelectorGroupChat
是将整个Team的上下文发给LLM,然后让LLM或者你自定义的选择函数使用其中一个Agent与LLM对话。
How Does it Work?
SelectorGroupChat
之所以能够实现上面提到的选择功能是依靠在 run()
或者 run_stream()
函数中按照下面的步骤执行:
- Team分析当前对话的上下文,包括历史记录、每一个Agent的
name
和description
,以此为依据选择下一个与LLM对话的Agent;默认情况下不会选择上一次与LLM对话的Agent,尽量避免只有一个Agent持续与LLM进行对话,除非这个Team中只有一个Agent,但也可以通过参数allow_repeated_speaker=True
的方式允许Agent持续与LLM对话;你也可以通过自定义的选择函数来筛选下一次要和LLM对话的Agent; - 被选中的Agent会将自己的prompt和LLM的response都广播给整个Team中的所有其他Agent;
- 只有当终止条件被触发时间才会终止Team,否则整个Team会持续运行下去;
- 当对话结束时会返回一个
TaskResult
类型,其中包含了所有的聊天记录;
和RoundRobinGroupChat
用法一样,一旦任务结束后Team仍然会保留完整的上下文以便你进行二次激活,并且可以使用 reset()
函数清空上下文。
Example: Web Search/Analysis
官网在这里给出了一个使用 SelectorGroupChat
进行Web内容搜索和数据分析的任务,整个Team的结构如下,设计了三个内部Agent:
- Planning Agent:将一个复杂任务拆解成简单任务并决策由哪个Agent执行,相当于上面提到的选择函数,只不过这个Agent用了LLM进行选择;
- Web Search Agent:网络内容搜索Agent使用
search_web_tool
工具进行搜索; - Data Analyst Agent:数据分析Agent使用
percentage_change_tool
工具进行计算;
上面提到的两个 search_web_tool
和 percentage_change_tool
定义如下:
# Note: This example uses mock tools instead of real APIs for demonstration purposes
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 pointsDwayne Wade: 1397 pointsJames 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
来定义上面三个Agent,这里官方提示在定义时最重要的是些明白Agent的 name
和 description
,因为这两个信息会变成LLM选择下一个与其对话的依据。
- 定义一个基于
gpt-4o
的模型,后面三个Agent都要用这个模型接口:
model_client = OpenAIChatCompletionClient(model="gpt-4o")
- Planning Agent 任务拆解Agent(在这里就是选择对话的Agent):
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 informationDataAnalystAgent: Performs calculationsYou 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 内容搜索Agent,调用
search_web_tool
工具进行搜索:
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 Agen 数据分析Agent,调用工具
percentage_change_tool
对内容进行分析:
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.""",
)
【Note】:如果你的工具函数返回的不是自然语言格式的字符串,可以在定义Agent的时候使用 reflect_on_tool_use=True
参数让Agent帮你将字符串整理成自然语言,本质还是调用LLM。因为Team内部广播或者沟通的基本单元仍然是一个封装好自然语言的Message。
Workflow
根据官网描述,上面定义的Team运行流程如下:
SelectorGroupChat
首先接受到一个Task任务,然后根据Agent的属性name
与descriptions
信息 自主选择 最适合的一个Agent来启动整个任务,通常情况是 Planning Agent;- Planning Agent将这个Task拆分成子任务,然后按照
<Agent>:<task>
的格式分发给对应的Agent; - 根据整个Team中的上线文环境、各个Agent的
descriptions
,SelectorGroupChat
动态选择下一个与LLM进行对话的Agent; - Web Search Agent执行一次搜索动作,并将LLM返回的结果保存在共享的记录中;
- 如果Data Analyst Agent被选中,那么就使用tools来处理数据;
- 整个Team的终止条件是如果子任务中检测到
TERMINATE
或者其他终止条件;
【注意】:在自定义Agent的时候,尽量将descriptions
写成 精炼、完备、排他,因为SelectorGroupChat
会根据Team内的所有Agent的描述进行决策下一个与LLM对话的是哪个Agent;
Termination Conditions
官方在这里定义了两个终止条件TextMentionTermination
和MaxMessageTermination
,这两个终止条件我们在前面已经用了很多次了,分别是文本关键字终止和最大组内沟通信息条数终止;
text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_termination
Selector Prompt
SelectorGroupChat
基于组内的上下文环境来选择下一个与LLM对话的Agent,因此这里我们自己写一个prompt来告诉SelectorGroupChat
选择Agent的依据是什么:
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.
"""
官网在如何设置这个prompt时给了以下几个Tips:
- 这个提示词不要写的太长,防止选择器过载;
- 如何判断自己提示词是不是过长了,这个是根据LLM模型规模决定的,如果你使用的模型是GPT-4o的话就可以写稍微长一点,但模型规模较小时就不能太长,官方提供的上面demo就是对于小模型设计的;
- 如果你对每一个Agent都写了多个条件,那么其实最适合的是使用自定义选择函数,由
SelectorGroupChat
自主选择的初衷是减少你的工作量;
Running the Team
然后将上面我们提到的Agent、终止条件、自定义选择prompt结合起来形成一个Team:
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, # Allow an agent to speak multiple turns in a row.
)
然后再定义一个传给Team的任务:
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?"
那么完整代码如下:
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Consoleimport asyncio, osos.environ["OPENAI_API_KEY"] = "你的OpenAI API Key"#-----------------------------------------------------------------------------#
# Part1. 定义两个搜索工具
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 pointsDwayne Wade: 1397 pointsJames 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#-----------------------------------------------------------------------------#
# Part2. 定义三个Agent和model
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 informationDataAnalystAgent: Performs calculationsYou 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.""",
)#-----------------------------------------------------------------------------#
# Part3. 定义Team的终止条件
text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_terminationselector_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.
"""#-----------------------------------------------------------------------------#
# Part4. 定义任务Task
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?"#-----------------------------------------------------------------------------#
# Part5. 将Agent、model、终止条件、prompt组合成一个team
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, # Allow an agent to speak multiple turns in a row.
)#-----------------------------------------------------------------------------#
# Part6. 运行team
asyncio.run(Console(team.run_stream(task=task))
)
运行结果如下,从输出内容来看除了实际执行的部分,其他都是Team内部上下文同步的过程,感兴趣的可以自己运行看看他们的同步逻辑:
$ python demo.py
Custom Selector Function
上面提到了你也可以自定义选择函数,但如果你自定义的选择函数返回的是 None
对象那么 SelectorGroupChat
仍然会使用基于LLM模型的Agent选择。
这里官方demo中自定义选择函数非常简单,当组内最新的消息不是由PlanningAgent生成时,就直接调用PlanningAgent,否则让LLM来选择,实际上就是每执行一步都让PlanningAgent重新规划一下:
def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:if messages[-1].source != planning_agent.name:return planning_agent.namereturn None
然后需要在定义Team的时候就将选择函数设置进去:
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,
)
完成代码如下:
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.messages import ChatMessage, AgentEvent
from typing import Sequenceimport asyncio, osos.environ["OPENAI_API_KEY"] = "你的OpenAI API Key"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 pointsDwayne Wade: 1397 pointsJames 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) * 100model_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 informationDataAnalystAgent: Performs calculationsYou 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_terminationselector_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.
"""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?"# 上面部分完全一致
#-----------------------------------------------------------------------------#
# Part1. 定义选择函数
def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:if messages[-1].source != planning_agent.name:return planning_agent.namereturn None# Part2. 设置team使用自己的选择函数
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,
)# Part3. 运行team
asyncio.run(Console(team.run_stream(task=task))
)
运行结果如下:
$ python demo.py
User Feedback
在之前的文章 AutoGen学习笔记系列(五)Tutorial -Human-in-the-Loop 中提到了 “人在回路” 策略,让人在Team走向的 关键节点 上让人来决策。在这里我们同样可以使用 UserProxyAgent
将人在回路策略引入 SelectorGroupChat
中:
首先定义 UserProxyAgent
和选择函数,在选择函数中使用 Agent 以实现人在回路,这里的逻辑如下:
- 首先第一次使用 PlanningAgent 激活整个Team的Task;
- PlanningAgent通过LLM得到下一个想要执行的Agent名;
- 由人来确认是否使用这个Agent,允许就输入
APPROVE
,否则会打回给LLM重新选择一个再来确认;
# 定义 UserProxyAgent
user_proxy_agent = UserProxyAgent("UserProxyAgent", description="A proxy for the user to approve or disapprove tasks.")# 定义使用 UserProxyAgent 的选择函数
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:# 必须让PlanningAgent作为第一个被调用的,否则任务无法启动return planning_agent.nameif messages[-1].source == planning_agent.name:if messages[-2].source == user_proxy_agent.name and "APPROVE" in messages[-1].content.upper(): # type: ignore# 如果检测到了人输入的 APPROVE 则确认下一个Agent是被被使用return Nonereturn user_proxy_agent.nameif messages[-1].source == user_proxy_agent.name:# 如果人输入的不是 APPROVE 则让 PlanningAgent重新选择if "APPROVE" not in messages[-1].content.upper(): # type: ignorereturn planning_agent.namereturn None
完整代码如下:
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.messages import ChatMessage, AgentEvent
from typing import Sequenceimport asyncio, osos.environ["OPENAI_API_KEY"] = "你的OpenAI API Key"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 pointsDwayne Wade: 1397 pointsJames 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) * 100model_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 informationDataAnalystAgent: Performs calculationsYou 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_terminationselector_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.
"""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?"# 上面部分完全一致
#-----------------------------------------------------------------------------#
# Part1. 定义 UserProxyAgent
user_proxy_agent = UserProxyAgent("UserProxyAgent", description="A proxy for the user to approve or disapprove tasks.")# Part2. 定义使用 UserProxyAgent 的选择函数
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.nameif messages[-1].source == planning_agent.name:if messages[-2].source == user_proxy_agent.name and "APPROVE" in messages[-1].content.upper(): # type: ignorereturn Nonereturn user_proxy_agent.nameif messages[-1].source == user_proxy_agent.name:if "APPROVE" not in messages[-1].content.upper(): # type: ignorereturn planning_agent.namereturn None# Part2. 设置team使用自己的选择函数
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,
)# Part3. 运行team
asyncio.run(Console(team.run_stream(task=task))
)
运行结果如下,可以发现每到选择Agent的时候都会等待人进行决策:
$ python demo.py
Using Reasoning Models
上面所有的demo都是基于 gpt-4o
或 Gemini
这种满血大模型,根据上面小节 Selector Prompt
提到的几个 tips 内容,对于像 o3-mini
这种小模型而言还是要尽可能写短描述选择的prompt,而是让模型自行决策,这样可以减小模型本身的压力。官方在下面的示例中使用 o3-mini
作为模型:
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.messages import ChatMessage, AgentEvent
from typing import Sequenceimport asyncio, osos.environ["OPENAI_API_KEY"] = "你的OpenAI API Key"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 pointsDwayne Wade: 1397 pointsJames 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) * 100text_mention_termination = TextMentionTermination("TERMINATE")
max_messages_termination = MaxMessageTermination(max_messages=25)
termination = text_mention_termination | max_messages_terminationtask = "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?"# 上面部分完全一致
#-----------------------------------------------------------------------------#
model_client = OpenAIChatCompletionClient(model="o3-mini")web_search_agent = AssistantAgent("WebSearchAgent",description="An agent for searching information on the web.",tools=[search_web_tool],model_client=model_client,system_message="""Use web search tool to find information.""",
)data_analyst_agent = AssistantAgent("DataAnalystAgent",description="An agent for performing calculations.",model_client=model_client,tools=[percentage_change_tool],system_message="""Use tool to perform calculation. If you have not seen the data, ask for it.""",
)user_proxy_agent = UserProxyAgent("UserProxyAgent",description="A user to approve or disapprove tasks.",
)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.
When the task is complete, let the user approve or disapprove the task.
"""team = SelectorGroupChat([web_search_agent, data_analyst_agent, user_proxy_agent],model_client=model_client,termination_condition=termination, # Use the same termination condition as before.selector_prompt=selector_prompt,allow_repeated_speaker=True,
)# Part3. 运行team
asyncio.run(Console(team.run_stream(task=task))
)
运行结果如下,如果你运行的话会发现这个过程慢了不少,而且很容易出现一个Agent不停被循环调用的情况,大小模型之间的差异还是很明显的:
$ python demo.py