首页 > 其他分享 >OpenAI函数调用:使用Assistants API函数工具的一个示例

OpenAI函数调用:使用Assistants API函数工具的一个示例

时间:2024-06-14 22:57:55浏览次数:19  
标签:function Function run 示例 AI 函数调用 API OpenAI email

Are you looking to expand GPT's capabilities? Check out this tutorial for a complete example of an AI Assistant that can send emails whenever we ask it to.

您是否希望扩展GPT的功能?查看这个教程,它提供了一个完整的示例,展示了一个AI助手如何在我们要求时发送电子邮件。

New updates on 17th of April 2024 from OpenAI

2024年4月17日来自OpenAI的最新更新

OpenAI announced significant updates to the Assistants API. The update includes enhancements aimed at improving the capabilities and performance of the assistants.

OpenAI宣布对Assistants API进行了重大更新。此次更新包括旨在提高助手功能和性能的增强措施。

  • Knowledge retrieval now supports up to 10,000 files.知识检索现在支持多达10,000个文件。
  • More control over token and model configuration.   对令牌和模型配置拥有更多的控制权
  • Streaming support.   流支持

Introduction        引言

If you've been playing around or building something using the OpenAI API you've probably run into the Function Calling feature. We're going to build an example app that implements the Assistants API and makes use of the Function Calling tool to send an email.

如果你一直在使用OpenAI API进行开发或构建一些东西,你可能已经遇到了函数调用功能。我们将构建一个示例应用程序,它实现Assistants API并使用函数调用工具来发送电子邮件。

The Function Calling functionality in AI Assistants is usually referred to only as Functions.

AI助手中的函数调用功能通常仅称为函数(Functions)。

OpenAI AI Assistants Tools        OpenAI AI助手工具

The Assistants API uses tools to perform actions. The following OpenAI built-in tools are currently available:

Assistants API使用工具来执行操作。目前可用的OpenAI内置工具有:

  • Function Calling (aka Functions)        函数调用(也被称为函数)
  • Code Interpreter   代码解释器
  • Knowledge Retrieval (Retrieval)   知识检索(检索)

Assistants API is still in beta. The OpenAI team mentioned that there will be new tools coming soon.

Assistants API 目前仍处于测试阶段(beta)。OpenAI 团队提到很快会有新的工具推出。

We'll look at the Code Interpreter and Knowledge Retrieval tools in a future post. For this one, we'll build an AI Assistant that uses the Functions tool to call a custom function in our code.

我们将在未来的文章中探讨代码解释器和知识检索工具。对于这篇文章,我们将构建一个 AI 助手,该助手使用 Functions 工具来调用我们代码中的自定义函数。

What is Function Calling?        什么是函数调用

New OpenAI models gpt-3.5-turbo-1106 and gpt-4-1106-preview can detect when a function should be called. This means that the models will invoke a function that you specify and will pass the necessary parameters in JSON format which match the function's signature.

新的 OpenAI 模型 gpt-3.5-turbo-1106 和 gpt-4-1106-preview 能够检测何时应该调用一个函数。这意味着这些模型将调用您指定的函数,并以与函数签名匹配的 JSON 格式传递必要的参数。

This means that you could extend the model's capabilities such as calling a send_email function.

这意味着您可以扩展模型的能力,比如调用一个 send_email 函数。

Why use Functions?        为什么要使用函数(Functions)?

Suppose you're having a conversation with the chatbot and you ask it to do something beyond its native capabilities such as sending an email or querying your SQL database.

假设你正在与聊天机器人进行对话,并请求它执行一些超出其原生功能的事情,比如发送电子邮件或查询你的SQL数据库。

How would you do this? Well, within your application code, you will let your model know that for specific user requests it could request the calling of a function to perform a custom action.

你该如何实现这一点呢?在你的应用程序代码中,你会让你的模型知道,对于特定的用户请求,它可以请求调用一个函数来执行自定义操作。

How to use Function Calling        如何使用函数调用

Let's assume that we're creating an AI assistant that generates random funny quotes. Occasionally, the user may ask the assistant to send the quote by email.

假设我们正在创建一个AI助手,该助手可以生成随机的有趣引语。偶尔,用户可能会要求助手通过电子邮件发送这些引语。

Generating funny quotes is already within GPT's native capabilities but sending emails is not. Let's see how we can make the model call a function that sends an email to our user.

生成有趣的引语已经是GPT的原生能力之一,但发送电子邮件则不是。让我们看看如何使模型调用一个函数,以便向我们的用户发送电子邮件。

Creating the AI Assistant using the API      使用API创建AI助手

