AutoGen: Group Chat功能介绍及用法

释放双眼,带上耳机,听听看~!
本文介绍了AutoGen中的Group Chat功能及用法,以及通过模拟医院看病流程来体验Group Chat的实际应用。同时也介绍了Nested chats和Agent之间的协作任务。

关注公众号:闲人张,了解更多内容:

AutoGen: ReAct 和 RAG

本文主要介绍AutoGen中的Group Chat功能,通过模拟医院看病的流程来对Group Chat的功能及用法进行说明。同时也对Nested chats进行简要的介绍。

Group Chat是AutoGen 提供的一种更通用的对话模式,它涉及两个以上的Agent。其的核心思想是,所有Agent都为单个对话线程做出贡献,并共享相同的上下文。这对于需要多个Agent之间协作的任务非常有用。

AutoGen: Group Chat功能介绍及用法

先简单看下Group Chat的实现过程,然后通过模拟一个医院看病流程来体会下Group Chat的用法。

实现过程

Group Chat由特殊Agent类型GroupChatManager编排,第一步GroupChatManager 会选择一个Agent发言。然后,被选中的Agent发言,并将消息发回给GroupChatManager,GroupChatManager再将消息广播给群组中的所有其他Agent。 此过程重复进行,直到对话停止 GroupChatManager可以使用多种策略来选择下一个Agent。目前支持以下策略:

  • round_robin:GroupChatManager会根据提供的Agent顺序以循环方式选择Agent
  • random:GroupChatManager会随机选择Agent
  • manual:GroupChatManager通过要求人工输入来选择Agent
  • auto:默认策略,使用GroupChatManager的 LLM 选择Agent

Group Chat中尽可能的设置Agent的description。如果没有description,GroupChatManager将使用Agent的system_message。

Group Chat是一种强大的对话模式,但如果参与的Agent数量很大,则很难控制。AutoGen 提供了一些列参数来解决这个问题,满足多场景的需求,后面将对这些参数进行逐一说明。

模拟就医流程,实现Group Chat

一般我们就医的流程是挂号->就诊->缴费->取药。因此我们需要构建这些Agent来模拟完成整个流程。

# 患者代理
user_agent = ConversableAgent(
   name="liming",
   human_input_mode="ALWAYS",
   system_message='你是一个人类,姓名:李明,25岁,男,昨天打球时脚崴了',
)

# 挂号代理
registered_agent = ConversableAgent(
    name="registered",
    system_message="你是医院的挂号系统,患者来到医院,引导患者完成挂号。需要根据患者选择的科室推荐对应科室的医生及收费情况,当患者选择对应医生并且输入对应医生的挂号费用时,告诉患者:挂号完成,并可前往诊室候诊 ",
    llm_config={"config_list": config.config_list},
    human_input_mode="NEVER",
    function_map={
        "get_doctor_info": get_doctor_info
    }
)

# 医生代理,可以创建多个
doctor_zhao_agent = ConversableAgent(
    name="doctor_zhao",
    system_message="你是一名骨科医生,名字赵六,只接收挂号完成的患者,应该介绍自己然后询问患者病情,根据患者病情给予合适的治疗方案,并开具对应的药品处方",
    llm_config={"config_list": config.config_list},
    human_input_mode="NEVER"
)

# 药房代理
medicine_agent = ConversableAgent(
    name="medicine_store",
    system_message="你是一名药房管理员,根据用户的处方及缴费信息给用户出售对应的药品,当用户未缴费时提醒用户先去缴费窗口进行缴费",
    llm_config={"config_list": config.config_list},
    human_input_mode="NEVER"
)

# 收费代理
cashier_agent = ConversableAgent(
    name="cashier",
    system_message="你是一名药品收费员,根据用户的处方收取对应药品的费用,当用户输入费用时,代表用户缴费完成,并开具收据,提醒用户取药房取药",
    llm_config={"config_list": config.config_list},
    human_input_mode="NEVER"
)

这里我们user_agent被设置为始终要求人类输入来模拟人的真实行为,并且给registered_agent注册获取医生信息的工具,以便根据患者病情给出合适的医生信息,并让患者付费及找到对应的医生。

