跳到主要内容

Azure函数示例

nbviewer

这个笔记本展示了如何使用Azure OpenAI服务的函数调用功能。函数允许聊天完成的调用者定义模型可以使用的功能,以扩展其功能到外部工具和数据源。

您可以在OpenAI的博客上阅读更多关于聊天函数的内容:https://openai.com/blog/function-calling-and-other-api-updates

注意:聊天函数要求模型版本从gpt-4和gpt-35-turbo的-0613标签开始。它们不受旧版本模型的支持。

设置

首先,我们安装必要的依赖项并导入我们将使用的库。

! pip install "openai>=1.0.0,<2.0.0"
! pip install python-dotenv

import os
import openai
import dotenv

dotenv.load_dotenv()

认证

Azure OpenAI 服务支持多种认证机制,包括 API 密钥和 Azure Active Directory 令牌凭据。

use_azure_active_directory = False  # 将此标志设置为 True,如果您正在使用 Azure Active Directory。

使用API密钥进行身份验证

要设置OpenAI SDK以使用Azure API密钥,我们需要将api_key设置为与您的端点关联的密钥(您可以在Azure门户的*“资源管理”下的“密钥和端点”*中找到此密钥)。您还将在此处找到您资源的端点。

if not use_azure_active_directory:
endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
api_key = os.environ["AZURE_OPENAI_API_KEY"]

client = openai.AzureOpenAI(
azure_endpoint=endpoint,
api_key=api_key,
api_version="2023-09-01-preview"
)

使用Azure Active Directory进行身份验证

现在让我们看看如何通过Azure Active Directory进行身份验证。我们将从安装azure-identity库开始。这个库将提供我们需要进行身份验证的令牌凭据,并通过get_bearer_token_provider辅助函数帮助我们构建一个令牌凭据提供程序。建议使用get_bearer_token_provider而不是向AzureOpenAI提供静态令牌,因为这个API会自动为您缓存和刷新令牌。

有关如何设置Azure Active Directory身份验证与Azure OpenAI的更多信息,请参阅文档

! pip install "azure-identity>=1.15.0"

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

if use_azure_active_directory:
endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
api_key = os.environ["AZURE_OPENAI_API_KEY"]

client = openai.AzureOpenAI(
azure_endpoint=endpoint,
azure_ad_token_provider=get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"),
api_version="2023-09-01-preview"
)

注意:如果未提供以下参数,则AzureOpenAI将从其对应的环境变量中推断出来:

  • api_keyAZURE_OPENAI_API_KEY
  • azure_ad_tokenAZURE_OPENAI_AD_TOKEN
  • api_versionOPENAI_API_VERSION
  • azure_endpointAZURE_OPENAI_ENDPOINT

部署

在本节中,我们将创建一个GPT模型的部署,以便我们可以用来调用函数。

部署:在Azure OpenAI Studio中创建

让我们部署一个模型,用于与聊天完成一起使用。前往 https://portal.azure.com,找到您的Azure OpenAI资源,然后导航到Azure OpenAI Studio。点击“部署”选项卡,然后为您想要用于聊天完成的模型创建一个部署。您在模型中给出的部署名称将在下面的代码中使用。

deployment = "" # 在此处填写从门户获取的部署名称

函数

完成设置和身份验证后,现在可以使用Azure OpenAI服务中的函数。这将分为几个步骤:

  1. 定义函数
  2. 将函数定义传递到聊天完成API
  3. 使用响应中的参数调用函数
  4. 将函数响应反馈到聊天完成API

1. 定义函数

可以定义一个函数列表,每个函数包含函数的名称、可选描述以及函数接受的参数(描述为一个JSON模式)。

functions = [
{
"name": "get_current_weather",
"description": "Get the current weather",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"format": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The temperature unit to use. Infer this from the users location.",
},
},
"required": ["location"],
},
}
]

2. 将函数定义传递给聊天完成API

现在我们可以将函数传递给聊天完成API。如果模型确定应该调用该函数,则在选择中会填充一个”finish_reason”为”tool_calls”,并且message中将包含要调用的函数及其参数的详细信息。可选地,您可以设置tool_choice关键字参数来强制模型调用特定的函数(例如 {"type": "function", "function": {"name": get_current_weather}})。默认情况下,这被设置为auto,允许模型自行决定是否调用该函数。

messages = [
{"role": "system", "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous."},
{"role": "user", "content": "What's the weather like today in Seattle?"}
]

chat_completion = client.chat.completions.create(
model=deployment,
messages=messages,
tools=functions,
)
print(chat_completion)

3. 使用响应中的参数调用函数

函数调用的名称将是最初提供的名称,参数将包括与函数定义中包含的模式匹配的JSON数据。

import json

def get_current_weather(request):
"""
此功能仅供说明之用。
应根据位置和单位来确定天气情况,而非返回硬编码的响应。
"""
location = request.get("location")
unit = request.get("unit")
return {"temperature": "22", "unit": "celsius", "description": "Sunny"}

function_call = chat_completion.choices[0].message.tool_calls[0].function
print(function_call.name)
print(function_call.arguments)

if function_call.name == "get_current_weather":
response = get_current_weather(json.loads(function_call.arguments))

4. 将函数的响应反馈到聊天完成API中

函数的响应应该被序列化为一个角色设置为“function”的新消息。现在模型将使用响应数据来制定其答案。

messages.append(
{
"role": "function",
"name": "get_current_weather",
"content": json.dumps(response)
}
)

function_completion = client.chat.completions.create(
model=deployment,
messages=messages,
tools=functions,
)

print(function_completion.choices[0].message.content.strip())