The Assistants API is a new feature that was introduced by Sam Altman during the DevDay keynote on Nov. 6, 2023. It allows us to create AI Assistants for our applications.

Assistants API 是一项新功能,由 Sam Altman 在 2023 年 11 月 6 日的 DevDay 主题演讲中介绍。它允许我们为我们的应用程序创建 AI 助手。

To add this function, we'll need to go through the steps below:

要添加这个功能,我们需要按照以下步骤操作:

  1. Prepare environment        准备环境
  2. Create our AI Assistant using the Assistants API  使用 Assistants API 创建我们的 AI 助手
  3. Include the custom Function as one of the Tools 将自定义函数作为工具之一包含在内
  4. Prompt the model by asking it to send the quote in an email  通过请求模型将引语通过电子邮件发送来提示模型
  5. Check whether the model wants to use the custom Function from its toolset  检查模型是否想从其工具集中使用自定义函数
  6. Call the Function within our code  在我们的代码中调用该函数
  7. Let the model know that we executed the custom Function  让模型知道我们已经执行了自定义函数
  8. Get the final response back from the model  从模型中获取最终响应

Step 1: Prepare environment        第一步 准备环境

First things first, we'll need to create our new directory, a virtual environment, and install the OpenAI Python SDK.

首先,我们需要创建新的目录,虚拟环境,并安装 OpenAI Python SDK。

Grab your OpenAI API Key        获取你的 OpenAI API 密钥

Head over to your OpenAI account and create a new API key that you'll be using for this application.

前往你的 OpenAI 账户并创建一个新的 API 密钥,这个密钥将用于这个应用程序。

It's generally good practice to create a new API key for each application that you use.

通常,为每个你使用的应用程序创建一个新的 API 密钥是一个好习惯。

Set up Python application        设置 Python 应用程序

Let's create our new directory. I am going to call it openai-function-calling:

让我们创建新的目录。我将它命名为 openai-function-calling

mkdir openai-function-calling

Let's cd into the new directory and create our main.py file:

让我们进入新目录并创建我们的 main.py 文件:

cd openai-function-calling
touch main.py

Now, we'll create and activate our virtual environment:

现在,我们将创建并激活我们的虚拟环境:

python -m venv venv
source venv/bin/activate

Install OpenAI Python SDK                安装 OpenAI Python SDK

Great, with the above set up, let's install the OpenAI SDK using pip:

太好了,有了上述设置,我们现在使用 pip 来安装 OpenAI SDK:

pip install openai

Step 2: Create the assistant        步骤 2: 创建助手

To create our shiny new AI Assistant, we'll use the following function client.beta.assistants.create, in your main.py file add the following:

为了创建我们闪亮的新 AI 助手,我们将使用 client.beta.assistants.create 这个函数。在你的 main.py 文件中添加以下内容:

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
)


def create_assistant():
    assistant = client.beta.assistants.create(
        name="Wise Guy",
        instructions="You are a wise philosopher that generates funny quotes.",
        model="gpt-3.5-turbo-1106",
        tools=tools
    )
    
    return assistant

The create_assistant() will create a new assistant called Wise Guy with the given parameters. We also passed in the tools parameter which tells the Assistant that it has tools at its disposal in case it needs to use them.

create_assistant() 函数将使用给定的参数创建一个名为 Wise Guy 的新助手。我们还传递了 tools 参数,它告诉助手在需要时可以使用哪些工具。

That's where we tell the Assistant that it has a custom function it can use. Okay, let's do that and define our custom Function and add it to the tools variable.

这就是我们告诉助手它有一个可以使用的自定义函数的地方。好的,让我们来定义我们的自定义函数,并将其添加到 tools 变量中。

Currently, the supported tools are functionretrieval, and code_interpreter. However, the OpenAI team announced that other tools will be added in the future as well as custom tools.

目前,支持的工具包括 functionretrieval 和 code_interpreter。然而,OpenAI 团队宣布未来将添加其他工具以及自定义工具。

Step 3: Define the custom Function as a tool        步骤 3: 定义自定义函数作为工具

Just to recap, our Function takes in a quote and then sends it via email. First, let's define the function in Python:

简单回顾一下,我们的函数接收一个引语,然后通过电子邮件发送它。首先,让我们在 Python 中定义这个函数:

Defining send_email in Python        在 Python 中定义 send_email 函数
def send_email(quote, recipient = "[email protected]"):
    # 
    # ...
    print(f"Quote: {quote}\nSending to: {recipient}")
    return "Message sent to " + recipient

Next, let's inform the AI Assistant about our Function and its parameters.

