Skip to main content

使用提供的工具作为函数解决任务(异步函数调用)

AutoGen提供了由LLM、工具或人类驱动的可对话代理,可以通过自动聊天来共同执行任务。这个框架通过多代理对话允许工具使用和人类参与。关于这个功能的文档可以在这里找到。

在这个笔记本中,我们演示了如何使用AssistantAgentUserProxyAgent来使用OpenAI模型的新功能进行函数调用(在模型版本0613中)。必须将指定的提示和函数配置传递给AssistantAgent来初始化代理。相应的函数必须传递给UserProxyAgent,它将执行AssistantAgent发出的任何函数调用。除了需要将描述与函数匹配之外,我们建议在AssistantAgent中检查系统消息,以确保指令与函数调用描述一致。

要求

安装pyautogen

pip install pyautogen

更多信息,请参阅安装指南

import time

from typing_extensions import Annotated

import autogen
from autogen.cache import Cache

config_list = autogen.config_list_from_json(env_or_file="OAI_CONFIG_LIST", filter_dict={"tags": ["tool"]})
tip

了解如何为代理配置LLM的更多信息,请参阅这里

进行异步和同步函数调用

在这个示例中,我们演示了使用AssistantAgentUserProxyAgent进行函数调用执行的过程。使用AssistantAgent的默认系统提示,我们允许LLM助手使用代码执行任务,而UserProxyAgent将从LLM的响应中提取代码块并执行它们。通过新的“function_call”功能,我们在AssistantAgent的OpenAI配置中定义函数并指定函数的描述。然后我们在UserProxyAgent中注册这些函数。

llm_config = {
"config_list": config_list,
}

coder = autogen.AssistantAgent(
name="chatbot",
system_message="对于编码任务,请仅使用您提供的函数。您有一个秒表和一个计时器,这些工具可以并且应该同时使用。完成任务后回复 TERMINATE。",
llm_config=llm_config,
)

# 创建一个名为 "user_proxy" 的 UserProxyAgent 实例
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
system_message="用户的代理,用于执行代码。",
is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
human_input_mode="NEVER",
max_consecutive_auto_reply=10,
code_execution_config={"work_dir": "coding"},
)

# 根据函数描述定义函数

# 使用 register_for_llm 和 register_for_execution 装饰器注册的示例异步函数
@user_proxy.register_for_execution()
@coder.register_for_llm(description="创建一个持续 N 秒的计时器")
async def timer(num_seconds: Annotated[str, "计时器的秒数"]) -> str:
for i in range(int(num_seconds)):
time.sleep(1)
# 应该打印到标准输出
return "计时器已完成!"


# 使用 register_function 注册的示例同步函数
def stopwatch(num_seconds: Annotated[str, "秒表的秒数"]) -> str:
for i in range(int(num_seconds)):
time.sleep(1)
return "秒表已完成!"


autogen.agentchat.register_function(
stopwatch,
caller=coder,
executor=user_proxy,
description="创建一个持续 N 秒的秒表",
)

开始对话。await 用于暂停和恢复代码执行,以便进行异步 IO 操作。如果没有 await,异步函数会返回一个协程对象,但不会执行该函数。使用 await,异步函数会被执行,并且当前函数会被暂停,直到等待的函数返回结果。

with Cache.disk() as cache:
await user_proxy.a_initiate_chat( # noqa: F704
coder,
message="创建一个5秒的定时器,然后创建一个5秒的秒表。",
cache=cache,
)
user_proxy (to chatbot):

创建一个5秒的定时器,然后创建一个5秒的秒表。

--------------------------------------------------------------------------------
chatbot (to user_proxy):

***** 建议的工具调用 (call_h6324df0CdGPDNjPO8GrnAQJ): timer *****
参数:
{"num_seconds":"5"}
**********************************************************************

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

>>>>>>>> 执行异步函数 timer...
user_proxy (to chatbot):

user_proxy (to chatbot):

***** 调用工具 "call_h6324df0CdGPDNjPO8GrnAQJ" 的响应 *****
定时器已完成!
**********************************************************************

