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

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 OpenAIclient = 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 = "your@email.com"):# # ...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.namearguments = 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! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/349614.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索智慧农业系统架构的设计与应用

随着科技的不断进步和农业现代化的推进,智慧农业正逐渐成为农业发展的重要趋势。智慧农业系统架构的设计与应用,将农业生产与信息技术相结合,为农业生产提供了新的思路和解决方案。本文将深入探讨智慧农业系统架构的设计与应用,从…

遥控玩具车电机驱动应用中的双H桥驱动芯片

遥控玩具车的基本工作原理是通过无线电遥控器发送信号,这些信号被玩具车内的接收器接收并解码,从而控制玩具车的运行。根据车身外型的不同,可以分为:普通的私家房车、越野车、货柜车、翻斗车等等。遥控器的操作,如前进…

NG32031单片机串口初始化

目录 1. 串口基础 2. 串口配置步骤 3. N32G031串口初始化示例 3.1开启时钟 3.2 配置GPIO 3.3 配置USART 3.4 使能中断(如果需要) 3.5. 示例代码 4. 调试和验证 5. 注意事项 6. 额外功能 NG32G031单片机的串口(UART)通常…

鸿蒙轻内核M核源码分析系列二十 Newlib C

LiteOS-M内核LibC实现有2种,可以根据需求进行二选一,分别是musl libC和newlibc。本文先学习下Newlib C的实现代码。文中所涉及的源码,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。 使用Musl C库的时候&#xff0c…

c++实战知识点

c实战知识点 一、概述1.数据2.C11的原始字面量3.数据类型的别名4.const修饰指针5.void关键字6.内存模型7.二级指针8.函数指针和回调函数9.数组10.C风格字符串11.二维数组用于函数的参数行指针(数组指针) 12.引用引用与const 13.各种形参的使用场景14.重载…

MySQL中的正排/倒排索引和DoubleWriteBuffer

正排/倒排索引 正排索引 文档1:词条A,词条B,词条C 文档2:词条A,词条D 文档3:词条B,词条C,词条E正排表是以文档的ID为关键字,表中记录文档中的每个字的位置信息&#xff…

python中的turtle

turtle个别指令 初始箭头默认指向为东(右) 往前(右)三个格:turtle.forward(3) 往后(左)三个格:turtle.backward(3) 往左转90度:turtle.left(90) 往右转90度&#xf…

现代X86汇编-C和ASM混合编程举例

端午假期安装好了vs c2022,并写了个简单的汇编代码,证明MASM真的可以运行。今天需要搞一个实实在在的C和ASM混合编程的例子,因为用纯汇编的求伯君写WPS的时代一去不复返了。个别关键函数用汇编,充分发挥CPU的特色功能,偶尔还是需要…

关于RDMA传输的基本流量控制

Basic flow control for RDMA transfers | The Geek in the Corner (wordpress.com) 名词解释 IB : InfiniBand的缩写,指的就是InfiniBand技术。 MAD : Management Datagram的缩写。MAD是InfiniBand架构中用于设备管理和配置的一种特殊消息…

用数据说话,效果好上一万倍,不是空口说白话的“好很多”

作为一名大数据开发者,我深知数据的有很大的魔力(我这句话就没用数据,听上去很无力)。数据不仅仅是数字和图表,它还能赋予我们强大的说服力和权威感。让我给你详细讲讲数据如何让理论插上翅膀。 目录 数据的“靠谱”…

关于dwarf 中 DW_AT_data_member_location 的理解

1、用python elftool解析结构体的时候,成员偏移量存在DW_AT_data_member_location字段解析;此字段是可变长的(uleb128编码); 第一个字节是操作码 后续是偏移量 uleb128编码,正如其名,是小端结尾…

【权威出版/投稿优惠】2024年智慧城市与信息化教育国际会议(SCIE 2024)

2024 International Conference on Smart Cities and Information Education 2024年智慧城市与信息化教育国际会议 【会议信息】 会议简称:SCIE 2024 大会时间:点击查看 大会地点:中国北京 会议官网:www.iacscie.com 会议邮箱&am…

BIO、NIO编程与直接内存、零拷贝

Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,其实就是一个门面模式。 本质上就是操作系统提供的一系列的API 网络通信编程基本常识 服务端、客户端、通信编程关注的三件事 连接(客户端连接服务器,服务…

Python自动化

python操作excel # 安装第三个库 cmd -> pip install xlrb 出现success即安装成功 # 导入库函数 import xlrb # 打开的文件保存为excel文档对象 xlsx xlrb.open_workbook("文件位置") # C:\Users\Adminstator\Desktop\学生版.xlsx # 操作工作簿里的工作表 # 1.…

提升你的编程体验:自定义 PyCharm 背景图片

首先,打开 PyCharm 的设置菜单,点击菜单栏中的 File > Settings 来访问设置,也可以通过快捷键 CtrlAItS 打开设置。 然后点击Appearance & Behavior > Appearance。 找到Background image...左键双击进入。 Image:传入自己需要设置…

Golang的GC

目录 介绍GC 概要 什么是根对象 三色标记法 什么情况下三色标记法会失效 屏障机制 “强-弱” 三色不变式 插入屏障 (强三色) 删除屏障(弱三色) Go 的混合写屏障机制 混合写屏障规则 介绍GC 概要 作用范围:只回收堆内存,不回收栈内存&#xf…

list容器的基本使用

目录 前言一,list的介绍二,list的基本使用2.1 list的构造2.2 list迭代器的使用2.3 list的头插,头删,尾插和尾删2.4 list的插入和删除2.5 list 的 resize/swap/clear 前言 list中的接口比较多,与string和vector类似&am…

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法 下滑查看解决方法 🌈 欢迎莅临我的个人主页 👈这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地!🎇 🎓 博主简介:985高…

Mysql学习(九)——存储引擎

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 七、存储引擎7.1 MySQL体系结构7.2 存储引擎简介7.3 存储引擎特点7.4 存储引擎选择7.5 总结 七、存储引擎 7.1 MySQL体系结构 连接层:最上层是一些客户…

SpringBoot之请求映射原理

前言 我们发出的请求,SpringMVC是如何精准定位到那个Controller以及具体方法?其实这都是 HandlerMapping 发挥的作用,这篇博文我们以 RequestMappingHandlerMapping 为例并结合源码一步步进行分析。 定义HandlerMapping 默认 HandlerMappi…