Skip to main content

允许人类对代理进行反馈

在 Colab 中打开 在 GitHub 上打开

在前两章中,我们介绍了 ConversableAgent 类,并展示了如何使用它创建可以完成任务的自主(human_input_mode=NEVER)代理。我们还展示了如何正确终止代理之间的对话。

但是,许多应用程序可能需要将人类与代理放在一个循环中。例如,允许人类反馈来引导代理朝正确的方向发展、指定目标等。在本章中,我们将展示 AutoGen 如何支持人类干预。

在 AutoGen 的 ConversableAgent 中,人类循环组件位于自动回复组件之前。它可以拦截传入的消息,并决定是将其传递给自动回复组件还是提供人类反馈。下图展示了该设计。

人类循环

人类循环组件可以通过 human_input_mode 参数进行自定义。我们将在下面的章节中向您展示如何使用它。

人类输入模式

目前,AutoGen 支持三种人类输入模式。模式是通过 ConversableAgenthuman_input_mode 参数指定的。这三种模式分别是:

  1. NEVER:从不请求人类输入。
  2. TERMINATE(默认):仅在满足终止条件时请求人类输入。请注意,在此模式下,如果人类选择拦截并回复,对话将继续进行,并且 max_consecutive_auto_reply 使用的计数器将被重置。
  3. ALWAYS:始终请求人类输入,人类可以选择跳过并触发自动回复,拦截并提供反馈,或终止对话。请注意,在此模式下,基于 max_consecutive_auto_reply 的终止将被忽略。

前面的章节已经展示了许多 human_input_modeNEVER 的情况的示例。下面我们再次展示一个这种情况的示例,并展示当将此模式设置为 ALWAYSNEVER 时的区别。

人类输入模式 = NEVER

在此模式下,从不请求人类输入,并使用终止条件来终止对话。当您希望代理完全自主地行动时,此模式非常有用。

以下是使用此模式运行简单的猜数字游戏的示例,其中两个代理参与,终止消息设置为检查是否猜对了数字。

import os

from autogen import ConversableAgent

# 创建一个名为 agent_with_number 的 ConversableAgent 对象
agent_with_number = ConversableAgent(
"agent_with_number",
system_message="你正在玩一个猜数字的游戏。你心里想的数字是53,我会尝试猜出来。如果我猜得太高,请说'太高';如果我猜得太低,请说'太低'。",
llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
is_termination_msg=lambda msg: "53" in msg["content"], # 如果对方猜中了数字,终止对话
human_input_mode="NEVER", # 不需要人类输入
)

# 创建一个名为 agent_guess_number 的 ConversableAgent 对象
agent_guess_number = ConversableAgent(
"agent_guess_number",
system_message="我心里有一个数字,你要猜出来。如果我说'太高',你应该猜一个更小的数字。如果我说'太低',你应该猜一个更大的数字。",
llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
human_input_mode="NEVER",
)

# agent_with_number 发起对话,并将 agent_guess_number 作为对话对象
result = agent_with_number.initiate_chat(
agent_guess_number,
message="我心里有一个1到100之间的数字。猜猜看吧!",
)
agent_with_number (对 agent_guess_number 说):

我心里有一个数字,范围在1到100之间。猜一下吧!

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是50吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number 说):

太低了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是75吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number 说):

太高了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是63吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number 说):

太高了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是57吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number 说):

太高了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是54吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number 说):

太高了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是52吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number 说):

太低了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number 说):

是53吗?

--------------------------------------------------------------------------------

太棒了!游戏结束了。猜测的代理使用了二分查找,非常高效!你可以看到,在猜测的代理说出正确的数字后,对话被终止了,这触发了基于消息的终止条件。

人类输入模式 = ALWAYS

在这种模式下,总是要求人类输入,人类可以选择跳过、拦截或终止对话。让我们通过与之前的代理一起玩同样的游戏,以人类的身份参与游戏,我们将成为猜测数字的代理,并与之前的代理进行对战。

human_proxy = ConversableAgent(
"human_proxy",
llm_config=False, # 人类代理不使用LLM
human_input_mode="ALWAYS", # 总是要求人类输入
)