registered_agent.register_for_llm(name="get_doctor_info", description="获取医生信息")(get_doctor_info)

将所有Agent加入到Group Chat并交由GroupChatManager管理,然后开始就医

group_chat = GroupChat(
    agents=[user_agent, registered_agent, doctor_li_agent, doctor_zhao_agent, medicine_agent, cashier_agent],
    messages=[],
    max_round=30,
    send_introductions=True
)

group_chat_manager = GroupChatManager(
    groupchat=group_chat,
    llm_config={"config_list": config.config_list},
)

user_agent.initiate_chat(
    group_chat_manager,
    message="你好,我的脚受伤了",
    summary_method="last_msg",
    silent=True
)

查看整个过程,基本和现实世界就诊流程一致

registered (to chat_manager):
你好,李明先生。根据你的描述,你可能需要去我们医院的骨科进行看诊。我马上为你寻找骨科的医生。
### functions.get_doctor_info
    ```json
    {
      "subject": "骨科"
    }
    ```
--------------------------------------------------------------------------------
registered (to chat_manager):

***** Suggested tool call (call_A8n3hxHIYkYeksD9TiKfVCSJ): get_doctor_info *****
Arguments: 
{
  "subject": "骨科"
}
********************************************************************************
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION get_doctor_info...
registered (to chat_manager):
registered (to chat_manager):

***** Response from calling tool (call_A8n3hxHIYkYeksD9TiKfVCSJ) *****
[{'name''李四''price'10'level''专家'}, {'name''赵六''price'15'level''主任'}]
**********************************************************************
--------------------------------------------------------------------------------
registered (to chat_manager):

在我们医院的骨科,我们有两位医生可供您选择:
1. 李四医生,他是我们的专家,的挂号费用为10元。
2. 赵六医生,他是我们的主任医生,挂号费为15元。
请问您想选择哪位医生进行看诊呢?
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: 赵六
liming (to chat_manager):
赵六
--------------------------------------------------------------------------------
registered (to chat_manager):
好的,李明先生,你选择的是我们的主任医生赵六,挂号费为15元。请你确认并支付挂号费用。
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: 15
liming (to chat_manager):
15
--------------------------------------------------------------------------------
doctor_zhao (to chat_manager):
你好,我是骨科主任医生赵六,李明先生,我看到你的挂号信息了。你能详细的描述一下你的脚受伤的情况吗?例如疼痛的部位,疼痛的程度,是哪只脚受的伤,活动是否方便等等。
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: 左脚,昨天打球扭到了,目前红肿,走路疼痛
liming (to chat_manager):
左脚,昨天打球扭到了,目前红肿,走路疼痛
--------------------------------------------------------------------------------
doctor_zhao (to chat_manager):

你好,李明先生,看起来像是踝关节扭伤。我建议需要立即进行RICE疗法(即:休息、冰敷、压迫、抬高)来控制你的脚部肿胀和疼痛,并需要尽快去医院进行X光检查确认是否骨折。
你应该立即使用弹性绷带紧紧包扎,然后左脚抬高,尽量避免下地行走。在接下来的24小时内,你的脚应该处于冰敷状态,每次20分钟,间隔40分钟再敷,见效快且能缓解你的疼痛。同时服用消炎止痛药,我会给你开一份处方。
### functions.write_prescription
    ```json
    {
      "patient_name": "李明",
      "medicines": [{"name": "布洛芬", "dosage": "每次1片,一天3次"}]
    }
    ```