--------------------------------------------------------------------------------
chatbot (to user_proxy):

***** 建议的工具调用 (call_7SzbQxI8Nsl6dPQtScoSGPAu): stopwatch *****
参数:
{"num_seconds":"5"}
**************************************************************************

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

>>>>>>>> 执行异步函数 stopwatch...
user_proxy (to chatbot):

user_proxy (to chatbot):

***** 调用工具 "call_7SzbQxI8Nsl6dPQtScoSGPAu" 的响应 *****
秒表已完成!
**********************************************************************

--------------------------------------------------------------------------------
chatbot (to user_proxy):

终止

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

异步函数调用与群聊

同步和异步可以在超过两个代理的拓扑中使用。下面,我们展示了在群聊中使用此功能的示例。

markdownagent = autogen.AssistantAgent(
name="Markdown_agent",
system_message="请只用 Markdown 进行回复",
llm_config=llm_config,
)

# 添加一个用于结束群聊的函数


@user_proxy.register_for_execution()
@markdownagent.register_for_llm()
@coder.register_for_llm(description="结束群聊")
def terminate_group_chat(message: Annotated[str, "要发送到群聊的消息"]) -> str:
return f"[GROUPCHAT_TERMINATE] {message}"


groupchat = autogen.GroupChat(agents=[user_proxy, coder, markdownagent], messages=[], max_round=12)

llm_config_manager = llm_config.copy()
llm_config_manager.pop("functions", None)
llm_config_manager.pop("tools", None)

manager = autogen.GroupChatManager(
groupchat=groupchat,
llm_config=llm_config_manager,
is_termination_msg=lambda x: "GROUPCHAT_TERMINATE" in x.get("content", ""),
)

最后,我们初始化了一个使用上述定义的函数的聊天:

message = """
1) 同时创建一个5秒的计时器和一个5秒的秒表。
2) 将结果以md格式打印出来。
3) 当1和2都完成后,终止群聊。
"""

with Cache.disk() as cache:
await user_proxy.a_initiate_chat( # noqa: F704
manager,
message=message,
cache=cache,
)
user_proxy (发送给 chat_manager):


1) 同时创建一个5秒的计时器和一个5秒的秒表。
2) 将结果以md格式打印出来。
3) 当1和2都完成后,终止群聊。


--------------------------------------------------------------------------------
chatbot (发送给 chat_manager):

***** 建议的工具调用 (call_qlS3QkcY1NkfgpKtCoR6oGo7): timer *****
参数:
{"num_seconds": "5"}
**********************************************************************
***** 建议的工具调用 (call_TEHlvMgCp0S3RzBbVsVPXWeL): stopwatch *****
参数:
{"num_seconds": "5"}
**************************************************************************

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

>>>>>>>> 执行异步函数 timer...

>>>>>>>> 执行异步函数 stopwatch...
user_proxy (发送给 chat_manager):

user_proxy (发送给 chat_manager):

***** 调用工具 "call_qlS3QkcY1NkfgpKtCoR6oGo7" 的响应 *****
计时器已完成!
**********************************************************************

--------------------------------------------------------------------------------
user_proxy (发送给 chat_manager):

***** 调用工具 "call_TEHlvMgCp0S3RzBbVsVPXWeL" 的响应 *****
秒表已完成!
**********************************************************************

--------------------------------------------------------------------------------
Markdown_agent (发送给 chat_manager):

***** 建议的工具调用 (call_JuQwvj4FigfvGyBeTMglY2ee): terminate_group_chat *****
参数:
{"message":"计时器和秒表都已完成倒计时。群聊已终止。"}
*************************************************************************************

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

>>>>>>>> 执行异步函数 terminate_group_chat...
user_proxy (发送给 chat_manager):

user_proxy (发送给 chat_manager):

***** 调用工具 "call_JuQwvj4FigfvGyBeTMglY2ee" 的响应 *****
[GROUPCHAT_TERMINATE] 计时器和秒表都已完成倒计时。群聊已终止。
**********************************************************************

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