# 与之前的代理开始对话,初始猜测为10。
result = human_proxy.initiate_chat(
agent_with_number, # 这是之前的代理,拥有一个数字
message="10",
)
human_proxy (to agent_with_number):

10

--------------------------------------------------------------------------------
agent_with_number (to human_proxy):

太小了。

--------------------------------------------------------------------------------
human_proxy (to agent_with_number):

79

--------------------------------------------------------------------------------
agent_with_number (to human_proxy):

太大了。

--------------------------------------------------------------------------------
human_proxy (to agent_with_number):

76

--------------------------------------------------------------------------------
agent_with_number (to human_proxy):

太大了。

--------------------------------------------------------------------------------
human_proxy (to agent_with_number):

我放弃了。

--------------------------------------------------------------------------------
agent_with_number (to human_proxy):

没关系!我想的数字是53。

--------------------------------------------------------------------------------

如果你运行上面的代码,每次轮到你说话时都会提示你输入回答。你可以看到,人类在猜测数字方面并不是很好...但是嘿,代理最终还是很好心地给出了数字。

人类输入模式 = TERMINATE

在这种模式下,只有在满足终止条件时才会要求人类输入。如果人类选择拦截并回复,计数器将被重置;如果人类选择跳过,将使用自动回复机制;如果人类选择终止,对话将被终止。

让我们再次玩同样的游戏,但这次猜测的代理只有两次机会猜测数字,如果失败,将要求人类提供反馈,并且对话将被终止。 猜数字的代理获得了两次猜测的机会。如果最终猜对了数字,对话将终止。

agent_with_number = ConversableAgent(
"agent_with_number",
system_message="你正在玩一个猜数字的游戏。在第一局中,你心里想的数字是53,我会试着猜出来。如果我猜得太高,请说'太高',如果我猜得太低,请说'太低'。",
llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
max_consecutive_auto_reply=1, # 在要求人类输入之前,连续自动回复的最大次数
is_termination_msg=lambda msg: "53" in msg["content"], # 如果其他代理猜对了数字,终止对话
human_input_mode="TERMINATE", # 直到游戏终止前一直要求人类输入
)

agent_guess_number = ConversableAgent(
"agent_guess_number",
system_message="我心里有一个数字,你要试着猜出来。如果我说'太高',你应该猜一个更小的数字。如果我说'太低',你应该猜一个更大的数字。",
llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
human_input_mode="NEVER",
)

result = agent_with_number.initiate_chat(
agent_guess_number,
message="我心里有一个1到100之间的数字。猜猜看吧!",
)
agent_with_number (对 agent_guess_number):

我有一个介于1和100之间的数字。猜猜看吧!

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是50吗?

--------------------------------------------------------------------------------

>>>>>>>> 使用自动回复...
agent_with_number (对 agent_guess_number):

太低了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是75吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number):

太高了,朋友。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是60吗?

--------------------------------------------------------------------------------

>>>>>>>> 使用自动回复...
agent_with_number (对 agent_guess_number):

太高了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是55吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number):

还是太高了,但你很接近了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是52吗?

--------------------------------------------------------------------------------

>>>>>>>> 使用自动回复...
agent_with_number (对 agent_guess_number):

太低了。

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是54吗?

--------------------------------------------------------------------------------
agent_with_number (对 agent_guess_number):

快了!

--------------------------------------------------------------------------------
agent_guess_number (对 agent_with_number):

是53吗?

--------------------------------------------------------------------------------

在之前的对话中,

  1. 当代理猜测“74”时,人类说:“太高了,我的朋友。”
  2. 当代理猜测“55”时,人类说:“还是太高了,但你很接近了。”
  3. 当代理猜测“54”时,人类说:“快了!”

每次代理给出一个数字后,都会要求人类提供反馈。一旦人类提供了反馈,计数器就会重置。在代理正确猜到“53”后,对话终止。

总结

在本章中,我们向您展示了如何使用人机协作组件向代理提供人类反馈并终止对话。我们还向您展示了不同的人类输入模式以及它们对人机协作组件行为的影响。

下一章将介绍代码执行器——仅次于LLM的最强大组件。