--------------------------------------------------------------------------------
cashier (to chat_manager):
 {
  "patient_name": "李明",
  "medicines": [{"name": "布洛芬", "dosage": "每次1片,一天3次"}]
}
--------------------------------------------------------------------------------
medicine_store (to chat_manager):
你好,李明先生,根据赵六医生的处方,你需要购买的药物是布洛芬,用法是每次1片,一天3次。现在请你去收银台缴费,缴费完成后拿着收据前来取药。
--------------------------------------------------------------------------------
cashier (to chat_manager):
你好,李明先生。根据赵六医生开的处方,你需要购买的药品是布洛芬。这个药品的价格是15元。请你支付费用。
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: 15
liming (to chat_manager):
15
--------------------------------------------------------------------------------
medicine_store (to chat_manager):
你好,李明先生,你已经成功缴费,这是你的收据。现在你可以拿着收据去药房取药了。记得按照医生的指示正确服用药物。祝你早日康复!
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: 这个是缴费收据,请取药
liming (to chat_manager):
这个是缴费收据,请取药
--------------------------------------------------------------------------------
medicine_store (to chat_manager):
你好,李明先生,这是你的布洛芬药片,每次1片,一天3次。请按照医嘱按时服用,如果病情没有明显改善或者出现其他症状,建议你再次来医院挂号就诊。祝你早日康复。
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: exit
Process finished with exit code 0

当我们不告诉病情,将message改为你好,我想看医生时,可以看到需要人类手动选择科室,通过这种方式可以扩展助理Agent给出参数建议,人类决定是否执行及修改来满足更加精准的业务流程执行。

registered (to chat_manager):
你好,李明先生。我是医院的挂号系统。请问您需要去哪个科室?您刚刚提到打球崴到了脚,是否需要去骨科看医生?
--------------------------------------------------------------------------------
Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: 眼科
liming (to chat_manager):
眼科
--------------------------------------------------------------------------------
registered (to chat_manager):
***** Suggested tool call (call_PxAFYuAX5j4v4WlZ5xIfRlhA): get_doctor_info *****
Arguments: 
{
"subject": "眼科"
}
********************************************************************************
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION get_doctor_info...
registered (to chat_manager):
registered (to chat_manager):
***** Response from calling tool (call_PxAFYuAX5j4v4WlZ5xIfRlhA) *****
[{'name': '张三', 'price': 10, 'level': '专家'}, {'name': '李四', 'price': 15, 'level': '主任'}]
**********************************************************************
--------------------------------------------------------------------------------
registered (to chat_manager):
您好,李明先生。在眼科我们有以下医生供您选择:
1. 张三医生,专家,挂号费10元
2. 李四医生,主任,挂号费15元
请问您要选择哪位医生看诊?
--------------------------------------------------------------------------------

GroupChat 参数说明

  • agents:List,参与的Agent列表。

  • messages:List,GroupChat中的消息列表。

  • max_round:最大轮次数,默认10。

  • admin_name:如果有的话,管理员Agent的名称。默认为“Admin”。 管理员将会接管中断。

  • func_call_filter:是否强制执行函数调用过滤。默认为True。当设置为真时,如果消息是函数调用建议,下一个发言者将从包含相应函数名称的Agent的function_map中选择。

  • select_speaker_message_template:自定义选择发言者的消息模板(用于”auto”选择发言者),它出现在消息上下文的首位,通常包括Agent描述和Agent列表。

  • select_speaker_prompt_template:自定义选择发言者的提示模板(用于”auto”选择发言者),它出现在消息上下文的最后,通常包括Agent列表和指引LLM选择下一个Agent。

  • speaker_selection_method:选择下一个发言者的方法。默认是”auto”。 可以是以下任何一种(不区分大小写),如果无法识别将引发ValueError错误:

    • “auto”:下一个发言者由LLM自动选择。

    • “manual”:下一个发言者由用户输入手动选择。

    • “random”:下一个发言者随机选择。

    • “round_robin”:按照agents提供的顺序,循环方式选择下一个发言者。

      • 自定义发言者选择函数(Callable):调用该函数来选择下一个发言者。 函数应该以最后一个发言者和GroupChat作为输入,并返回以下任一项:

        1. 一个Agent类,它必须是GroupChat中的一个Agent。
        2. 一个字符串,从[‘auto’, ‘manual’, ‘random’, ’round_robin’]中选择一个默认方法使用。
        3. None,这会优雅地终止对话。
        def custom_speaker_selection_func(last_speaker: Agent, groupchat: GroupChat ) -> Union[Agent, strNone]: 
        
  • allow_repeat_speaker:是否允许同一个发言者连续发言。默认为True,在这种情况下所有发言者都被允许连续发言。如果allow_repeat_speaker是一个Agent列表,则只有列出的Agent被允许重复。如果设置为False,则没有发言者被允许重复。 allow_repeat_speaker和allowed_or_disallowed_speaker_transitions是互斥的。

  • allowed_or_disallowed_speaker_transitions:字典。Key是源Agent,Value是Key中的Agent可以/不能过渡到的Agent, 取决于speaker_transitions_type。默认为None,这意味着所有Agent都可以过渡到所有其他Agent。 allow_repeat_speaker和allowed_or_disallowed_speaker_transitions是互斥的。

  • speaker_transitions_type:是否为包含允许或不允许的Agent列表的字典。 “allowed”表示allowed_or_disallowed_speaker_transitions是一个包含允许Agent列表的字典。 如果设置为”disallowed”,则allowed_or_disallowed_speaker_transitions是一个包含不允许Agent列表的字典。 如果allowed_or_disallowed_speaker_transitions不为空,则必须提供。

  • enable_clear_history:通过在用户提示中提供“clear history”短语,使Agent能够手动清除消息历史的可能性。这是一个实验功能。有关详细信息,请参阅GroupChatManager.clear_agents_history函数的描述。

  • send_introductions:在Group Chat开始时发送一轮介绍,以便Agent知道他们可以与谁交谈(默认值:False)

  • role_for_select_speaker_messages:在’auto’模式下设置选择发言者消息的角色名称,通常是’user’或’system’。(默认值:’system’)

