货币计算器:使用提供工具作为函数的问题解决
AutoGen 提供了由LLM、工具或人类驱动的可对话代理,这些代理可以通过自动聊天共同执行任务。该框架允许通过多代理对话使用工具和人类参与。请参阅有关此功能的文档这里。
在本笔记本中,我们演示了如何使用 AssistantAgent
和
UserProxyAgent
来利用 OpenAI 模型的新功能(模型版本 0613)进行函数调用。必须将指定的提示和函数配置
传递给 AssistantAgent
以初始化代理。相应的函数必须传递给 UserProxyAgent
,它将
执行由 AssistantAgent
进行的任何函数调用。除了需要确保描述与函数匹配之外,我们建议
检查 AssistantAgent
中的系统消息,以确保指令与函数调用描述一致。
要求
AutoGen 需要 Python>=3.8
。要运行此笔记本示例,请安装 autogen-agentchat
:
pip install autogen-agentchat~=0.2
# %pip install "autogen-agentchat~=0.2"
设置您的API端点
config_list_from_json
函数从环境变量或 JSON 文件加载配置列表。
from typing import Literal
from pydantic import BaseModel, Field
from typing_extensions import Annotated
import autogen
from autogen.cache import Cache
config_list = autogen.config_list_from_json(
"OAI_CONFIG_LIST",
filter_dict={"tags": ["tool"]}, # comment out to get all
)
首先,它会查找环境变量“OAI_CONFIG_LIST”,该变量需要是一个有效的JSON字符串。如果未找到该变量,它会接着查找名为“OAI_CONFIG_LIST”的JSON文件。然后,它会根据标签过滤配置(你也可以通过其他键进行过滤)。只有符合过滤条件的配置会被保留在列表中。
配置列表如下所示:
config_list = [
{
'model': 'gpt-3.5-turbo',
'api_key': '<your OpenAI API key here>',
'tags': ['tool', '3.5-tool'],
},
{
'model': 'gpt-3.5-turbo',
'api_key': '<your Azure OpenAI API key here>',
'base_url': '<your Azure OpenAI API base here>',
'api_type': 'azure',
'api_version': '2024-02-01',
'tags': ['tool', '3.5-tool'],
},
{
'model': 'gpt-3.5-turbo-16k',
'api_key': '<your Azure OpenAI API key here>',
'base_url': '<your Azure OpenAI API base here>',
'api_type': 'azure',
'api_version': '2024-02-01',
'tags': ['tool', '3.5-tool'],
},
]
你可以以任何你喜欢的方式设置config_list的值。请参考此 notebook 以获取不同方法的完整代码示例。
进行函数调用
在这个例子中,我们演示了使用AssistantAgent
和UserProxyAgent
执行函数调用。通过AssistantAgent
的默认系统提示,我们允许LLM助手使用代码执行任务,而UserProxyAgent
将从LLM响应中提取代码块并执行它们。通过新的“function_call”功能,我们在OpenAI配置中为AssistantAgent
定义了函数并指定了函数的描述。然后我们在UserProxyAgent
中注册这些函数。
llm_config = {
"config_list": config_list,
"timeout": 120,
}
chatbot = autogen.AssistantAgent(
name="chatbot",
system_message="For currency exchange tasks, only use the functions you have been provided with. Reply TERMINATE when the task is done.",
llm_config=llm_config,
)
# create a UserProxyAgent instance named "user_proxy"
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
human_input_mode="NEVER",
max_consecutive_auto_reply=10,
)
CurrencySymbol = Literal["USD", "EUR"]
def exchange_rate(base_currency: CurrencySymbol, quote_currency: CurrencySymbol) -> float:
if base_currency == quote_currency:
return 1.0
elif base_currency == "USD" and quote_currency == "EUR":
return 1 / 1.1
elif base_currency == "EUR" and quote_currency == "USD":
return 1.1
else:
raise ValueError(f"Unknown currencies {base_currency}, {quote_currency}")
@user_proxy.register_for_execution()
@chatbot.register_for_llm(description="Currency exchange calculator.")
def currency_calculator(
base_amount: Annotated[float, "Amount of currency in base_currency"],
base_currency: Annotated[CurrencySymbol, "Base currency"] = "USD",
quote_currency: Annotated[CurrencySymbol, "Quote currency"] = "EUR",
) -> str:
quote_amount = exchange_rate(base_currency, quote_currency) * base_amount
return f"{quote_amount} {quote_currency}"
装饰器 @chatbot.register_for_llm()
读取函数 currency_calculator
的注释签名,并生成以下由OpenAI API用于建议调用该函数的JSON模式。我们可以通过以下方式检查生成的JSON模式:
chatbot.llm_config["tools"]
[{'type': 'function',
'function': {'description': 'Currency exchange calculator.',
'name': 'currency_calculator',
'parameters': {'type': 'object',
'properties': {'base_amount': {'type': 'number',
'description': 'Amount of currency in base_currency'},
'base_currency': {'enum': ['USD', 'EUR'],
'type': 'string',
'default': 'USD',
'description': 'Base currency'},
'quote_currency': {'enum': ['USD', 'EUR'],
'type': 'string',
'default': 'EUR',
'description': 'Quote currency'}},
'required': ['base_amount']}}}]
装饰器 @user_proxy.register_for_execution()
将OpenAI API建议的函数名称映射到实际实现。映射的函数被包装,因为我们还自动处理函数的输出序列化,如下所示:
-
字符串保持不变,并且
-
Pydantic BaseModel类型的对象被序列化为JSON。
我们可以通过使用封装函数的 ._origin
属性来检查函数映射的正确性,如下所示:
assert user_proxy.function_map["currency_calculator"]._origin == currency_calculator
最后,我们可以使用这个函数来准确计算交易金额:
with Cache.disk() as cache:
# start the conversation
res = user_proxy.initiate_chat(
chatbot, message="How much is 123.45 USD in EUR?", summary_method="reflection_with_llm", cache=cache
)
How much is 123.45 USD in EUR?
--------------------------------------------------------------------------------
***** Suggested tool call (call_9ogJS4d40BT1rXfMn7YJb151): currency_calculator *****
Arguments:
{
"base_amount": 123.45,
"base_currency": "USD",
"quote_currency": "EUR"
}
************************************************************************************
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION currency_calculator...
***** Response from calling tool (call_9ogJS4d40BT1rXfMn7YJb151) *****
112.22727272727272 EUR
**********************************************************************
--------------------------------------------------------------------------------
123.45 USD is equivalent to 112.23 EUR.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
TERMINATE
--------------------------------------------------------------------------------
print("Chat summary:", res.summary)
Chat summary: 123.45 USD is equivalent to 112.23 EUR.
Pydantic 模型
我们也可以使用Pydantic基础模型来重写该函数,如下所示:
llm_config = {
"config_list": config_list,
"timeout": 120,
}
chatbot = autogen.AssistantAgent(
name="chatbot",
system_message="For currency exchange tasks, only use the functions you have been provided with. Reply TERMINATE when the task is done.",
llm_config=llm_config,
)
# create a UserProxyAgent instance named "user_proxy"
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
human_input_mode="NEVER",
max_consecutive_auto_reply=10,
)
class Currency(BaseModel):
currency: Annotated[CurrencySymbol, Field(..., description="Currency symbol")]
amount: Annotated[float, Field(0, description="Amount of currency", ge=0)]
# another way to register a function is to use register_function instead of register_for_execution and register_for_llm decorators
def currency_calculator(
base: Annotated[Currency, "Base currency: amount and currency symbol"],
quote_currency: Annotated[CurrencySymbol, "Quote currency symbol"] = "USD",
) -> Currency:
quote_amount = exchange_rate(base.currency, quote_currency) * base.amount
return Currency(amount=quote_amount, currency=quote_currency)
autogen.agentchat.register_function(
currency_calculator,
caller=chatbot,
executor=user_proxy,
description="Currency exchange calculator.",
)
chatbot.llm_config["tools"]
[{'type': 'function',
'function': {'description': 'Currency exchange calculator.',
'name': 'currency_calculator',
'parameters': {'type': 'object',
'properties': {'base': {'properties': {'currency': {'description': 'Currency symbol',
'enum': ['USD', 'EUR'],
'title': 'Currency',
'type': 'string'},
'amount': {'default': 0,
'description': 'Amount of currency',
'minimum': 0.0,
'title': 'Amount',
'type': 'number'}},
'required': ['currency'],
'title': 'Currency',
'type': 'object',
'description': 'Base currency: amount and currency symbol'},
'quote_currency': {'enum': ['USD', 'EUR'],
'type': 'string',
'default': 'USD',
'description': 'Quote currency symbol'}},
'required': ['base']}}}]
with Cache.disk() as cache:
# start the conversation
res = user_proxy.initiate_chat(
chatbot, message="How much is 112.23 Euros in US Dollars?", summary_method="reflection_with_llm", cache=cache
)
How much is 112.23 Euros in US Dollars?
--------------------------------------------------------------------------------
***** Suggested tool call (call_BQkSmdFHsrKvmtDWCk0mY5sF): currency_calculator *****
Arguments:
{
"base": {
"currency": "EUR",
"amount": 112.23
},
"quote_currency": "USD"
}
************************************************************************************
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION currency_calculator...
***** Response from calling tool (call_BQkSmdFHsrKvmtDWCk0mY5sF) *****
{"currency":"USD","amount":123.45300000000002}
**********************************************************************
--------------------------------------------------------------------------------
112.23 Euros is equivalent to 123.45 US Dollars.
TERMINATE
--------------------------------------------------------------------------------
print("Chat summary:", res.summary)
Chat summary: 112.23 Euros is equivalent to 123.45 US Dollars.
with Cache.disk() as cache:
# start the conversation
res = user_proxy.initiate_chat(
chatbot,
message="How much is 123.45 US Dollars in Euros?",
cache=cache,
)
How much is 123.45 US Dollars in Euros?
--------------------------------------------------------------------------------
***** Suggested tool call (call_Xxol42xTswZHGX60OjvIQRG1): currency_calculator *****
Arguments:
{
"base": {
"currency": "USD",
"amount": 123.45
},
"quote_currency": "EUR"
}
************************************************************************************
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION currency_calculator...
***** Response from calling tool (call_Xxol42xTswZHGX60OjvIQRG1) *****
{"currency":"EUR","amount":112.22727272727272}
**********************************************************************
--------------------------------------------------------------------------------
123.45 US Dollars is equivalent to 112.23 Euros.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
TERMINATE
--------------------------------------------------------------------------------
print("Chat history:", res.chat_history)
Chat history: [{'content': 'How much is 123.45 US Dollars in Euros?', 'role': 'assistant'}, {'tool_calls': [{'id': 'call_Xxol42xTswZHGX60OjvIQRG1', 'function': {'arguments': '{\n "base": {\n "currency": "USD",\n "amount": 123.45\n },\n "quote_currency": "EUR"\n}', 'name': 'currency_calculator'}, 'type': 'function'}], 'content': None, 'role': 'assistant'}, {'content': '{"currency":"EUR","amount":112.22727272727272}', 'tool_responses': [{'tool_call_id': 'call_Xxol42xTswZHGX60OjvIQRG1', 'role': 'tool', 'content': '{"currency":"EUR","amount":112.22727272727272}'}], 'role': 'tool'}, {'content': '123.45 US Dollars is equivalent to 112.23 Euros.', 'role': 'user'}, {'content': '', 'role': 'assistant'}, {'content': 'TERMINATE', 'role': 'user'}]