接下来,让我们告诉 AI 助手有关我们的函数及其参数的信息。

JSON Function send_email definition        JSON 中 send_email 函数的定义
tools = [{
    "type": "function",
    "function": {
      "name": "send_email",
      "description": "Sends a quote via email",
      "parameters": {
        "type": "object",
        "properties": {
            "quote": {
                "type": "string",
                "description": "A generated funny quote"
            }
        },
        "required": [
            "quote"
        ]
      }
    }
}]

Let's break it down:        让我们来详细解释一下:

  • "type": "function": This lets the Assistant know that this tool is of type Function.  

"type": "function":这告诉助手这个工具的类型是 Function。

  • "parameters": Here, we let the Assistant know about the function parameters. In our case, we just have one property called quote and it is required.

"parameters":在这里,我们让助手了解函数的参数。在我们的例子中,我们只有一个名为 quote 的属性,并且它是必需的。

Great! Remember in Step 2 we passed in the tools parameter? This is what we just defined and we'll pass it to our client.beta.assistants.create() method.

太好了!记得在步骤 2 中我们传递了 tools 参数吗?这就是我们刚才定义的,我们将它传递给 client.beta.assistants.create() 方法。

Step 4: Prompting the AI assistant        步骤 4: 提示 AI 助手

Prompting the AI Assistant requires that we execute a Run given a thread and an assistant and then wait for the response.

提示 AI 助手需要我们给定一个线程和一个助手来执行一个运行(Run),然后等待响应。

Creating our assistant        创建我们的助手
assistant = create_assistant()
Creating a thread
thread = client.beta.threads.create()
Prompting the assistant and waiting for a response        提示助手并等待响应

To prompt the model, we need to create a message within a thread using the client.beta.threads.messages.create method and then create a run using the client.beta.threads.runs.create method.

要提示模型,我们需要使用 client.beta.threads.messages.create 方法在线程中创建一条消息,然后使用 client.beta.threads.runs.create 方法创建一个运行(Run)。

Here's what our send_and_run function:        这是我们的 send_and_run 函数:

def send_and_run(content):
    message = client.beta.threads.messages.create(
        thread_id=thread.id,
        role="user",
        content=content,
    )
    
    return client.beta.threads.runs.create(
        thread_id=thread.id,
        assistant_id=assistant.id,
    )

Since a run runs asynchronously, we'll need to wait until it finishes. OpenAI says streaming support is coming soon, in the meantime, we can poll the run's status property by using the client.beta.threads.runs.retrieve method, like so:

由于一个运行(Run)是异步进行的,我们需要等待它完成。OpenAI 表示即将支持流式处理,在此期间,我们可以通过使用 client.beta.threads.runs.retrieve 方法轮询运行的 status 属性来检查其状态,如下所示:

def wait_on_run(run):
    while run.status == "queued" or run.status == "in_progress":
        run = client.beta.threads.runs.retrieve(
            thread_id=thread.id,
            run_id=run.id,
        )
        
        time.sleep(0.5)
    return run

Finally, we can simply call our send_and_run function and wait for the response:

最后,我们可以简单地调用我们的 send_and_run 函数并等待响应:

run = wait_on_run(send_and_run("Create a funny quote and email it"))

Behind the scenes, a Thread was created with the following message: "Create a funny quote and email it" and then sent to our AI Assistant as we executed the Run.

在幕后,当我们执行运行(Run)时,创建了一个带有以下消息的线程:“Create a funny quote and email it”(创建一个有趣的引语并通过电子邮件发送),然后将该消息发送给我们的 AI 助手。

After the run completes, we can inspect its contents to see whether the AI Assistant wants to use our custom send_email Function. Let's see how below.

运行完成后,我们可以检查其内容以查看 AI 助手是否想使用我们自定义的 send_email 函数。让我们看看下面如何操作。

Step 5: Check if the assistant needs to use our Function

步骤 5:检查助手是否需要使用我们的函数

Since the prompt contains "and email it", our AI Assistant will most likely decide to call our custom Function to execute this task.

由于提示中包含“and email it”,我们的 AI 助手很可能会决定调用我们的自定义函数来执行这个任务。

We're looking for the requires_action status of the run which means that the model determined that a function should be called. The model also determined the names and arguments needed to call the function.

我们正在寻找运行的 requires_action 状态,这意味着模型已经确定应该调用一个函数。模型还确定了调用函数所需的函数名和参数。

Let's check the run status and try to see if the assistant picked up the Function name and its associated arguments:

让我们检查运行的状态,并尝试看看助手是否选择了函数名及其相关参数:

if run.status == "requires_action":

    tool_call = run.required_action.submit_tool_outputs.tool_calls[0]
    name = tool_call.function.name
    arguments = json.loads(tool_call.function.arguments)

    print("Waiting for custom Function:", name)
    print("Function arguments:")
    print(arguments)

Here's the response:        响应如下:

Waiting for custom Function: send_email
Function arguments:
{'quote': 'I told my wife she should embrace her mistakes. She gave me a hug. Then filed for divorce.'}

Not very funny, but it works!                 起作用了

Step 6: Call the Function from our Python code        

步骤 6:从我们的 Python 代码中调用函数

Now the AI Assistant is waiting for us to execute the function and inform it that it's done.

现在,AI 助手正在等待我们执行函数并通知它已完成。

Let's do it:

task = send_email(**arguments)

Step 7: Inform the model that the Function was called

步骤 7:通知模型已调用函数

We'll now let the Assistant know that the function was executed, by using the client.beta.threads.runs.submit_tool_outputs method as shown below:

现在,我们将使用 client.beta.threads.runs.submit_tool_outputs 方法通知助手函数已执行,如下所示:

run = client.beta.threads.runs.submit_tool_outputs(
    thread_id=thread.id,
    run_id=run.id,
    tool_outputs=[
        {
            "tool_call_id": tool_call.id,
            "output": "done",
        }
    ],
)

This executes a run with the tool_outputs parameters which lets the model formulate a proper response based on the Function's output.

这执行了一个带有 tool_outputs 参数的运行,使模型能够根据函数的输出来制定适当的响应。

I hard-coded the output to "done" since we're just sending an email. In a real-world application, you may want to pass whatever your custom function returns.

由于我们只是发送一封电子邮件,因此我将输出硬编码为“done”。在真实应用中,您可能希望传递自定义函数返回的任何内容。

Step 8: Getting the final response from the model

步骤 8:从模型中获取最终响应

In the previous step, we executed a run and provided the Assistant with the Function's response.

在之前的步骤中,我们执行了一个运行,并向助手提供了函数的响应。

Now we're just going to wait until the run completes and print out the response by calling the client.beta.threads.messages.list method as shown here:

现在,我们将等待运行完成,并通过调用 client.beta.threads.messages.list 方法来打印出响应,如下所示:

run = wait_on_run(run)

print(client.beta.threads.messages.list(thread_id=thread.id, order="asc"))
SyncCursorPage[ThreadMessage](data=[ThreadMessage(id='msg_GxTLNJDPYe0dDDUnedDQLRHS', assistant_id=None, content=[MessageContentText(text=Text(annotations=[], value='Create a funny quote and email it'), type='text')], created_at=1701803371, file_ids=[], metadata={}, object='thread.message', role='user', run_id=None, thread_id='thread_g2PvjM4UdWNOAY1YlQ4dT6hu'), ThreadMessage(id='msg_tzzNFJodk7ksqVA1xu6tnlSA', assistant_id='asst_TsDAtpgi7EKAzWrV9lLKFgUT', content=[MessageContentText(text=Text(annotations=[], value='The funny quote has been sent via email!'), type='text')], created_at=1701803375, file_ids=[], metadata={}, object='thread.message', role='assistant', run_id='run_aib9MQMWgHnjp2ylGrbw4NJR', thread_id='thread_g2PvjM4UdWNOAY1YlQ4dT6hu')], object='list', first_id='msg_GxTLNJDPYe0dDDUnedDQLRHS', last_id='msg_tzzNFJodk7ksqVA1xu6tnlSA', has_more=False)

As you can see in the MessageContentText object the model responded with "The funny quote has been sent via email!". Beautiful, exactly what we need.

如您在 MessageContentText 对象中所见,模型以“The funny quote has been sent via email!”(有趣的引语已通过电子邮件发送!)进行了响应。太棒了,这正是我们所需要的。

And that's a wrap!        结束了

Wrapping up        总结

After you execute your code by running the python main.py command in your terminal, you can go to your OpenAI assistants page, where you should be able to see something similar to the below:

在您的终端中运行 python main.py 命令来执行您的代码后,您可以前往您的 OpenAI 助手页面,在那里您应该能看到类似于以下内容的输出:

You could click on the Test button found at the top right of the screen to test your assistant in the Playground.

您可以点击屏幕右上角的“Test”按钮,在 Playground 中测试您的助手。

In this post, we've seen how we can use the OpenAI Assistants API to create an AI assistant that uses the Function Calling (or Functions) tool to perform a specific action beyond its native capabilities.