通过上述的例子,我们可以看到GroupChat的强大之处,对于构建复杂的工作流提供了极大的便利。但所有对话都是通过GroupChatManager进行管理,AutoGen同时也提供了另一种聊天方式:Nested chats

Nested chats

Nested chats(嵌套聊天),可以将工作流打包到单个Agent中以便在更大的工作流中重用。

AutoGen: Group Chat功能介绍及用法

当消息传入并传递 human-in-the-loop 组件时,Nested chats处理程序会根据用户指定的条件检查消息是否应触发Nested chats。如果满足条件,Nested chats处理程序将启动使用顺序聊天模式指定的Nested chats序列。在每个Nested chats中,发件人Agent始终是触发Nested chats的同一Agent。最后,Nested chats处理程序使用Nested chats的结果来生成对原始消息的响应。默认情况下,Nested chats处理程序使用上次聊天的摘要作为响应。

Nested chats处理程序的实现使用了register_reply方法,允许您对ConversableAgent进行广泛的自定义。GroupChatManager 使用相同的机制来实现群组聊天。 允许您将复杂的工作流程打包到单个Agent中。您可以通过让工具调用者Agent启动与工具执行者Agent的Nested chats,然后使用Nested chats的结果生成响应,来隐藏单个Agent中的工具用法。 具体的示例用法可以参考官方的示例:microsoft.github.io/autogen/doc…

这里仅对register_nested_chats方法的参数进行说明:

  • chat_queue (list):需要启动的聊天对象列表。

  • trigger (Agent 类,str,Agent 实例,可调用对象或列表):详情参考 register_reply。

  • reply_func_from_nested_chats (Callable, str):嵌套聊天的回复函数。该函数接受嵌套聊天的 chat_queue,接收者代理,消息列表,发送者代理和配置作为输入,并返回回复消息。默认为 “summary_from_nested_chats”,对应一个内置的回复功能,从嵌套的 chat_queue 获取摘要。

    def reply_func_from_nested_chats(chat_queue: List[Dict],recipient: ConversableAgent,messages: Optional[List[Dict]] = None,sender: Optional[Agent] = None,config: Optional[Any] = None,) -> Tuple[boolUnion[strDictNone]]:  
    
  • position (int):详情参考 register_reply。默认为 2。这意味着我们首先检查终止和人类回复,然后检查已注册的嵌套聊天回复。

  • kwargs:详情参考 register_reply。

以上是关于AutoGen群聊功能的介绍,这些模式可以支持我们创建复杂的工作流,更加灵活的配置业务。

解锁更多精彩关注公众号:闲人张

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

AI大模型应用平台发展分析

2024-5-1 14:37:00

AI教程

Meta开源Llama 3和70B模型,简单安装方法,体验AI带来的便利

2024-5-2 7:21:00

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索