OpenAI API 秘籍(一)
原文:
annas-archive.org/md5/0574f0264c82a1b1d4f1647846c643cc译者:飞龙
序言
在快速发展的生成式 AI 领域,能够创建创新应用程序,如聊天机器人、虚拟助手、内容生成工具和生产力增强工具,可能成为改变游戏规则的关键。OpenAI API 是实现这一目标的关键,帮助你在各行各业构建高性能的智能应用,或通过将 ChatGPT 添加到工作流中提升生产力。
你将从 OpenAI API 的基础知识开始,包括设置、身份验证和关键参数,为使用 API 打下坚实的基础。
接下来,你将了解 OpenAI API 的不同元素以及如何有效使用它,同时掌握调整某些参数以获得更好结果的重要性。你将发现 OpenAI API 的附加功能,这些功能将改善用户体验并帮助你获得更精细的输出。此外,你还将学习如何从开发阶段过渡到实际应用,掌握如何为公众使用和应用后端设置 API。随后,你将能够构建知识型助手和多模型应用,满足特定需求。
到本书结束时,你将全面掌握 OpenAI API,能够构建智能和 AI 驱动的解决方案。
本书适合人群
本书非常适合那些希望使用并掌握 OpenAI API 的在职专业人士和公民开发者。它非常适合快速创建智能应用程序,如聊天机器人或内容生成器,适合初学者和有经验的专业人士。
本书中的 OpenAI API 通过 Python 进行访问。虽然熟悉 Python 和 API 是有帮助的,但绝对不是必须的。
本书内容概览
第一章,解锁 OpenAI 并设置你的 API 游乐场 环境,介绍了开始使用 API 和 OpenAI API Playground 所需的步骤。
第二章,OpenAI API 端点解析,深入讲解了 OpenAI API 中各种端点,并附带实际案例和用例。
第三章,理解关键参数及其对生成响应的影响,讨论了关键 API 参数的重要性。
第四章,整合 OpenAI API 的附加功能,解释了如何使用 API 中的隐藏宝石,例如嵌入和微调。
第五章,为应用开发搭建 OpenAI API 环境,从调试 API 过渡到使用 API 构建实际应用。
第六章,使用 OpenAI API 构建智能应用,介绍了如何使用 API 构建各种不同的智能应用。
第七章,使用 OpenAI API 构建助手,提供了如何利用 API 构建知识型助手的教程。
本书包含许多长截图。这些截图的目的是为读者提供各种功能的概览。因此,在 100%缩放时,图像中的文本可能会显得很小。
为了充分利用本书
本书使用 Python 访问 OpenAI API。建议具备 Python 基础知识,以便充分利用本书的内容,但并非必需,因为书中使用的所有代码片段都会分享。
由于本书使用了 API,建议了解 API 及其工作原理,但同样并非必需。
需要对一些编程概念如函数和循环有基本的了解,因为书中不会涉及这些内容。
| 书中涉及的软件/硬件 | 操作系统要求 |
|---|---|
| Python | Windows、macOS 和 Linux(任何) |
| Postman | Windows、macOS 和 Linux(任何) |
| Bubble | Windows、macOS 和 Linux(任何) |
本书利用 OpenAI API,如果你不符合免费层的资格,可能需要支付额外费用。API 是按使用量计费的,因此,任何不当使用或滥用 API 都可能导致 OpenAI 发送一份巨额账单。你应始终在创建的 API 账户上设置使用限制。
本书还使用 Google Cloud Platform 来创建和部署云函数,像 OpenAI API 一样,如果使用不当,也可能会很贵。访问该服务需要 Google 账户。
如果你正在使用本书的数字版,我们建议你自己输入代码或通过 GitHub 仓库访问代码(下节提供链接)。这样做有助于避免因复制粘贴代码而导致的潜在错误 **。
下载示例代码文件
你可以从 GitHub 下载本书的示例代码文件,地址为github.com/PacktPublishing/OpenAI-API-Cookbook。如果代码有更新,它将会在现有的 GitHub 仓库中更新。
我们还有其他代码包,来自我们丰富的书籍和视频目录,可以在github.com/PacktPublishing/找到。快来看看吧!
使用的约定
本书中使用了许多文本约定。
文本中的代码:表示文本中的代码词语、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入以及 Twitter 用户名。例如:“在系统消息中,输入以下内容:你是一个创建 营销标语的助手。”
一段代码按以下方式书写:
{
"model": "gpt-3.5-turbo",
"messages":
{
"role": "system",
"content": "You are an assistant that creates marketing slogans based on descriptions of companies"
}
当我们希望引起你对某个代码块中特定部分的注意时,相关的行或项会以粗体显示:
"role": "assistant",
"content": "Thank you for your kind words! Vanilla is always a classic favorite. 😊🍦"
},
任何命令行输入或输出都按以下方式书写:
Donald Trump's presidency showcased divisive politics and tumultuous events.
粗体:表示新术语、重要词汇或屏幕上显示的文字。例如,菜单或对话框中的文字会像这样出现在文本中。以下是一个例子:“成功登录后,导航到右上角的个人资料,选择个人。”
提示或重要说明
看起来像这样。
章节
本书中包含了几个经常出现的标题(准备工作、如何操作...、它是如何工作的...、还有更多...、和另见)。
为了提供清晰的食谱完成指导,请按以下方式使用这些章节:
准备工作
本节告诉您食谱中应期待的内容,并描述如何设置所需的软件或任何前置配置。
如何操作…
本节包含遵循该食谱所需的步骤。
它是如何工作的……
本节通常包含对上一节内容的详细解释。
还有更多内容……
本节包含关于该食谱的附加信息,旨在帮助您对该食谱有更深入的了解。
另见
本节提供了其他有用信息的链接,帮助您了解该食谱。
联系我们
我们始终欢迎读者的反馈。
一般反馈:如果您对本书的任何方面有疑问,请在邮件主题中提及书名,并通过[customercare@packtpub.com 与我们联系。
勘误:尽管我们已尽力确保内容的准确性,但错误偶尔还是会发生。如果您在本书中发现任何错误,欢迎您向我们报告。请访问 www.packtpub.com/support/err…,选择您的书籍,点击“勘误提交表单”链接并填写相关详情。
盗版:如果您在互联网上发现任何我们作品的非法副本,请提供相关的地址或网站名称。请通过版权@packtpub.com 与我们联系,并附上链接。
如果您有兴趣成为作者:如果您在某个领域具有专业知识,并且有兴趣撰写或参与编写书籍,请访问 authors.packtpub.com。
分享您的想法
在您阅读完OpenAI API Cookbook后,我们非常希望听到您的想法!请点击此处直接进入亚马逊评论页面并分享您的反馈。
您的评论对我们以及技术社区非常重要,能帮助我们确保提供高质量的内容。
下载本书的免费 PDF 版
感谢您购买本书!
你喜欢随时阅读,但又无法随身携带印刷书籍吗?
您购买的电子书无法与您的设备兼容吗?
不用担心,现在每本 Packt 书籍都附赠无 DRM 版本的 PDF 电子书,且免费提供。
在任何地方、任何设备上阅读。直接从你最喜欢的技术书籍中搜索、复制并粘贴代码到你的应用程序中。
福利不仅仅如此,你还可以获得独家折扣、新闻通讯以及每日送达的优质免费内容
按照以下简单步骤来获取福利:
- 扫描二维码或访问以下链接
packt.link/free-ebook/9781805121350
-
提交你的购买证明
-
就这样!我们将直接通过电子邮件将你的免费 PDF 和其他福利发送给你
第一章:解锁 OpenAI 并设置你的 API Playground 环境
ChatGPT 是由 OpenAI 开发的先进 人工智能 (AI) 语言模型,是历史上增长最快的原生消费应用,仅用 2 个月就达到了 1 亿用户。相比之下,TikTok 排名第二,达到同样的用户数用了超过 9 个月(www.forbes.com/sites/cindygordon/2023/02/02/chatgpt-is-the-fastest-growing-ap-in-the-history-of-web-applications/?sh=3551e45d678c)。它之所以如此受欢迎,可以归因于其使 自然语言处理 (NLP) 模型对普通用户普及的能力。NLP 是 AI 中一个关注计算机与人类通过自然语言互动的领域。NLP 的终极目标是使计算机能够以既有意义又有用的方式解释、理解并响应人类语言。传统上,这个领域的任务——从情感分析到语言翻译——都需要强大的数据集和机器学习与数据科学的专业知识才能有效执行。
然而,ChatGPT 的崛起及其相关的 应用程序接口 (API) 已彻底改变了 NLP 领域。得益于它使 NLP 模型普及的能力,任何人,包括普通用户,现在都可以通过简单的提示生成类人文本,而不需要具备深入的数据科学或机器学习知识。例如,以前可能需要设计一个复杂的模型来将文本分类,现在通过 ChatGPT,一个简单的提示就能实现相同的目标。
从本质上讲,ChatGPT 的出现使得以前复杂的 NLP 任务变得更易接触和用户友好,弥合了先进技术与大众之间的鸿沟。
程序员和开发者们正在关注并将 GPT 的强大功能融入他们自己的应用程序中,使其变得智能。事实上,许多资金充足的初创公司(Typeface、Jasper AI、Copy.ai)将 ChatGPT 和其他 大型语言模型 (LLMs) 作为其产品的基础,无论是用于总结文本、寻找信息还是创建聊天机器人。这需要对 OpenAI API 及其如何用于构建智能应用程序有一个基本的了解,而这就是我们将要开始的地方。
这从基础开始,包括创建 OpenAI 账户、访问 API Playground 并发出 API 请求。
本章中,我们将介绍以下内容:
-
设置你的 OpenAI Playground 环境
-
在 OpenAI Playground 中运行完成请求
-
在 OpenAI Playground 中使用系统消息
-
使用聊天记录修改模型行为
-
使用 Postman 发出 OpenAI API 请求
技术要求
这一章需要您能够访问 OpenAI API。您可以在platform.openai.com/overview创建账户并注册以获取访问权限。
设置您的 OpenAI Playground 环境
OpenAI Playground是一个交互式的基于 Web 的界面,旨在允许用户尝试 OpenAI 的语言模型,包括 ChatGPT。这是一个您可以通过输入提示并实时查看生成响应来了解这些模型能力的地方。该平台充当一个沙盒,开发者、研究人员和好奇的个人都可以在此进行实验、学习,甚至原型设计他们的想法。
在 Playground 中,您可以自由参与各种活动。您可以测试 AI 模型的不同版本,尝试使用各种提示来查看模型的响应,并且您可以通过调整不同的参数来影响生成的响应。这提供了一个实时的窥视,展示了这些强大的 AI 模型如何思考、反应和创造基于您的输入。
准备工作
在开始之前,您需要创建一个OpenAI Platform账户。
转到platform.openai.com/并登录您的 OpenAI 账户。如果您没有账户,您可以使用电子邮件地址免费注册。或者,您可以使用有效的 Google、Microsoft 或 Apple 账户登录 OpenAI。按照说明完成账户创建。您可能需要使用有效的电话号码进行身份验证。
如何操作…
-
成功登录后,在右上角菜单中选择Profile,然后选择左侧菜单中的Personal,接着选择Usage。或者,您可以在登录后转到
platform.openai.com/account/usage。此页面显示您 API 的使用情况,更重要的是,它展示了您可用的学分数量。 -
通常,OpenAI 为新账户提供$5 的学分,您应该能在页面的Free Trial Usage部分看到这一点。如果您有学分,请继续第四步。然而,如果您没有任何学分,您需要升级并设置一个付费账户。
-
如果您已经获得了免费学分,则无需设置付费账户。然而,如果您用完了免费学分,这里是如何设置付费账户的方法:从左侧菜单选择Billing,然后选择Overview。接着,选择Set up paid account按钮。您将被提示输入支付详细信息并设置一个美元阈值,可以设置为您感到舒适的任何消费水平。请注意,执行本书中包含的每一个配方可能需要的学分总额不太可能超过*$5*。
-
创建 OpenAI 平台账户后,你应该能通过选择顶部菜单栏中的Playground,或者访问
platform.openai.com/playground来进入 Playground。
如何工作…
根据我的经验,OpenAI Playground 界面简洁、直观,旨在为用户提供便捷访问 OpenAI 强大语言模型的途径。Playground 是一个极好的地方,可以学习在不同设置下模型的表现,允许你尝试诸如温度和最大令牌数等参数,它们分别影响输出的随机性和长度。你所做的更改会立即反映在模型的响应中,提供即时反馈。
如图 1.1所示,Playground 包含三个部分:系统消息、聊天日志和参数。你将在在 OpenAI Playground 中运行完成请求的教程中了解这三个功能的更多信息。
图 1.1 – OpenAI Playground
现在,你的 Playground 已经设置好并准备使用了。你可以用它来运行完成请求,查看修改提示和参数如何影响 OpenAI 的响应。
在 OpenAI Playground 中运行完成请求
在本教程中,我们将实际操作 Playground,并执行来自 OpenAI 的完成请求。在这里,你将看到 OpenAI API 的强大功能,以及它如何用于为几乎任何提示提供完成。
准备就绪
确保你有一个拥有可用使用额度的 OpenAI 平台账户。如果没有,请按照设置你的 OpenAI Playground 环境的教程进行操作。本章中的所有教程都会有这个相同的要求。
如何操作…
让我们开始用 Playground 测试模型吧。我们来创建一个编写营销标语的助手:
-
进入OpenAI Playground。
-
在系统消息中,输入以下内容:你是一个根据公司描述创建营销标语的助手。在这里,我们明确指示模型的角色和上下文。
-
在聊天日志中,填写用户消息如下:一个编写吸引人的 悬疑小说的公司。
-
选择页面底部的提交按钮。
-
现在你应该能看到 OpenAI 返回的完成响应。在我的例子中(图 1.2),响应如下:
Unlock the Thrilling Pages of Suspense with Our Captivating Mystery Novels!
图 1.2 – OpenAI Playground 与提示和完成
注意
由于 OpenAI 的大语言模型(LLMs)是基于概率的,你可能不会看到和我一样的输出。实际上,如果你多次运行这个教程,你可能会看到不同的答案,这也是预期的,因为这是模型随机性的内在特征。
如何工作…
OpenAI 的文本生成模型使用一种特定的神经网络架构,称为 transformer。在深入探讨之前,我们先来解释一些这些术语:
-
神经网络架构:从高层次来看,这指的是一个受到人脑互联神经结构启发的系统。它设计用来识别模式,可以被认为是许多现代 AI 系统的基础构建块。
-
Transformer:这是一种神经网络设计,已被证明在理解序列方面特别有效,使其非常适合处理与人类语言相关的任务。它专注于词语之间的关系及其在句子或更大文本段落中的上下文。
在机器学习中,无监督学习通常指的是在没有任何标签数据的情况下训练模型,让模型自行发现模式。然而,OpenAI 的方法论更为细致。模型最初是在一个庞大的文本数据语料库上进行训练,配合各种任务进行监督。这帮助它们预测句子中的下一个词。例如,后续的改进是通过人类反馈强化学习(RLHF)进行的,其中模型会根据人类评估者的反馈进一步优化。
通过这些技术的结合以及大量数据,模型开始捕捉到人类语言的细微差别,涵盖了上下文、语气、幽默,甚至讽刺。
在这种情况下,完成的响应是基于系统消息和聊天记录提供的。系统消息在塑造和引导你从 Open AI 获得的响应中起着至关重要的作用,因为它决定了模型的个性、角色、语气和上下文等属性。在我们的案例中,系统消息包含了我们希望模型采取的个性:你是一个根据公司描述创作营销口号的助手。
聊天记录包含了模型在生成响应之前可以访问的消息历史,其中包含我们的提示信息,一个编写引人入胜的 悬疑小说的公司。
最后,参数包含了一些更细粒度的设置,你可以为模型调整这些设置,比如温度。这些设置会显著改变 OpenAI 的完成响应。我们将在 第三章 中详细讨论温度和其他参数。
还有更多……
值得注意的是,ChatGPT 并不读取和理解文本背后的意义——相反,响应是基于它在训练过程中观察到的模式的统计概率。
模型并不像人类一样理解文本;相反,完成内容是基于模型神经网络中从大量相似文本中训练出来的统计关联和模式生成的。现在,你知道如何在 OpenAI Playground 中运行完成请求了。你可以为自己的提示尝试这个功能,并查看得到的完成内容。试试富有创意的提示,比如为我写一首关于灯泡的歌,或者更专业的提示,比如解释牛顿的 第一定律。
在 OpenAI Playground 中使用系统消息
在这个示例中,我们将观察修改系统消息如何影响从模型收到的完成响应。这很重要,因为当你开始使用 OpenAI API 时,你可能会根据具体需求调整和优化系统消息,而 Playground 是一个很好的实验平台。
如何操作…
-
进入 OpenAI Playground。
-
在SYSTEM字段中,输入以下内容:你是一个根据公司描述生成有趣且专业公司名称的助手。
-
在聊天记录中,填写USER消息为:一个帮助你处理 税务问题的公司。
-
点击页面底部的Submit按钮。
-
现在你应该能看到来自 OpenAI 的完成响应。以我在图 1.3中的例子,响应如下:
TaxGuardian.
图 1.3 – 带有提示和完成的 OpenAI Playground
-
将鼠标悬停在ASSISTANT响应上,然后点击右侧的减号图标,删除聊天记录中的模型响应。这一步是必要的,因为我们希望 OpenAI 不仅仅生成一个响应,而是以ASSISTANT的身份生成响应。
-
修改系统消息为你是一个根据公司描述生成潜在客户群体和营销策略的助手。
-
点击页面底部的Submit按钮。
-
现在你应该能看到来自 OpenAI 的更长的完成响应。以我在图 1.4中的例子,响应详细列出了潜在的客户群体:
图 1.4 – 修改系统消息后的 OpenAI Playground 响应
它是如何工作的…
即使聊天记录中的提示完全相同,修改系统消息后,模型生成的响应类型会完全不同。响应从一个单词的回答变成了多段的回复,这是因为系统消息中的指示。我们还需要删除默认的助手响应,因为我们希望 OpenAI 生成自己的响应,而不是提供一个现成的回答。
系统消息作为对话中的第一条消息,通过提供参考框架或上下文,深刻影响模型的思维。这个上下文至关重要,因为没有它,模型将缺乏必要的指导,无法适当地响应后续的用户输入。它是定义与模型互动的基石,允许你提供重要的背景信息和高层次的指令,引导对话或任务的进行。
因此,当我们开始使用 OpenAI API 来创建商业应用时,必须谨慎考虑我们在系统消息中输入的指令。
还有更多内容…
系统消息的优点在于,你可以根据需要将指令做得简单或复杂。例如,以下是可以用于不同目的的常见系统消息:
-
你是一个帮助年轻学生通过简明易懂的语言解释科学概念的助手
-
你是一个根据公司描述创建营销标语的助手 提供给你
-
我计划在两周后为我的五岁侄女举办生日派对,你是我的派对策划师,告诉我应该做什么
使用聊天记录来修改模型的行为
在这个过程中,我们将学习如何修改聊天记录以及它如何影响我们从模型获得的响应。这很重要,因为开发者通常认为这是微调模型的最佳方法,而无需实际创建一个新模型。这也符合提示工程中必须提供适当示例的要求。
如何操作…
我们可以在聊天记录中添加提示和回应的示例,以修改模型的行为。让我们通过以下步骤观察这一点:
-
导航到OpenAI Playground。如果你已经填充了消息,请刷新页面以重新开始。
-
在系统消息中输入以下内容:你是一个根据公司描述创建营销标语的助手。在这里,我们明确指示模型其角色和上下文。
-
在聊天记录中,输入
Sham - the ice cream thatnever melts!。 -
选择添加消息按钮,并确保消息标签现在显示为USER。在USER消息中输入以下内容:一家公司制作 喜剧电影。
-
选择添加消息按钮,并确保消息标签显示ASSISTANT。在ASSISTANT消息中输入以下内容:Sham - the best way to tickle your funny bone!。
-
再次重复步骤 4-5,依次输入以下USER和ASSISTANT消息:为企业提供法律援助的公司,Sham - 我们懂商业法律!。此时,你应该看到如下内容:
图 1.5 – 填充了聊天日志的 OpenAI Playground
-
最后,选择添加消息按钮,并创建一条USER消息,内容为:一家编写引人入胜的 悬疑小说的公司。
-
选择页面底部的提交按钮。
-
现在你应该能看到来自 OpenAI 的回复。在我的情况下(图 1.6),回复内容如下:
Sham – unravel the secrets with our captivating mysteries!你的情况可能不同,但你看到的回复肯定会以“Sham –”一词开头,并以感叹号结尾。通过这种方式,我们已经训练模型,只以这种格式给我们提供回复。
图 1.6 – 修改聊天日志后的 OpenAI Playground 与完成内容
它是如何工作的……
正如我们在在 OpenAI Playground 中运行完成请求的示例中所学,ChatGPT 及其 GPT 模型是基于变换器架构构建的,该架构处理输入并根据给定的即时聊天历史生成回复。它没有对过去互动的持续记忆,也没有存储超出当前对话的上下文理解。聊天日志对模型的回复有显著影响。当模型接收到一个提示时,它会考虑最近的提示、系统消息以及聊天日志中所有先前的消息。
我们可以通过在Playground中提供我们自己的用户和助手消息集来观察这一点,然后看看模型如何改变它的回复,就像我们在前面的步骤中所做的那样。
特别是,模型在聊天日志中检测到了两种模式,并生成了与这些行为相符的回复:
-
模型检测到所有手动助手的回复都以Sham一词开头,因此它将该前缀添加到自己的回复中。
-
模型识别到所有标语都以感叹号结尾,因此在生成回复时,它也加上了一个感叹号。
总体而言,聊天日志可以用来训练模型生成用户希望创建的特定类型的回复。此外,聊天日志帮助模型理解并维持更大对话的上下文。
例如,如果你添加了一条用户消息什么是飞机?,并紧接着又发送了另一条用户消息它们是如何飞行的?,模型会理解它们指的是飞机,因为聊天日志的上下文。
提示工程
聊天日志在影响模型回复方面起着至关重要的作用,这一观察揭示了提示工程的更广阔领域。提示工程是一种技巧,通过精心设计给模型的输入或提示,引导模型生成所需的输出。
在提示工程的领域中,有一些显著的概念,如下所示:
-
零-shot 提示:在这种情况下,模型接收到的任务是它没有被明确训练过的。它完全依赖其现有的知识和训练来生成相关的响应。本质上,这就像是在没有任何先前示例的情况下,冷启动地要求模型执行任务。
-
少-shot 提示:这意味着向模型提供与目标任务相关的少量示例。目的是通过这些示例引导模型识别模式或上下文,从而生成与这些少量示例相关的响应。
理解如何构造提示的这些细微差别,使用户能够更有效地利用 ChatGPT 的功能,根据特定需求定制互动。
总的来说,聊天记录(以及我们在前面章节中学习到的系统消息)是将 OpenAI 的响应与预期目标对齐的一种非常低成本的方法,无需对模型本身进行微调。现在我们已经使用 Playground 测试了提示和完成,是时候使用实际的 OpenAI API 了。
使用 Postman 发起 OpenAI API 请求
OpenAI Playground 是测试模型完成情况的一个极好的方式,提供与 OpenAI API 相同的响应,但它有不同的目的。Playground 被视为一个实验沙盒,使用简单、互动性强,非常适合学习,而 OpenAI API 则使用户能够将模型直接集成到他们的应用程序中。
准备工作
为了发起 HTTP 请求,我们需要一个客户端,比如 Postman,来向 API 发送请求。我们还需要生成一个 API 密钥,这是一个唯一标识符,授权我们向 OpenAI 的 API 发起请求。
在本书中,我们将选择 Postman 作为我们的 API 客户端,但请注意,市面上有许多替代工具,包括 WireMock、Smartbear 和 Paw。我们选择 Postman 是因为它是最广泛使用的工具,支持跨平台(即可以在 Windows、Mac 和 Linux 上运行),而且对于我们的使用场景来说,它是完全免费的。
安装 Postman
Postman 是一个广泛认可的独立 API 测试工具,已有超过 1700 万用户使用 (blog.postman.com/postman-public-api-network-is-now-the-worlds-largest-public-api-hub/)。它包含许多功能,但其核心用途是让开发者能够发送 HTTP 请求并在易于使用的用户界面中查看响应。实际上,Postman 还提供了一个基于 Web 的版本(无需下载),这就是我们在本节中将使用的版本。
要使用 Postman,请访问 www.postman.com/ 并通过点击Sign Up for Free按钮创建一个免费账户。按照屏幕上的指示操作,直到进入平台,在那里您应该能看到顶部菜单栏,包含Home、Workspaces、API Network等选项。或者,您也可以选择下载并安装 Postman 应用程序(按照网站上的步骤),这样就不需要创建 Postman 账户。
现在我们已经进入 Postman 平台,接下来配置我们的工作区:
-
选择顶部的Workspaces,然后点击Create Workspace。
-
选择Blank Workspace,然后点击Next。
-
给工作区命名(例如OpenAI API),选择Personal,然后选择Create。
图 1.7 – 配置 Postman 工作区
获取您的 API 密钥
API 密钥用于对 OpenAI 服务器的 HTTP 请求进行身份验证。每个 API 密钥都是唯一的,且与一个 OpenAI Platform 账户关联。要获取您的 OpenAI API 密钥:
-
访问
platform.openai.com/并登录您的 OpenAI API 账户。 -
在右上角选择Personal,点击View API keys。
-
选择Create new secret key按钮,输入任意名称,然后选择Create secret key。
-
您的 API 密钥现在应该对您可见——请将其记下来并存放在安全的地方,例如一个受密码保护的**.txt**文件中。
注意
您的 API 密钥是您与 OpenAI 进行身份验证的凭证——它不应与任何人共享,并应像任何密码一样安全存储。
如何操作…
在设置好 Postman 工作区并生成 OpenAI API 密钥后,我们就可以开始进行 HTTP 请求。我们首先创建并发送请求,然后分析请求的各个组成部分。
为了使用 Postman 发起 API 请求,请按照以下步骤进行操作:
-
在您的 Postman 工作区中,选择左上角菜单栏中的New按钮,然后从出现的选项列表中选择HTTP。这将创建一个新的Untitled Request。
-
在Method下拉菜单中将 HTTP 请求类型从GET更改为POST(默认为GET)。
-
输入以下 URL 作为 Chat Completions 的终端:
api.openai.com/v1/chat/completions -
在子菜单中选择Headers,并将以下键值对添加到其下方的表格中:
| Key | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer <your API key here> |
在子菜单中选择Body,然后选择raw作为请求类型。输入以下请求正文,向 OpenAI 提供需要生成响应的提示、系统消息、聊天记录及其他参数:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "You are an assistant that creates marketing slogans based on descriptions of companies"
},
{
"role": "user",
"content": "A company that writes engaging mystery novels"
}
]
}
Postman 请求的Headers和Body部分应如下所示:
图 1.8 – Postman 头部
图 1.9 – Postman 主体
- 点击右上角的 发送 按钮以发起 HTTP 请求。
发送 HTTP 请求后,您应该会看到来自 OpenAI API 的响应。响应的形式是 JavaScript 对象表示法(JSON)对象。
图 1.10 – Postman 请求主体和响应
它是如何工作的……
为了构建智能应用,我们需要开始使用 OpenAI API 而不是 Playground。使用 OpenAI API 还有其他好处,包括以下几点:
-
更多的灵活性、控制和定制模型、其参数及其补全
-
使您能够直接将 OpenAI 模型的强大功能集成到您的应用中,而无需您的最终用户与 OpenAI 进行任何交互
-
提供了根据您的应用负载来扩展模型请求数量的能力
我们现在将专注于 API,但有经验的开发者总是会返回到 Playground 来测试他们的系统消息、聊天记录和参数。
要发起 API 请求,我们需要两样东西:
-
发起我们请求的一种方式 – 为此,我们使用了 Postman,因为它是一个易于使用的工具。然而,在开发应用时,应用本身会发起请求。
-
验证我们请求的一种方式 – 为此,我们从 OpenAI 账户中生成了一个 API 密钥。这告诉 OpenAI 谁在发起这个请求。
实际的 API 请求由四个元素组成:端点、头部、主体,最后是 响应。请注意,这一概念不仅仅适用于 OpenAI,也适用于大多数 API。
端点
端点 是您的 HTTP 请求的目标位置,以特定的 URL 形式表现出来。端点 URL 上存在一个 Web 服务器,用来监听请求并提供相应的数据。在 OpenAI 中,每个功能对应一个不同的端点。
例如,OpenAI 中的两个额外示例端点如下:
# used for generating images
https://api.openai.com/v1/images/generations
# used for generating embeddings
https://api.openai.com/v1/embeddings
此外,OpenAI API 端点只接受 POST 方法的请求。可以将 HTTP 方法(POST、GET 等)视为不同的方式去一个目的地:火车、飞机或海运。在这种情况下,OpenAI 只接受 POST 请求。
头部(Header)
API 请求的 头部 包含有关请求本身的元数据。头部标签中表示的信息包含关于主体的相关和重要元素,帮助服务器解释请求。具体来说,在我们的案例中,我们设置了两个头部:
-
Content-Type:我们将请求的内容类型设置为 application/json,这意味着我们告诉服务器我们的请求主体将采用 JSON 格式。
-
授权:我们将授权值设置为 API 密钥,该密钥允许服务器验证发出特定请求的客户端(在我们的例子中是 Postman 和 OpenAI 平台账户)。服务器可以使用 API 密钥检查客户端是否有权限发起请求,并且是否有足够的信用来执行请求。值得注意的是,通常,API 密钥作为 Bearer token 发送在授权头中。Bearer token 表示持有此令牌的用户(即发出请求的客户端)被授权访问特定资源。它作为一种紧凑且自包含的方法,用于在客户端和服务器之间传输身份和授权信息。
正文
最后,请求头中定义的 Content-Type。我们使用的端点(聊天完成)的必需参数是 model 和 messages:
-
model:这表示用于生成完成内容的特定模型。在我们的案例中,我们使用了 gpt-3.5-turbo,这是当时可用的最新模型。这相当于在 OpenAI Playground 的 模型 下拉菜单中选择模型,就像我们在 设置你的 OpenAI Playground 环境 示例中看到的那样。
-
messages:这表示模型在生成完成内容时可以访问的系统消息和聊天记录。在对话中,它代表迄今为止组成对话的消息列表。在 JSON 中,列表通过 [] 来表示,指示消息参数包含一个 JSON 对象列表(消息)。每个 messages 中的 JSON 对象(或消息)必须包含 role 字符串和 content 字符串:
-
role:在每条消息中,这表示消息作者的角色。要创建系统消息,角色应等于 system。要创建用户消息,角色应等于 user。要创建助手消息,角色应等于 assistant。
-
content:这表示消息本身的内容。
-
在我们的案例中,我们将系统消息设置为 你是一个根据公司描述创建营销标语的助手,用户消息或提示设置为 一个写引人入胜的悬疑小说的公司。在 JSON 形式中,这与我们的第一个 Playground 示例相当。
响应
当我们使用 Postman 发出前述请求时,我们收到了来自 OpenAI 的 响应,以 JSON 格式表示。JSON 是一种轻量级的数据格式,易于人类读取和编写,也容易被机器解析和生成。该数据格式由参数组成,这些参数是键值对。每个参数值可以是字符串、另一个 JSON 对象、字符串列表或 JSON 对象列表的形式。
图 1.11 – Postman OpenAI API 响应
如你在图 1.11中所见,响应包含了元数据和实际内容。参数及其含义描述如下:
-
id:事务的唯一标识符——每个响应都有不同的 ID。通常用于记录和跟踪目的。
-
object:请求的名称和由 API 返回的对象类型,在本例中是chat.completion(因为我们使用了聊天完成端点),表示聊天请求的结束。
-
created:一个时间戳,表示聊天完成创建的确切时间(基于 Unix 时间)。
-
模型:生成响应时使用的精确模型,在本例中是gpt-3.5-turbo-0613。请注意,这与请求正文中的模型参数不同。Body部分中的模型参数指定了使用的模型类型(gpt-3.5-turbo),而Response部分中的模型参数不仅指定了模型类型,还指定了模型版本(在本例中为0613)。
-
Choices:一个数组,包含模型生成的响应。该数组的每个元素包含以下内容:
-
索引:一个表示选择顺序的数字,第一个选择的索引是0。
-
消息:一个包含助手生成的消息的对象,包含以下内容:
-
role:生成消息的实体的角色。这与 Playground 屏幕中的聊天日志中的角色非常相似。
-
content:由 OpenAI 模型生成的文字或输出。
-
-
finish_reason:一个字符串,表示 OpenAI 模型决定停止生成进一步输出的原因。在本例中,stop意味着模型以自然的方式结束了消息。
-
-
使用情况:表示特定 API 请求使用情况或费用的参数列表:
-
prompt_tokens:在初始提示或输入消息中使用的令牌数量。
-
completion_tokens:模型根据提示生成的令牌数量。
-
total_tokens:提示令牌和完成令牌的总和,表示特定 API 调用所消耗的令牌总数。
-
JSON 格式的响应可能不容易阅读。事实上,我们特别关心的不是id、index或created,而是包含响应内容的content参数。
Unleash your inner sleuth with our captivating mysteries!
然而,JSON 响应格式在将 API 集成到你自己的应用程序中时是至关重要的。
这个食谱总结了 OpenAI API 的基本要素,并展示了如何使用像 Postman 这样的 API 客户端发送请求并接收响应。这一点很重要,因为这是我们用来了解 API 及其其他方面(如参数、不同端点、解析响应等)的主要方法。
第二章:OpenAI API 端点解析
OpenAI API 不仅仅是一个端点,而是一个由多个不同端点组成的集合,这些端点可以用来生成文本补全、图片,甚至转录音频。在本章中,我们将深入探讨所有这些用例,涵盖开发人员在将 OpenAI API 集成到应用程序时使用的主要端点。通过本章的学习,你将了解如何利用 OpenAI API 的多种功能,这是构建智能应用程序的第一步。你将理解每个端点的细微差别,确保能够根据你的具体需求定制集成方案。无论你是希望创建动态文本内容、生成引人注目的视觉效果,还是转录音频,你都将学会如何使用 API 完成这些任务。
本章中,我们将具体介绍以下配方:
-
使用聊天补全端点生成自定义响应
-
使用图像端点创建图片
-
使用音频端点生成转录
技术要求
本章要求你拥有访问 OpenAI API 的权限(通过生成的 API 密钥)并安装 API 客户端,如 Postman。你可以参考 第一章 中的 使用 Postman 发出 OpenAI API 请求 配方,了解如何获取 API 密钥并设置 Postman。
使用聊天补全端点生成自定义响应
我们之前在 第一章 末尾探讨了聊天补全端点,但我们的请求体相对简单,并未使用我们在 在 OpenAI Playground 中运行补全请求 配方中讨论的关键参数。例如,我们了解了如何使用聊天记录来 微调 生成的响应。此外,聊天记录功能还可以用于在应用程序中部署聊天机器人。
在本配方中,我们将介绍如何使用聊天补全端点和聊天记录参数生成响应。
准备工作
确保你拥有一个 OpenAI Platform 账户并且有可用的使用积分。如果没有,请参考 第一章 中的 设置 OpenAI Playground 环境 配方。
此外,确保你已安装 Postman,创建了一个新的工作区,创建了一个新的 HTTP 请求,并且该请求的 Headers 配置正确。这一点非常重要,因为没有正确配置 Authorization,你将无法使用 API。如果你没有按上述说明安装和配置 Postman,请参考 第一章 中的 使用 Postman 发出 OpenAI API 请求 配方。
本章中的所有配方都将具有相同的要求。
如何操作……
-
在 Postman 中,通过点击左上角菜单栏中的 New 按钮,选择 HTTP 来创建一个新的请求。
-
将 HTTP 请求类型从GET更改为POST,方法下拉菜单(默认情况下,它将设置为GET)。
-
将以下 URL 作为聊天完成的端点:
api.openai.com/v1/chat/completions。 -
从子菜单中选择Headers,并将以下键值对添加到下面的表格中:
| 键 | 值 |
|---|---|
Content-Type | application/json |
Authorization | Bearer <your API key here> |
从子菜单中选择Body,然后选择请求类型中的raw。在Body中输入以下内容。之后,选择发送:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "You are an assistant that creates short one-line responses to comments that users have left on your ice cream shop's Google reviews page"
},
{
"role": "user",
"content": "Comments: Great experience - I love the vanilla flavor!"
}
]
}
- 发送 HTTP 请求后,你应该看到来自 OpenAI API 的以下响应。请注意,你的响应可能会有所不同。我们特别需要注意 HTTP 响应中的
content值:
{
"id": "chatcmpl-7l0Y7gmS2gtyxyvX7VaSCKiU2oHgB",
"object": "chat.completion",
"created": 1691437883,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Thank you for your kind words! Vanilla is always a classic favorite. 😊🍦"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 47,
"completion_tokens": 19,
"total_tokens": 66
}
}
- 现在,让我们将消息添加到聊天记录中(或称为 API 中的
messages),以修改和调整生成的响应。修改messages:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "You are an assistant that creates short one-line responses to comments that users have left on your ice cream shop's Google reviews page"
},
{
"role": "user",
"content": "Comments: Great experience - I love the vanilla flavor!"
},
{
"role": "assistant",
"content": "Hello Ice Cream Fan, thank you so much. Vanilla is our favorite too. SCREAM FOR ICE CREAM!"
},
{
"role": "user",
"content": "Comments: I liked the many different flavors they have, and there's no line!"
},
{
"role": "assistant",
"content": "Hello Ice Cream Fan, thanks for that - we have over 50 different flavors. SCREAM FOR ICE CREAM!"
},
{
"role": "user",
"content": "Comments: The customer service was great - they were all so helpful!"
},
{
"role": "assistant",
"content": "Hello Ice Cream Fan, much appreciated. So glad we were helpful. SCREAM FOR ICE CREAM!"
},
{
"role": "user",
"content": "Comments: great location and great staff"
}
]
}
- 点击发送以执行 HTTP 请求。你应该会看到来自 OpenAI API 的类似响应:
{
"id": "chatcmpl-7l0vHiJlRrMrrWhjeJhBMEnT1HyHD",
"object": "chat.completion",
"created": 1691439319,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello Ice Cream Fan, thank you for the kind words. We love our location and our staff too. SCREAM FOR ICE CREAM!"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 177,
"completion_tokens": 28,
"total_tokens": 205
}
}
它是如何工作的……
OpenAI API 的工作方式与Playground非常相似,开发者可以将消息添加到聊天记录中。这样可以微调 API 生成的响应——它从我们创建的助手响应中学习。
我们通过首先执行一个简单的聊天完成请求,并且只指定了系统消息和用户消息(即提示),如图 2.1所示。
图 2.1 – 请求体中消息对象的摘录
这是通过在Body中添加消息对象到消息对象中完成的。每个消息对象必须包含一个角色和一些内容,正如我们在第一章中学到的那样。
然后我们可以添加额外的助手和用户消息,教模型如何制定其响应。重要的是,模型将尝试匹配它在标记为助手的消息中看到的任何模式。就好像我们在教模型如何生成响应一样。在这种情况下,所有的助手响应都包含了Hello Ice Cream Fan和为冰淇淋欢呼!
通过将消息添加到聊天记录中,当我们向 API 提供额外的提示时,它返回的响应与前面段落中描述的模式相匹配:
Hello Ice Cream Fan,感谢你的好评。我们也喜欢我们的地点和员工。为 冰淇淋欢呼!
在这个教程中,我们学习了如何使用 OpenAI API 中的 Chat Completions 端点生成文本,以及如何使用系统消息、用户提示和聊天日志来修改生成的文本。这一点很重要,因为 Chat Completions 端点是与其他系统集成以创建智能应用程序时最常用的 OpenAI API 端点。此外,当我们开始实际加载 API 时,了解如何通过使用聊天日志等方法调整生成的文本以适应我们的预期用途也非常重要。
还有更多…
向Chat Log中添加消息不仅仅是为了微调助手的响应。另一个重要的应用场景是创建聊天机器人,在这种情况下,必须在生成响应之前考虑到对话(即前面的 User 和 Assistant 消息)。例如,考虑以下示例:
System: You are an AI assistant that answers questions about the solar system
User: What's the largest planet in our solar system?
Assistant: The largest planet in the solar system is Jupiter
User: How big is it?
请注意,前面的代码块是为了说明目的而编写的伪代码,因为它比 OpenAI API 所需的正式 JSON 结构更易于阅读。为了在 OpenAI API 中使用这个示例,请求的 Body 必须是以下代码块中显示的内容:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": " You are an AI assistant that answers questions about the solar system"
},
{
"role": "user",
"content": "What's the largest planet in our solar system?"
},
{
"role": "assistant",
"content": "The largest planet in the solar system is Jupiter"
},
{
"role": "user",
"content": "How big is it?"
}
]
}
在这里,用户提示是 How big is it?。但是,如果我们只使用这个提示调用 API,它将无法生成正确的答案——事实上,它根本不知道我们在说什么,因为之前的 User 和 Assistant 消息并不在请求的 Body 中。
因此,我们需要构造请求体,将前面的代码块中列出的所有消息包含进去,才能让模型提供准确的响应。
使用图像端点创建图片
OpenAI API 不仅能生成文本(虽然这是它的主要功能);它还可以创建图像。它使用与文本生成类似的方法来实现这一点,但不是预测字符,而是预测像素。模型的内部工作原理是复杂的(它涉及编码器、解码器和嵌入技术),但这并不妨碍我们实际使用这个模型。
这极大地拓宽了您可以使用 OpenAI API 创建的应用程序类型。例如,您可以创建一个根据用户提示生成库存图像的应用程序。在本教程中,我们将使用 OpenAI API 生成几种类型的图像。
如何操作…
-
在 Postman 中,通过点击左上角菜单栏的New按钮创建一个新请求,然后选择HTTP。
-
在Method下拉菜单中将 HTTP 请求类型从GET更改为POST(默认情况下,它将设置为GET)。
-
作为图像的端点,请输入以下 URL:
api.openai.com/v1/images/generations -
在子菜单中选择Headers,并将以下键值对添加到其下方的表格中:
| Key | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer <your API key here> |
在子菜单中选择Body,然后选择请求类型为raw。输入以下内容后,点击Send:
{
"prompt": "A dog",
"n": 1,
"size": "1024x1024"
}
- 发送 HTTP 请求后,你应该会看到来自 OpenAI API 的以下响应。请注意,你的响应会有所不同——它会生成一个完全不同的 URL。以下的 URL 已被人工压缩:
{
"created": 1691525818,
"data": [
{
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-SdhfpAqxiHTuyKDLiHYAve6V/user-6A9i4gNyfxN9e9i2e0IUqomI/img-[...]%3D"
}
]
}
- 图像包含在响应中生成的 URL 内。从
url对象中复制该 URL,并粘贴到你的互联网浏览器中。你应该能看到一张狗的图片。和文本生成类似,你看到的图像与以下的图像会有所不同。
图 2.2 – DALL-E 2 OpenAI 图像生成的狗的输出
-
返回到 Postman 并修改请求为
一只棕色毛茸茸的中等大小柯基狗站在绿草地上,侧面视图。 -
从Response字段复制并粘贴 URL 到浏览器中,你应该能看到一张清晰的柯基狗照片。
图 2.3 – DALL-E 2 OpenAI 图像生成的更详细提示输出
它是如何工作的……
图像端点使用一个名为DALL-E的 AI 模型,该模型是 GPT 模型的一种变体,但用于生成可视化内容,而不是文本输出。该模型在数十亿的图像-文本提示对上进行了训练,以将特定的文本特征与视觉表示关联起来。该模型的强大功能在 OpenAI 内部可以使用,但需要使用特定的端点,如我们在教程中所描述的。
注意
DALL-E 是 OpenAI 在 2021 年初推出的首个文本到图像生成模型。DALL-E 2 是其下一版本,于一年后发布(openai.com/dall-e-2)。
DALL-E 和 DALL-E 2 都具有相同的功能(根据文本生成图像),并且通过相同的 API 调用。关键区别在于,DALL-E 2 使用了一种更先进且更流行的技术,叫做扩散,这是一种特殊的图像生成方法,能够生成更逼真和高分辨率的图像。
在本书中,DALL-E 和 DALL-E 2 将交替使用,用来指代 OpenAI 的文本到图像生成模型。
请求体和响应
图像端点的请求Body其实比聊天完成功能的请求要简单得多。以下是它的所有组成部分:
-
prompt:这是提供给模型的文本指令,用于图像生成。通常,这个指令越详细,生成的图像就会越接近你的需求。
-
n:这告诉 API 模型应生成的图像数量。每张图像都会有些微不同的变化,因为模型尝试根据提示提供不同的解释或角度。
-
size: 这指定生成图像的尺寸。目前,仅能生成以下尺寸的图像:256x256、512x512 和 1024x1024。
我们从图像端点收到的响应也非常容易理解:
-
created: 这表示图像生成时的 Unix 时间戳
-
data: 该对象的值实际上是一个对象数组,每个对象都包含url参数:
- url: 这是生成图像的直接链接
详细描述的重要性
与文本生成不同,文本生成你可以稍微泛泛而谈,任何歧义通常可以通过聊天记录和系统消息的上下文来解决,而图像生成需要详细、描述性和具体的语言来产生期望的输出。在本食谱中我们清楚地看到了这一点。简单的提示A dog(一只狗)生成了一张标准的狗的图像,但请观察图 2.4,当我们使用相同的提示再次进行图像生成时,生成的图像呈现出了不同的变化。
图 2.4 – 相同图像提示生成的输出
这些图像包含不同种类的狗、不同的环境、不同的角度和不同的光照。与我们使用的更详细提示进行对比——下图展示了使用关于这张柯基狗图像的更详细提示所生成的额外图像。
图 2.5 – 从特定提示生成的不同输出
更具描述性的提示显著缩小了可能性,引导模型生成符合用户需求和意图的图像。指定颜色、位置、物体、情感、光照等细节非常重要,以便用户可以确保生成的图像不仅相关,而且精细地契合他们的需求。
OpenAI API 中的图像端点解锁了多种不同的使用场景。例如,该端点可以用于在故事中创建个性化的图片、可视化不同的食谱创意,甚至为贺卡制作有趣的图片。可能性真的是无限的!
使用音频端点生成转录文本
在本食谱中,我们将学习如何使用 OpenAI API 的音频端点,该端点将音频转换为文本。这使开发者能够创建语音应用程序,如语音助手和语音对话机器人。
准备就绪
本食谱还将使用 Postman,但我们通常使用的 Header 设置需要进行修改,以便 HTTP 客户端使用表单数据而不是典型的 JSON 格式。另外,我们需要一个示例音频文件,用于将语音转换为文本。表单数据是一种以键值对的方式编码和发送数据的 HTTP 请求格式,通常用于上传文件。
打开 Postman 中的新请求后,导航到Content-Type application/json条目。这样 Postman 将强制默认根据请求Body中的内容来设置请求的Content-Type。
接下来,我们需要一个音频文件。任何短的(即小于一分钟)文件都可以,但它必须包含可以转录的词语,并且必须是以下格式之一:.mp3、.mp4、.mpeg、.mpga、.m4a、.wav或.webm。你也可以下载我创建的一个 10 秒钟的音频片段,点击此处:下载链接。
如何操作…
我们可以添加提示和响应的示例到聊天日志中,以修改模型的行为。让我们通过以下步骤来观察这一点:
-
在 Postman 中,将Endpoint的值改为以下 URL,并将请求类型更改为Post:
https://api.openai.com/v1/audio/transcriptions -
选择Body,然后选择form-data单选按钮。这将打开表单数据字段。每个字段包含一个Key和一个Value。
注意
我们可以选择将每个字段设置为文本或文件。我们可以通过将鼠标悬停在Key上,并从下拉菜单中选择我们选择的选项,正如图 2.6所示。
- 在表单数据中输入以下字段:
| Key | 指令/值 |
|---|---|
file | 点击选择文件并上传你之前创建或下载的音频文件 |
model | whisper-1 |
图 2.6 – 在 Postman 中选择字段类型
-
选择发送按钮以提交 HTTP 请求。
-
你应该会看到 OpenAI 返回的以下响应,指明了被转录的文本:
{
"text": "This is a test of the Whisper model."
}
它是如何工作的…
这个方法使用了音频端点,但请注意,我们与这个端点的 API 交互方式与其他端点完全不同。特别是,这个端点要求请求的Content-Type为form-data,而不是之前看到的典型 JSON 结构。原因在于form-data能够处理文件流,这正是我们在上传音频文件到 OpenAI 时所需要的。而在其他端点中,由于只是发送文本而非文件,原始的 JSON 就足够了。
HTTP 请求是网络数据通信的基石,并且通常用于与 API 进行交互。发送数据的两种方式是JSON和表单。由于 JSON 在结构上的灵活性,现在已经成为了广泛使用的数据交换格式——它可以用于传输键值对、列表和层级结构等概念。然而,我们使用表单的原因是,它们允许开发者编码二进制数据。简而言之,表单使得你能够传输文件(例如在此案例中是一个 10 秒钟的 MP3 文件)。
在表单中,有两个字段:file 和 model。file 字段表示我们想要转录的音频文件对象,model 字段表示我们想要使用的特定转录模型——在这种情况下,实际上仅限于一个选项:whisper-1。
响应很简单——一个 JSON 对象(text),表示转录的文本。
现在我们知道如何使用这个端点,我们可以集成它来创建强大而智能的商业应用程序。例如,典型的工作流程,如转录录制的会议和讲座,可以通过单个 API 请求完成。可以链式地连接多个端点,以实现更高级的用例。例如,我们可以创建类似于 Siri 的语音助手,它接收录制的声音,将其转换为文本,然后调用聊天完成 API 获取响应。
重要的是要知道,OpenAI API 不仅仅是文本生成;它可以执行图像生成、语音转文本,甚至为语义搜索创建嵌入。OpenAI API 是几个不同端点的集合,结合使用时,为开发者提供了一个无价的工具集,用于构建智能应用程序。
第三章:理解关键参数及其对生成响应的影响
在上一章中,我们学到了 OpenAI API 不仅仅是一个端点,它还是一个由多个端点组成的集合。这些端点通过model和messages触发——我们主要看到的是如何通过改变消息参数来影响生成的响应。然而,还有许多可选参数影响 API 的行为,比如温度、N 和最大令牌数。
在本章中,我们将探索这些可选的关键参数,并理解它们如何影响生成的响应。参数就像你在复杂机器上找到的旋钮和按钮。通过调整这些旋钮和按钮,你可以根据自己的喜好改变机器的行为。同样,在 ChatGPT 的领域中,参数允许我们调整模型行为的细节,影响它如何处理输入并生成输出。每个参数在塑造 OpenAI 的响应中扮演着独特的角色。
在本章结束时,你将知道如何调整这些参数以更好地满足你的特定需求,了解它们如何影响输出的质量、长度和风格,并学会如何有效使用它们以获得最理想的结果。学习这些内容很重要,因为随着我们开始将 API 集成到智能应用程序的不同用例中,这些参数需要进行调整,理解生成的响应如何随这些参数变化,将帮助我们确定正确的设置。
具体来说,我们将介绍以下教程,每个教程将聚焦一个关键参数:
-
更改模型参数并理解其对生成响应的影响
-
使用 n 参数控制生成响应的数量
-
使用温度参数来确定生成响应的随机性和创造性
技术要求
本章中的所有教程都要求你能够访问 OpenAI API(通过生成的 API 密钥),并安装了 API 客户端,如 Postman。你可以参考第一章中的教程使用 Postman 发起 OpenAI API 请求,了解如何获取你的 API 密钥并设置 Postman。
更改模型参数并理解其对生成响应的影响
在第一章和第二章中,聊天完成请求是使用模型参数和消息参数发起的,其中model始终等于gpt-3.5-turbo的值。我们基本上忽略了模型参数。然而,这个参数可能是所有参数中对生成响应影响最大的。与普遍看法相反,OpenAI API 不仅仅是一个模型;它由多个不同能力和价格点的模型组成。
在这个配方中,我们将介绍两个主要模型(GPT-3.5 和 GPT-4),学习如何更改 model 参数,并观察这两个模型生成的响应有何不同。
准备工作
确保你有一个具有可用使用额度的 OpenAI 平台账户。如果没有,请参阅 第一章 中的 设置 OpenAI Playground 环境 配方。
此外,请确保你已安装 Postman,已创建一个新的工作区,已创建一个新的 HTTP 请求,并且该请求的 Headers 配置正确。这非常重要,因为如果没有正确配置 Authorization,你将无法使用 API。如果你没有按照上述步骤安装和配置 Postman,请参阅 第一章 中的 使用 Postman 发送 OpenAI API 请求 配方。 如果你记不起来了,接下来的 步骤 1–4 会解释配置过程。
本章中的所有配方都有相同的要求。
如何操作…
-
在你的 Postman 工作区,选择左上角菜单栏中的 New 按钮,然后从弹出的选项中选择 HTTP。这将创建一个新的 Untitled Request。
-
通过选择 Method 下拉菜单(默认设置为 GET),将 HTTP 请求类型从 GET 更改为 POST。
-
输入以下 URL 作为聊天完成的端点:
api.openai.com/v1/chat/completions。 -
在子菜单中选择 Headers,并将以下键值对添加到下方的表格中:
| Key | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer <your API key here> |
在子菜单中选择 Body,然后选择 raw 作为请求类型。输入以下请求体,这些内容将向 OpenAI 说明提示、系统消息、聊天日志和生成完成响应所需的其他参数:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "user",
"content": "Describe Donald Trump's time in office in a sentence that has six five-letter words. Remember, each word must have 5 letters"
}
]
}
- 发送 HTTP 请求后,你应该看到来自 OpenAI API 的以下响应。请注意,你的响应可能会有所不同。我们特别需要注意的 HTTP 响应部分是
content值:
{
"id": "chatcmpl-7rocZGT1K0edeqZ2dTx65sfWIGdQm",
"object": "chat.completion",
"created": 1693060327,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Donald Trump's presidency showcased divisive politics and tumultuous events."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 33,
"completion_tokens": 12,
"total_tokens": 45
}
}
- 现在,让我们重复 步骤 4 中的 HTTP 请求,并保持其他内容一致,但修改
model参数。具体来说,我们将把该参数的值更改为gpt-4。输入以下端点和请求体,然后点击 Send:
{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "Describe Donald Trump's time in office in a sentence that has six five-letter words. Remember, each word must have 5 letters"
}
]
}
- 你应该看到来自 OpenAI API 的类似响应。请注意,这个响应与我们之前收到的响应有很大不同。特别地,它更接近于生成六个五个字母单词的提示要求:
# Response
{
"id": "chatcmpl-7rohvZHiQHG0GPh0Ii0Qlcukdk8k7",
"object": "chat.completion",
"created": 1693060659,
"model": "gpt-4",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Trump faced query, shook norms, split base"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 33,
"completion_tokens": 8,
"total_tokens": 38
}
}
- 重复步骤 1-4,但将
messages中的content参数改为以下提示:香烟中有多少种化学物质,多少种已知对人体有害,多少种已知会导致癌症?只回答数字,其他一律不提。
再次执行一个聊天完成请求,其中model参数为gpt-3.5-turbo,另一个请求中model参数为gpt-4。
- 以下是我使用 GPT-3.5-turbo 和 GPT-4 收到的 HTTP 响应摘录:
-
当model = gpt-3.5-turbo时:
"content": "There are thousands of chemicals in cigarettes, more than 7,000\. Over 70 of them are known to be harmful, and at least 69 are known to cause cancer." -
当model = gpt-4时:
"content": "6000, 250, 60"
- 重复步骤 4-7,但将
messages中的content参数改为以下逻辑问题提示:
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "user",
"content": "Which conclusion follows from the statement with absolute certainty?\n1\. None of the stamp collectors is an architect.\n2\. All the drones are stamp collectors.\nOptions:\na) All stamp collectors are architects.\nb) Architects are not drones.\nc) No stamp collectors are drones.\nd) Some drones are architects.\nOnly reply with the answer"
}
]
}
请注意,HTTP 请求中,若请求体为 JSON 格式,无法处理多行字符串。因此,如果需要将多行字符串写入任何 API 参数(例如此处的messages),请改用换行字符(\n):
例如,
"
Line 1
Line 2
"
会变成
"Line 1\nLine 2"
- 以下是我收到的 HTTP 响应摘录:
-
当model = gpt-3.5-turbo时:
"content": "c) No stamp collectors are drones." -
当model = gpt-4时:
"content": "b) Architects are not drones."
它是如何工作的……
在这个例子中,我们观察了三种不同的model参数变化如何影响生成的文本。下表总结了 OpenAI 基于不同模型参数生成的不同响应:
| 提示 | 当 model = gpt-3.5-turbo时的响应 | 当 model = gpt-4时的响应 |
|---|---|---|
| 用六个五个字母的单词描述唐纳德·特朗普的任期。记住,每个单词必须有五个字母 |
Donald Trump's presidency showcased divisive politics and tumultuous events.
|
Trump faced query, shook norms, split base
|
| 香烟中有多少种化学物质,多少种已知对人体有害,多少种已知会导致癌症?只回答数字,其他一律不提 |
|---|
There are thousands of chemicals in cigarettes, more than 7,000\. Over 70 of them are known to be harmful, and at least 69 are known to cause cancer.
|
6000, 250, 60
|
| 哪个结论可以从该陈述中得到绝对的确定性?
-
没有一个邮票收藏家是建筑师。
-
所有的无人机都是邮票收藏家。
|
c) No stamp collectors are drones.
|
b) Architects are not drones.
|
在所有情况下,gpt-4模型比gpt-3.5-turbo模型生成的结果更准确。例如,在关于描述唐纳德·特朗普任期的第一个提示中,gpt-3.5-turbo模型没有理解应只使用五个字母的单词,而gpt-4则能够成功回答。
GPT-4 与 GPT-3.5
为什么会这样呢?这两个模型的内部工作原理不同。在像 GPT 这样的神经网络模型中,参数是一个单一的数值,它与其他参数组合在一起,通过计算将输入(如提示)转化为输出数据(如聊天完成响应)。参数的数量越大,模型捕捉数据模式的能力越强。
GPT-3.5 模型集经过了 1750 亿个参数的训练,而 GPT-4 模型集预计经过了超过 100 万亿个参数的训练(通过多个较小的模型集合),这个数量比之前大了许多倍(www.pcmag.com/news/the-new-chatgpt-what-you-get-with-gpt-4-vs-gpt-35)。GPT-4 背后的神经网络更为密集,使其能够理解更多细微的差异并给出更准确的回答。
GPT 模型通常在处理非常复杂和冗长的指令时会遇到困难。例如,在香烟问题中,指令明确要求“只回复数字,其他不要”。GPT-3.5 提供了一个合适的答案,但格式不正确,而 GPT-4 返回的答案则符合正确的格式。
一般来说,GPT-4 更可靠,并且能够处理比 GPT-3.5 更复杂的指令。值得注意的是,这一区别对于主要是简单任务的情况可能很微妙,甚至不存在。为了辨别这些差异,两种模型在多种基准测试和常见考试中进行了测试,结果展示了 GPT-4 的强大。你可以在这里了解这些测试结果:openai.com/research/gpt-4。总的来说,GPT-4 在各种标准化考试中超越了 GPT-3.5,例如 AP 微积分、AP 英语文学和 LSAT。
GPT-4 和 GPT-3.5 之间的其他差异包括:
-
记忆和上下文窗口:GPT-4 可以保留更多记忆,并且具有更大的上下文窗口(
platform.openai.com/docs/models),这意味着它可以处理比 GPT-3.5 更大、更复杂的提示。上下文窗口指的是模型在生成回答时,能够考虑的最近输入的数量(以标记或文本块为单位)。可以想象你在阅读一本书中间的一段文字;你能看到和记住的句子越多,你对这段文字的理解就越好。同样,拥有更大的上下文窗口,GPT-4 可以看到并记住更多的先前输入,从而生成更具上下文相关性的回答。 -
视觉输入:GPT-4 可以同时处理文本和图像,而 GPT-3.5 仅限于文本。
-
语言能力:GPT-3.5 和 GPT-4 都具有多语言能力,意味着它们可以理解、解释并用英语以外的语言作答。然而,尽管 GPT-3.5 可以处理多种语言,但 GPT-4 提供了更为精细的语言能力,能够在其他语言中超越简单的语言表达。
-
对齐性:GPT-4 已经过更多的对齐,意味着它倾向于不提供有害的建议、错误的代码或不准确的信息,这得益于基于人类对抗测试的优化。在此背景下,对齐性指的是调整 GPT-4 的回答,使其更符合伦理和安全标准,从而降低提供有害建议、错误代码或不准确信息的可能性。
成本考虑
GPT-4 和 GPT-3.5 之间的一个重要区别是费用。GPT-4 的 token 费用高得多,如果选择更大的上下文窗口模型,费用还会增加。
token 是模型读取的输入或生成的输出的一部分文本。这些 tokens 可能是一个字符、一个单词的一部分或整个单词。大致来说,1 个 token 相当于 0.75 个单词(platform.openai.com/docs/introduction/key-concepts)。
在进行 API 请求以完成聊天时,响应中总是包含请求中使用的 tokens 数量,位于 usage 对象中。例如,以下是 步骤 5 中响应的摘录:
"usage": {
"prompt_tokens": 33,
"completion_tokens": 12,
"total_tokens": 45
}
这告诉我们,我们的 Describe Donald Trump's time in office in a sentence that has six five-letter words. Remember, each word must have 5 letters 提示用了 33 个 tokens,而以下的回应用了 12 个 tokens,总共 45 个 tokens:
Donald Trump's presidency showcased divisive politics and tumultuous events
tokens 数量重要的原因有两个:
-
根据所选择的模型,总的 tokens 数量不能超过模型的最大 token,也称为上下文窗口。对于 GPT-3.5-turbo,该值为 4,096 个 tokens。这意味着在使用该模型的任何 API 请求中,消息的内容总和不能超过 4,096 个 tokens,约为 3,000 个单词。相比之下,GPT-4 有一个子模型叫做 gpt-4-32k,其上下文窗口为 32,768 个 tokens,约为 24,000 个单词。
-
总的 tokens 数量和所使用的模型决定了你为 API 请求付费的金额。例如,在 步骤 5 中,我们使用 gpt-3.5-turbo 模型时,使用了 45 个 tokens,这意味着该请求的费用为 0.0000675 美元。相比之下,使用 gpt-4 的相同 45 个 tokens 费用为 0.00135 美元,是原费用的 20 倍。
决策标准
确定在聊天完成请求中使用哪个模型应考虑以下因素:
-
上下文窗口:确定聊天完成请求的可能上下文窗口。如果你的提示可能超过 12,000 个单词,那么你需要使用 GPT-4,因为 GPT-3.5 以下的最大模型只有 16,384 个 tokens 的最大值。
-
复杂性:确定你的聊天完成请求的复杂性。一般来说,如果它需要细致的理解和格式化指令(如食谱中的前两个示例),或需要复杂的信息综合和逻辑问题解决(如食谱中的第三个示例),那么你需要使用 GPT-4。这对于任何数学或科学推理尤其如此——GPT-4 的表现要好得多。
-
成本:评估选择 GPT-4 而非 GPT-3.5 的成本影响。如果你使用具有最大上下文窗口的 GPT-4 模型,这将是使用 GPT-3.5 的请求价格的 40 倍。
一般来说,你应该始终首先使用并测试 GPT-3.5,看看它是否能够提供合适的对话补全,然后在绝对必要的情况下再切换到 GPT-4。
总体而言,model参数会影响生成响应的质量,这是非常重要的,因为不同的 API 请求用例会要求不同层次的复杂响应。
使用 n 参数控制生成的响应数量
对于你构建的某些智能应用,你可能需要从相同的提示生成多个文本。例如,如果我们正在构建一个生成公司口号的应用,你可能不只希望生成一个响应,而是多个响应,以便用户可以选择最佳的一个。n参数控制每个输入消息生成多少个对话补全选择。当使用Images端点时,它也可以控制生成的图像数量。
在这个教程中,我们将看到n参数如何影响生成的响应数量,并理解它的不同用例。
如何操作…
-
在 Postman 中,输入以下 URL 作为对话补全的端点:
api.openai.com/v1/chat/completions。 -
在请求正文中,输入以下内容并点击发送。请注意,我们已添加h和n参数,并明确将其设置为默认值1:
{ "model": "gpt-3.5-turbo", "messages": [ { "role": "user", "content": "Create a slogan for a company that sells Italian sandwiches" } ], "n": 1 } -
发送 HTTP 请求后,你应该看到来自 OpenAI API 的以下响应(相似但不完全相同):
{ "id": "chatcmpl-7rqKJ2fxKkltvcIpAPiNH1MUPMBIO", "object": "chat.completion", "created": 1693066883, "model": "gpt-3.5-turbo-0613", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "\"Indulge in the taste of Italy, one sandwich at a time.\"" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 17, "completion_tokens": 16, "total_tokens": 33 } } -
现在,我们将重复第 2 步中的请求,但将n参数改为3。发送 HTTP 请求后,我们得到以下响应。请注意,现在在choices中有三个独立的对象或响应。我们实际上收到了三个不同的生成响应:
{ "id": "chatcmpl-7rqc4P2PY6BxEhVF7gSGRXPkAtoKt", "object": "chat.completion", "created": 1693067984, "model": "gpt-3.5-turbo-0613", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "\"Indulge in authentic flavor with our heavenly Italian sandwiches!\"" }, "finish_reason": "stop" }, { "index": 1, "message": { "role": "assistant", "content": "\"Deliciously Authentic: Taste Italy in Every Bite!\"" }, "finish_reason": "stop" }, { "index": 2, "message": { "role": "assistant", "content": "\"Delizioso Flavors in Every Bite!\"" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 17, "completion_tokens": 35, "total_tokens": 52 } } -
现在,让我们生成图像并观察n参数如何影响返回的图像数量。在 Postman 中,输入以下端点:
api.openai.com/v1/images/generations。在请求正文中,输入以下内容,然后点击发送:{ "prompt": "Ice cream", "n": 3, "size": "1024x1024" } -
发送 HTTP 请求后,你应该看到来自 OpenAI API 的以下响应。特别地,你应该看到三个不同的 URL,每个 URL 对应一个生成的图像。以下代码块中的 URL 已被人工简化。将这些 URL 复制并粘贴到浏览器中,你应该会看到冰淇淋的图像:
{ "created": 1693068271, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-...%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-...s%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-...%3D" } ] }
图 3.1 – OpenAI 图像端点的输出(n=3)
它是如何工作的…
n参数仅指定从 OpenAI API 生成的响应数量。对于对话补全,它可以是任何整数;这意味着你可以要求 API 返回成千上万的响应。对于图像生成,这个参数的最大值是10,意味着每次请求最多只能生成 10 张图像。
n 的应用
n 参数的应用非常广泛——通常,具有控制并重复生成相同提示的参数非常有用,且所有操作都能在一个 HTTP 请求中完成。包括以下内容:
-
创造力:对于创意类应用和任务,如标语生成、歌曲创作或头脑风暴,提供更多的素材集可以帮助用户更轻松地完成任务。
-
冗余:由于 OpenAI API 在相同提示下生成的响应可能会有很大差异,因此创建多个响应并交叉验证信息非常有用,特别是在关键任务工作流中。
-
A/B 测试:在营销中非常常见,n 参数使你可以生成多个响应,用户可以尝试不同的响应,看看哪一个效果更好。
n 的考虑
然而,多个生成通常意味着较低的速度和较高的成本,这些都是在决定 n 参数值时需要考虑的因素。例如,在我们的食谱中,当我们请求生成一个响应时,成本为 33 token(如响应中所示)。然而,当 n = 3 时,总 token 数跳升到 52 token。我们在前面的食谱中了解到,OpenAI API 根据生成的总 token 数收费。
请注意,成本增加并不是线性的——生成三个额外的响应仅增加约 60% 的 token,而不是预期的 3 倍。这是由于两个原因:
-
无论生成多少次响应,提示 token 的数量保持不变,无论是 1 次还是 100 次。
-
当模型知道需要生成多个完成项而非单一项时,会产生计算节省。
这也是为什么从成本角度来看,使用 n 参数比多次执行 HTTP 请求要好得多的原因。在底层,当你设置 n = 3 时,模型会在一次模型推理中并行处理请求,从而利用内在的效率。举例来说,我们本可以执行三次 HTTP 请求,而不是设置 n = 3 的一次请求,但那样会花费约 3 倍的成本和开销。
总的来说,n 参数影响生成的响应数量,对于特定用例来说,这非常有价值,同时也能降低成本。
使用温度参数来确定生成响应的随机性和创造力。
温度 可能是最难理解的参数之一。总体来说,它控制文本生成的创造力或随机性。温度越高,结果就会越多样化和富有创意——即使对于相同的输入。在实际应用中,温度根据使用场景来设置。对于需要一致且标准生成的应用,应使用非常低的温度,而对于需要创造性方法的解决方案,应选择较高的温度。
在本配方中,我们将了解温度参数,并观察它如何影响 OpenAI API 生成的文本。
如何操作…
-
在 Postman 中,输入以下端点:
api.openai.com/v1/chat/completions。在请求体中,输入以下内容,然后点击发送。我们的提示是用一句话解释引力。请注意,我们已经添加了温度参数,并将其显式设置为0。我们将重复此操作三次,并记录每次生成的内容参数的响应:{ "model": "gpt-3.5-turbo", "messages": [ { "role": "user", "content": "Explain gravity in one sentence" } ], "temperature": 0 } # Response 1 Gravity is the force that attracts objects with mass towards each other. # Response 2 Gravity is the force that attracts objects with mass towards each other. # Response 3 Gravity is the force that attracts objects with mass towards each other. -
接下来,让我们编辑请求体,并将温度参数更改为可能的最高值2。点击发送,然后再次重复三次,记录每次生成的内容参数的响应:
{ "model": "gpt-3.5-turbo", "messages": [ { "role": "user", "content": "Explain gravity in one sentence" } ], "temperature": 2 } # Response 1 Gravity is the force that attract objects with mass towards each other, creating weight. # Response 2 Gravity is a natural force that attracts objects toward each other based on their mass and distance between them. # Response 3 Gravity is the universal force of attraction that pulls every object toward the Earth. -
现在,让我们重复步骤 1-2,但使用一个更具创意的提示,例如为一本 AI 学习书籍创建一个创意标语。同样,我们首先会将温度参数设置为0,然后进行三次聊天生成。接着,我们将温度参数提高到2,再进行三次请求。每次生成的内容参数的响应会列在以下代码块中。请注意,你的结果可能会有所不同:
# Request Body { "model": "gpt-3.5-turbo", "messages": [ { "role": "user", "content": "Create a creative tag line for an AI learning book" } ], "temperature": 0 } # Response 1 Unlock the Power of Artificial Intelligence: Ignite Your Mind, Transform Your Future! # Response 2 Unlock the Power of Artificial Intelligence: Ignite Your Mind, Transform Your Future! # Response 3 Unlocking Minds, Unleashing Code: Navigating the Frontiers of AI Learning # Request Body { "model": "gpt-3.5-turbo", "messages": [ { "role": "user", "content": "Create a creative tag line for an AI learning book" } ], "temperature": 2 } # Response 1 Spark your mind – Accelerate with Artificial Excellence. # Response 2 Unlock limitless intelligence: Medium approach, myth together. # Response 3 Unleashing Minds: The AI Odyssey Awaits.
它是如何工作的…
正如我们在配方中所看到的,温度参数控制着文本生成的随机性和创造性。当温度设置得非常低时,API 会为相同的提示生成非常一致和确定的结果。在第一个示例中,引力在每次聊天完成时都以完全相同的方式进行解释:
Gravity is the force that attracts objects with mass towards each other.
当我们提高温度时,我们看到了非常不同、更加富有创意和出人意料的响应,例如以下内容:
Gravity is the universal force of attraction that pulls every object toward the Earth.
把温度设置想象成收音机上的旋钮。较低的温度就像将收音机调到一个信号强且清晰的电台,在这里你会获得一种一致且预期的音乐或脱口秀节目。这类似于模型生成的响应是可靠的、直接的,并且与最可能的答案紧密对齐。
相反,较高的温度类似于调节收音机到一个频率,在这个频率上你可能会接收到多种不同的电台,一些信号清晰,一些信号杂乱,播放着各种各样的音乐风格。这创造了一个环境,在这里意外、新颖和多变的内容会涌现出来。在语言模型的背景下,这意味着生成更加富有创意、多样化,并且有时是不可预测的响应,就像将收音机调到一个不太明确的频率上,从而接收到各种不同的内容。
温度的内部工作机制
如我们之前所讨论的,当模型生成文本时,它会根据已构建的提示和响应计算下一个单词的概率。在实践中,温度通过改变下一个单词的概率分布来影响响应。
使用较高的温度时,这个分布会变得更平坦,意味着较不可能的词语有更高的概率被选中。较低的温度则使得分布更加突出或尖锐,意味着每次选择的都是最可能的词语,从而减少了随机性。
根据用例做决定
关于使用哪种温度的决定完全取决于具体的使用场景。一般来说,这个参数可以分为三类。
-
低温度值(0.0 到 0.8):这些应主要用于分析性、事实性或逻辑性任务,以使模型更加确定性和集中。在这些用例中,追溯性和可重复性也很重要,因此较低的温度更好,因为它减少了随机性。较低的温度也意味着遵循已建立的模式和惯例,从而产生更正确的答案。
例如,生成代码、执行数据分析和回答事实性问题。
-
中等温度值(0.8 到 1.2):这些应适用于一般用途和类似聊天机器人的任务,其中平衡连贯性和创造性至关重要。这使得模型更加灵活,可以产生新想法,但仍然能集中在当前提示上。
例如,聊天机器人/对话代理和问答系统。
-
高温度值(1.2 到 2.0):这些应用于创意写作和头脑风暴,因为模型不受已建立模式的约束,可以探索各种多样的风格。在这里,正确的答案是不存在的,目标是创造多样的输出。这意味着你可能会得到完全不符合实际提示的意外输出。
例如,讲故事、生成营销口号和头脑风暴公司名称。
在这个食谱中,当解释重力时,较低的温度更为合适,因为提示鼓励的是事实性且直接的回答。然而,第二个提示关于创建标语的任务,更适合使用较高的温度,因为这是一个需要创造性和跳出思维框架的任务。
总的来说,设置温度值意味着在连贯性和创造性之间进行权衡,这种权衡取决于你如何在应用程序中使用 API。经验法则是,最好将温度设置为 1,然后以 0.2 为增量进行调整,直到达到你想要的输出集。
第四章:引入 OpenAI API 的附加功能
OpenAI API 提供了比我们在上一章中学到的标准端点和参数更多的功能。这些功能为现有模型提供了更多自定义选项,并通过将模型与其他方法连接,拓展了更多的应用场景。
特别是,OpenAI API 包含一个强大的嵌入模型,使用户能够将文本向量化,执行典型的 NLP 功能,如文本聚类、文本分类、文本比较等。这是与 Google 等搜索引擎使用的相同技术,例如,搜索引擎使用它来返回相关的搜索结果。现在,通过 OpenAI API,它触手可及。
API 还包含一个方法来 微调 或定制某个模型以适应特定的应用场景。与我们之前所做的微调(需要通过多个示例来 引导 模型)不同,这是一种更好且通常更便宜的替代方案。
最后,API 还具备创建 函数调用 的能力。这使你能够向 API 提供一组函数及其描述,模型则智能地生成一个包含调用该函数所需参数的 JSON 对象,从而使你能够将 OpenAI API 与任何用户定义的函数连接。
然而,为了使用这些功能,我们需要通过编程语言(如 Python)而非通过一次性的 HTTP 请求(如 Postman)来调用 API。因此,我们将首先介绍如何使用 Python 而非 Postman 调用 OpenAI API,并了解这种方法变更所带来的好处。
到本章结束时,你将能够在应用程序中使用这些功能。这很重要,因为理解这些功能将为你打开一扇门,使你能够执行大量其他本来无法实现的应用场景。此外,我们还将探讨每个功能在各个食谱之外的应用。
本章将涵盖以下内容:
-
使用 Python 库调用 OpenAI API
-
使用嵌入模型进行文本比较和其他应用场景
-
微调完成模型及其相关应用
技术要求
本章中的所有食谱都需要你可以访问 OpenAI API(通过生成的 API 密钥)并且已经安装了 API 客户端。如果你不记得如何操作,可以参考 第一章 食谱 使用 Postman 发起 OpenAI API 请求。
在之前的章节中,我们使用了 Postman 作为 API 客户端。在本章中,我们将改用编程语言 Python。具体来说,本章的食谱将使用 OpenAI Python 库来调用 OpenAI API。
我们将在一个叫做 Google Colab 的服务中运行 Python。Colab 是由 Google 提供的在线托管 Jupyter Notebook 服务,使用时无需设置,并且可以在浏览器中运行 Python 代码。Jupyter Notebook 是一个开源的 Web 应用程序,允许您创建和共享文档,并包含可以逐步运行的实时代码。这就是我们将用来运行 Python 代码的环境。
要使用 Google Colab,您需要创建并登录有效的 Google 账户,这是完全免费的。按照以下步骤创建新的 Google 账户:accounts.google.com/。
使用 Python 库调用 OpenAI API
之前,我们使用 HTTP 请求和 Postman 来调用 OpenAI API。现在,我们转向通过 Python 和专用的 OpenAI Python 库来调用 API。为什么这很重要?
使用 Python 库调用 OpenAI API 相比于在 Postman 等工具中手动发起 HTTP 请求,具有显著优势,尤其对于那些希望将 ChatGPT 功能无缝集成到其应用程序中的开发者来说。
Python 的库通过提供更友好和直观的接口,简化了直接发起 HTTP 请求的复杂性。这促进了快速原型开发、简化的错误管理和高效的响应解析。该库封装了协议的基本细节,使开发人员能够专注于应用程序的核心功能,而不必被请求头、查询字符串和 HTTP 方法的具体细节所困扰。
此外,Python 广泛的包生态系统能够轻松支持将 OpenAI API 与其他服务和系统集成,从而实现可扩展和可维护的代码库。
总的来说,如果您认真考虑使用 OpenAI API 构建智能应用程序,您需要使用一种能够实现复杂逻辑和与其他系统连接的编程语言来调用 API。通过 OpenAI 库,Python 是实现这一目标的途径之一。
在本食谱中,我们将使用 Python 和 OpenAI 库创建一些简单的 API 调用。有关该库的更多信息,请参见:github.com/openai/openai-python。
准备工作
确保您有一个 OpenAI 平台账户并拥有可用的使用积分。如果没有,请参阅 第一章 中的 设置 OpenAI Playground 环境 食谱。
此外,请确保您已登录 Google 账户并能访问笔记本。您可以通过访问 colab.google/ 并在右上角选择 New Notebook 来验证这一点。之后,您应该会看到一个空白屏幕,并打开一个空的笔记本。
本章中的所有食谱都具有相同的要求。
如何操作…
-
在你的 Google Colab notebook 中,点击第一个空白单元格,输入以下代码来下载并安装 OpenAI Python 库。输入完代码后,按 Shift + Enter 运行该单元格中的代码。或者,你也可以通过点击单元格左侧的 播放 按钮来运行代码。此代码将尝试安装 OpenAI Python 库及其所有依赖项。你可能会看到类似 Requirements already satisfied 或 Installing httpcore 的输出。这是 Google 在尝试安装 OpenAI 运行所需的库,这是完全正常的:
!pip install openai from openai import OpenAI -
确保你能看到 Successfully installed openai-X.XX.X 字样,如 图 4.1 中所示。
图 4.1 – 安装 OpenAI 库后 Jupyter notebook 的输出
-
接下来,我们需要进行身份验证。这与前几章类似,我们必须通过将 API 密钥放入一个名为 Authorization 的 Header 参数来验证 Postman 请求。在 Python 中,这要简单得多。在你在 步骤 1 中使用的单元格下方,写入以下代码并按 Shift + Enter。注意,将 替换为你在 第一章 的最后一个食谱中生成的 API 密钥:
api_key = "<api-key>" client = OpenAI(api_key=api_key) -
我们现在将向 OpenAI API 发起聊天完成请求。与 Postman 类似,我们可以使用不同的端点,并在请求中定义各种不同的参数。在下方的一个新单元格中输入以下代码并按 Shift + Enter,这将运行代码并将输出保存在一个名为 completion 的变量中:
completion = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {'role': 'system', 'content': 'You are an assistant that creates a slogan based on company description'}, {"role": "user", "content": "A company that sells ice cream"} ], n=1, temperature=1 ) -
输出 completion 变量,它是一个 ChatCompletion 对象。我们可以通过输入以下代码并按 Shift + Enter 运行代码,将其转换为更熟悉的 JSON 格式(与 Postman 中完全相同):
import json completion_json = json.loads(completion.json()) print(completion_json)图 4.2 显示了你运行此代码后将看到的输出。
图 4.2 – Python OpenAI 完成请求的 JSON 输出
-
使用 Python,我们可以解析 JSON,并仅输出包含公司标语的 JSON 部分。我们可以通过在下方的单元格中输入以下代码并按 Shift + Enter 来运行代码:
print(completion_json['choices'][0]['message']['content'])
图 4.3 – 第六步的输入和输出
- 现在你已经有了一个可以调用 OpenAI API、发起聊天完成请求并输出结果的工作 Python Jupyter notebook。
工作原理…
在本教程中,我们进行了与之前相同的操作,不同之处在于我们使用了 OpenAI Python 库,而不是通过 Postman 发起 HTTP 请求。我们通过 API 密钥进行了身份验证,发起了聊天完成请求,并调整了几个参数(如 Model、Messages、N 和 Temperature),并打印了输出结果。
代码讲解
在本教程中运行的代码可以分为四个部分进行解释:
-
库安装:第一行 – !pip install openai; import openai – 是一个命令,用于将 OpenAI 库作为 Python 中的包安装。第二行将其导入当前 Python 命名空间,使得可以使用该库的函数和类。
-
身份验证:openai.api_key = "sk-..." 这一行设置了用于验证请求的 OpenAI API 密钥。
-
API 调用:openai.ChatCompletion.create() 这一行调用 API 并发起聊天完成请求。如你所见,它包含了我们在前几章中讨论过的典型参数。
-
输出:print(completion); print(completion['choices'][0]['message']['content']) 这一行打印出来自 API 调用的原始响应。响应不仅包括完成的内容,还包含一些元数据,类似于我们使用 Postman 发起 HTTP 请求时的情况。第二行深入响应对象,提取并仅打印消息的内容。
大多数 API 调用在 Python 中遵循以下步骤。需要注意的是,步骤 1 和 2(即库安装和身份验证)只需要执行一次。这是因为一旦库安装完成,它将成为 Python 环境的一部分,可以在任何程序中使用,而无需每次都重新安装。同样,身份验证通常是验证凭证以获取访问 API 的权限的过程,通常每个会话或配置只需要执行一次,因为凭证会被存储并在后续的 API 调用中重复使用。
总的来说,我们深入探讨了如何使用 OpenAI Python 库与 OpenAI API 进行交互,逐步过渡到之前使用 Postman 中 HTTP 请求的方法。我们将在未来的教程中继续沿着这个过程进行。
Python 库的组成部分
我们在前几章讨论过的端点和参数,都可以在 OpenAI Python 库中使用。语法上稍有不同,因为我们现在使用的是 Python 代码,而不是 JSON(通过 Postman)来发起 API 请求,但基本的思路是一样的。以下是一个表格,比较了 Postman 和 Python 库中端点调用的区别。
| 端点 | Postman 中通过 JSON 的 HTTP 请求(Body 组件) | Python OpenAI 库 |
|---|---|---|
| 聊天完成 |
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Hello!"
}
]
}
|
completion = client.chat.completions.create (
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
)
|
| 图片 |
|---|
{
"prompt": "A cute baby sea otter",
"n": 2,
"size": "1024x1024"
}
|
client.images.generate(
prompt="A cute baby sea otter",
n=2,
size="1024x1024"
)
|
| 音频 |
|---|
-F file="@/path/to/file/audio.mp3" \
-F model="whisper-1"
|
audio_file = open("audio.mp3", "rb")
transcript = client.audio.transcriptions.create ("whisper-1", audio_file)
|
表 4.1 – 比较 Postman 和 Python 库中端点调用的区别
使用 Python 库的优缺点
除了它只是未来工作流的前提条件外,这种做法还有几个好处。它对 API 请求本身提供了抽象,带来了以下好处:
-
简化认证:该库处理 API 密钥和令牌管理,将认证过程的细节抽象化,免去了用户的操作。例如,在这种情况下,我们不需要为 Bearer 创建新的参数,这与 HTTP 不同。此外,与 HTTP 请求不同,我们不需要为每一个请求都声明我们的 API 密钥。
-
易用性:它提供了一个高层接口,方法和类代表 API 端点,使得理解和实现更加容易;库会自动处理正确的 HTTP 请求构造、参数编码和响应解析。
-
做更多的事情:该库通常包含一些方便的特性,这些特性在简单的 HTTP 请求中不可用,如分页辅助、流式处理、会话管理、嵌入、函数调用等(这也是我们在这一章切换到 Python 库的原因——后续的工作流涵盖了这些特性)。
-
可编程性:Python OpenAI 库充分利用了 Python 的编程能力,支持变量、逻辑条件和函数(即,你可以使用编程语言的所有优势,而 Postman 无法提供这些)。
然而,使用 Python 库也有一些特定的缺点:
-
定制性有限:高级抽象可能限制了对某些 API 功能的直接访问。
-
维护和兼容性:依赖于库的更新,且可能与不同的 Python 版本发生冲突。
-
性能开销:额外的抽象层可能导致在资源紧张的应用中性能变慢。
-
控制力降低:它对需要对 API 交互进行详细控制的用户提供的灵活性较低。
使用嵌入模型进行文本比较及其他应用场景
OpenAI 提供了一个模型和端点,允许用户创建嵌入。 这是 API 中一个较少为人知的功能,但在实现许多应用场景(如文本搜索、文本分类等)方面具有广泛的应用。
什么是嵌入?文本嵌入是自然语言处理(NLP)中一种复杂的技术,它将文本转换为机器能够理解的数值格式。 本质上,嵌入是高维向量,捕捉了单词、句子甚至整个文档的精髓,概括了它们的单独意义以及它们之间的细微差别和关系。
从数学角度来看,向量是一个 n 维向量空间中的点,但为了简化,你可以把向量看作只是一个数字列表。然而,本章讨论的配方不要求你了解将单词转换为数字的过程和背后的科学原理。想了解更多关于嵌入背后的科学,可以阅读一篇很好的入门文章:stackoverflow.blog/2023/11/09/an-intuitive-introduction-to-text-embeddings/。
在这个配方中,我们将使用 OpenAI API 将各种文本转换为嵌入,并将这些嵌入用于文本比较的应用场景。
如何操作…
-
打开一个新的笔记本,导航到
colab.google/并选择右上角的 新建笔记本。 -
在第一个单元格中,输入以下代码并按 Shift + Enter 来运行代码。这将安装 OpenAI 库并导入本配方所需的模块:
!pip install openai from openai import OpenAI from numpy import dot from numpy.linalg import norm -
与前面的配方类似,将以下代码输入下面的单元格,并将****替换为你的 OpenAI API 密钥。按 Shift + Enter 来运行代码:
api_key = "<Insert your API-key here>" client = OpenAI(api_key=api_key) -
接下来,我们将用 Python 创建两个函数。第一个函数将根据文本字符串创建一个嵌入。为此,我们将使用 OpenAI API 的 Embeddings 端点。下一个函数接受两个嵌入,并使用 余弦相似度 计算它们之间的差异,这一概念我们将在下一节讨论。为此,输入以下代码并按 Shift + Enter:
def create_embeddings(text): embedding = client.embeddings.create(input=text, model="text-embedding-ada-002").data[0].embedding return embedding def compare_two_embeddings(a, b): cos_sim = dot(a, b)/(norm(a)*norm(b)) return cos_sim -
现在,我们已经准备好通过创建嵌入并计算它们之间的差异来开始比较文本。我们从两段语义上非常相似的文本开始:I like apples 和 I like bananas。输入以下代码,按 Shift + Enter,并注意输出结果:
text_1 = "I like apples" text_2 = "I like bananas" round(compare_two_embeddings(create_embeddings(text_1), create_embeddings(text_2)), 2)
图 4.4 – 相似文本的余弦相似度输出
-
接下来,让我们比较两段不相似的文本:I like apples 和美国宪法第一条的第一部分:All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives (
www.archives.gov/founding-docs/constitution-transcript)。输入以下代码,按 Shift + Enter,并注意输出结果:text_1 = "I like apples" text_2 = "All legislative Powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and House of Representatives." round(compare_two_embeddings(create_embeddings(text_1), create_embeddings(text_2)), 2)
图 4.5 – 相似文本的余弦相似度输出
-
注意,第一组文本的相似度(0.90)高于下一组文本(0.70)。这意味着第一组文本在语义上比后两组文本更相似,这在语言上是有道理的。
-
让我们更进一步。用以下文本重复步骤 5-7。我也记录了得到的输出相似度:
text_1 = "Birds like to fly" text_2 = "Airplanes can soar above the ground" Output = 0.88 text_1 = "Birds like to fly" text_2 = "A fly can irritate me" Output = 0.84
工作原理……
在这个示例中,我们将文本转换为嵌入向量,并进行比较。结果表明,与I like applies相比,文本I like bananas在语义上更接近美国宪法的第一部分。
此外,它还展示了文本Birds like to fly与Airplanes can soar above the ground在语义上比与A fly can irritate me更为相似。这是有道理的,因为前两段文本的句子都与飞行物体有关。
嵌入基础
如前所述,嵌入过程将文本转换为数字列表。这在自然语言处理(NLP)中至关重要,因为现在机器可以处理这些数字列表,而不是文本。
OpenAI 嵌入模型的关键特性是它能够捕捉语言特性和语义含义。这意味着两个语义相似的文本会有相似的向量(即相似的数字列表)。语义相似意味着两段文本传达相同或相关的意义、概念或思想,即使它们使用了不同的词语或结构。
代码结构
我们使用了 OpenAI 的嵌入模型来创建这些向量,通过 Embedding 端点来实现。可以通过openai.Embedding.create()函数调用该端点,传入两个参数:
-
输入:此参数代表你想要创建嵌入的文本。
-
模型:这是你想要用来创建嵌入的模型 ID。它与其他端点中的模型参数类似。在这个示例中,我们使用了标准的ada模型,即text-embedding-ada-002。OpenAI 建议使用这个作为起始嵌入模型,因为它非常实惠,且性能优秀。
函数调用返回一个 JSON 格式的嵌入对象,我们通过解析它来获取嵌入本身(这仍然是 Python 中的一个数字列表)。解析是通过["``data"][0]["embedding"]代码完成的。
在得到两组文本的嵌入后,我们需要对它们进行比较。如何比较两个向量(即如何比较两个数字列表)?最常用的方法叫做余弦相似度。余弦相似度衡量两个向量之间夹角的余弦值,结果是一个介于 0 和 1 之间的数值。
余弦相似度常被选用而非其他相似度测量方法,因为它在高维空间中(例如文本数据)特别有效,强调的是向量的方向而非大小。这种方法使它能够专注于向量的方向对齐,从而在评估文本之间的语义相似性时更加稳健,即使它们的长度或词频不同。
这里的数学细节不重要——其含义是余弦相似度越高,两个文本在语义上就越相关:
-
余弦相似度接近 1:文本非常相似或具有相似的上下文或含义
-
余弦相似度接近 0:文本无关
-
余弦相似度接近 -1:文本在语义上是相反的,这在自然语言处理(NLP)中很少见,因为大多数文本嵌入是设计成具有非负成分的
在 Python 中,可以通过以下代码实现,它计算两个向量的点积,并将其除以这两个向量的欧几里得范数的乘积:
def compare_two_embeddings(a, b):
cos_sim = dot(a, b)/(norm(a)*norm(b))
return cos_sim
在我们设置好一个函数来返回每个文本的嵌入,并计算两个嵌入之间的余弦相似度后,我们拥有了所有必要的工具来比较两段文本。
这个公式中的归一化(norm)确保我们在比较的是两个向量的方向,而不是它们的大小。这意味着我们关注的是两个向量在方向上的相似度,而不考虑它们的长度,这在许多应用中非常重要,比如比较句子的相似性。
文本比较的应用
嵌入是比较两段文本的高效方式,开启了许多不同的现实世界应用。回想一下在食谱中计算出的相似度得分,如下表所示:
| 测试 | 基础文本 | 比较文本 | 嵌入的余弦相似度 |
|---|---|---|---|
| 1 | 我喜欢苹果 | 我喜欢香蕉 | 0.90 |
| 所有在此授予的立法权力应由美国国会行使,该国会应由参议院和众议院组成 | 0.71 | ||
| 2 | 鸟类喜欢飞翔 | 飞机可以飞越地面 | 0.88 |
| 一只苍蝇能让我感到恼火 | 0.84 |
表 4.2 – OpenAI 嵌入对不同文本集的余弦相似度
OpenAI API 使你能够计算并排名不同文本集之间的语义相似度。请注意,语义相似度理解文本意义的细微差别。在测试 2中,飞机可以飞越地面与一只苍蝇能让我感到恼火的语义相似度更高。
这有悖直觉,因为你可能会认为共享单词苍蝇的文本应该更为相似。然而,嵌入模型识别到单词苍蝇在鸟类喜欢飞翔和一只苍蝇能让我感到恼火中的使用上下文是不同的。在这种情况下,嵌入是比较文本意义的强大工具。
嵌入还有其他应用,得益于 OpenAI API,你可以在构建应用时进行探索。这不是一个详尽的列表,但应该能帮助你对 API 的潜力有所了解:
-
搜索引擎中的信息检索:增强搜索算法,使其返回与查询在语义上相关的结果,而不仅仅是文本上匹配的结果 (
www.mage.ai/blog/building-semantic-search-engine-with-dual-space-word-embeddings) -
文档检索:即使文档没有共享相同的关键词,也能找到涉及类似主题的文档 (
arxiv.org/pdf/1810.10176v2.pdf) -
内容推荐系统:根据用户之前喜欢的项目与当前项目在语义上的相似性,推荐文章、产品或媒体给用户 (
towardsdatascience.com/introduction-to-embedding-based-recommender-systems-956faceb1919) -
文本分类:根据语义内容自动将文档分类到预定义类别中 (
realpython.com/python-keras-text-classification/)
总体来说,OpenAI API 的嵌入功能开启了许多其他的使用案例,从文本比较到信息检索。另一个关键的好处是,这些端点比 Completions 或 Images 端点便宜得多,成为了你工具库中强大而高效的工具。
微调一个完成模型
微调是将一个预训练模型进一步适应特定任务或数据集的过程。其目标通常是将一个已经在大型通用数据集上训练的原始模型应用到更为专业的领域,或者提升其在特定类型数据上的表现。
我们之前在 第一章 的第一个食谱中看到过微调的一个版本,在那里我们通过 messages 参数添加了输出示例来 微调 输出响应。在这个例子中,模型并没有真正地进行微调——我们实际上执行了 少量学习,即在提示中直接提供了输出示例给 Chat Completion 模型。然而,微调是一个过程,其中会创建一个全新的子集 Chat Completion 模型,并使用训练数据(输入和输出)进行训练。
在本教程中,我们将探索如何微调一个模型并执行该微调后的模型。接着,我们将讨论使用 OpenAI API 微调模型的优缺点。
如何实现…
-
打开一个新的笔记本,访问
colab.google/并在右上角选择 新建笔记本。 -
在第一个单元格中,输入以下代码并按 Shift + Enter 来运行代码。这将安装 OpenAI 库并导入本教程所需的模块:
!pip install openai from openai import OpenAI import os -
类似于前面的操作,输入以下代码到下方的单元格中,并将****替换为你的 OpenAI API 密钥。按 Shift + Enter 来运行代码:
api_key = "<Insert your API-key here>" client = OpenAI(api_key=api_key) -
将训练数据导入到 Google Colab 中。训练数据文件可以在此找到:
drive.google.com/file/d/1x0ciWtW3phjPHAosiCL90qsQY--ZoxsV/view?usp=sharing。要将文件上传到 Google Colab,请选择左侧的文件图标,并选择该菜单顶部的上传文件按钮。这两个图标在图 4.6中已被突出显示。请注意,训练数据包含多个示例,其中提示是一个场景(例如图书馆里的学生),而补全是一个单行笑话,后面跟着Haha(例如为什么学生带梯子去图书馆?因为他们听说知识在最上层的 书架上!Haha*)。
图 4.6 – 如何将文件添加到 Google Colab
-
接下来,通过输入以下代码并按 Shift + Enter,将训练数据集上传到 OpenAI API。我们还将通过上传获取file_id:
training_data = client.files.create( file=open("chapter4trainingdata.json", "rb"), purpose='fine-tune' ) file_id = training_data.id -
之后,我们将开始微调模型,通过输入以下代码并按 Shift + Enter。这将开始微调过程,指示 OpenAI 使用我们通过file_id变量上传的文件:
fine_tune_job = client.fine_tuning.jobs.create(training_file=file_id, model="gpt-3.5-turbo") -
微调可能需要几分钟时间才能完成。我们可以通过输入以下代码并按 Shift + Enter 来检查任务的状态。如果输出是running,意味着微调仍在进行中。等待直到代码返回succeeded:
client.fine_tuning.jobs.retrieve(fine_tune_job.id).status -
现在微调任务已经完成,我们需要微调模型的名称,我们可以通过输入以下代码并按 Shift + Enter 来获得。我们将把它保存到fine_tuned_model变量中:
fine_tuned_model = client.fine_tuning.jobs.retrieve(fine_tune_job.id).fine_tuned_model -
接下来,让我们使用我们微调过的模型。我们将创建一个简单的聊天补全请求,但我们会修改model参数,使用我们刚刚创建的fine_tuned_model对象:
Completion = client.chat.completions.create( model=fine_tuned_model, messages=[ {"role": "system", "content": "You are an assistant that creates funny one-line jokes based on a given scenario."}, {"role": "user", "content": "A man walking across the road"} ] ) print(completion.choices[0].message)
图 4.7 – 使用微调模型时的聊天补全请求与输出
- 请注意,在没有提供任何示例的情况下,补全输出是一个单行笑话,后面跟着单词Haha。我们成功地微调了一个模型,并且使用了这个微调后的模型。
它是如何工作的…
在这个方案中,我们通过向 OpenAI API 提供训练数据来创建了一个微调后的模型,这些数据教会模型如何响应提示。在这个案例中,我们训练它使得它的输出应该是一个笑话,并紧接着是词语 Haha。然后,我们将 model 参数更改为我们刚刚创建的模型 ID,并进行了一次 聊天完成 请求。之后,我们注意到,模型对从未见过的提示生成的输出,也同样是一个笑话,后面跟着 Haha。从本质上讲,我们成功地微调了 gpt-3.5-turbo 模型,使其能够在给定任何提示时讲一个笑话。
微调步骤
微调模型并使用该微调模型时需要遵循五个步骤:
-
准备训练数据文件:训练数据由示例或提示和期望的完成组成。至少需要 10 个示例才能成功训练模型。每个示例看起来非常相似(有明确的意图),与进行聊天完成请求时的 messages 参数类似。不同之处在于,它还包括完成部分(也就是助手的输出)。以下是一个示例:
{"messages": [{"role": "system", "content": "You are an assistant that creates funny one-line jokes based on a given scenario."}, {"role": "user", "content": "A student in a library"}, {"role": "assistant", "content": "Why did the student bring a ladder to the library? Because they heard the knowledge was on the top shelf! Haha"}]}这些示例可以添加到 JSON 文件中,每行代表一个示例。
图 4.8 – 包含训练数据的 JSON 文件图像
-
导入到 OpenAI:训练文件制作完成后,需要将其上传到 OpenAI 的服务器,这就是我们使用以下代码所做的:
training_data = client.files.create( file=open("chapter4trainingdata.json", "rb"), purpose='fine-tune' ) -
分配 ID:上传文件后,API 会分配一个 ID。可以通过查看前面的代码响应 JSON,并解析 id 参数来确定该 ID:
file_id = training_data.id -
微调模型:之后,我们需要指示 API 使用上传的训练数据来微调模型。我们会将从 API 获取的响应存储在一个变量中:
fine_tune_job = client.fine_tuning.jobs.create(training_file=file_id, model="gpt-3.5-turbo") client.fine_tuning.jobs.retrieve(fine_tune_job.id).status微调任务完成后,API 将分配一个
fine_tuned_model参数,给微调后的模型一个特定的标识符,我们可以将其存储在一个变量中:fine_tuned_model = client.fine_tuning.jobs.retrieve(fine_tune_job.id).fine_tuned_model -
使用微调后的模型:最后一步相对简单——像平常一样调用聊天完成 API,但将 model 参数修改为刚刚创建的微调模型:
completion = client.chat.completions.create( model=fine_tuned_model, messages=[ {"role": "system", "content": "You are an assistant that creates funny one-line jokes based on a given scenario."}, {"role": "user", "content": "A man walking across the road"} ] ) print(completion.choices[0].message.content)
微调的好处
微调通过允许你在比典型提示上下文窗口所能容纳的更多示例上进行训练,来改善少量样本学习。一旦模型被调优,这些示例在每次进行完成请求时就不再需要,从而节省了 token(和费用),并降低了延迟(即更快的速度)。请记住,token 是文本中最小的语义单位(通常是单词、标点符号或其他元素),在自然语言处理(NLP)中常常构成 OpenAI 收费的基础。
例如,我们来比较两种模型的 token 数量:(i)一个使用Gpt-3.5基础模型且没有微调,但每次都需要在提示中加入示例的模型,和(ii)一个微调后的模型。
| 模型 | Gpt-3.5 | 已微调的 Gpt-3.5 |
|---|---|---|
| 提示 | 你是一个基于给定场景创作幽默单句笑话的助手。这里有 10 个例子:一位骑士准备上战场 为什么骑士在战斗前总是很冷静?因为他擅长保持他的“盔甲”冷静!哈哈……[还有 9 个例子]……场景:北极的一只企鹅 | 你是一个基于给定场景创作幽默单句笑话的助手。场景:北极的一只企鹅 |
| 提示中的 token 数量(估算) | 400 | 36 |
表 4.3 – 非微调与微调后的 GPT-3.5 模型之间的提示示例和 token 数量比较
微调后的模型使用的 token 数量约为少量学习基础模型的十分之一。这意味着,使用微调后的模型可以节省 90%的成本,如果将这些模型部署到高频使用的应用中,这个节省是非常可观的。
微调的其他好处包括通过能够在数千个示例上进行训练,从而获得更高质量的结果,而这在使用少量学习时是无法实现的,因为提示词的长度有限。
注
微调模型以获得更高质量的结果应该仅在充分尝试过提示工程和提示链的优化之后进行。微调模型需要大量资源和精力,因此首先最大化提示工程和提示链的潜力更为高效,因为它们通常能够在不需要额外训练的情况下实现预期的结果。提示工程是指创建更详细和结构化的提示,以获得更好的完成效果。提示链是将更复杂的提示分解为更简单任务的理念。
微调的应用
什么时候你会选择微调模型,而不是(i)使用基础的 gpt-3.5 或 gpt4 模型,或(ii)使用少量学习来预先训练模型呢?一般来说,以下是一些常见的需要微调模型的使用场景:
-
增强期望输出:当需要在生成特定类型的响应时获得更高的可靠性时,微调至关重要。通过在专门的数据集上训练模型,您可以增加模型一致性地产生期望输出的机会。这在特定品牌语音的内容创作、必须遵循特定语言的教育资源创建等方面非常常见。
-
复杂提示遵从性:当模型在多次尝试后仍无法始终遵循复杂的提示或指令时,微调可以帮助纠正这些不足。这可以确保模型更好地理解和遵循详细或多层次的指令。例如,在创建编程助手时,这种情况非常常见。
-
专门化风格和语气调整:当需要特定风格、语气或格式时——例如法律语言、幽默语气或新闻风格——微调能帮助模型更准确地捕捉这些定性方面。这在开发客户服务机器人时非常常见,因为这些机器人需要保持既友善又坚定的语气。
-
定制任务性能:对于教授模型一项新技能或任务,如果单靠提示无法传达,微调让模型可以通过示例学习。这对一些特定领域的应用或创新任务尤其有用,这些任务可能在模型初始训练时没有接触过,或者像医疗诊断这样的更复杂任务。
总体而言,微调模型是一种非常好的、高性价比的方式,可以获得更高质量、一致性的结果。如果你打算构建一些预期类似提示和响应的应用程序,且需要特定的语气和风格,这种方法尤其有用。
第五章:OpenAI API 在应用开发中的分阶段应用
到目前为止,我们通过直接连接到 OpenAI 的端点并发送请求来使用 OpenAI API。然而,在构建应用和工作流时,通常不会直接连接到 OpenAI。相反,开发人员倾向于通过他们自己的后端 API 来分阶段调用 OpenAI API,然后将信息返回给应用程序。
本质上,应用程序的前端和 OpenAI API 之间存在一层,如图 5.1所示。此层通常处理来自前端的请求,调用 OpenAI API(或一系列其他端点),接收完成内容,处理后再将数据返回给前端。我们将这层称为后端层或服务器层。
图 5.1 – 使用 OpenAI API 的典型应用架构示意图
将 OpenAI API 集成到应用程序中通常涉及一种架构,其中前端层(用户界面)与后端层(服务器)通信,后者又与 OpenAI API 进行交互。这种方法有几个优势:
-
安全性与 API 密钥管理:OpenAI API 密钥不会暴露给前端,从而降低了被泄露的风险。后端可以安全地存储和管理 API 密钥。
-
控制与定制:后端可以控制发送到 OpenAI API 的请求的速率和性质。它还可以对来自前端的请求进行预处理,或对 OpenAI 的响应进行后处理,根据应用需求定制数据。
-
与其他服务的集成:通常,应用程序需要来自多个来源的数据。后端可以将 OpenAI API 与其他 API 或数据源集成,创建一个集中式的数据处理和分发点。
-
用户身份验证和授权:后端可以实施安全措施,如用户身份验证和授权,确保只有授权用户才能访问某些功能。
这个后端层通常被分阶段并托管在像 Azure Functions、Amazon Web Services Lambda 或 Google Cloud Functions 这样的无服务器系统上。使用无服务器架构有几个好处,其中最重要的是简化操作——创建一个无服务器架构的后端层既简单又快速。
本章将迈出使用 OpenAI API 进行应用开发的第一步。我们将学习如何创建一个无服务器的后端层,以连接和处理来自 OpenAI API 的数据。然后,我们将学习如何将其与前端层集成,使用无代码平台和代码平台。到本章结束时,您将具备开发自己智能应用所需的一切。
本章将介绍以下内容:
-
创建一个调用 OpenAI API 的公共端点服务器
-
扩展端点服务器以接受参数并返回数据
-
从无代码应用程序调用用户创建的端点
技术要求
本章中的所有教程都要求您能够访问 OpenAI API(通过生成的 API 密钥)并安装 API 客户端。有关如何获取 API 密钥的更多信息,请参阅第一章中的教程使用 Postman 发出 OpenAI API 请求。这还需要了解 Python 以及 Python OpenAI 库,我们在第四章的第一个教程中有详细介绍。
我们还将使用Google Cloud Platform(GCP)来托管我们的公共端点。GCP 是 Google 提供的一套云计算服务。它提供一系列托管和计算服务,包括数据库、数据存储、数据分析、机器学习等,所有服务都托管在 Google 的基础设施上。
为了做到这一点,您需要创建一个 Google Cloud 账户,您可以在这里创建:cloud.google.com/。
创建一个调用 OpenAI API 的公共端点服务器
如前所述,创建您自己的公共端点服务器来调用 OpenAI API,而不是直接连接 OpenAI API,有许多重要的好处——最大的好处是控制和定制,我们将在本教程和下一个教程中进一步探讨。
在本教程中,我们将使用 GCP 来托管我们的公共端点。每当调用此端点时,它将向 OpenAI 请求一个冰淇淋公司的口号,然后将结果返回给用户。这听起来简单,几乎不需要创建一个公共端点,但这是我们构建一个真正智能应用程序的最后一步,利用了 OpenAI 的强大功能。
为此,我们将创建一个名为Cloud Functions的 GCP 资源,稍后将在教程的*工作原理…*部分进行探讨。
准备工作
确保您拥有 OpenAI 平台账户并且有可用的使用配额。如果没有,请参阅第一章中的设置 OpenAI Playground 环境教程。
此外,请确保您已创建了一个 GCP 账户。为此,请访问cloud.google.com/,然后从右上角选择开始免费使用,并按照页面上的指示进行操作。
您可能还需要提供一个计费资料,以便创建任何 GCP 资源。请注意,GCP 确实提供免费的层级,在本教程中,我们不会超出免费层级(因此,基本上,您不应该为任何费用付费)。
如果这是您第一次登录Google Cloud Platform,可能需要创建一个项目。登录后,从左上角选择选择项目,然后选择新建项目。提供项目名称后,点击创建。
本章中的下一个教程也有相同的要求。
如何操作…
- 导航至
console.cloud.google.com/。在页面顶部的搜索字段中,键入Cloud Functions并从下拉菜单中选择第一个选项,Cloud Functions。
图 5.2 – 下拉菜单中的云函数
-
从页面顶部选择创建函数。这将开始创建我们的自定义后端端点并启动配置步骤。
在配置页面中,填写以下步骤:
-
环境:从下拉菜单中选择第二代。
-
函数名称:由于我们正在创建一个生成公司标语的后端端点,函数名称将为slogan_creator。
-
区域:选择离您最近的环境位置。
-
在触发器菜单中,选择HTTPS。在身份验证子菜单中,选择允许未经身份验证的调用。我们需要勾选这个选项,因为我们将创建一个可以从前端服务访问的公共端点。
-
图 5.3 – Google Cloud Function 配置示例
-
选择页面底部的下一步按钮,然后进入代码部分。
-
从运行时下拉菜单中,选择Python 3.12。这确保我们的后端端点将使用 Python 编程语言进行编码。
-
对于入口点选项,输入create_slogan。这指的是在公共端点被访问并触发时调用的 Python 函数名称。
-
在左侧菜单中,您会看到两个文件:main.py和requirements.txt。选择requirements.txt文件。这将列出我们为使 Cloud Function 正常运行而需要安装的所有 Python 包。
-
在屏幕中央显示requirements.txt内容的地方,输入一行新内容并键入openai。这将确保安装最新的openai库包。您的屏幕应显示为图 5.4所示。
图 5.4 – requirements.txt 文件快照
-
在左侧菜单中,选择main.py。将以下代码复制并粘贴到屏幕中央(该文件的内容显示区域)。这些是公共端点在触发时运行的指令:
import functions_framework from openai import OpenAI @functions_framework.http def create_slogan(request): client = OpenAI(api_key = '<API Key here>') response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ { "role": "system", "content": "You are an AI assistant that creates one slogan based on company descriptions" }, { "role": "user", "content": "A company that sells ice cream" } ], temperature=1, max_tokens=256, top_p=1, frequency_penalty=0, presence_penalty=0 ) return response.choices[0].message.content如您所见,它仅调用 OpenAI 端点,请求聊天完成,然后将输出返回给用户。您还需要您的 OpenAI API 密钥。
-
接下来,通过点击页面底部的部署按钮来部署该函数。
-
等待函数完全部署,通常需要两分钟。你可以通过观察页面左上方的进度来验证函数是否已部署(如图 5.5所示)。一旦它变为绿色并打上勾,构建就成功了,你的函数已经部署。
图 5.5 – Cloud Function 部署页面
-
现在,让我们验证一下我们的函数是否正常工作。选择位于页面顶部、接近URL的位置的端点 URL。它通常是**https://[location]-[project-name].cloudfunctions.net/[function-name]**的形式。它也在图 5.5中有所突出显示。
-
这将打开一个新网页,触发我们的自定义公共端点,并返回一个聊天完成内容,在本例中是一个冰淇淋业务的标语。请注意,这是一个公共端点——它可以在您的计算机、手机或任何连接到互联网的设备上工作。
图 5.6 – Google Cloud Function 输出
它是如何工作的……
在这个食谱中,我们创建了一个公共端点。任何人都可以访问这个端点(包括你在未来食谱中的应用)。这个端点的逻辑很简单,之前也有提到:为一个销售冰淇淋的公司返回一个标语。新的地方在于,这是我们自己在 Google Cloud 中托管的公共端点,使用了 Cloud Function 资源。
请注意,我们使用了 Google Cloud Functions 的免费层,该层有一些限制,例如每月函数调用次数的上限、执行时间的限制以及计算资源的约束。然而,对于我们当前的目的,这些限制并不构成障碍,让我们能够有效地部署和测试函数,而无需产生费用。这种设置非常适合小规模应用,或者用于学习和实验,提供了一种以低成本方式理解云功能和无服务器架构的实用方法。
Cloud Function 中的代码
我们在 Cloud Function 中使用的代码应该很熟悉——它正是我们在第四章中第一个食谱中使用的代码,不过它被封装成了一个名为create_slogan的函数。这个代码仅仅是创建了一个 OpenAI 聊天完成,其中system和user消息分别是你是一个根据公司描述创建标语的 AI 助手和一个销售冰淇淋的公司。什么是 GCP Cloud Functions?
云函数,通常称为无服务器函数或函数即服务(FaaS),是无服务器计算的关键组成部分。在这种模型中,开发者编写并部署单个函数——小的、单一目的的代码块——这些函数在云中执行。这些函数通常是事件驱动的,意味着它们设计来响应特定的触发器或事件。
云函数有两个主要优势,使其非常适合创建我们的后端层和公共端点:
-
无需服务器管理:开发者无需配置或管理任何服务器。云服务提供商动态分配并管理基础设施,无需任何设置或维护。我们在不到 10 分钟内就创建好了它。
-
自动扩展:云函数会根据传入事件触发的数量自动扩展或缩减。这意味着它们可以处理每天一个请求,或者每秒处理成千上万的请求。在构建应用程序时,尤其重要——无论应用程序上只有一个用户,还是有数百万用户,你都希望它能正常工作。
然而,必须牢记的是,和任何其他工具一样,云函数也有其自身的优缺点。它们在此场景中主要被选择是因为在初期阶段,它们提供了经济且简单的设置优势。就像每个选择一样,权衡潜在的挑战与优势总是值得的。
GCP 提供免费的云函数服务,这意味着您可以免费设置它们(前提是它们的请求量低于 200 万次以及其他一些阈值(参见 cloud.google.com/functions/pricing),在这些配方中我们肯定不会超过这些限制)。
设置云函数
在设置云函数时,我们故意选择了几项配置选项。以下是对这些重要配置的解释:
-
触发器:此设置定义了如何调用您的云函数。简单来说,它指定了将导致您的函数(或函数中的代码)运行的事件或条件。通常有两个选项:
-
HTTP 触发器:该函数通过 HTTP 请求触发,这是我们在之前的配方中使用的协议,用来在 Postman 中调用 OpenAI API。如果您正在创建将由其他应用程序手动调用的公共端点,这会非常有用,这也是我们选择此选项的原因。
-
事件触发器:此选项允许您的函数响应来自云环境的事件(例如,Cloud Storage 存储桶中的更改)。
-
-
认证:此设置控制谁可以调用你的云函数。这是保护你的函数免受未经授权访问的重要部分。目前,我们选择了允许未经身份验证的调用,这意味着任何人都可以调用你的公共端点。尽管这不是最安全的选项,但它是最方便的选择,因为你不需要在 Postman 或任何其他需要调用 Google Cloud Function 的前端层中创建身份验证逻辑。需要注意的是,这不是最安全的选择,我们强烈不建议在实际应用中使用。此选项在此实例中被使用是出于方便考虑——避免在 Postman 或任何其他与 Google Cloud Function 交互的前端层中创建身份验证逻辑。
-
入口点:指的是在访问公共端点并触发时,Python 中被调用的函数名称。本质上,这就是在公共端点被调用时执行的函数或代码部分。
本质上,现在我们已经创建了一个调用 OpenAI API 的公共端点,我们不再需要担心将其托管在自己的计算机或服务器上。现在,任何人都可以全球访问它,甚至是一个智能应用(这是我在暗示的)。这非常重要,因为将其包装在公共端点中是构建智能应用的第一步。
扩展端点服务器以接受参数并返回数据
在上一个教程中,我们成功创建了一个云函数,当被调用时,它会返回一个冰淇淋公司的口号。虽然它作为云端服务有用,但我们希望修改这个函数,让它能够做两件事:
-
接受参数:我们需要修改函数,以便将输入参数作为 HTTP 请求的一部分进行接受。这意味着我们将能够创建一个云函数,该函数不仅返回冰淇淋业务的口号,还能返回任何我们提供描述的业务类型的口号。
-
构建输出结构:我们不想只是简单地输出聊天完成内容(在本例中为口号)。相反,我们希望处理数据并输出一个 JSON 对象,因为它在 web 应用中广泛使用且容易操作。
在这个教程中,我们将创建一个公共端点服务器,该服务器将接受一个名为business_description的参数,并以结构化的输出形式返回生成的口号。
如何实现…
-
访问
console.cloud.google.com/。在页面顶部的搜索框中输入Cloud Functions,然后从下拉菜单中选择名为Cloud Functions的第一个选项。 -
从页面顶部选择创建函数。这将开始创建我们的自定义后端端点,并开始配置步骤。
在配置页面,填写以下步骤:
-
环境:从下拉菜单中选择2nd gen。
-
函数 名称:slogan_creator_with_parameters。
-
区域:选择离你最近的环境位置,因为服务器离你越近,响应速度越快。
-
从Trigger菜单中选择HTTPS。在Authentication子菜单中,选择允许 无身份验证的调用。
-
-
点击页面底部的Next按钮,进入Code部分。
-
在Runtime下拉菜单中选择Python 3.12。这确保我们的后台端点将使用 Python 编程语言进行编码。
-
对于Entry point选项,输入create_slogan_with_parameters。这指的是当公共端点被访问并触发时,在 Python 中调用的函数名称。
-
在左侧菜单中,你将看到两个文件:main.py和requirements.txt。选择requirements.txt文件。这将列出所有需要安装的 Python 包,以便我们的云函数正常运行。
-
在屏幕中央显示requirements.txt内容的区域,输入新的一行并键入openai。这将确保安装最新的openai库包。
-
从左侧菜单中选择main.py。将以下代码复制并粘贴到屏幕中央(显示该文件内容的地方)。你仍然需要你的 OpenAI API 密钥。如你所见,代码与之前的示例非常相似,有两个关键的变化已被高亮显示:
import functions_framework from openai import OpenAI @functions_framework.http def create_slogan_with_parameters (request): request_json = request.get_json(silent=True) business_description = request_json['name'] client = OpenAI(api_key = '<API-key>') response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ { "role": "system", "content": "You are an AI assistant that creates one slogan based on company descriptions" }, { "role": "user", "content": business_description } ], temperature=1, max_tokens=256, top_p=1, frequency_penalty=0, presence_penalty=0 ) slogan = response.choices[0].message.content return {"slogan": slogan, "number_of_characters": len(slogan)} -
接下来,通过点击页面底部的Deploy按钮部署函数。等待函数完全部署,通常需要两分钟。记下云函数的 URL,通常形式为https://[location]-[project-name].cloudfunctions.net/[function-name]。
现在,我们可以测试我们的函数了。由于我们创建了一个接受 JSON 体作为输入的云函数,我们需要使用 Postman 向我们的公共端点发出 HTTP 请求。
-
在 Postman 中,通过点击左上方菜单栏的New按钮然后选择HTTP来创建一个新请求。
-
通过选择Method下拉菜单(默认为GET),将HTTP 请求类型从GET更改为POST。
-
将第 9 步中的云函数 URL 作为Endpoint输入。
-
在子菜单中选择Headers,并将以下键值对添加到下面的表格中:
| 键 | 值 |
|---|---|
Content-Type | application/json |
在子菜单中选择Body,然后选择raw作为请求类型。输入以下请求体。之后,点击Send:
# Request Body
{
"name": "A company that sells ice cream"
}
发送 HTTP 请求后,你应该会看到来自公共端点的以下响应。注意,你的消息值可能不同,但结构应保持一致:
# Response
{
"number_of_characters": 63,
"slogan": "\"Scoop up happiness with our irresistible ice cream creations!\""
}
它是如何工作的……
在这个示例中,我们创建了一个云函数,它能够接受输入并生成结构化输出。这很重要,因为当我们构建智能应用时,我们需要创建像这样的端点,应用程序依赖于它们。
为了实现这一点,我们对第一个示例中使用的 Python 代码进行了两次修改。
接受输入
云函数有一个对象,用于收集来自 HTTP Post 请求的输入。这个对象作为输入函数的参数,在本例中是 create_slogan_with_parameters (request),因此对象就是 request。这个对象存储了 HTTP 请求(包括其请求体和头部),并且可以通过代码转换为 JSON。我们随后可以解析 JSON 对象来获取特定的输入,在这种情况下是 name,并将其赋值给 business_description 变量。
通过这种方式,我们创建了一个云函数,能够从 HTTP 请求的请求体中接收并解析任何输入。
创建结构化输出
接下来,我们需要以结构化的形式(如 JSON)从云函数返回输出。使用 JSON 而不是字符串来获取输出有两个主要原因:
-
结构化的多个输出:JSON 允许我们以有序的方式构建多个数据点。你可以轻松地将不同的输出表示为单个 JSON 对象内的独立键值对。这种结构使得处理和访问云函数返回的多个数据变得简单。
-
嵌套和复杂数据:JSON 可以处理嵌套结构,意味着你可以在 JSON 对象内嵌套 JSON 对象。这个特性在你的云函数需要返回具有多个层次或层级信息的复杂数据时特别有用。
在代码中,我们通过定义一个包含两个元素的 JSON 对象来实现这一点:slogan 和 number of characters。通过这种方式,无论是谁或什么调用我们的端点,都能够轻松解析这些输出。
在这个示例中,我们通过创建一个端点,将用户自定义的可定制输入进行处理,调用 OpenAI API,然后返回可以解析的结构化 JSON 输出,迈出了构建智能应用的又一步。
从无代码应用程序调用用户创建的端点
在这个示例中,我们将通过创建一个应用程序(或前端用户界面)来完成开发过程,应用程序将调用前面示例中的公共端点。为了高效地完成此操作,我们将使用一个名为Bubble的无代码应用程序开发平台。
无代码应用程序开发 是一种无需传统编程的方式来创建软件应用程序。它使用图形界面和配置,而不是编写编程语言中的代码。这种方法使没有编程背景的人也能参与应用程序开发,民主化了创建和部署应用程序的能力。
像 Bubble 这样的平台是无代码开发环境的典型例子。Bubble 是一个流行的无代码开发平台,使个人和企业能够在无需传统编程的情况下创建 Web 应用程序。它使用户能够创建具有强大功能的 Web 应用程序,而无需理解或编写任何编程代码。
这种方法在小企业和初创公司中越来越流行,并且在企业环境中用于开发内部工具和原型。Bubble 还使用户能够创建调用公共端点和 API 的应用程序,我们将在本教程中利用这一功能。
在本教程中,我们将创建一个简单的 Bubble 应用,它调用我们创建的公共端点,该端点返回营销口号。
准备就绪
你必须创建一个 Bubble 账户才能按照本书的步骤操作。你可以通过访问 bubble.io 创建一个免费的 Bubble 账户。无需支付付费套餐—本书中使用的所有功能都可以通过免费套餐完成。
如何操作…
-
在你创建并登录 Bubble 账户后,前往
bubble.io/home/apps,然后选择屏幕右上角的 创建一个应用。 -
留空 从模板开始 选项。为你的应用取一个独特的名称,如 marketingslogan154。选择 从基础功能开始 按钮。
-
如果出现名为 跳过应用助手 的选项,请选择它,因为我们将手动逐步完成所有步骤。现在你应该能看到 Bubble UI Builder,这是一个空白的画布,左侧是菜单栏,如 图 5.7 所示。
图 5.7 – Bubble UI Builder 屏幕
- 我们要做的第一件事是设置端点/API 连接。选择左侧菜单中的 插件,然后选择 添加插件。
图 5.8 – 为我们的应用选择插件
-
通过选择 安装 按钮来安装 API 连接器 元素。这将使你的 Bubble 应用能够调用端点和 API。安装完成后,选择 完成。
-
之后,你应该能在 插件 页面上看到 API 连接器。选择 添加另一个 API 按钮。一个配置选项的集合将会出现。
-
现在,我们需要初始化我们的 API/端点连接。对于配置选项,请选择或输入以下内容。请注意,您可能需要选择位于
Content-Type和application/json旁边的展开按钮:-
正文 类型:JSON
-
正文:
{ "name": "A company that sells ice cream" }
您的屏幕应类似于图 5.9。
-
图 5.9 – API 连接器配置
-
选择页面底部附近的初始化调用按钮。如果您遇到500 错误,请检查前面的步骤,确保您的端点/API 可访问并且正常工作。有时,如果 GCP 服务器在您测试调用时很繁忙,您可能需要多次重复此步骤。
-
现在,您应该会看到一个名为返回值 – API 调用的屏幕。确保看到两行数据,并且每一行的数据类型都正确设置,如下所示(这些应该是默认值)。选择保存。
字符数 | 数字 |
|---|---|
slogan | text |
- 现在我们已经设置好 Bubble,接下来让我们添加一些元素。从左侧菜单中选择设计按钮。然后选择文本元素,并将其拖动到屏幕中央。此时,您应该看到该元素被高亮显示,并且右侧会显示该元素的属性菜单。
图 5.10 – Bubble UI 构建器中的文本元素
-
在属性菜单中,选择显示**...编辑我…的框,并选择插入** 动态数据。
-
在下拉菜单中,选择从外部 API 获取数据,左侧将弹出一个菜单。
图 5.11 – Bubble 中的文本菜单
- 从下拉菜单中,选择在第 7 步中创建的 API。在正文(JSON 对象)菜单中,确保它反映出第 7 步中的 JSON 数据。然后,选择文本框并选择slogan。
图 5.12 – Bubble 中的文本菜单
我们的无代码 Bubble 应用程序已经完成!
- 点击屏幕右上角的预览按钮,以打开我们刚刚创建的 Web 应用程序。
图 5.13 – Bubble 中的输出
正如您所见,我们现在已经创建了一个生成冰淇淋公司标语的 Web 应用程序。继续刷新屏幕,您将看到更多的标语。
注意
每次刷新屏幕时,您将使用 OpenAI API 的令牌,因此不宜连续刷新太多次。
它是如何工作的…
在这个步骤中,我们创建了一个前端应用程序,调用了我们在前一个步骤中设置的公共端点。这是使用 OpenAI API 创建智能应用程序的最终构建模块。我们也完全是使用无代码工具完成的。
Bubble HTTP 请求
这个方案的主要成就是能够从前端应用程序(如 Bubble)发出 HTTP 请求。大多数应用平台都可以发出外部 API 请求,使用传统编程语言(如 JavaScript)构建应用程序时,也可以如此操作。
在 Bubble 中,我们通过 API 连接器插件完成了这项工作,该插件简化了与外部 API 集成的过程。这个插件充当了 Bubble 与外部服务之间的桥梁,允许我们无缝地发送和接收数据。通过配置 API 连接器与适当的端点、身份验证和参数,我们能够扩展 Bubble 应用程序的功能,与其他 web 服务进行交互。
直接将 Bubble 连接到 OpenAI
值得注意的是,我们为什么必须创建自己的后台层端点,而不是直接连接到 OpenAI。为什么我们需要一个中间层?
-
安全问题:直接集成外部 API,特别是处理敏感数据或需要身份验证的 API,可能会带来安全风险。通过使用后台层,可以将敏感信息(如 OpenAI API 密钥或身份验证令牌)保密,避免在用户可能看到的客户端代码中暴露这些信息。
-
数据处理和缓存:中间层可以在将数据发送到前端之前进行处理、过滤或缓存。这可以优化性能,减少客户端负担,更有效地管理数据流。例如,我们在后台处理数据时,还会提取number_of_characters。
-
自定义逻辑实现:后台层允许实现一些在客户端可能无法处理或不高效的自定义逻辑。这包括数据转换、复杂计算或基于从 OpenAI 接收到的数据进行决策的过程。
总体来说,在本章中,我们迈出了重要的一步,向 OpenAI API 的分阶段部署和托管以及构建智能应用程序迈进。我们通过创建一个后台层,接收输入、处理并生成结构化输出,证明了我们可以从前端应用程序调用这个端点。