在本文中,我们了解了如何使用 OpenAI Assistants API 创建一个 AI 助手,该助手使用函数调用(或函数)工具来执行超出其原生能力的特定操作。

I'd love to know if you found this post helpful or if you have any questions or comments.

我想知道这篇文章是否对您有帮助,或者您是否有任何问题或评论。

Thanks for reading! 

标签:function,Function,run,示例,AI,函数调用,API,OpenAI,email
From: https://blog.csdn.net/suiusoar/article/details/139683116

相关文章

  • Superset二次开发之基于GitLab OpenAPI 查询项目的提交记录中修改的文件
    背景:Superset二次开发,在处理版本升级的过程中,需要手动迁移代码,如何在Superset项目众多的文件中,记录修改过的文件,迁移代码时只需重点关注这些文件修改的内容即可,但是针对项目中多次的commit信息,每个commit又涉及不同的文件,如何快速梳理出这些二开工作中修改的文件,是我们......
  • 利用某些平台(聚合API、百度AI、科大讯飞API)的API接口,利用HTTP协议向服务器发送请求,并
    要使用C语言通过HTTP协议向服务器发送请求并接收响应,你可以使用如libcurl这样的库来发送HTTP请求。libcurl是一个免费且易于使用的客户端URL传输库,支持多种协议,包括HTTP。同时,为了解析服务器响应中的JSON数据,你可以使用cJSON库,这是一个轻量级的JSON解析库。以下是一个简单的示例......
  • 【简历写作技巧大揭秘】第2节:精准传达个人信息,提升第一印象,轻松赢得面试机会(文末提供
    精准有效地传达个人信息,是简历写作中至关重要的一环。个人信息部分既是简历的起点,也是用人单位了解求职者的第一步。因此,一个正确、清晰的个人信息展示,不仅能提升初次印象,更能增加获得面试的机会。本文将详细讲解如何在简历中精准、专业地展示个人信息。......
  • 设计优秀的API接口如何实现?
    电商大数据是指通过对电子商务平台产生的海量数据进行收集、存储、处理和分析,以揭示其中蕴藏的商业价值和规律性,并据此进行决策和优化的一项技术和方法体系。在设计接口时,有很多因素要考虑,如接口的业务定位,接口的安全性,接口的可扩展性、接口的稳定性、接口的跨域性、接口的协议......
  • 实时api接入指南|1688商品详情实时数据接口(1688.item_get)图片、库存、规格、销量等数
    接入1688商品详情实时数据接口(1688.item_get),涉及到图片、库存、规格、销量等重要信息的获取,这些数据对于电商平台来说至关重要,可用于商品展示、分析市场趋势、优化库存管理等。下面将详细讨论如何接入此API接口,并有效利用返回的数据:注册与创建应用账号注册:需要进行账号注册......
  • 界面组件DevExpress Office File API - 如何用OpenAI增强文档可访问性(二)
    DevExpressOfficeFileAPI是一个专为C#,VB.NET和ASP.NET等开发人员提供的非可视化.NET库。有了这个库,不用安装MicrosoftOffice,就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS,XLSx,DOC,DOCx,RTF,CSV和SnapReport等企业级文......
  • 华为OD API集群负载统计
    题目描述:某个产品的RESTfulAPI集合部署在服务器集群的多个节点上,近期对客户端访问日志进行了采集,需要统计各个API的访问频次,根据热点信息在服务器节点之间做负载均衡,现在需要实现热点信息统计查询功能。RESTfulAPI的由多个层级构成,层级之间使用/连接,如/A/B/C/D这个地址......
  • FastAPI快速入门1 Hello World
    1HelloWorld1.1HelloWorldch01/main.pyfromfastapiimportFastAPI,APIRouter#1app=FastAPI(title="RecipeAPI",openapi_url="/openapi.json")#2api_router=APIRouter()#3@api_router.get("/",status_code......
  • ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 添加自定义(GLSL)数据
    ArcGISJSAPI高级教程-ArcGISMapsSDKforJavaScript-添加自定义(GLSL)数据核心代码完整代码在线示例ArcGISMapsSDKforJavaScript从4.29开始增加RenderNode类,可以添加数据以及操作FBO(ManagedFBO);通过操作FBO,可以通过后处理实现很多效果,官方提供了几......
  • select()API
    编写TCP客户端和服务端程序,客户端通过多路IO复用同时处理标准输入(文件描述符为0)和套接字。当输入为quit时程序结束;当通过套接字收到对方消息时把收到的消息再次转发给对方,服务器端需通过select()监控listenfd和accept()后建立的新的套接字newfd,可只写select()相关的主要代码。  ......