Azure 函数示例

本笔记本展示了如何将函数调用功能与 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  # 如果您正在使用 Azure Active Directory,请将此标志设置为 True

使用 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_key 来自 AZURE_OPENAI_API_KEY
  • azure_ad_token 来自 AZURE_OPENAI_AD_TOKEN
  • api_version 来自 OPENAI_API_VERSION
  • azure_endpoint 来自 AZURE_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 schema)。

functions = [
    {
        "name": "get_current_weather",
        "description": "获取当前天气",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "城市和州,例如旧金山, CA",
                },
                "format": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "要使用的温度单位。请根据用户的地点推断此信息。",
                },
            },
            "required": ["location"],
        },
    }
]

2. 将函数定义传递到聊天补全 API

现在我们可以将函数传递到聊天补全 API。如果模型确定应调用该函数,则选择项上的 finish_reason 将填充为“tool_calls”,并且有关调用哪个函数及其参数的详细信息将出现在 message 中。可以选择将 tool_choice 关键字参数设置为强制模型调用特定函数(例如 {"type": "function", "function": {"name": get_current_weather}})。默认情况下,此设置为 auto,允许模型自行选择是否调用该函数。

messages = [
    {"role": "system", "content": "不要假设要将哪些值填入函数。如果用户请求不明确,请寻求澄清。"},
    {"role": "user", "content": "今天西雅图的天气怎么样?"}
]

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": "晴朗"}

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())