GPT3-探索指南-全-

GPT3 探索指南(全)

原文:zh.annas-archive.org/md5/e19ec4b9c1d08c12abd2983dace7ff20

译者:飞龙

协议:CC BY-NC-SA 4.0

序言

如果这本书是由人工智能写的呢?你会阅读吗?我希望会,因为其中的部分确实是由人工智能写的。是的,GPT-3 被用来创建这本书的部分内容。我知道这有点元,一本关于 GPT-3 的书被 GPT-3 写的。但创造内容是 GPT-3 的许多伟大用途之一。那又何妨呢?此外,对我来说,内容生成是最引起我的兴趣的用例之一。我想知道是否可以在我正在开发的产品中使用 GPT-3 自动化生成技术学习材料。

你可能也有自己对 GPT-3 感兴趣的特定原因。也许是出于求知欲。或者可能是因为你有一个你认为 GPT-3 可以实现的想法。你可能已经在网上看过 GPT-3 生成内容、编写代码、写诗或其他东西的演示,并且想知道 GPT-3 是否可以用于你的想法。如果是这样,那么这本书就是专门为你写的。

我写这本书的目标是为了提供一个实用的资源,帮助你尽快入门 GPT-3,而无需任何必要的技术背景。话虽如此,在我写这些文字的时候,GPT-3 仍然处于私有测试阶段。因此,每个人都在不断学习。但我确切学到的一件事是,GPT-3 的可能应用是广泛的,而且没有办法知道所有可能性,更不用说把它写进一本书中了。所以,我希望这本书使入门变得容易,但我也希望它只是你探索 探索 GPT-3 旅程的开始。

这本书适合谁

这本书适合任何对自然语言处理或学习 GPT-3 感兴趣的人,无论其是否具有技术背景。想要了解自然语言处理、人工智能和 GPT-3 的开发人员、产品经理、企业家和爱好者都会发现这本书很有用。只需基本的计算机技能就能充分利用这本书。虽然有现代编程语言的经验会有所帮助,但并非必需。提供的代码示例适合初学者,即使你是编写代码的新手也很容易理解。

这本书涵盖了哪些内容

第一章介绍 GPT-3 和 OpenAI API,是对 GPT-3 和 OpenAI API 的高级介绍。

第二章GPT-3 的应用和用例,概述了核心 GPT-3 的用例:文本生成、分类和语义搜索。

第三章使用 OpenAI Playground,是对 OpenAI Playground 和开发者门户的半深入介绍。

第四章使用 Postman 调用 OpenAI API,是介绍如何使用 Postman 调用 OpenAI API 的简介。

第五章在代码中调用 OpenAI API,是介绍如何使用 Node.js/JavaScript 和 Python 调用 OpenAI API 的简介。

第六章内容过滤,解释了如何实现内容过滤。

第七章生成和转换文本,包含了用于生成和转换文本的代码和提示示例。

第八章文本分类和分类,更详细地讨论了文本分类和 OpenAI API 分类端点。

第九章构建基于 GPT-3 的问答应用,讲解了如何构建一个功能齐全的基于 GPT-3 的网络知识库。

第十章使用 OpenAI 应用上线,讲解了 OpenAI 应用审查和批准流程,并讨论了为审查做准备的事项。

要充分利用本书

本书中的所有代码示例都是使用来自replit.com的基于 Web 的集成开发环境IDE)编写的。一个免费的 replit.com 账户就足以跟随示例。要使用 replit.com,只需一个现代的 web 浏览器和一个 replit.com 账户即可。该代码还在 macOS 上使用 Visual Studio Code 进行了测试,尽管它应该可以在任何代码编辑器和适当配置的操作系统上正常工作。代码示例提供了 Node.js/JavaScript 和 Python 两种版本。对于 Node.js,使用的是版本 12.16.1,对于 Python,使用的是版本 3.8.2。

本书中的所有代码示例都需要 OpenAI API 密钥和对 OpenAI API 的访问权限。您可以通过访问 https://openai.com/api 来申请对 OpenAI API 的访问权限。

如果您使用本书的数字版,我们建议您自己打字输入代码或通过 GitHub 存储库(链接在下一部分中可用)访问代码。这样做可以帮助您避免与复制和粘贴代码相关的潜在错误

下载彩色图片

我们还提供了一个 PDF 文件,其中包含了本书中使用的屏幕截图/图表的彩色图片。您可以在这里下载:https://static.packt-cdn.com/downloads/9781800563193_ColorImages.pdf。

使用的约定

本书中使用了许多文本约定。

文本中的代码:表示文本中的代码词,数据库表名,文件夹名,文件名,文件扩展名,路径名,虚拟 URL,用户输入和 Twitter 句柄。这里有一个例子:“然而,假设您不希望完成生成对话的人的一面,您希望使用标签AI:而不是Assistant:?”

代码块如下所示:

English: I do not speak Spanish Spanish: 

粗体:表示一个新术语,一个重要词,或屏幕上看到的词。例如,菜单或对话框中的单词在文本中出现如下所示。这里有一个例子:“每次单击 提交 按钮时”。

提示或重要说明

看起来像这样。

联系方式

我们始终欢迎读者的反馈。

customercare@packtpub.com

勘误: 尽管我们已尽一切努力确保内容的准确性,但错误确实会发生。如果您在本书中发现了错误,我们将不胜感激您向我们报告。请访问 www.packtpub.com/support/errata,选择您的书,点击勘误提交表单链接,并输入详细信息。

copyright@packt.com,并附上材料的链接。

如果您有兴趣成为作者:如果您在某个主题上有专业知识,并且对编写或贡献一本书感兴趣,请访问 authors.packtpub.com。

评论

请留下您的评论。一旦您阅读并使用了这本书,为什么不在您购买它的网站上留下一条评论呢?潜在的读者可以看到并使用您的公正意见来做出购买决定,我们在 Packt 可以了解您对我们产品的看法,而我们的作者可以看到您对他们的书的反馈。谢谢!

欲了解更多关于 Packt 的信息,请访问 packt.com。

第一部分:理解 GPT-3 和 OpenAI API

本部分的目标是向您提供关于 GPT-3 和 OpenAI API 的高层介绍,以及展示开始使用起来是多么容易。目标是通过有趣的例子吸引您,这些例子快速而简单地实现。

本部分包括以下章节:

  • 第一章介绍 GPT-3 和 OpenAI API

  • 第二章GPT-3 应用与使用案例

第一章:介绍 GPT-3 和 OpenAI API

关于生成式预训练变换器第 3 版GPT-3)的讨论始于 2020 年 6 月 11 日,由领先的人工智能AI)研究实验室 OpenAI 发布的一篇博客文章。该帖子以以下方式开始:

我们正在发布一个用于访问 OpenAI 开发的新 AI 模型的 API。与大多数专为一个用例设计的 AI 系统不同,该 API 今天提供了一个通用的“文本输入,文本输出”接口,允许用户在几乎任何英语语言任务上尝试它。

早期测试人员的在线演示很快就出现了——有些看起来太好以至于难以置信。GPT-3 正在撰写文章,写诗,回答问题,以栩栩如生的方式进行聊天,将文本从一种语言翻译为另一种语言,总结复杂的文件,甚至编写代码。这些演示令人印象深刻——这是我们以前从未见过的一般用途人工智能系统所做的事情——但同样令人印象深刻的是,许多演示是由在人工智能和机器学习ML)方面具有有限或没有正式背景的人创造的。GPT-3 提高了标准,不仅在技术方面,还在人工智能可访问性方面。

GPT-3 是一个通用的语言处理 AI 模型,几乎任何人都可以在几分钟内理解并开始使用。您不需要计算机科学的哲学博士PhD)——甚至不需要知道如何编写代码。实际上,您开始所需的一切都在这本书中。在本章中,我们将从以下主题开始:

  • GPT-3 简介

  • 使 NLP 大众化

  • 理解提示、完成和标记

  • 介绍达芬奇、巴贝奇、居里和艾达

  • 理解 GPT-3 的风险

技术要求

本章需要您访问OpenAI 应用程序编程接口API)。您可以通过访问openapi.com注册 API 访问权限。

GPT-3 简介

简言之,GPT-3 是一个语言模型:一个计算一系列单词的概率分布的统计模型。换句话说,GPT-3 是一个系统,当输入文本时,猜测接下来的文本是什么。

现在,在我们更深入地了解 GPT-3 是什么之前,让我们对自然语言处理NLP)进行简要介绍(或复习)。

简化自然语言处理(NLP)

NLP 是人工智能的一个分支,它专注于利用自然人类语言进行各种计算应用。NLP 是一个广泛的类别,涵盖了许多不同类型的语言处理任务,包括情感分析、语音识别、机器翻译、文本生成和文本摘要等。

在自然语言处理中,语言模型用于计算一系列单词的概率分布。语言模型的重要性在于人类语言的复杂和微妙的特性。例如,pay in fullpainfultee timeteatime 听起来相似,但意思完全不同。she's on fire 这样的表达可能是字面的,也可能是比喻的;而 biglarge 这样的词在某些情况下可以互换使用,但在其他情况下不能——例如,用 big 来指代一个年长的兄弟就不会有使用 large 的含义。因此,语言模型用于处理这种复杂性,但这说起来容易做起来难。

尽管人们对词义和适当的使用似乎很容易理解,但自然语言处理任务对机器来说可能是具有挑战性的。这对于更复杂的语言处理任务尤为真实,例如识别讽刺或挖苦——甚至有时连人类本身都会感到困难。

如今,对于特定的自然语言处理任务来说,最好的技术方法取决于任务本身。因此,大多数表现最佳的 最先进SOTA)自然语言处理系统都是针对单一目的或狭窄范围任务进行了细化调整的专门系统。然而,理想情况下,一个单一系统应该能够成功地处理任何自然语言处理任务。这就是 GPT-3 的目标:提供一个通用的自然语言处理系统。因此,尽管今天表现最佳的自然语言处理系统往往是专门的、针对特定任务定制的系统,GPT-3 在多个常见自然语言处理任务中达到了 SOTA 表现,展现了未来通用自然语言处理系统能够为任何自然语言处理任务提供 SOTA 表现的潜力。

GPT-3 到底是什么?

尽管 GPT-3 是一种通用的自然语言处理系统,但它实际上只做了一件事:基于提供的文本预测接下来会出现什么。但事实证明,通过合适的架构和足够的数据,这“一件事”能够处理惊人的一系列语言处理任务。

GPT-3 是来自 OpenAI 的 GPT 语言模型的第三个版本。因此,尽管它在 2020 年夏天开始变得流行,但 GPT 的第一个版本是在 2 年前宣布的,接下来的版本 GPT-2 是在 2019 年 2 月宣布的。但即使 GPT-3 是第三个版本,系统的设计和架构与 GPT-2 没有太大的变化。然而,有一个很大的区别,那就是用于训练的数据集的大小。

GPT-3 是使用从互联网、书籍和其他来源获取的文本组成的海量数据集进行训练的,包含大约 570 亿个单词和 1750 亿个参数。这比 GPT-2 和其他最大规模的语言模型大 10 倍。为了让模型的大小有所了解,一个普通人一生中可能会读、写、说和听到超过 10 亿个单词。因此,GPT-3 在估计处理的单词数量上约是大多数人的 57 倍。

GPT-3 语言模型庞大而庞大,因此它不是你可以在笔记本电脑上下载和摸索的东西。但即使你可以(事实上你不可以因为它无法下载),每次构建模型都需要数百万美元的计算资源。如果你必须依靠自己的计算资源来使用它,这将使 GPT-3 对大多数小公司和几乎所有个人都不可及。幸运的是,你不必这样做。OpenAI 通过一个既经济又易于使用的 API 提供 GPT-3,所以,任何人都可以使用一些有史以来最先进的人工智能!

使自然语言处理民主化

任何人都可以通过访问 OpenAI API 使用 GPT-3。API 是一个通用的文本输入,文本输出接口,几乎可以用于任何语言任务。要使用 API,你只需输入文本,然后得到一个文本回复。任务可能是情感分析、写一篇文章、回答一个问题或总结一篇文档。对于 API 来说,这并不重要 —— 它都是以相同的方式完成的,这使得即使对非程序员来说,使用 API 也变得非常容易。

你传入的文本被称为提示,返回的文本称为完成。提示被 GPT-3 用于确定如何最好地完成任务。在最简单的情况下,提示可以提供一些词语作为开始。例如,如果提示是 如果今天是星期一,明天是,GPT-3 可能会回复 星期二,以及一些额外的文本,例如 如果今天是星期二,明天是星期三,依此类推。这意味着你从 GPT-3 中得到的取决于你发送给它的内容。

你可能会猜到,完成的质量在很大程度上取决于提示。GPT-3 使用提示中的所有文本来帮助生成最相关的完成。每个词语以及提示的结构方式都有助于改善语言模型的预测结果。因此,理解如何编写和测试提示是解锁 GPT-3 真正潜力的关键

理解提示、完成和标记

实际上,任何文本都可以用作提示 —— 输入一些文本,得到一些文本返回。然而,尽管看到 GPT-3 如何处理随机字符串可能很有趣,但真正的力量来自于理解如何编写有效的提示。

提示

提示是让 GPT-3 做你想要的事情的方式。这就像编程,但用的是简单的英语。所以,你必须知道自己想要实现什么,但不是编写代码,而是使用单词和纯文本。

当你编写提示时,要记住的主要事情是,GPT-3 正试图弄清楚接下来应该出现的文本,因此包括诸如说明和示例等内容提供了上下文,帮助模型找出最佳完成的方式。此外,质量很重要 —— 例如,拼写、不清晰的文本以及提供的示例数量都会影响完成的质量。

另一个关键考虑因素是提示大小。虽然提示可以是任何文本,但提示和生成的完成必须少于 2048 个令牌。我们将稍后在本章中讨论令牌,但大致相当于 1500 个单词。

因此,提示文本可以是任何文本,没有像编写代码时必须遵循的硬性规则。但是,有一些指导原则可以帮助您在获得最佳结果方面构建提示文本的结构。

不同类型的提示

我们将在本书中深入探讨提示写作,但让我们从不同的提示类型开始。以下是概述:

  • 零次提示

  • 单次提示

  • 少数提示

零次提示

一个Subject::

Write an email to my friend Jay from me Steve thanking him for covering my shift this past Friday. Tell him to let me know if I can ever return the favor.
Subject:

以下屏幕截图来自一个名为Playground的基于 Web 的测试工具。我们将在 Chapter 2, GPT-3 Applications and Use Cases,Chapter 3, Working with the OpenAI Playground 中更多地讨论 Playground,但现在我们将其用作显示由于前面的提示而生成的完成的演示。请注意,原始提示文本为粗体,完成显示为普通文本:

![Figure 1.1 – Zero-shot prompt example

](img / B16854_01_001.jpg)

图 1.1-零次提示示例

因此,零次提示只是一些词或短描述,没有任何示例的任务。有时候,这就是 GPT-3 完成任务所需要的全部。其他时候,您可能需要包括一个或多个示例。提供单个示例的提示称为单次提示。

单次提示

单次提示提供一个示例,GPT-3 可以利用它来学习如何最好地完成任务。以下是一个提供任务描述(第一行)和单个示例(第二行)的单次提示的示例:

A list of actors in the movie Star Wars 
1\. Mark Hamill: Luke Skywalker

仅凭描述和一个示例,GPT-3 就会了解任务是什么以及应该完成任务。在此示例中,任务是创建《星球大战》电影演员的列表。以下屏幕截图显示了此提示生成的完成:

![Figure 1.2 – One-shot prompt example

](img / B16854_01_002.jpg)

图 1.2-单次提示示例

单次提示适用于列表和通常理解的模式。但有时您需要多个例子。在这种情况下,您将使用几次提示。

少数提示

几次提示提供多个例子-通常为 10 到 100 个。多个示例可用于显示 GPT-3 应该继续完成的模式。少数提示和更多示例可能会增加完成的质量,因为提示为 GPT-3 提供了更多的学习机会。

以下是生成模拟对话的几次提示的示例。请注意,这些示例提供了来回对话,提供了可能在对话中说的内容:

This is a conversation between Steve, the author of the book Exploring GPT-3 and someone who is reading the book.
Reader: Why did you decide to write the book?
Steve: Because I'm super fascinated by GPT-3 and emerging technology in general.
Reader: What will I learn from this book?
Steve: The book provides an introduction to GPT-3 from OpenAI. You'll learn what GPT-3 is and how to get started using it.
Reader: Do I need to be a coder to follow along?
Steve: No. Even if you've never written a line of code before, you'll be able to follow along just fine.
Reader: 

在下面的截图中,您可以看到 GPT-3 继续了在提示中提供的示例中启动的模拟对话:

图 1.3 – 少量示例提示

图 1.3 – 少量示例提示

现在您了解了不同的提示类型,让我们来看一些提示示例。

提示示例

OpenAI API 可以处理各种任务。可能性范围从生成原始故事到执行复杂的文本分析,以及其中的所有内容。为了熟悉 GPT-3 可以执行的任务类型,OpenAI 提供了许多提示示例。您可以在 Playground 和 OpenAI 文档中找到示例提示。

在 Playground 中,这些示例被称为预设。再次强调,我们将在第三章与 OpenAI Playground 一起工作中详细介绍 Playground,但下面的截图显示了一些可用的预设:

图 1.4 – 预设

图 1.4 – 预设

示例提示也可以在 OpenAI 文档中找到。OpenAI 文档非常出色,包含许多优秀的提示示例,并提供了链接以在 Playground 中打开和测试它们。下面的截图显示了来自 OpenAI 文档的示例提示。请注意提示示例下方的在 Playground 中打开此示例链接。您可以使用该链接在 Playground 中打开提示:

图 1.5 – OpenAI 文档提供提示示例

图 1.5 – OpenAI 文档提供提示示例

现在您了解了提示,让我们谈谈 GPT-3 如何使用它们来生成完成。

完成

再次强调,完成指的是生成并返回的文本,作为提供的提示/输入的结果。您还会记得,GPT-3 并没有专门训练来执行任何一种类型的自然语言处理任务——它是一个通用的语言处理系统。然而,GPT-3 可以通过提示来展示如何完成给定任务。这称为元学习。

元学习

大多数自然语言处理系统,在训练基础的机器学习模型时,使用的数据是提供的。所以,要改进给定任务的结果,必须更新底层训练,并构建新版本的模型。GPT-3 的工作方式不同,因为它没有针对任何特定任务进行训练。相反,它被设计为识别提示文本中的模式,并使用底层的通用模型继续模式。这种方法被称为元学习,因为提示被用来教导 GPT-3 如何生成最佳完成,而无需重新训练。因此,不同的提示类型(零次、一次和少次)可以用于为不同类型的任务编程 GPT-3,你可以在提示中提供大量指令——最多 2,048 个令牌。好的——现在是谈论令牌的好时机。

令牌

当提示被发送到 GPT-3 时,它会被分解为令牌。令牌是单词或更常见的单词部分的数值表示。数字被用作令牌而不是单词或句子,因为它们可以更有效地处理。这使得 GPT-3 能够处理相对较大的文本量。尽管如此,正如你所学到的,仍然存在 2,048 个令牌的限制(约~1,500 个单词),用于组合提示和生成的完成结果。

你可以通过估算提示和生成的完成结果中将使用的令牌数量来保持在令牌限制以下。平均而言,对于英文单词,每四个字符代表一个令牌。所以,只需将提示中的字符数加上响应长度,然后除以四即可。这将给你一个大致的所需令牌数量。如果你想要了解完成一系列任务所需的令牌数量,这非常有帮助。

另一种获取令牌计数的方法是使用 Playground 中的令牌计数指示器。这位于大型文本输入框的正下方,位于右下角。以下屏幕截图中放大的区域显示了令牌计数。如果你将鼠标悬停在数字上,你还将看到完成后的总计数。对于我们的示例,提示Do or do not. There is no try.—来自尤达大师的智慧—使用了10个令牌,完成后的总计数为74个令牌:

图 1.6 – 令牌计数

图 1.6 – 令牌计数

虽然理解令牌对于保持在 2,048 个令牌限制以下很重要,但它们也很重要,因为令牌是 OpenAI 用作使用费基础的东西。你的账户中可以获得整体令牌使用情况报告,网址为beta.openai.com/account/usage。下面的屏幕截图显示了一个示例使用报告。我们将在第三章使用 OpenAI Playground中进一步讨论这个:

图 1.7 – 使用统计

图 1.7 – 使用统计

除了令牌使用外,影响使用 GPT-3 的成本的另一件事是你选择用来处理提示的引擎。引擎是指将要使用的语言模型。引擎之间的主要区别在于相关模型的大小。较大的模型可以完成更复杂的任务,但较小的模型更高效。因此,根据任务的复杂性,你可以通过使用较小的模型显着降低成本。以下屏幕截图显示了发布时的模型定价。正如你所见,成本差异可能很大:

图 1.8 – 模型定价

图 1.8 – 模型定价

因此,每个引擎或模型的成本都不同,但你需要的那个取决于你正在执行的任务。接下来我们来看看不同的引擎选项。

介绍达芬奇、巴贝奇、居里和艾达

用于训练 GPT-3 的庞大数据集是其如此强大的主要原因。然而,当有必要时,更大并不总是更好——更多的能力会带来成本。出于这些原因,OpenAI 提供了多个可供选择的模型。今天有四个主要模型可用,以及一个用于内容过滤和指令模型的模型。

可用的模型或引擎(也称为)分别命名为达芬奇巴贝奇居里艾达。在这四个中,达芬奇是最大且最强大的。 达芬奇可以执行任何其他引擎可以执行的任务。 巴贝奇是下一个最强大的引擎,可以做任何居里艾达可以做的事情。 艾达是最不强大但性能最佳且成本最低的引擎。

当你刚开始并且在初步测试新提示时,通常会想从达芬奇开始,然后尝试艾达巴贝奇居里,看看它们中的哪一个可以更快或更具成本效益地完成任务。以下是每个引擎的概述以及可能最适合每个引擎的任务类型。但是,请记住,你需要测试。尽管较小的引擎可能没有受过太多数据的训练,但它们仍然是通用模型。

达芬奇

达芬奇是最强大的模型,可以做任何其他模型能做的事情,而且更多——通常只需更少的指令。 达芬奇能够解决逻辑问题,确定因果关系,理解文本意图,生成创意内容,解释人物动机,并处理复杂的总结任务。

居里

居里试图平衡力量和速度。它可以做任何艾达巴贝奇可以做的事情,但它还能处理更复杂的分类任务和更细致的任务,如总结、情感分析、聊天机器人应用和问答。

巴贝奇

BabbageAda更有能力,但并不那么高效。它可以执行与Ada相同的所有任务,但还可以处理更复杂的分类任务,并且非常适合语义搜索任务,以确定文档与搜索查询匹配程度。

Ada

Ada通常是最快的模型,成本最低。它最适合于较少细微差别的任务,例如解析文本、重新格式化文本和更简单的分类任务。您提供给Ada的上下文越多,它的表现就越好。

内容过滤模型

为了防止不当补全,OpenAI 提供了一个内容过滤模型,该模型经过微调,以识别可能含有冒犯性或伤人的言语。

指导模型

这些模型是在DavinciCurie模型的基础上构建的。指导模型被调整过,以使得更容易告诉 API 想让它做什么。清晰的指示通常比相关的核心模型产生更好的结果。

时间的一瞥

关于所有引擎的最后一点要牢记的是,它们都是一个时间的一瞥,也就是说用于训练它们的数据截止于构建模型的日期。因此,GPT-3 并非使用最新的甚至最新的数据——它可能是几周甚至几个月之前的数据。OpenAI 打算在未来增加更多的持续训练,但今天这是一个需要考虑的因素。

所有的 GPT-3 模型都非常强大,能够生成与人类编写的文本几乎无法区分的文本。这对各种潜在应用都具有巨大的潜力。在大多数情况下,这是一件好事。但是,并非所有潜在的用例都是好事。

了解 GPT-3 风险

GPT-3 是一项了不起的技术,具有许多实际和有价值的潜在应用。但通常情况下,强大技术的潜力就意味着风险。对 GPT-3 而言,其中一些风险包括不当的结果和潜在的恶意用途。

不当或冒犯性的结果

GPT-3 文本生成得如此出色,以至于看起来像是它意识到自己在说什么。但其实不是这样的。它是一个具有出色语言模型的 AI 系统-绝对不会有意识,所以从来不会在说出伤人或不当的话语。

但是,理解 GPT-3 有时会生成冒犯性文本,并考虑在使用 GPT 或向他人公开 GPT-3 结果时需要理解这一点。特别是对于可能被儿童看到的结果。我们将在第六章中更详细地讨论这一点,内容过滤

恶意使用的潜力

想象一下,GPT-3 可能被用于恶意或有害用途并不难。OpenAI 甚至描述了 GPT-3 可能被“武器化”用于误导性宣传或制造虚假产品评论。但 OpenAI 的宣称使命是“确保人工通用智能造福于人类”,因此,追求该使命包括采取负责任的措施,防止他们的 AI 被用于错误的目的。因此,OpenAI 为所有使用 GPT-3 或 OpenAI API 的应用程序实施了一个应用批准流程。

但作为应用程序开发人员,我们也需要考虑这一点。当我们构建使用 GPT-3 的应用程序时,我们需要考虑应用程序可能被用于错误的目的,并采取必要的措施来防止它。我们将在第十章中更详细地讨论这个问题,OpenAI 动力应用的实时运行

摘要

在本章中,您了解到 GPT-3 是一个用于处理几乎任何语言处理任务的通用语言模型。您了解了 GPT-3 的高级工作原理,以及关键术语和概念。我们介绍了可用的模型,并讨论了所有 GPT-3 应用程序必须经过批准流程才能防止潜在的不适当或有害结果。

在接下来的章节中,我们将讨论使用 GPT-3 不同的方式,并查看特定的 GPT-3 用例示例。

第二章:GPT-3 的应用和用例

GPT-3 被设计为通用语言处理模型,这意味着它并未专门针对任何一种语言处理任务进行训练。因此,可能的应用包括几乎任何您能想象到的自然语言处理任务,以及可能还有一些尚未被想象到的任务。新的 GPT-3 用例不断被发现,这对很多用户来说是其魅力的一大部分。当然,它在某些任务上表现更好,但仍然有数百种可能的用途。在本章中,我们将分解一些通用用例,并看看如何开始测试自己的提示。

本章的主题如下:

  • 理解通用 GPT-3 用例

  • 介绍游乐场

  • 处理文本生成和分类任务

  • 理解语义搜索

技术要求

本章需要您访问 OpenAI API。您可以通过访问openapi.com注册 API 访问权限。

理解通用 GPT-3 用例

在上一章中,您了解到 OpenAI API 是一个文本输入,文本输出接口。因此,它总是对文本输入(称为提示)返回一个文本响应(称为完成)。完成可能是生成新文本,分类文本,或为语义搜索提供结果。GPT-3 的通用性意味着它可以用于几乎任何语言处理任务。为了让我们集中精力,我们将看一下以下常见用例:文本生成,分类和语义搜索。

  • 文本生成:文本生成任务是创建新的原创文本内容的任务。例如包括文章写作和聊天机器人。

  • 分类:分类任务标记或分类文本。分类任务的例子包括情感分析和内容过滤。

  • 语义搜索:语义搜索任务将查询与语义相关的文档进行匹配。例如,查询可能是一个问题,会匹配一个或多个提供答案的文档。

为了说明不同的用例,我们将使用 OpenAI Playground。因此,在我们深入研究不同的示例用例之前,让我们先熟悉一下游乐场。

介绍游乐场

要开始使用 GPT-3,OpenAI 提供了游乐场。游乐场是一个基于 Web 的工具,它可以方便地测试提示,并熟悉 API 的工作原理。几乎你可以通过调用 API 来做的每件事情(我们稍后将更详细地讨论),你也可以在游乐场中完成。最重要的是,通过游乐场,你可以开始使用 GPT-3 而不需要编写一行代码-你只需提供一个用简单英语编写的文本输入(提示)。

开始使用游乐场

要访问游乐场,您需要登录openai.com。在验证登录后,您将能够从主菜单中导航到游乐场。

游乐场非常简单易用。主要由一个大文本输入组成。您只需将文本输入到大文本输入框中,然后单击提交按钮即可开始测试 GPT-3。

单击提交按钮后,您将看到原始输入文本之后添加了额外的文本 – 这是由 GPT-3 生成的完成文本。

每次单击提交按钮后,GPT-3 将在文本输入框中附加一个附加的完成。附加的完成使用您的原始文本以及先前的完成作为下一个完成的提示。

以下屏幕截图显示了具有初始提示文本的游乐场:如果今天是星期一,明天就是。您会注意到原始提示文本以粗体显示,而完成文本则以普通文本显示。在此示例中,单击提交按钮多次以说明每个完成是如何在上一个完成的基础上构建的:

图 2.1 – 游乐场窗口

图 2.1 – 游乐场窗口

除了用于提示和完成文本的大文本输入外,游乐场还允许您指定各种 API 设置,这些设置可以在 GPT-3 处理提示时提供一些控制。我们稍后将更详细地讨论这些设置,但是如果您查看图 2.1中的屏幕截图,您将看到一个响应长度设置。这是将返回的响应的长度。因此,每次单击提交按钮时,将向文本框添加一个新的具有该长度的响应。

再次,我们稍后将更详细地介绍所有设置。目前,这是每个设置所做的快速介绍:

  • 引擎:将要使用的语言模型

  • 响应长度:包含在完成中的文本量

  • 温度:控制结果的随机性

  • Top P:用于控制随机性的温度的替代品

  • 频率惩罚:减少模型重复同一行的可能性

  • 存在惩罚:增加模型谈论新主题的可能性

  • 最佳选择:仅返回n个完成中的最佳一个

  • 停止序列:用于结束完成的一系列字符

  • 注入起始文本:将包含在提示之前的文本

  • 注入重新启动文本:将包含在完成后的文本

  • 显示概率:显示完成中每个单词/标记的权重

熟悉游乐场就是开始使用 GPT-3 所需的一切。从那里,您可以开始尝试如何使用提示来编程GPT-3 来处理不同类型的语言处理任务,例如文本生成和分类任务。

现在我们已经看到了如何开始使用游乐场,让我们再学习一些关于文本生成和分类任务的知识。

处理文本生成和分类任务

文本生成和文本分类是自然语言处理任务的两个常见类别。每个类别都涵盖了许多 GPT-3 处理得非常出色的潜在用例。让我们看看其中一些,从文本生成用例开始。

文本生成

关于 GPT-3 可以做的所有事情中,文本生成是它的超能力。文本生成有很多潜在的用例,所以我们将进一步将文本生成分为三个子主题:生成文本、总结文本和转换文本。

生成文本

GPT-3 能够生成通常与人工书写的文本难以区分的原始文本内容。这可以用于各种应用,从创造网页内容到头脑风暴、对话应用、诗歌、歌词创作、写作编码和创建数据列表。让我们看一些例子。

内容创建

内容创建是 GPT-3 所能做的最酷的事情之一。有了正确的提示,GPT-3 可以创建文章、博客文章或社交媒体内容。下面的截图显示了一个提示的结果,引导 GPT-3 创建首次购房者的建议清单。然而,这种通用方法可以用于创建几乎任何主题的内容:

图 2.2 – 文本生成示例 – 首次购房者的建议

图 2.2 – 文本生成示例 – 首次购房者的建议

再次,你可以使用 GPT-3 来创建几乎任何主题的列表,因此有很多可能性。另一个很好的示例用例是创意生成。

创意生成

GPT-3 还可以是头脑风暴的一个好工具。以下提示和随后的截图显示了 GPT-3 被用于生成 3D 打印项目创意的制造者日活动。当然,这也可以是几乎任何事情的想法清单:

Maker day 3D printer project ideas 
1\. GoPro Mount A mount for a GoPro camera that mounts the camera on a mountain bike 
2.

结果显示在以下截图中:

图 2.3 – 文本生成示例 – 3D 打印项目创意

图 2.3 – 文本生成示例 – 3D 打印项目创意

图 2.3中的粗体文本是提供的提示,常规文本是由 GPT-3 生成的。很酷,对吧?这里还有另一个很酷的例子——对话应用。

对话应用

对话应用也是 GPT-3 的一个潜在用例,例如在聊天机器人、IVR 和语音助手中。下面的文本可以用来提示 GPT-3 模拟 AI 支持助手与客户之间的对话:

The following is a conversation with a customer support AI assistant. The assistant is helpful, creative, clever, and very friendly. 
Customer: Hello, can you help me?
AI: I can sure try. I'm an AI support assistant and I'm here to help!
Customer:

前面提示的结果显示在以下截图中。在这种情况下,GPT-3 生成了对话的两端,但在现实世界的应用中,对话的用户端会来自实际的客户:

图 2.4 – 文本生成示例 – 客服 AI 助手

图 2.4 – 文本生成示例 – 客服 AI 助手

您可以使用多种技术来帮助引导 GPT-3 如何作出回应。例如,在图 2.4中,您会注意到提示包括 The assistant is helpful creative, clever, and very friendly - 这指导了 GPT-3 关于回应的整体风格和语调。我们将在接下来的章节中更详细地讨论这一点,但现在,让我们继续并看看如何使用 GPT-3 生成列表。

列表生成

以下截图显示了 GPT-3 正在用于创建一份公司及其所属类别的列表。您可以从提示中看到,它正在继续之前开始的模式。所以,您可以用这种方式生成几乎任何列表:

The following is a list of companies and the categories they fall into
Cisco – Technology, Networking, Enterprise Software
AT&T – Telecom, Technology, Conglomerate
United Airlines – Aviation, Transportation
Nvidia – Technology, Computing, Semiconductors

上一个提示的结果如下截图所示:

图 2.5 – 文本生成示例 – 列表生成

图 2.5 – 文本生成示例 – 列表生成

图 2.5中,您会注意到不仅添加了更多公司到列表中,GPT-3 也能够准确地按行业对公司进行分类。记住,GPT-3 并不是从数据库中提取这些信息 - 而是生成它!但令人印象深刻的是,GPT-3 还能完成更复杂的生成任务。例如,在下一个示例中,我们将看看如何使用 GPT-3 生成一份测验。

测验生成

GPT-3 也能够生成测验。例如,下面的提示可以用于编制测试问题和可能的答案,以测试学生识别押韵单词的能力:

words that rhyme have similar sounding endings 
q: what rhymes with "cat" 
a: bat, hat, mat 
q: what rhymes with "small" 
a: tall, wall, call 
q: what rhymes with "pig" 
a: big, dig, fig 
q:

以下截图显示了 GT-3 从先前提示生成的完成状态:

图 2.6 – 文本生成示例 – 测验生成

图 2.6 – 文本生成示例 – 测验生成

内容创建,创意生成,对话应用程序,创建列表和生成测验只是可能文本生成用例中的一小部分。但文本生成不仅仅是关于创建新内容;还可以用于其他用例,如总结现有内容。

总结文本

除了创作新的原始文本,您还可以使用 GPT-3 创建文档摘要。有多种方法可以用于总结文本。您可以使用基本摘要、一句话总结、年级调整的摘要,或者通过从文档中提取关键点进行总结。让我们快速看一下每种方法。

基本摘要

创建摘要的最简单方法就是在想要总结的文本后加上tl;dr:。这将提示 GPT-3 总结前面的文本。在每种情况下这并不是一种可靠的总结方法,但对许多情况来说都很有效。例如,下面的提示提供了有关量子力学的文本,该文本是从 en.wikipedia.org/wiki/Quantum_mechanics 复制的:

Quantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles.[2]:1.1 It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science. 
Classical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.[3] 
tl;dr:

上一个提示的结果如图 2.7所示:

图 2.7 – 文本生成示例 – tl;dr:摘要

图 2.7 – 文本生成示例 – tl;dr:摘要

您会注意到原始文本由三段组成,但生成的摘要只有几句话。您还可以指示 GPT-3 将文本总结为一句话。

单句摘要

另一种总结文本的方法是在您想总结的文本后面添加 单句摘要:。这个与将 停止序列 设置为句号一起,将生成提供文本的单句摘要。

以下提示将创建一个单句摘要,摘自位于 beta.openai.com/terms-of-use 的 OpenAI 使用条款页面的段落:

(b) Ownership. As between you and OpenAI, we and our affiliates own all rights, title, and interest in and to the APIs, Content, and Developer Documentation and all associated elements, components, and executables. Subject to the foregoing, you own all rights, title, and interest in and to your Application. You have no right to distribute or allow access to the stand-alone APIs. Except as expressly provided in these Terms, neither party grants, nor shall the other party acquire, any right, title or interest (including any implied license) in or to any property of the first party or its affiliates under these Terms. All rights not expressly granted in these Terms are withheld. 
one-sentence summary:

以下截图显示了前述单句摘要提示的结果:

图 2.8 – 文本生成示例 – 单句摘要

图 2.8 – 文本生成示例 – 单句摘要

根据您要总结的文本,一个单句可以非常有帮助,以简化内容。另一种简化内容的方法是用更简单的文字重新书写它。这可以通过年级摘要来完成。

年级摘要

要用适合某个年龄段的语言总结文本,您可以使用年级摘要。这可以通过在要总结的文本后面跟上类似以下示例提示中的最后一句话来完成。在这个例子中,我们使用了从 en.wikipedia.org/wiki/Milky_Way 复制的文本:

The Milky Way[a] is the galaxy that contains our Solar System, with the name describing the galaxy's appearance from Earth: a hazy band of light seen in the night sky formed from stars that cannot be individually distinguished by the naked eye. The term Milky Way is a translation of the Latin via lactea, from the Greek γαλακτικός κύκλος (galaktikos kýklos, "milky circle").[19][20][21] From Earth, the Milky Way appears as a band because its disk-shaped structure is viewed from within. Galileo Galilei first resolved the band of light into individual stars with his telescope in 1610\. Until the early 1920s, most astronomers thought that the Milky Way contained all the stars in the Universe.[22] Following the 1920 Great Debate between the astronomers Harlow Shapley and Heber Curtis,[23] observations by Edwin Hubble showed that the Milky Way is just one of many galaxies. The Milky Way is a barred spiral galaxy with an estimated visible diameter of 150-200,000 light-years,[9][24][25] an increase from traditional estimates of 100,000 light-years. Recent simulations suggest that a dark matter disk, also containing some visible stars, may extend up to a diameter of almost 2 million light-years.[11][12] 
I rephrased this in plain language that a third grader could understand.

在下面的截图中,您可以看到之前提示的结果:

图 2.9 – 文本生成示例 – 年级摘要

图 2.9 – 文本生成示例 – 年级摘要

请注意 图 2.9 中显示的摘要以一种可能被三年级学生理解的方式书写。在这种情况下,GPT-3 正在(以某种方式)为年轻读者翻译文本。但您也可以使用 GPT-3 将文本翻译成不同的语言。

转换文本

您还可以使用 GPT-3 转换文本,例如,从一种语言到另一种语言,或者从英语到其他内容,比如表情符号或软件代码。我们先来看一个语言翻译的例子。

翻译

在下面的截图中,GPT-3 正被用于将英语翻译成法语。这是一个在 Playground 中提供的预设;我们将在下一章中更多地讨论预设:

图 2.10 – 文本生成示例 – 从英语翻译成法语的示例

图 2.10 – 文本生成示例 – 从英语翻译成法语

你可以在 图 2.10 中看到一些翻译示例被用在了提示中。这对一些语言翻译任务是有帮助的,但对于许多简单的翻译来说,你甚至不需要示例。例如,以下提示很可能会用正确的翻译完成:

English: I do not speak Spanish 
Spanish:

语言翻译确实令人印象深刻。但如果你想要在英语和除了另一种自然语言以外的其他东西之间进行翻译呢?例如,将英语转换为表情符号文本?

转换

这是 OpenAI 提供的另一个例子。在这个例子中,提示用于将电影名称转换为表情符号形式。这样做是因为表情符号只是文本字符,所以它们是 GPT-3 训练数据的一部分。注意一些表情符号版本不仅使用标题中的单词。例如,变形金刚 有一辆汽车和一个机器人表情符号,如果你看过电影就能理解,但如果你只看单词 变形金刚 就不知道是什么。所以,这是怎么回事?GPT-3 不仅使用提示中提供的内容,还使用其庞大的模型中包含的有关每部电影的额外细节:

图 2.11 – 文本生成示例 – 从文本转换为表情符号

图 2.11 – 文本生成示例 – 从文本转换为表情符号

因此,对于文本生成用例有很多可能性,但请记住,GPT-3 是一个通用的语言处理系统。因此,生成文本只是个开始。另一个常见的 NLP 用例是文本分类。

文本分类

文本分类涉及评估一些提供的文本,并为其分配一个标签、分数或其他将文本分类的属性。情感分析是常见的文本分类用例,但这只是 GPT-3 可以用于的许多文本分类任务中的一个。

有多种方法可以让 GPT-3 对文本进行分类。在最简单的情况下,甚至不需要提供示例;这被称为零-shot 分类,这是一种进行基本分类的简单方式,例如情感分析。

零-shot 分类

从上一章回想一下,零-shot 提示不提供任何示例。同样,零-shot 分类 是一项没有示例的分类任务。

这是一个零-shot 分类提示的例子。在这个例子中,目标是对 Twitter 帖子进行情感分析,以确定它是积极的、中立的还是消极的:

Twitter post: "I think I nailed my interview today!"
Sentiment (positive, neutral, negative): 

你可以从以下的截图中看到零-shot 分类示例的情感分类结果:

图 2.12 – 文本生成示例 – 零-shot 分类

图 2.12 – 文本生成示例 – 零-shot 分类

这是另一个零-shot 分类的例子。这个例子显示,GPT-3 可以理解文本进行分类任务。注意提示提供了一个问题,GPT-3 对旅行类型进行分类:

Comprehension Question: "What is the best way to travel from New York to London?"
Travel Type (swim, drive, fly):

以下是显示结果的截图:

图 2.13 – 文本生成示例 – 零-shot 分类

图 2.13 – 文本生成示例 – 零-shot 分类

零样本分类是非常简单的,对于各种分类任务来说也非常有用。但有时分类任务会更为复杂,需要一些示例。对于这些情况,你会使用少样本分类。

少样本分类

进行分类的另一种方式是通过示例;这被称为少样本分类。当你提供文本分类的示例时,模型可以根据你提供的样本学习如何标记文本。如果模型无法正确分类你的文本,提供示例可能会改善结果。这可以用于使用不同术语的情况 – 例如,情感而不是情绪

下面的提示和随后的截图展示了对动物爱好者进行少样本分类的示例:

Q:"I like Dalmatians"
A:Dog Lover
Q:"I like Tigers"
A:Cat Lover
Q:"I like Wolves"
A:Dog Lover

上一个提示的结果显示在下面的截图中:

图 2.14 – 文本生成示例 – 少样本分类

图 2.14 – 文本生成示例 – 少样本分类

请注意图 2.14,如何只需几个示例就足以让 GPT-3 理解如何对任何动物类型进行分类。在该示例中,分类是逐个进行的,但 GPT-3 也可以进行批量分类。

批量分类

如果你能成功地使用少样本分类提示对文本进行分类,你也可以向模型展示如何对一系列项目进行分类。这被称为批量分类

下面的提示展示了一个进行批量分类的提示示例。注意提示中提供了分类示例和批量分类示例:

Tweet: "I loved the new Batman movie!" 
Sentiment: Positive 
### 
Tweet: "I hate it when my phone battery dies" 
Sentiment: Negative 
### 
Tweet: "My day has been great!"
Sentiment: Positive 
### Tweet: "This is the link to the article" 
Sentiment: Neutral 
### 
Tweet text 
1\. "I loved the new Batman movie!" 
2\. "I hate it when my phone battery dies" 
3\. "My day has been great!" 
4\. "This is the link to the article" 
5\. "This new music video blew my mind" 
Tweet sentiment ratings: 
1\. Positive 
2\. Negative 
3\. Positive 
4\. Neutral 
5\. Positive 
### Tweet text 
1\. "I can't stand homework" 
2\. "This sucks. I'm bored " 
3\. "I can't wait for Halloween!!!" 
4\. "My cat is adorable" 
5\. "I hate chocolate" 
Tweet sentiment ratings: 
1.

现在我们已经看到了 GPT-3 在文本生成和分类方面的应用,让我们来看一下 GPT-3 如何用于语义搜索。

理解语义搜索

语义搜索会将搜索词或查询词与包含任意量文本的语义相似文档进行匹配。简单的关键字搜索可能只会查找查询中匹配文档中单词的单词。然而,语义搜索远不止如此。它会分析单词的含义,并对文档进行排名,排名最高的文档表示与查询最为语义相似的文档。例如,假设我们有一个查询“一种有翅膀的动物”和五个一词文档:狗,猫,蛇,兔子,老鹰。语义搜索会对这五个文档进行排名,并将包含单词“老鹰”的文档排名最高,因为它在语义上最接近查询。

每次你查询谷歌,你都在使用语义搜索,和谷歌一样,GPT 3 也可以在文档上进行搜索。不过,与在网络上搜索文档不同,这些文档是作为对 OpenAI API 的请求的一部分或者作为预先上传的文件提供的。

搜索查询可能是一个问题、一个陈述或只是几个词。查询会针对提供的文档进行评估,并在每个文档的结果中提供一个分数。分数通常在 0 和 300 之间,但有时可能会更高。较高的分数,超过 200,通常意味着文档在语义上与查询类似。

当 API 请求附带文档时,最多可以包含 200 个文档。但是,您可以通过上传文档文件或发送多个具有相同查询但不同文档的请求来超出 200 文档限制。我们将在第四章**,使用 OpenAI API中更详细地了解其工作原理。

在使用 GPT 3 进行语义搜索时,另一个考虑因素是选择的引擎。回想一下上一章中提到的,尽管 davinci 是最大、最能胜任任务的引擎,但其他引擎在某些任务上往往表现更好且成本更低。在语义搜索方面,准确性方面的折衷通常很小。因此,测试更快、更高效的引擎如 ada 或 babbage 是有意义的,您可以使用语义搜索工具来完成这项任务。

语义搜索工具

Playground 用于测试提示和补全。但是,语义搜索工具可用于测试搜索查询。您可以通过访问gpttools.com/semanticsearch来访问语义搜索工具。这是一个简单的基于 Web 的应用程序(类似于 Playground),让您可以使用不同的引擎测试语义搜索。下面的截图显示了语义搜索工具:

图 2.15 – 语义搜索工具

图 2.15 – 语义搜索工具

您会注意到语义搜索工具需要一个 OpenAI API 密钥。您可以从beta.openai.com/account/api-keys的 OpenAI API Keys 页面获取您的 API 密钥。您需要登录才能访问 API Keys 页面。我们将在第四章中更多地讨论 API 密钥,但目前,最重要的是您应该保持 API 密钥私密,并不与他人分享。

下面的截图显示了 API Keys 页面(API 密钥被有意地模糊掉了),您可以在这里复制您的语义搜索工具的 API 密钥:

图 2.16 – OpenAI API Keys 页面

图 2.16 – OpenAI API Keys 页面

语义搜索工具还提供了预设,这些是帮助您熟悉不同语义搜索示例的模板。下面的截图显示了使用导演和电影预设进行搜索的语义搜索工具的结果:

图 2.17 – 文本生成示例 – 语义搜索工具

图 2.17 - 文本生成示例 - 语义搜索工具

希望您能看到,到目前为止,GPT 3 的可能用例相当广泛。我们甚至还没有探讨到可能性的表面,也没有讨论 GPT 3 如何在生产应用中使用。我们将在本书中深入探讨更具体的示例和用例。此外,还有越来越多的基于 GPT 3 的应用程序和在线示例,您应该查看以获取更多的用例和灵感。可以说,在线应用的范围令人印象深刻。您可以开始谷歌搜索使用 GPT-3 的应用程序列表。您将找到越来越多的策划列表和视频,突出了各种各样的 GPT-3 驱动的应用程序和提示示例。位于 gpt3demo.com/ 的 GPT-3 演示值得一看。OpenAI 的博客位于 openai.com/blog/gpt-3-apps/,列出了应用程序和行业用例,以及一些使用和提示示例位于 beta.openai.com/examples

总结

在本章中,我们探讨了 GPT-3 的不同潜在用例。我们讨论了使用 GPT-3 进行文本生成、分类和语义搜索,并举例说明了每种用例。我们介绍了 Playground 网页版测试工具,并讲解了如何访问它以及如何开始使用它。我们探讨了编写文本生成和文本分类提示的不同方法,以及 GPT-3 如何支持语义搜索。

在下一章中,我们将深入探讨 Playground,并看看不同的引擎和 API 设置如何影响完成结果。

第二部分:GPT-3 入门

本节介绍如何通过 OpenAI Playground 和 OpenAI API 使用 GPT-3。

本节包括以下章节:

  • 第三章使用 OpenAI Playground

  • 第四章使用 OpenAI API

  • 第五章在代码中调用 OpenAI API

第三章:使用 OpenAI Playground

在上一章中,我们简要介绍了 Playground。很可能您将花费大量时间在 Playground 中,因为它是一个非常好的工具,既用于学习也用于快速原型设计和测试提示和设置。因此,在本章中,我们将更深入地了解 Playground,重点放在 Playground 设置上。我们还将介绍其他您需要了解的 OpenAI 开发者工具和资源。

本章将涉及的主题如下:

  • 探索 OpenAI 开发者控制台

  • 更深入地探索 Playground

  • 使用预设设置

技术要求

本章需要您可以访问OpenAI API。您可以通过访问 openapi.com 来请求访问权限。

探索 OpenAI 开发者控制台

Playground 是 OpenAI 开发者控制台的一部分。开发者控制台是一个提供开发者资源和工具的私人网站门户,其中 Playground 是其中之一。要访问开发者控制台,您需要有效的 OpenAI 开发者帐户。虽然本章主要关注 Playground,特别是 Playground 设置,但值得花一分钟查看 OpenAI 开发者控制台中的其他资源,从开发者文档开始。

开发者文档

当您使用新技术时,很多时候好的文档并不容易找到。幸运的是,GPT-3 并不符合这种情况。OpenAI 的文档做得非常出色。内容完整,易于理解,并提供了许多非常有用的示例。我们在第一章介绍 GPT 3 和 OpenAI API 中查看了其中一个示例 - 分类提示示例。但让我们再看看文档中的另一个很好的例子,即事实性回答示例。

事实性回答示例

下一个提示示例来自 OpenAI 开发者文档。它位于 beta.openai.com/docs/introduction/prompt-design-101。它提供了一个示例问答提示,向模型显示对于它可能没有正确答案的问题应返回一个问号。这告诉模型 不要 来编造答案,这通常情况下它可能会默认这样做。这是一个重要的示例,因为尽管 GPT-3 的回答几乎总是语法正确的,但它们往往不是事实性的。因此,即使它们听起来不错,它们可能是完全虚构的。

在下一个提示中需要注意的关键点是所提供的示例向 GPT-3 展示如何处理没有事实答案的问题,或者 GPT-3 不知道如何回答的问题。也有一些设置用于帮助确保事实回答,但我们将在本章稍后讨论这些设置:

Q: Who is Batman?
A: Batman is a fictional comic book character.
###
Q: What is torsalplexity?
A: ?
###
Q: What is Devz9?
A: ?
###
Q: Who is George Lucas?
A: George Lucas is American film director and producer famous for creating Star Wars.
###
Q: What is the capital of California?
A: Sacramento.
###
Q: What orbits the Earth?
A: The Moon.
###
Q: Who is Fred Rickerson?
A: ?
###
Q: What is an atom?
A: An atom is a tiny particle that makes up everything.
###
Q: Who is Alvan Muntz?
A: ?
###
Q: What is Kozar-09?
A: ?
###
Q: How many moons does Mars have?
A: Two, Phobos and Deimos.
###
Q:

突出 OpenAI 文档的要点,正如您所期望的那样,是因为它可能是一个极其有价值的资源。但这只是众多资源中的一种。

开发者资源

文档仅是开发者门户中的可用资源之一。还有其他资源可用,包括以下:

  • 常见问题解答

  • 定价详细信息

  • 视频教程

  • 社区示例

  • 交互工具

  • 指南和法律文件

  • 标志资产

随着您熟悉 GPT-3 和 OpenAI API,您需要花时间审阅所有可用的开发者资源。我们将更深入地研究其中一些,但它们都是有价值且值得审阅的。

账户与组织

开发者控制台中另一个重要的区域是账户资料部分。这是您编辑开发者账户和组织详细信息的地方。

开发者账户用于认证和识别个别开发者。默认情况下,创建开发者帐户时,还会创建一个名为 Personal 的组织。组织用于计费目的和用户分组,这意味着用户可以创建或关联多个组织,每个组织都将单独计费。

每个组织都有一个您可以指定的标题(名称),以及一个自动生成的组织 ID。组织 ID 是用于将使用情况与正确组织关联以进行计费目的的唯一标识符。因此,当您登录到开发者控制台时,任何使用情况将与您所在的组织相关联。我们将在第四章中再次讨论组织 ID,使用 OpenAI API,在那里我们将探讨如何将 API 调用与特定组织关联,但您也可以在开发者控制台中将使用情况与组织关联。

以下屏幕截图显示了如何查看您的账户关联的组织以及如何在开发者控制台中切换不同组织之间:

图 3.1 – 在不同组织之间切换

图 3.1 – 在不同组织之间切换

如前所述,组织用于计费目的,与您的用户账户一起创建了一个名为Personal的组织。如果您喜欢,您可以将组织名称更改为除Personal之外的其他内容。下面的屏幕截图显示了您可以更改个人组织名称的位置:

图 3.2 – 个人组织

图 3.2 – 个人组织

当然,您是个人组织的所有者,如果您是为自己的个人使用而使用 API,那么这就是您为其设置计费的组织。

定价和计费

在进入定价细节之前,有一点很重要,那就是定价可能随时变动,因此您需要访问 https://beta.openai.com/pricing 获取最新的定价详情。有了这个免责声明,让我们继续。

首先,OpenAI API 的定价是按使用量计费的。因此,你只需支付你使用的资源。没有设置费用或重复费用。使用费用是基于使用的令牌。每个令牌的成本取决于你使用的引擎。我们在第一章介绍 GPT-3 和 OpenAI API 中讨论了令牌并介绍了可用的引擎。

DaVinci 是最大的模型和最能干的引擎,因此,它也是使用成本最高的引擎。在价格范围的另一端是 Ada。这是最小的模型,限制了它的功能。不过,Ada 是最高效的引擎,因此使用成本最低。

以下截图显示了本书出版时每个引擎的定价。再次说明,价格随时可能发生变化,所以请务必核实当前价格,因为它很可能已经变化了:

图 3.3 – 定价

图 3.3 – 定价

按使用量计费很好,因为如果你什么都没做,也就不会花费什么。话虽如此,不知道账单会是多少也可能有点可怕。不过,幸运的是,你可以设置一个硬限制或软限制来管理你的支出。这可以在你的计费设置中完成。硬限制防止 API 在达到限制后继续使用更多的令牌。当然,这会使 API 无法使用,这在生产应用中可能会成为问题。因此,还有设置软限制的选项。这会在达到使用限制时发送电子邮件提醒。

使用报告

除了设置硬限制或软限制来管理你的成本外,你还可以访问使用报告。在使用菜单下的组织设置中找到使用报告。以下截图显示了一个示例使用报告:

图 3.4 – 使用报告

图 3.4 – 使用报告

使用报告中的主要图表默认显示本月每天使用的总令牌数。每个柱状图还显示了用于提示和完成的令牌数。通过这个图表,你还可以查看按金额使用情况,并显示累计总数而不是每日总数。此外,在主要图表下方,你可以查看总使用量以及每天按引擎的详细使用情况。

成员管理

如前所述,当你获得开发者帐户时,会为你的个人使用设置一个组织。但你可能还想为一个用户团队拥有一个组织。为此,你可以通过发送电子邮件到 support@openai.com 请求一个多用户组织帐户。当新组织创建时,你将能够邀请其他用户加入组织。这可以在组织的成员菜单下完成。以下截图显示了一个组织的成员管理页面。从这个页面,你可以邀请新成员,删除成员或更改成员权限:

图 3.5 – 成员管理

图 3.5 – 成员管理

在游乐场之外,这应该涵盖了你需要了解开发者控制台的基本内容。所以,让我们回到游乐场,仔细看一看。

深入了解游乐场

此时,你应该已经了解了如何使用游乐场的基础知识。但是我们现在要更深入地讨论游乐场,并讨论所有可用的选项和设置。第二章GPT 3 应用和用例,提供了可用设置的快速概述,但让我们更仔细地看看每一个。

以下截图显示了游乐场中的设置。它们位于大型文本输入框的右侧:

图 3.6 – 游乐场设置

图 3.6 – 游乐场设置

第一个设置是引擎设置,所以我们从那里开始。

选择正确的引擎

通常,我们只把 OpenAI 语言模型称为 GPT-3。但是,正如你在第一章中所记得的那样,介绍 GPT-3 和 OpenAI API,有多个模型/引擎。

当你第一次打开游乐场时,默认选择达芬奇引擎。这通常是你想要开始测试提示的引擎。你会想要从达芬奇开始的原因是它是最大的模型,因此是最有能力的引擎。达芬奇引擎可以做任何其他引擎可以做的事情。然而,其他引擎可能能够更快地或更具成本效益地执行特定任务。因此,另一种方法可能是先从最便宜的引擎开始,然后在较便宜的引擎无法完成任务时测试下一个价格更昂贵的引擎。

所以,从达芬奇开始。然后,当你从达芬奇获得想要的结果时,请尝试将你的提示与其他引擎一起测试,看看你是否也能获得可接受的结果。或者从 ada 开始,这是最便宜的引擎,如果无法获得可接受的结果,则逐步升级。让我们看一个使用简单分类任务的示例。

以下是将项目分类为工具、食物、服装或其他的提示:

The following is a list of items classified as a tool, food, clothing, or something else 
Cake: Food 
Pants: Clothing 
Car: Other 
Pliers: Tool 

以下截图显示了使用达芬奇引擎时的结果。请注意,新增加的项目(衬衫锤子苹果飞机)都被正确分类:

图 3.7 – 使用达芬奇引擎的分类示例

图 3.7 – 使用达芬奇引擎的分类示例

现在,让我们看看当引擎从达芬奇更改为 ada 时的结果。您会注意到在以下截图中,新增加的项目(袜子钳子汉堡房子)也被 ada 正确分类:

图 3.8 – 使用 ada 引擎的分类示例

图 3.8 – 使用 ada 引擎的分类示例

所以,正如你从上面的例子可以看到的那样,有些任务并不需要 davinci 来获得可接受的结果。如果是这种情况,选择另一个引擎将减少你的使用成本,通常还会提高响应时间。当然,如果成本和性能不是问题,你也可以始终坚持使用 davinci。但再次提醒,根据任务的不同,davinci 可能并不是唯一的选择。

以下列表提供了每个引擎一般擅长的内容。这并不是硬性规定,只是一个指导方针。因此,你总是需要测试以确定基于结果的最佳选择:

  • Davinci: 复杂意图,因果关系,针对年龄的摘要。

  • 居里: 语言翻译,复杂分类,文本情感,摘要。

  • 巴贝奇: 适度分类,语义搜索分类。

  • 艾达: 文本解析,简单分类,地址校正,关键词。

响应长度

响应长度设置相当容易理解。它控制将生成的完成的长度。要记住的主要事情是,该值涉及要返回的令牌数量。请记住来自第一章介绍 GPT-3 和 OpenAI API,令牌可以代表单词或单词的部分。因此,不要把响应长度误认为是单词数或字符数。

另一点需要记住的是,你会被计费所使用的令牌 – 包括用于完成的令牌,这意味着你的响应长度越长,你将使用的令牌就越多。因此,如果你尝试优化成本,针对给定任务设置响应长度尽可能短。例如,如果任务是对一段文本进行情感分析,那么响应长度只需要足够长以显示情感结果即可。

温度和 Top P

接下来的两个设置是温度Top P。这两个设置是最重要的设置之一,但也可能是最难理解的。在更高的层面上,它们都会影响所生成响应的随机性或多样性。但了解何时使用其中一个而不是另一个可能会很棘手。

要理解温度和 Top P 设置的意义,了解机器学习系统可以以不同方式处理相同的输入很有帮助。这意味着即使输入没有改变,输出也可能会有所不同。这是因为像 GPT-3 这样的机器学习系统使用启发式(教育猜测)而不是具体的逻辑来生成结果。因此,机器学习系统不是试图找到完美的解决方案,而是根据其训练过的数据来确定最佳选择。

对于 GPT-3 来说,它训练所使用的数据集非常庞大且多样化。因此,大多数输入(提示)会导致多种可能的完成结果。这可能是一种好处,也可能是一种挑战,具体取决于任务。例如,如果你使用 GPT-3 为一本书的标题生成想法,你想要很多不同的选择。然而,如果你希望 GPT-3 能准确回答历史问题,你希望得到一致和事实准确的回应。这就是温度和 Top P 设置发挥作用的地方。温度和 Top P 设置可以帮助控制用于生成完成结果的变化性和选项数量。

温度

温度设置影响模型在生成结果时的确定性程度。因此,温度提供了一定程度上控制结果变化的能力。较低的数值会让模型更趋向确定性(较少变量),而较高的数值会使模型更趋向不确定性或者更多变。其范围可以在 0 到 1 之间。为了看到温度设置的效果,让我们来看一些例子。

我们将从一个使用默认 Playground 温度为0.7的示例开始。在这个示例中,我们将研究大多数完成结果的默认随机性。我们将从一个包含词组很久以前但没有其他内容的提示开始,就像下面的截图所示的提示:

图 3.9 – 温度示例 1

图 3.9 – 温度示例 1

正如你所猜测的,这个提示可能有很多可能的完成结果。因此,当我们重复提交这个提示三次时,我们得到以下三个完成结果,每一个都不同。

  • 很久以前,有一个小公主诞生了。

  • 很久以前,有三只小猪。

  • 很久以前,有一个女孩,她每天都看到一个男孩从她家门前跑过。

这个例子很简单,结果并不令人惊讶。但理解为什么同样的提示会导致三种不同的完成结果很重要。所以,让我们更详细地谈谈我们的第一个例子。

实际上,我们之所以在前一个例子中得到不同的回应,有三个原因。第一个原因是底层模型可以想出很多不同的方式来完成这个提示。这是因为有很多以很久以前开头的故事,而训练模型使用的数据包含了这些故事的许多例子。

第二个原因是默认的温度设置相对较高(0.7 占 1)。因此,在生成回应时,模型被指示要冒更多的风险,并更加随机。

最后一个原因与 Top P 设置有关,但我们稍后再谈。

现在,让我们再次考虑同样的示例,但这次我们将把温度设置为 0. 再次,我们提交相同的提示三次,但这次结果如下 – 每次都相同:

  • 从前,有一个非常难过的小女孩。

  • 从前,有一个非常难过的小女孩。

  • 从前,有一个非常难过的小女孩。

那么,到底发生了什么?较低的温度值告诉 GPT-3 在处理提示时要更少地变化,因此完成结果保持一致。因为我们使用零作为温度值(最低值),结果很可能始终相同。但是,您可以使用介于零和一之间的值(例如 0.2)来更好地控制结果的随机性。然而,改变温度并不总是会影响完成,因为完成结果还取决于模型训练时的数据示例。为了说明这一点,让我们看看另一个例子。

对于这个示例,我们将使用默认温度设置为0.7的提示,只包括单词A robot may not injure,如下图所示:

 图 3.10 – 温度示例 2

图 3.10 – 温度示例 2

这一次,当我们多次提交前一个屏幕截图中的提示时,我们得到了以下结果-每次都是相同的完成结果:

  • A robot may not injure a human being or, through inaction, allow a human being to come to harm.

  • A robot may not injure a human being or, through inaction, allow a human being to come to harm.

  • A robot may not injure a human being or, through inaction, allow a human being to come to harm.

那么,现在你可能想知道发生了什么。由于设定了较高的温度,完成结果难道不应该变化吗?同样,完成结果还取决于模型训练时的数据。在这种情况下,完成结果没有变化的原因(并且可能不管温度设置如何都不会变化)是因为五个单词(或五个标记)A robot may not injure通常被看作是艾萨克·阿西莫夫机器人三大定律的一部分。因此,由于模型的训练,无论温度如何,最佳可能的结果几乎总是相同的。因此,请记住,只有在有各种不同的方式可以完成提示时,温度设置才会产生显着效果。

Top P

虽然温度控制了基于模型生成的结果的随机性,但 Top P 设置控制了考虑用于完成的结果(或标记)的数量。该值可介于 0-1 之间,其中较高的值考虑较多的标记。例如,值为 1 将考虑所有可能的选项,而值为 0.5 将将选项减少一半。

类似于温度,Top P 可以被用来增加或限制完成的看似随机性。然而,与温度不同的是,它通过限制应该考虑的可能结果的范围来影响随机性。为了说明这一点,想象一下,在完成中可能有 100 个潜在的标记选项可以被选为下一个标记。Top P 值为 0.1 可以用于将选项限制为 10 个,从而减少可以选择的标记数量。但这仍然取决于从模型派生出的可能的标记选项的数量。因此,如果只有 10 个潜在选项,0.5 的 Top P 设置将把它限制为 5 个选项 – 减少了变异性。此外,Top P 值为 0 将总是将选项减少到顶部标记,这意味着即使可能有很多的选项并且温度设置为 1(这会生成最多的选项),如果 Top P 设置为 0,只有最佳选项会被选择,这将与将温度设置为 0 的效果相同 – 你很可能总是得到相同的结果。为了说明这一点,让我们再次看一下我们的从前,有一段时间的提示。这一次,我们将温度设置为 1,Top P 值设置为 0,就像我们在下面的截图中所做的那样:

图 3.11 – Top P 示例

图 3.11 – Top P 示例

如果我们使用前面截图中的设置三次提交提示,我们会得到以下结果(相同的完成),即使温度设置为 1。这是因为 Top P 限制了选项:

    • 从前,*有一个很伤心的小女孩。
    • 从前,*有一个很伤心的小女孩。
    • 从前,*有一个很伤心的小女孩。

因此,尽管温度和 Top P 设置都影响完成的看似随机性,它们是相互关联的,每一个都可以影响另一个。如果你不清楚它们是如何工作的,这就使它们有些令人困惑。因此,你最好单独使用每个设置。所以,如果你想用温度影响随机性,就把 Top P 设置为 1,只改变温度。如果你想用 Top P 值影响随机性,就把温度设置为 1。

频率和存在惩罚

频率存在惩罚设置也可能会有些令人迷惑,因为它们似乎类似于温度或者 Top P,它们都是用来控制变化性的设置。然而,与考虑模型不同,频率和存在惩罚设置考虑的是提示文本和之前的完成文本,以影响选择下一段文本的标记。因此,这两个设置可以在现有文本的基础上,对生成的新文本进行一些控制。

频率和存在惩罚设置对于防止同一完成文本在多个请求中重复使用非常有用。这两个设置非常相似,唯一的区别在于,如果文本存在多次,则应用频率惩罚,而如果文本存在,则应用存在惩罚。让我们看另一个例子。

以下截图显示了从前有座山示例的结果,温度设置为 1,Top P 设置为 0,并且没有频率或存在惩罚。单击提交按钮 5 次,每个完成生成一个新句子。虽然没有重复的句子,但有许多重复的标记序列—请注意每个完成句子都以她很伤心因为她没有开头:

图 3.12 – 频率和存在示例 1

图 3.12 – 频率和存在示例 1

对于上一个示例,我们可以添加存在或频率惩罚以限制每个完成项如此相似的可能性。

下一张截图显示了在添加存在惩罚并单击提交五次后的结果(就像我们在上一个示例中所做的那样)。这次,您可以看到完成句子不太相似:

图 3.13 – 频率和存在示例 2

图 3.13 – 频率和存在示例 2

频率惩罚根据标记在文本中已经存在的频率来惩罚新标记。另一方面,存在惩罚如果标记在文本中存在则对其进行惩罚。在这两种情况下,值可以介于 0 和 1 之间,较高的值增加惩罚,从而减少重复的可能性。

最佳选择

最佳选择设置将使模型在服务器端生成多个完成项,并返回x个完成项中的最佳选择(其中x是最佳选择的值)。这可以帮助获得最高质量的结果,而无需向 API 发出多个请求。但是,在使用最佳选择时需要考虑的事项是,您将为生成的每个完成项使用的标记收费。例如,如果您的响应长度为 50,并且将最佳选择值设置为 10,则响应将消耗 500 个标记。因此,如果您提供了最佳选择值,请务必将响应长度值设置得尽可能低,以最小化使用的标记数。您还可以使用停止序列设置来帮助限制不必要的标记使用。

停止序列

一个停止序列是一个文本序列,当在完成中遇到该序列时,将导致完成结束。您最多可以提供四个序列。例如,如果您想要将完成限制在句号后和回车之前的文本上,您可以提供句号和回车作为停止序列。

在 Playground 中,您通过键入停止序列,然后按下 tab 键来完成您的输入。以下屏幕截图显示了换行符作为停止序列。在这个例子中,输入了回车键,然后是 tab 键:

图 3.14 – 停止序列

图 3.14 – 停止序列

让我们继续下一节!

注入起始文本和注入重新开始文本

注入起始文本注入重新开始文本输入分别在完成的开头或结尾插入文本。这些设置可以用来确保所需的模式作为完成的一部分继续。通常,在与停止序列一起使用时,这些设置最有帮助。让我们看一个例子。例如,让我们从以下提示开始:

The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly. 
Human: I'm feeling sad. Can you cheer me up?

使用默认的 Playground 设置,完成可能看起来像以下截图中的完成:

图 3.15 – 默认设置

图 3.15 – 默认设置

在上一张屏幕截图中,您可以看到引擎很好地判断出这是一段对话,并继续了对话。但是,假设您不希望完成生成对话的人类一侧,并且您希望使用标签AI:而不是助手:?如果是这样的话,您可以使用停止序列在生成对话的人类一侧之前结束完成。然后,您可以使用注入重新开始文本值提示人类输入。最后,注入起始文本值可以设置为换行符,然后是AI:来开始助手的回应。以下截屏显示了使用这些设置完成可能会看起来如何:

图 3.16 – 使用停止序列、注入起始文本和一起注入重新开始文本

图 3.16 – 使用停止序列、注入起始文本和一起注入重新开始文本

通过上一张截图中使用的设置,您可以看到完成在生成对话的人类一侧之前结束。然后,重新开始的文本Human:被附加到完成中,提示人类输入。

显示概率

在游乐场中,显示概率选项切换文本突出显示,显示一个标记生成的可能性有多大。当您尝试排查完成时,这可以让您检查可能使用的选项。它还可以帮助您查看您可能想使用的替代选项。要使用显示概率,您可以通过选择以下设置之一切换它打开:

  • 最可能

  • 最不可能

  • 全光谱

最有可能的值将显示最有可能被选中的标记,最不可能的将显示可能被选中的最不可能的标记,而完整光谱将显示可能被选中的标记范围。以下截图显示了一个示例。在这个示例中,输入提示只是Hi,。使用的设置是默认设置,除了响应长度设置为 1,以及显示概率设置为最有可能。你可以看到完成的词是my,但也考虑了一些其他可能的选项:

图 3.17 – 显示概率 – 最有可能的标记

图 3.17 – 显示概率 – 最有可能的标记

设置提供了对完成生成的控制,但是选择正确的设置可能需要一些试错。幸运的是,Playground 包含了预设,可以帮助你了解如何为给定的任务选择正确的设置组合。

使用预设

第二章GPT 3 应用与用例,我们简要介绍了 Playground 中的预设。具体来说,我们看了英语到法语的预设,但那只是众多预设中的一个。预设就像提供了示例提示以及 Playground 设置的模板。它们是创建新提示的绝佳起点,或者作为熟悉提示设计和设置使用的工具。

有许多可用的预设,包括以下内容:

  • 聊天

  • 问与答

  • 语法标准英语

  • 给二年级生总结

  • 文本转命令

  • 英语到法语

  • 解析非结构化数据

  • 分类

在 Playground 的大输入框上方会找到预设的下拉列表。以下截图显示了位置:

图 3.18 – 预设

图 3.18 – 预设

我们不会审查所有的预设,但让我们看看其中一些,以了解如何使用设置来帮助从提示中获得最佳完成。我们将首先审查的是语法标准英语预设。

语法标准英语

语法标准英语预设展示了一个用例,其中非标准的美式英语文本被转换为标准的美式英语文本。以下是该预设的提示文本:

Non-standard English: Please provide me with a short brief of the design you're looking for and that'd be nice if you could share some examples or project you did before.
Standard American English: Please provide me with a short brief of the design you're looking for and some examples or previous projects you've done would be helpful.
Non-standard English: If I'm stressed out about something, I tend to have problem to fall asleep.
Standard American English: If I'm stressed out about something, I tend to have a problem falling asleep.
Non-standard English: There is plenty of fun things to do in the summer when your able to go outside.
Standard American English: There are plenty of fun things to do in the summer when you are able to go outside.
Non-standard English: She no went to the market.
Standard American English: She didn't go to the market.

如前所述,预设还包括设置。因此,在选择语法标准英语预设后,你会注意到一些默认的 Playground 设置已经发生了变化。

默认的 Playground 设置如下:

  • 引擎: davinci

  • 响应 长度: 64

  • 温度: 0.7

  • 顶部 P: 1

  • 频率惩罚: 0

  • 存在惩罚: 0

  • 最佳选项: 1

  • 停止序列: 空

  • 注入开始文本: 空

  • 注入重新开始文本: 空

  • 显示概率: 关闭

但是当你选择一个预设时,一些默认设置会更新。对于语法标准英语预设,使用的设置如下:

  • 响应长度: 120

  • 温度:1

  • Top P:0.7

  • 停止序列

  • 注入开始文本:标准美国英语:

  • 注入重启文本:非标准英语:

请注意,温度设置为 1,Top P 用于限制考虑的结果达到了可能选项的 70%。 还请注意,停止序列与注入开始文本和注入重新启动文本一起使用,以使完成保持简短,同时继续下一个短语的提示模式以使其标准化。

文本转命令

文本转命令预设提供了一个示例,展示了如何将英语命令转换为机器命令以发送消息。 以下是“文本转命令”预设的提示文本:

Q: Ask Constance if we need some bread
A: send-msg `find constance` Do we need some bread?
Q: Send a message to Greg to figure out if things are ready for Wednesday.
A: send-msg `find greg` Is everything ready for Wednesday?
Q: Ask Ilya if we're still having our meeting this evening
A: send-msg `find ilya` Are we still having a meeting this evening?
Q: Contact the ski store and figure out if I can get my skis fixed before I leave on Thursday
A: send-msg `find ski store` Would it be possible to get my skis fixed before I leave on Thursday?
Q: Thank Nicolas for lunch
A: send-msg `find nicolas` Thank you for lunch!
Q: Tell Constance that I won't be home before 19:30 tonight — unmovable meeting.
A: send-msg `find constance` I won't be home before 19:30 tonight. I have a meeting I can't move.
Q: 

更新的设置如下:

  • 响应长度:100

  • 温度:0.5

  • Top P:1

  • 频率惩罚:0.2

  • 停止序列

  • 注入开始文本:A:

  • 注入重启文本:Q:

在这个预设中,注意到温度设置为 0.5,并且使用了轻微的频率惩罚 0.2。

解析非结构化数据

解析非结构化数据预设提供了一个示例,展示了如何从非结构化文本中提取值。 提示提供了一段文本,说明和一些示例:

There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy. There are also loheckles, which are a grayish blue fruit and are very tart, a little bit like a lemon. Pounits are a bright green color and are more savory than sweet. There are also plenty of loopnovas which are a neon pink flavor and taste like cotton candy. Finally, there are fruits called glowls, which have a very sour and bitter taste which is acidic and caustic, and a pale orange tinge to them.
Please make a table summarizing the fruits from Goocrux
| Fruit | Color | Flavor |
| Neoskizzles | Purple | Sweet |
| Loheckles | Grayish blue | Tart |

解析非结构化数据预设中使用的设置如下:

  • 响应长度:100

  • 温度:0

  • Top P:1

  • 停止序列

在这个预设中,值得注意的设置是温度和 Top P 设置。

总结

在本章中,我们简要介绍了 OpenAI 开发者控制台中可用的工具和资源。 我们还更深入地了解了“游乐场“,并深入了解了“游乐场”设置。 我们学会了如何选择合适的引擎,还了解了如何使用温度和 Top P,以及频率和存在惩罚,以及其他选项。 最后,我们看了一些预设,以进一步了解这些设置如何使用。

在下一章中,我们将超越“游乐场”,开始学习如何使用 Open AI API。

第四章:使用 OpenAI API

到目前为止,我们用 GPT-3 所做的一切都是通过 Playground 完成的。虽然 Playground 是学习和测试的好地方,但是当你构建包含 GPT-3 的应用程序时,你也需要理解如何直接使用 OpenAI API。因此,在本章中,我们将通过发出 HTTP 请求来直接使用 OpenAI API。我们将首先对 API 和 HTTP 协议进行一般介绍。然后我们将看一下一些用于处理 API 请求和 JSON 数据交换格式的开发人员工具。

我们将涵盖的主题如下:

  • 理解 API

  • 熟悉 HTTP

  • 查看 OpenAI API 端点

  • 介绍 CURL 和 Postman

  • 理解 API 身份验证

  • 发出对 OpenAI API 的经过身份验证的请求

  • 介绍 JSON

  • 使用 Completions 端点

  • 使用语义搜索端点

技术要求

本章需要你能够访问OpenAI API。你可以通过访问openapi.com来请求访问权限。

理解 API

缩写API代表应用程序编程接口。API 允许软件在系统之间进行通信和交换数据,共享计算机系统资源和软件功能。由于功能可以共享,它们也可以实现代码重用。这通常提高了系统的质量,同时也降低了开发工作量。

Web-based APIs 是通过 HTTP 在互联网上公开的,这与你在网络浏览器中访问 URL 时使用的协议相同。因此,使用基于 Web 的 API 非常类似于使用网站。例如,当你使用 API 时,你会向统一资源定位符URL)发出请求,就像你访问网站时所做的那样。URL 提供了 API 提供的资源、数据或功能的参考。

就像网站一样,每个 API 都是一个或多个 URL 的集合,也被称为端点。每个端点提供对特定资源或功能的访问。一些端点可能接受输入数据并执行任务,而其他端点可能只是返回数据。输入和输出数据的格式取决于 API。但是,大多数 API 使用常见的数据交换格式,如JavaScript 对象表示JSON)或纯文本。我们稍后会讨论 JSON 数据交换格式,因为这是 OpenAI API 所使用的格式。

由于基于 web 的 API 可以使用 HTTP 访问并使用常见数据格式,它们不依赖于任何特定的编程语言,这意味着几乎任何可以发出 HTTP 请求的编程语言或开发工具都可以与 HTTP API 互动。实际上,甚至可以使用 web 浏览器与一些基于 web 的 API 互动。例如,如果在您的 web 浏览器中打开 api.open-notify.org/astros.json,您将看到提供有关目前在太空的人数的数据的响应。结果并未以美观的格式呈现,因为它们是为机器使用而不是人类消费而设计的,但我们可以在浏览器中看到结果,因为它使用了网站使用的相同的 web 协议,如下面的屏幕截图中所示:

图 4.1 – Open-Notify API – JSON 响应

图 4.1 – Open-Notify API – JSON 响应

尽管 HTTP API 不是针对特定语言编程的,但许多 API 发布者提供了一个软件开发工具包SDK)或一个软件库,以便在特定语言中更简单地使用 API。例如,OpenAI 提供了简化在 Python 编程语言中使用 OpenAI API 的 Python 绑定(库)。这些工具本质上是 API 的包装器,如果没有库,你可能需要编写的代码会减少。稍后我们会在 第五章 中更详细地讨论可用于 OpenAI API 的一些库,在代码中调用 OpenAI API。目前,需要注意的重要事项是,只要选择能够发出 HTTP 请求的编程语言即可,编程语言并不重要。此外,SDK 或库可以提供帮助,但并不是使用 API 的必需条件。然而,必不可少的是对 HTTP 协议的基本理解。因此,我们接下来会讨论这个问题。

熟悉 HTTP

因为 API 设计用于在代码中使用,为了与其一起工作,你确实需要对 HTTP 协议有更多了解,而不仅仅是访问网站所需的知识。因此,在本节中,你将学习一些 HTTP 基础知识。

起初,HTTP 是一种请求-响应协议。因此,客户端(请求系统)向服务器(接收系统)发出请求,服务器然后响应客户端。客户端使用统一资源标识符URI)来引用服务器和所请求的资源。

统一资源标识符

HTTP URI 提供了需要向特定服务器请求特定资源的 HTTP 请求所需的详细信息。为了举例说明,让我们分解前面在理解 API部分中提到的api.open-notify.org/astros.json端点。端点始于对所使用协议的引用。在我们的示例中,这是 http://。对于基于 Web 的 API,这将始终是 HTTP 或 HTTPS。当使用 HTTPS 时,这是一个指示请求和响应之间将被加密的指示。URI 的第二部分(在本例中为api.open-notify.org)是资源所在的服务器的引用。在服务器名称之后是对服务器上资源位置的引用。有些 URI 还会包括参数和值。这些参数和值可用于提供服务器处理请求的附加细节或可变数据。

除 URI 之外,HTTP 协议还支持称为HTTP 方法的不同请求类型,它们提供有关正在进行的请求的附加信息。

HTTP 方法

HTTP 方法允许服务器使用相同的 URL 执行不同的操作。有六种不同的 HTTP 方法,但并非所有 URL 端点都支持所有方法。最常见的两种 HTTP 方法是GETPOST。GET 方法告诉服务器客户端要检索(或获取)信息,而 POST 方法告诉服务器客户端正在发送数据。因此,如果端点用于检索数据,通常会使用 GET 方法。但是,如果端点预期数据输入,可能会使用 POST 方法。

HTTP 正文

HTTP 请求或响应的正文包含主要数据负载。在请求的情况下,正文包含将被发送到服务器的数据。在响应的情况下,正文包含从服务器返回的数据。在 HTTP 正文中发送的数据可以是任何基于文本的有效载荷。常用的格式有 JSON、XML 和纯文本。因此,您还需要知道您将与之交互的 API 中发送和接收数据的格式。这通常可以在 API 文档中找到。

HTTP 头

HTTP 正文不是发送/接收数据的唯一方式。您还可以将数据作为 URL 的一部分或作为 HTTP 头包含在内。HTTP 头是键/值对,可用于在客户端和服务器之间发送/接收值。虽然 HTTP 头可以用于各种原因,但它们通常定义元数据或提供有关请求的详细信息的数据。例如,名为Content-Type的 HTTP 头用于告诉服务器传递正文中的数据类型,而Authorization头可用于发送认证详细信息,如用户名和密码。

HTTP 响应状态码

当客户端向有效服务器发出有效请求时,服务器将始终在响应中包含一个 HTTP 响应状态代码。状态代码是一个提供响应的高级结果状态的数字值。例如,200 表示成功的响应,而 500 表示内部服务器错误。有关不同状态代码的完整列表,您可以访问 developer.mozilla.org/en-US/docs/Web/HTTP/Status。虽然记住不同的状态代码并不重要,但熟悉它们并知道在哪里查找代码的含义是很好的。当您调用 API 端点时遇到问题时,状态代码非常有助于调试问题。

本节只是对 HTTP 提供了一个非常高层次的概述,但对于使用 OpenAI API 和大多数其他基于 Web 的 API,高层次的理解就足够了。

查看 OpenAI API 端点

通过 Playground 所做的一切也可以通过 OpenAI API 来完成 - 甚至更多。实际上,Playground 只是调用 OpenAI API 的 Web 接口。它只是使用图形界面暴露了 API 提供的功能。因此,在本节中,我们将审查通过 API 端点可用的 OpenAI 功能。您会对功能很熟悉,因为您已经通过 Playground 使用了它,但在本节之后,您将知道如何在代码中访问特定的功能。

使用 OpenAI API,您可以通过可用的端点执行以下操作:

  • 创建完成

  • 列出可用引擎

  • 获取引擎详情

  • 执行语义搜索

所有的 OpenAI API 端点都需要身份验证。因此,它们不能像我们之前查看的 Open-Notify API 那样,只需使用浏览器即可调用。但我们暂时不讨论身份验证,而是审查每个可用的端点。

列出引擎

列出引擎端点是一个元数据 API,意味着它提供有关系统本身的数据。具体来说,它提供了一份可用引擎的列表,以及每个引擎的一些基本信息。OpenAI 正在积极开发新引擎并更新现有引擎,因此列出引擎端点将提供当前可用引擎的列表。

列出引擎端点使用 HTTP GET 方法,不需要任何请求参数。以下是列出引擎端点的 HTTP 方法(GET)和 URI:

GET https://api.openai.com/v1/engines

接下来是检索引擎端点!

检索引擎

检索引擎端点也是一个元数据 API。它返回关于特定引擎的详细信息。与列出引擎端点一样,检索引擎端点也使用 HTTP GET 方法,并且要求将引擎 ID 包含在 URI 路径中。可以从列出引擎端点检索到可能的引擎 ID 值。

Retrieve Engine 端点使用 HTTP GET 方法和以下 URI,其中一个参数是引擎 ID:

GET https://api.openai.com/v1/engines/{engine_id}

接下来是 Create Completions 端点 - 你可能会经常使用它。

Create Completions

Create Completions 端点是你最常使用的端点。这个端点接收一个提示并返回完成结果。这个端点使用 HTTP POST 方法,并且要求引擎 ID 作为 URI 路径的一部分。Create Completions 端点还接受许多其他参数作为 HTTP 正文的一部分。我们将在本章后面讨论这些参数。

Completions 端点也使用 POST 方法,并且需要引擎 ID 作为 URI 参数:

POST https://api.openai.com/v1/engines/{engine_id}/completions

还值得注意的是,有一个实验性的 Create Completions 端点,用于将结果流式传输到浏览器。它使用 HTTP GET 方法,并且参数在 URI 中传递。您可以通过访问beta.openai.com/docs/api-reference/create-completion-via-get了解有关此端点的更多信息。

Semantic Search 端点可以用于在文档列表上执行语义搜索。语义搜索将搜索词与文档内容进行比较,以识别语义上相似的文档。要搜索的文档作为 HTTP 正文的一部分传递到端点中,最多可以包含 200 个文档。此端点使用 HTTP POST 方法,并要求将引擎 ID 作为端点 URI 的一部分传递。

Semantic Search 端点使用 POST 方法,并且需要引擎 ID 作为 URI 参数:

POST https://api.openai.com/v1/engines/{engine_id}/search

就基于 Web 的 API 而言,OpenAI API 相对简单易用,但在我们开始测试该 API 之前,让我们讨论一些可以用来开始测试 API 的开发工具。

介绍 CURL 和 Postman

在本节中,我们将介绍一些用于使用 API 的开发人员工具。如我们所讨论的,API 旨在用于代码中。但是,在开发过程中,您常常希望调用 API 端点,而不编写代码来熟悉功能或进行测试。为此,有许多开发人员工具可用。使用 API 的最受欢迎的两个开发人员工具是 CURL 和 Postman。

CURL

CURL 是一个流行的命令行工具,用于发起 HTTP 请求。它已经存在了 20 多年,所以非常成熟和广泛使用。许多 API 发布者,包括 OpenAI,在他们的文档中使用 CURL 语法提供 API 示例。下面的截屏显示了 OpenAI API 文档中使用的 CURL 语法示例。因此,即使 CURL 不是你长期决定使用的工具,熟悉它仍然有帮助。

下面的截屏显示了 OpenAI API 文档中的 CURL 语法:

图 4.2 - OpenAI API 文档中的 Curl 命令

图 4.2 - OpenAI API 文档中的 Curl 命令

CURL 可用于 Linux、Mac 和 Windows,并且默认情况下安装在大多数 Linux 和 Mac 机器上以及运行 Windows 10 Build 1707 或更高版本的 Windows 计算机上。

重要提示

要检查你的 Windows 版本,请在键盘上按下Windows+R来打开运行对话框。然后,输入winver(不带引号)并点击确定

你可以通过命令行验证是否已安装 CURL。在 Linux 和 Mac 上,可以使用终端应用程序访问命令行。在 Windows 上,打开命令提示符以访问命令行。在命令行中,你可以输入 curl --help 命令来确认是否已安装 CURL。如果 CURL 已安装,你应该会看到类似以下屏幕截图的内容:

图 4.3 – Curl 帮助命令

图 4.3 – Curl 帮助命令

如果你尚未安装 CURL,可以从官方 CURL 网站下载,网址为curl.se/download.html

有关使用 CURL 的整本书籍,因此我们这里只是简单介绍其功能。我们将讨论使用 CURL 处理 API 调用,但不仅限于处理 API – 它可以用来进行任何 HTTP 请求。例如,如果你在命令提示符下输入 curl dabblelab.com 并按下回车键,CURL 将抓取 dabblelab.com 的主页。但是,CURL 不是浏览器,因此你所看到的是原始的 HTML 代码,而不是像使用浏览器时看到的漂亮格式的网页。

当我们更详细地研究 OpenAI API 时,将使用 CURL 进行不同的 API 调用。但在此之前,让我们先看看 Postman,这是使用 CURL 的替代方案。

Postman

Postman 是另一个用于处理 API 的开发者工具。与 CURL 不同,Postman 具有图形用户界面。因此,如果你不太擅长命令行,可能更喜欢使用 Postman。你可以从浏览器中使用 Postman,或者可以下载适用于 Linux、Mac 或 Windows 的版本。在我们的示例中,我们将使用网络版本,因为无需安装任何软件;你只需在postman.com注册一个免费账户。

以下屏幕截图显示了 Postman 的主页。你只需要完成注册过程就能开始使用 Postman:

图 4.4 – Postman 主页

图 4.4 – Postman 主页

注册后,你将进入一个简短的入门流程。完成入门流程后,你应该看到类似以下屏幕截图的界面:

图 4.5 – Postman 欢迎界面

图 4.5 – Postman 欢迎界面

与 CURL 类似,Postman 有很多功能,我们只会查看 Postman 的一小部分。但是在其核心,Postman 是一个用于调用 API 端点并检查 API 端点返回结果的工具。我们将从一个快速的演示开始,向您展示如何使用 Postman 发出您的第一个 API 请求。

使用 Postman 发送请求

要开始使用 Postman,请向 Open-Notify API 端点发出我们先前在浏览器中查看过的请求。要做到这一点,请完成以下步骤:

  1. 登录到Postman.com后,单击创建新建链接。如果提示下载桌面代理,请单击现在跳过按钮。这将带您进入您的工作区,它看起来类似以下截图:图 4.6 – 我的工作空间

    图 4.6 – 我的工作空间

    请注意,工作区的右侧是一个选项卡界面,默认情况下将打开概述选项卡。在右侧,您会看到一个加号,可用于打开一个新选项卡。

  2. 单击加号以打开一个新选项卡,输入请求 URL(api.open-notify.org/astros.json),然后单击发送按钮。您应该会看到类似以下截图的结果:

图 4.7 – Postman 请求结果

图 4.7 – Postman 请求结果

注意观察图 4.7中的 JSON 结果是如何格式化的,以便易于阅读。这只是 Postman 为我们提供的许多有用功能之一。当我们深入研究 OpenAI API 时,我们还将涵盖更多的 Postman 功能。但是让我们继续并讨论如何调用 OpenAI API,因为这需要身份验证。

理解 API 身份验证

一些网站是公开的,而其他网站则要求您登录后才能访问内容或功能。对于 API 也是如此。我们在理解 API部分中查看的 Open-Notify API 是对公众开放的,并且不需要任何形式的身份验证。另一方面,OpenAI API 是私有的,因此需要身份验证才能使用它。

API 身份验证过程的作用与网站登录相同,但是以适用于应用程序而不是人类的方式进行。API 可以通过许多不同的方式对应用程序请求进行身份验证,但我们将重点放在基本身份验证上,因为这是 OpenAI API 使用的方法之一。

基本身份验证是一种原生于 HTTP 的身份验证方法。它允许将用户名和密码包含在 HTTP 头中。为了保护凭据安全,对 API 的请求和响应应进行加密。因此,使用基本身份验证的 API 端点 URL 应始终使用安全套接字层SSL),您可以通过 URL 以 HTTPS 开头而不仅仅是 HTTP 来识别。

对于 OpenAI API,你不是发送用户名和密码,而是使用 API 密钥。API 密钥就像一个字符串中的用户名和密码合二为一。使用 API 密钥的好处是可以轻松更改或更新,而不必更改 OpenAI 密码。

我们在第三章中介绍了你可以在哪里找到你的 API 密钥,使用 OpenAI Playground,但是作为回顾,你可以在用户设置下访问你的 OpenAI API 密钥。从相同位置,你也可以通过点击 Rotate Key 按钮来使 API 密钥失效并生成一个新的 API 密钥。

下面的截图显示了账户设置下的 API 密钥 屏幕:

图 4.8 – API 密钥

图 4.8 – API 密钥

使用你的 API 密钥,你拥有一切需要向 OpenAI API 发送请求的条件。但在我们进行之前,让我们谈一分钟关于保持 API 密钥私密性的重要性。

保持 API 密钥私密

即使 API 密钥可以轻松更改,它们也应该被保持私密,就像用户名和密码一样,因为它们也提供对你的账户的访问。所以,要小心确保你的 API 密钥不会意外泄露。如果你不小心的话,这可能很容易发生错误。例如,OpenAI 文档包含了你的 API 密钥,以便简化尝试代码示例。但是,如果你对博客文章或类似内容的文档进行截图,如果你没有将其模糊处理,你会将你的 API 密钥暴露给任何看到图像的人。以下截图显示了一个包含 API 密钥的文档页面示例。在示例中,密钥已经被模糊处理,但你可以看到如果情况不是这样的话它将会暴露:

图 4.9 – 文档中的 API 密钥

图 4.9 – 文档中的 API 密钥

另一种常见的错误暴露 API 密钥的方式是它们与共享的源代码一起包含。我们将在第五章中看到如何避免这种情况,在代码中调用 OpenAI API,但这里的主要观点是你需要小心,因为你的 API 密钥,就像你的用户名和密码一样,可以访问你的账户。

现在你知道如何找到你的 API 密钥并保持它安全,让我们看看如何使用它来第一次调用 OpenAI API。

对 OpenAI API 发送经过身份验证的请求

是时候直接向 OpenAI API 发送我们的第一个请求了。为此,我们需要将我们的 API 密钥作为 HTTP 标头的一部分。我们将要使用的标头名称是授权,值将是单词 Bearer,后跟一个空格,然后是你的 API 密钥。当 API 密钥像这样被使用时,通常也被称为令牌。这是由一种名为 OAuth 2.0 的授权协议定义的标准。你可以通过访问oauth.net/2/来了解更多关于 OAuth 2.0 的信息。

Postman 非常容易使用持有者标记。但在我们进行经过身份验证的请求之前,让我们看看如果我们尝试在没有我们的 API 密钥的情况下发出请求会发生什么。下图显示了向不带任何授权标头的请求https://api.openai.com/v1/engines发送的请求。您可以看到返回了一个错误消息。您还会注意到 HTTP 响应状态码为401 UNAUTHORIZED

图 4.10 – 不带 API 密钥的 API 请求

图 4.10 – 不带 API 密钥的 API 请求

为了解决错误,我们需要将我们的 API 密钥包含为持有者标记。由于我们将为每个请求使用 API 密钥,因此我们将为 API 密钥设置一个 Postman 变量。

设置 Postman 变量

Postman 中的变量允许您存储并重复使用值,而不必一遍又一遍地输入。变量还可以被分组到一个 Postman 环境中。因此,我们要设置一个名为openai-dev的环境,并添加一个名为OPENAI_API_KEY的变量来存储我们的 API 密钥。

要设置 Postman 环境和 API 密钥变量,请按照以下步骤进行操作:

  1. 点击请求右上角的眼睛图标。

  2. 点击Add链接以添加新环境。

  3. 将环境命名为openai-dev

  4. 添加一个名为OPENAI_API_KEY的变量。

  5. INITIAL VALUE输入框中输入您的 API 密钥。

  6. 点击Save图标以保存环境和变量。

  7. 关闭openai-dev环境选项卡。

  8. 在右上角的环境选项列表中选择新环境。默认情况下,应该显示无环境,你将要选择openai-dev,如下图所示:

图 4.11 – 设置环境的 Postman

图 4.11 – 设置环境的 Postman

环境和OPENAI_API_KEY变量就位后,你可以通过在实际密钥值位置包含{{OPENAI_API_KEY}}来使用你的 API 密钥。现在,让我们尝试使用它,将其用于为我们的请求设置授权标头到引擎端点。

设置授权标头

现在,您的 OpenAI API 密钥已设置为 Postman 变量,请执行以下步骤进行测试:

  1. 在请求 URL 输入框下方点击Authorization选项卡。

  2. 类型下拉列表中选择Bearer Token选项。

  3. Token 输入框中输入{{OPENAI_API_KEY}}

  4. 点击Send按钮。

您应该看到一个成功的响应(HTTP 状态200),如下图所示:

图 4.12 – 使用 API 密钥作为持有者标记的 API 请求

图 4.12 – 使用 API 密钥作为持有者标记的 API 请求

正如前面提到的,承载令牌作为 HTTP 标头发送。在 Postman 中查看标头,点击标头选项卡,然后取消隐藏标头,您将看到带有 API 密钥作为承载令牌值的授权标头,如下截图所示:

图 4.13 – 使用 API 密钥作为承载令牌的授权标头

图 4.13 – 使用 API 密钥作为承载令牌的授权标头

当我们谈论授权和 HTTP 标头时,还需要注意,如果您的用户帐户关联多个组织,您还需要提供组织 ID,以将 API 请求与您希望计费的组织关联起来。

处理多个组织

要将 API 请求与特定组织关联,您将在请求中包含一个OpenAI-Organization HTTP 标头,其中包含您要将请求与的组织的组织 ID。只有在您的用户帐户关联多个组织时才需要这样做。

要在 Postman 中添加 OpenAI-Organization 标头,请滚动到现有标头列表的底部,并添加一个新的标头,名称为OpenAI-Organization,并将值设为您的帐户关联的组织 ID。最好的方法是在 Postman 中添加一个名为OPENAI_ORGANIZATION_ID的新环境,并将{{OPENAI_ORGANIZATION_ID}}添加为值。作为提醒,您可以在 OpenAI 开发者控制台中的帐户设置页面上找到您的组织 ID,如下截图所示:

图 4.14 – 查找您的组织 ID

图 4.14 – 查找您的组织 ID

当您在 Postman 中的 OpenAI-Organization 标头中添加了您的组织 ID 值后,您将在标头列表中看到它,如下截图所示:

图 4.15 – 使用 OpenAI-Organization HTTP 标头

图 4.15 – 使用 OpenAI-Organization HTTP 标头

在本书的其余部分,我们将使用 Postman 来说明和测试 API 调用。但在我们继续之前,让我们看看如何使用 CURL 进行身份验证的 API 调用。

请记住,CURL 是一个命令行工具。因此,它没有像 Postman 那样的图形用户界面。使用 CURL,HTTP 标头作为命令行参数传递。以下是调用列表引擎端点的 CURL 命令示例:

curl https://api.openai.com/v1/engines \
  -H 'Authorization: Bearer {your-api-key}' \
  -H 'OpenAI-Organization: {your-orgainzation-id}'

在替换 {your-api-key} 占位符和 {your-organization-id} 占位符之后,这条命令将返回类似下面截图中所示的结果:

图 4.16 – 使用 CURL 调用列表引擎端点

图 4.16 – 使用 CURL 调用列表引擎端点

现在您知道如何进行对 OpenAI API 的身份验证调用,让我们花点时间来谈谈 JSON,这是 OpenAI API 使用的数据交换格式。

介绍 JSON

在本节中,我们将快速介绍 JSON。JSON 是一种流行的数据交换格式,它轻量级,易于机器解析,也易于人类阅读。

JSON 语法基于 JavaScript 编程语言的子集,它定义了两种数据结构:

  • 名称/值对的集合

  • 有序值列表

这两种数据结构在现代几乎所有编程语言中都以某种方式得到支持。因此,尽管 JSON 语法基于 JavaScript 的子集,但也可以轻松地与其他语言一起使用。

JSON 中的两种数据结构分别定义为对象或数组。对象以左大括号开头,以右大括号结束。一个空对象看起来像下面的示例:

{}

对象可以包含一组名称/值对,称为元素。对象中的元素不需要按任何特定顺序排列,值可以是字符串(用双引号括起来)、数字、true 或 false、null、另一个对象或数组。元素名称和值之间用冒号分隔,元素本身用逗号分隔。以下代码块是来自 OpenAI API 响应的 JSON 对象示例。您会注意到它以大括号开头和结束,并包含具有名称和值的不同元素。请注意,"choices" 元素的值包含以左方括号开头和以右方括号结尾的值 - 那是一个数组:

{
    "id": "cmpl-2T0IrOkctsOm8uVFvDDEmc1712U9R",
    "object": "text_completion",
    "created": 1613265353,
    "model": "davinci:2020-05-03",
    "choices": [
        {
            "text": ", there was a dog",
            "index": 0,
            "logprobs": null,
            "finish_reason": "length"
        }
    ]
}

一个数组是一组有序的值。这些值可以是一组字符串、数字、true 或 false 值、null 值、对象或其他数组。数组始终以左方括号开头,以右方括号结尾,值之间用逗号分隔。

在前面的示例对象中,"choices" 元素的值是一个包含一个对象的数组。该对象包含带有值的元素(textindexlogprobsfinish_reason)。因此,对象和数组可以嵌套。

关于 JSON 的最后一点是,文本的格式,诸如空格、制表符和换行符,是为了人类可读性而做的,但并不是机器所必需的。因此,只要语法有效,它就可以在代码中使用。

例如,以下两个 JSON 对象是相同的,且都是有效的:

例 1:

{"question":"Is this correct? ","answer":"Yes"}

例 2:

{
    "question" : "Is this correct?",
    "answer" : "Yes"
}

如本节前面提到的,OpenAI API 使用 JSON 在客户端和服务器之间发送和接收数据。本节的介绍应该足以开始使用 OpenAI API,但要了解更多关于 JSON 的信息,您也可以访问 www.json.org/

到目前为止,您已经学会了开始使用主要的 OpenAI API 端点 - Completions 端点所需的所有内容。所以,接下来让我们深入了解一下。

使用 Completions 端点

当你使用 OpenAI API 时,你大部分时间可能会涉及到使用 Completions 端点。这是你发送提示的端点。除了提交你的提示外,你还可以包含值来影响完成的生成,就像 Playground 中的设置一样。

使用 Completions 端点比我们在上一节介绍 JSON中看到的 List Engines 端点更加复杂。这是因为 Completions 端点使用 HTTP POST 方法,并且需要一个 JSON 对象作为正文。从技术上讲,JSON 正文可以只是一个空对象(就像 {} 一样),但至少,你会想至少包含 prompt 元素,并将其值设置为你的 prompt 字符串,例如以下的 JSON 示例:

{"prompt": "Once upon a time"}

前面的例子是一个简单的例子,但这是我们如何使用 Postman 提交它。假设授权如前一节所讨论的设置,从 Postman 完成调用 Completions 端点有五个步骤。这些步骤如下:

  1. 将请求类型设置为POST

  2. 输入 https://api.openai.com/v1/engines/davinci/completions 作为端点。

  3. 将正文设置为raw

  4. 选择JSON作为正文内容类型。

  5. 输入 {"prompt": "Once upon a time"} 作为 JSON 正文文本。

    下面的屏幕截图标签显示了每个步骤的完成位置:

图 4.17 - Completions 终端的 Postman 设置

图 4.17 - Completions 终端的 Postman 设置

点击Send按钮后,我们得到了 Completions 端点的响应,如下面的屏幕截图所示:

图 4.18 - Completions 终端的 Postman 响应

图 4.18 - Completions 终端的 Postman 响应

默认情况下,Postman 将使用Pretty设置来显示 JSON 响应,使其对人类查看友好。但是,如果切换到Raw设置,你将看到响应实际上是如何发送的,正如下面的屏幕截图所示:

图 4.19 - Completions 终端的 Postman 响应 – Raw

图 4.19 - Completions 终端的 Postman 响应 – Raw

前面的例子是一个简单的例子,只有一个请求参数 - prompt。然而,端点接受许多其他类似于 Playground 设置的额外参数。为了在请求中包含其他参数,这些参数被包含为 JSON 正文对象中的元素。例如,要发送提示并限制返回的标记数(就像 Playground 中的响应长度设置一样),我们可以包含 max_tokens 参数,如下面的屏幕截图所示:

图 4.20 - Completions 终端的 Postman 响应含有 max_tokens

图 4.20 - Completions 终端的 Postman 响应含有 max_tokens

注意,为了包含max_tokens参数和值,一个新的max_tokens元素被添加到 JSON 主体对象中,并且与"prompt"元素用逗号分隔。其他参数会以相同的方式添加。

可以在 beta.openai.com/docs/api-reference/create-completion 找到所有可用参数的列表,我们这里不会全部涵盖。然而,大多数参数在 Playground 中都有对应的设置,我们在第三章使用 OpenAI Playground 中已经介绍过,所以它们对你来说应该是熟悉的。

在我们继续之前,让我们看看另一个例子,一个你无法从 Playground 中完成的例子。在这个例子中,我们将同时提交多个提示,并针对每个提示返回一个完成。我们将使用以下 JSON:

{
  "prompt": ["The capital of California is:", "Once upon a time"],
  "max_tokens":7,
  "temperature": 0,
  "stop": "\n"
}

注意"prompt"元素的值是一个 JSON 数组,包含两个值,"加利福尼亚的首府是:", 和 "从前有一只"。通过发送提示的数组,完成端点将为每个提示返回完成,如下面的截图所示:

图 4.21 – 发送多个提示

图 4.21 – 发送多个提示

从这个例子中得出的主要结论是,有一些事情你可以通过 API 做到,但在 Playground 中做不到。因此,了解如何使用 OpenAI API 使你能够超越 Playground 的功能。

API 中可以做但 Playground 中无法做的另一个例子是语义搜索。下面我们来看看这个。

使用语义搜索端点

第二章GPT-3 应用与用例中,我们讨论了语义搜索。简单回顾一下,语义搜索让你可以在提供的文档列表上执行类似 Google 的搜索。一个查询(一个词、短语、问题或语句)会与文档内容进行比较,以确定是否存在语义相似性。结果是每个文档的排名或得分。得分通常介于 0 和 300 之间,但有时会更高。一个更高的分数,超过 200,通常意味着文档在语义上与查询相似。

要使用 API 进行语义搜索,您需要向语义搜索端点发出 POST 请求。 就像创建补全端点一样,在请求主体中还需要包含一个 JSON 对象。 JSON 主体对象有两个元素-文档元素和查询元素。 文档元素是要搜索的文档数组,数组中的每个项目都是表示文档的字符串。 或者,可以在请求中引用预先上传的文件中提供的文档。 在第九章构建一个 GPT-3 驱动的问答应用程序,我们将详细讨论如何使用文件。 然而,现在我们将重点放在通过端点请求提供文档。

一个文档可以是单词,句子,段落或更长的文本。 查询元素的值是包含将与文档进行搜索的搜索词或短语的字符串。 这可能是类似问题或陈述的一些东西。

再次,语义搜索根据其在语义上与一个或多个文档的相似性来对查询进行排名。 因此,这不一定是搜索相似单词。 例如,以下 JSON 对象提供了车辆(飞机,船,宇宙飞船或汽车)的列表作为文档,查询为"带轮子的车辆"

{
  "documents": [
    "plane",
    "boat",
    "spaceship",
    "car"
  ],
  "query": "A vehicle with wheels"
}

让我们看看上述 JSON 的结果会是什么样子。 我们将使用 Postman。 请记住,所有 OpenAI API 端点都需要授权,因此在 Postman 中,我们首先确保适当的授权设置得以展开。 从那里开始,步骤与发出对补全端点的请求是一样的:

  1. 将请求类型设置为POST

  2. 输入URI端点。

  3. 将主体设置为原始

  4. 选择JSON作为主体内容类型。

  5. 输入 JSON 主体。

语义搜索端点 URI 是 https://api.openai.com/v1/engines/{engine_id}/search,其中 {engine_id} 被有效的引擎 ID(如 davinciada)替换。 在 Postman 中设置并提交 API 调用后,您应该看到类似以下截图的结果:

图 4.22 – 语义搜索结果

图 4.22 – 语义搜索结果

语义搜索端点返回的 JSON 对象包含三个元素:对象,数据和引擎。 数据元素的值是结果的 JSON 数组-每个文档的一个项目。 从我们之前对 JSON 的介绍中回忆,数组中的项目是有序的,意味着每个项目都可以用数字引用,第一个从零开始。 因此,在我们的例子中,以下值会适用:

  • 0 = 飞机

  • 1 = 船

  • 2 = 太空船

  • 3 = 汽车

知道每个文档都与一个数字值相关联后,当您查看从搜索 API 返回的以下结果时,您会发现文档 3(汽车)获得了最高分,因此代表了与语义最相似的文档:

{
    "object": "list",
    "data": [
        {
            "object": "search_result",
            "document": 0,
            "score": 56.118
        },
        {
            "object": "search_result",
            "document": 1,
            "score": 46.883
        },
        {
            "object": "search_result",
            "document": 2,
            "score": 94.42
        },
        {
            "object": "search_result",
            "document": 3,
            "score": 178.947
        }
    ],
    "model": "davinci:2020-05-03"
}

数据数组中包含的是文档号而不是文档本身,因为文档本身可能是一长串文本,使用文档号更有效。因此,在匹配返回的结果与发送的文档时,您需要使用文档号。但当您使用代码进行操作时,这相对直接 – 这也是我们将在下一章开始的内容。

总结

在本章中,我们讨论了如何使用 OpenAI API。我们从介绍/回顾 API 是什么开始,然后熟悉了 HTTP 协议的基础知识。我们审查了 OpenAI API 的端点,并涵盖了如何使用 OpenAI API 密钥进行基本身份验证以访问 API,以及如何对具有对多个组织访问权限的帐户进行身份验证。然后,我们了解了 JSON 数据交换格式,然后学习了如何使用 Postman 对 Completions 端点、Engines 端点和 Semantic Search 端点进行 API 调用。

在下一章,我们将把本章学到的知识付诸实践,深入了解如何使用代码调用 API。

第五章:在代码中调用 OpenAI API

在上一章中,我们看了一下如何使用 Postman 调用 OpenAI API。在这一章中,你将学习如何在代码中开始使用 API。因为 OpenAI API 几乎可以与任何编程语言一起使用,我们将看一下两种流行的语言,JavaScript 和 Python。如果你不是程序员,没问题。我们将使用一个在线环境,让入门编程变得非常简单。而且,JavaScript 和 Python 都提供了易于跟随的代码示例,因此你可以选择最适合你的语言。此外,为了清晰起见,示例故意尽可能少地写代码。因此,示例可能并不总是遵循编码最佳实践,但目标是使跟随变得更容易!

本章将涵盖以下主题:

  • 选择编程语言

  • 介绍 replit.com

  • 使用 Node.js/JavaScript 使用 OpenAI API

  • 使用 Python 使用 OpenAI API

  • 使用其他编程语言

技术要求

本章需要你可以访问OpenAI API。你可以通过访问以下网址请求访问权限:openai.com

选择编程语言

OpenAI API 是一个基于标准的 API,可用于几乎任何现代编程语言。在本章中,我们将介绍 JavaScript 和 Python 的例子。但这只是众多可用语言中的两种。选择 JavaScript 和 Python 是因为它们都非常受欢迎且易于上手。如果你精通其他现代编程语言,那可能是最好的选择。但如果你是新手,或者你的编程技能有些生疏,或者想尝试一种新语言,那么 JavaScript 和 Python 都是很好的选择。但是每种语言的例子都是相同的,只是编程语言不同。因此,你可以跳到你偏好的语言部分。或者,如果你感到有冒险精神,当然你可以尝试两种语言!

介绍 replit

在本章以及接下来的章节中,我们将会编写代码。因此,我们需要某种代码编辑器。就像编程语言一样,当涉及到代码编辑器时,有很多选择。选择正确的代码编辑器是一个个人偏好和观点问题。对于我们的例子,我们将使用来自replit.com的在线代码编辑器。

虽然我们将要讨论的所有示例都可以在任何代码编辑器中完成,但 replit 可以让我们跳过安装和软件设置过程,因为我们可以在网页浏览器中完成所有操作。

此外,使用代码编辑器时,需要在本地计算机上进行一些设置。例如,JavaScript 和 Python 都需要安装运行环境。我们会跳过这些,这样就能更多时间专注于学习 GPT-3 和 OpenAI API。

那么,replit.com 是什么?它是一个基于浏览器的代码编辑器和集成开发环境(IDE),让你可以在 50 多种编程语言中开始编码,而无需花费时间设置本地开发环境。所以,对于我们的示例,即使你的本地计算机没有设置好运行 Node.js 或 Python 的环境,你也可以立即开始编码。

下面的截图展示了 replit 的主页,如果你还没有,则可以在这里免费注册一个 replit 账户:

图 5.1 – replit 主页

��5.1 – replit 主页

创建一个账户只需要点击注册按钮并完成注册过程。在本书的示例中,你只需要一个免费账户。

在你注册完后,你将登录到默认的主页,如图 5.2所示:

图 5.2 – Replit 默认主页

图 5.2 – Replit 默认主页

从这里,我们将创建两个代码项目,它们在 replit 中被称为repl

创建一个 repl

我们将会查看 JavaScript 和 Python 的代码示例。所以,我们需要分别为两种语言设置 repl。对于 JavaScript,我们将会使用Node.js(或者简称为 Node),它是 JavaScript 的运行环境。我们会在使用 Node.js/JavaScript 调用 OpenAI API部分详细讨论 Node.js。首先,我们会创建一个 Python 的 repl。然后,再创建一个 Node.js/JavaScript 的 repl。

为 Python 创建一个 repl

让我们从为 Python 创建一个新的 repl 开始。如果你更喜欢只使用 Node.js/JavaScript 进行示例,你可以直接跳到为 Node.js 创建一个 repl

从主页,点击+ New Repl按钮:

  1. 从 repl 类型下拉菜单中选择 Python。

  2. 将 repl 命名为 exploring-gpt3-python

  3. 点击创建 repl按钮。

接下来,我们将为 Node.js 创建一个 repl。如果你只会使用 Python,你可以跳过下一部分。

为 Node.js 创建一个 repl

如果你跟着做 Node.js 实例,你将需要一个 Node repl。要创建一个 Node repl,按照以下步骤。从主页,点击+ New Repl按钮:

  1. 从 repl 类型下拉菜单中选择 Node.js。

  2. 将 repl 命名为 exploring-gpt3-node

  3. 点击创建 repl按钮。

下面的截图展示了为 Python 创建一个新的 repl。同样的,对于 JavaScript,你会选择 Node.js 而不是 Python,然后将 repl 命名为 exploring-gpt3-node

图 5.3 – 设置 Python 的 repl

图 5.3 – 设置 Python 的 repl

创建完 repl 后,你会自动被重定向到 replit 编辑器,里面已经加载了你的新 repl。编辑器分为三个窗格:导航窗格、代码编辑窗格和输出窗格。新的 repl 包括一个默认文件,当你第一次访问 repl 时会在代码编辑器(中间窗格)打开。

对于 Python 项目, 默认文件命名为main.py; 对于 Node.js 项目,默认文件命名为index.js。以下屏幕截图显示了在编辑器窗格中打开的main.py的 replit 编辑器。Node.js repl 看起来相同,但默认文件名为index.js而不是main.py

图 5.4 - 具有默认 Python repl 的 Replit 编辑器

图 5.4 - 具有默认 Python repl 的 Replit 编辑器

默认文件是默认情况下在单击Run按钮时运行的代码文件。运行按钮位于位于三个编辑窗格正上方的顶部导航栏中间。然后,在 replit 控制台 - 右侧的输出窗格中显示代码的结果或输出。

重要提示

默认文件在首次创建 repl 时为空,因此单击Run按钮不会执行任何操作,直到您编写一些代码为止。

在三个编辑窗格的上方导航栏左侧是一个汉堡菜单(看起来像是叠在一起的线条的图标)。如果您点击该图标,则会显示主导航选项。您可以使用此菜单通过选择我的 repls菜单并选择要打开的 repl 来在 repl 之间导航。

以下屏幕截图显示了选定了我的 repls选项的主菜单:

图 5.5 - 访问主导航菜单

图 5.5 - 访问主导航菜单

为您想要使用的语言创建 repl(或两种语言),您将需要将您的 OpenAI API 密钥存储为环境变量。

将您的 OpenAI API 密钥设置为环境变量

环境变量是可以在代码中访问但不会与其他人共享的命名值。通常,您使用环境变量来设置私有或特定于用户的参数值,例如,您的 OpenAI API 密钥。

在 replit 中,您可以通过单击导航窗格中的挂锁图标(Secrets)并添加名称和值对来保存环境变量。您需要为您正在使用的每个 repl 进行此操作 - 因此,在您的exploring-gpt3-node repl 和/或exploring-gpt3-python repl 中的一个中都需要这样做。要将您的 OpenAI API 密钥添加为环境变量,请执行以下操作:

  1. 打开您的 repl。

  2. 单击导航窗格中间的挂锁图标(Secrets),如下面的屏幕截图所示:图 5.6 - 在 Replit 中添加新的秘密/环境变量

    图 5.6 - 在 Replit 中添加新的秘密/环境变量

  3. OPENAI_API_KEY中。

  4. Value输入文本区域中,粘贴您的 OpenAI API。

  5. 单击Add new secret按钮。

同样,如果您要跟随 Node.js 和 Python 进行操作,则需要向每个 repl 添加OPENAI_API_KEY秘密/环境变量。因此,如果您同时跟随两者,您将完成上述步骤两次。

重要提示

如果您使用的是 replit.com 的免费版本,默认情况下,您的代码将是公开的。但是,secrets/environment variables 不会被公开共享,但可以被明确邀请到 repl 的合作人员看到。这很重要,因为您不希望共享或意外暴露您的 OpenAI API 密钥。要了解更多关于在 replit 中使用秘密和环境变量的信息,访问docs.replit.com/repls/secret-keys

在开始编码之前,我们需要创建一个特殊的文件,即.replit文件。

理解并创建.replit文件。

在 replit 中,默认情况下,当您单击时,main.py 文件将为 Python repl 运行,index.js 文件将为 Node.js repl 运行。但是,您可以创建一个名为.replit的文件,并更改由.replit文件执行的代码文件。要创建.replit文件,请执行以下操作:

  1. 打开您的 repl。

  2. 单击导航窗格右上角的添加文件图标。

  3. 将文件命名为.replit

  4. 将以下文本添加到.replit文件的第一行中:

    对于 Python repl

    run = "python main.py"
    

    对于 Node.js repl

    run = "node index.js"
    

您可能已经注意到,我们刚刚添加了要按默认方式运行的文件的说明。现在没问题,稍后我们将回来编辑我们.replit文件中的run语句。

当您为 Node.js 或 Python 创建 repl,并将您的 OpenAI API 密钥添加为环境变量,并添加一个.replit文件后,您就可以开始编码了。因此,在下一节中,我们将看一下使用 Node.js/JavaScript 的示例。但是,如果您只是在 Python 方面跟着做,您可以直接跳到在 Python 中使用 OpenAI API

使用 Node.js/JavaScript 调用 OpenAI API

JavaScript 是我们要看的第一种编程语言。JavaScript 最初是为在网页上编写脚本功能而创建的。然而,如今,JavaScript 可以用于几乎任何类型的应用程序开发,从构建网站和移动应用程序到创建命令行工具、聊天机器人和语音助手 - 这一切都归功于 Node。如前所述,Node 是 JavaScript 的运行时环境。它使我们能够在网页浏览器之外使用 JavaScript。

JavaScript 和 Node.js 都是免费使用的,并且可以在 Linux、macOS 和 Windows 操作系统上运行。但我们不会安装 Node.js,也不会在本地运行任何东西,因为我们所有的代码都将在 replit 上运行。但是,我们将编写的代码中没有任何与 replit 有关的依赖。因此,我们将要做的所有事情都可以在任何为 Node 开发正确配置的环境中完成。

好了,让我们开始编码。为了在 Node 中使用 OpenAI API,我们基本上只需做和第四章与 OpenAI API 一起工作一样的步骤 – 对 OpenAI API 端点进行身份验证的 HTTP 请求。但是我们不会使用 Postman,而是会使用 JavaScript 进行 HTTP 请求。我们将从最简单的例子开始 – 调用 engines 端点。

调用 engines 端点

我们将首先设置一个新的文件夹来进行本章的工作。然后,我们将添加一个文件作为我们第一个示例,并更新 .replit 文件,以便 replit Run 按钮执行我们的新文件。以下是要遵循的步骤:

  1. 打开您的exploring-gpt3-node repl。

  2. 点击导航窗格右上角的添加文件夹图标。

  3. 命名文件夹为 chapter05

  4. 选择 chapter05 文件夹,然后单击 engines.js

  5. 编辑 .replit 文件,使 chapter05/engines.js 使用以下文本:

    run = "node chapter05/engines.js"
    
  6. 现在,通过单击导航窗格中的文件名来打开您的 replit 编辑器中的 chapter05/engines.js 文件。您的 replit 编辑器应该看起来类似以下屏幕截图:图 5.7 – 在 Replit 编辑器中编辑 engines.js

    图 5.7 – 在 Replit 编辑器中编辑 engines.js

  7. 现在,我们要编写一些代码调用 https://api.openai.com/v1/engines。有许多种方式可以使用 Node 和 JavaScript 进行 HTTP 请求。我们不会详细介绍所有不同选项或一个方法优于另一个方法的优点和缺点。我们只会使用一个流行的代码库(称为 axios)。

    重要提示

    Node.js 中打包和共享的代码库在大多数现代编程语言中都很常见。在 Node.js 中,包(或模块)最常使用一个名为 npm 的包管理器共享。要了解更多关于 npm 的信息,您可以访问 npmjs.com。replit 自动管理 Node.js 项目的包依赖关系。但是,在本地开发环境中,通常使用 Npm 命令行工具来管理代码中使用的包。

  8. 简而言之,axios 模块最大程度地减少了我们使用 JavaScript 进行 HTTP 请求时需要编写的代码。因此,我们将在我们的 engines.js 文件的第一行包含对 axios 模块的引用,代码如下:

    const axios = require('axios);
    
  9. 你会记得第四章, 与 OpenAI API 一起工作,所有 OpenAI API 端点都需要授权。因此,在下一行,我们将添加一个变量来保存我们的 OpenAI API 密钥。但是,我们不会硬编码数值,而是从我们设置的环境变量中获取:

    const apiKey = process.env.OPENAI_API_KEY;
    
  10. 接下来,我们将创建一个内部 HTTP 客户端来进行请求。axios 模块使这变得非常简单。为了创建 HTTP 客户端实例,我们将添加以下代码:

    const client = axios.create({
        headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    

    请注意,在上述代码中,我们添加了一个使用我们的 OpenAI API 密钥作为令牌的 HTTP Authorization头。这样,axios客户端可以对 API 端点进行身份验证请求。现在剩下的只是实际发出请求的代码。以下是该代码的样子:

    client.get('https://api.openai.com/v1/engines')
      .then(result => {
        console.log(result.data);
    }).catch(err => {
        console.log(err.message);
    });
    

    在上述代码中,我们使用axios客户端实例向https://api.openai.com/v1/engines端点发出 GET 请求。然后,我们将从端点返回的结果记录到控制台中。或者,在出现错误时,我们将错误消息记录到控制台中。

  11. 此时,您应该能够在 replit 中单击运行按钮,并在 replit 控制台中看到结果,在那里会有一个如下所示的输出:

图 5.8 – 运行 engines.js 代码的结果

图 5.8 – 运行 engines.js 代码的结果

因此,我们使用了 12 行代码(实际上是 11 行,因为有一行是空的),我们使用 JavaScript 和 Node 进行了我们的第一个 API 请求。

现在让我们看看如何调用 Completions 端点。这个稍微复杂一些,因为我们需要向端点发送数据。但是,代码仍然非常简单。

调用 Completions 端点

现在我们将看看如何调用完成端点。我们将首先在chapter05文件夹中创建一个名为completions.js的新文件,并编辑我们的.replit文件,以便运行按钮将执行我们的新文件。要做到这一点,请按照以下步骤操作:

  1. 打开您的exploring-gpt3-node repl。

  2. 在导航窗格中选择chapter05文件夹。

  3. 单击completions.js

  4. 编辑.replit文件,以便使用以下文本chapter05/completions.js

    run = "node chapter05/completions.js"
    
  5. 接下来,将chapter05/engines.js中的前五行代码复制到chapter05/completions.js中,以便您的completions.js文件以以下代码开始:

    const axios = require('axios');
    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
        headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    

    对于 Completions 端点,我们将发送参数。因此,我们接下来要做的是添加将成为 HTTP 正文中发送的 JSON 对象。请回想一下第四章使用 OpenAI API,Completions 端点接受许多参数。但是,对于本示例,我们只发送prompt参数和max_tokens参数。以下是代码的样子:

    const completionParams = {
      "prompt": "Once upon a time", 
      "max_tokens": 10
    }
    

    现在我们只需实际发出请求。这一次我们将进行 HTTP POST 请求并传递参数。因此,代码与上一个示例略有不同,但看起来像这样:

    client.post('https://api.openai.com/v1/engines/davinci/completions', completionParams)
      .then(result => {
      console.log(result.data);
    }).catch(err => {
      console.log(err);
    });
    

    就这样。现在当您在 replit 中单击运行按钮时,您应该会从 Completions 端点收到一个类似以下截图的结果:

图 5.9 – Completions.js 的输出

图 5.9 – Completions.js 的输出

正如我们在第四章中所讨论的,使用 OpenAI API,从端点返回的响应是以 JSON 格式返回的。但是,如果您想要格式化输出,您可以从 JSON 中提取您想要显示的内容。例如,您可以使用以下代码更新console.log(result.data)以显示 API 返回的原始提示文本从前,有一只...和完成文本:

console.log(completionParams.prompt + result.data.choices[0].text);

如果您进行了更改并再次运行代码,则输出将类似于以下截图中的输出:

图 5.10 – 来自 completions.js 的格式化结果

图 5.10 – 来自 completions.js 的格式化结果

仅仅通过两个示例,我们就介绍了您需要使用所有 OpenAI 端点的基本代码。但在我们继续之前,让我们看一看使用搜索端点的另一个示例。

调用搜索端点

对于我们的搜索示例,我们将在chapter05文件夹中创建一个名为search.js的新文件,并编辑我们的.replit文件,以便chapter05/search.js。要实现这一点,请按照以下步骤进行:

  1. 打开您的exploring-gpt3-node repl。

  2. 在导航窗格中选择chapter05文件夹。

  3. 点击search.js

  4. 编辑.replit文件,使chapter05/search.js使用以下run命令:

    run = "node chapter05/completions.js"
    
  5. 接下来,将chapter05/engines.js中的前五行代码复制到chapter05/search.js中,使您的search.js文件以以下代码开始:

    const axios = require('axios');
    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
        headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    
  6. 对于搜索端点,我们将发送参数。因此,接下来我们将添加即将发送到 HTTP 主体中的 JSON 对象。在第四章中,我们讨论了搜索端点的参数,但以下是我们将在此示例中使用的代码:

    const data = {
      "documents": ["plane", "boat", "spaceship", "car"],
      "query": "A vehicle with wheels"
    }
    
  7. 剩下的就是实际发出请求。就像完成示例一样,我们将进行 HTTP POST 并传递我们的参数:

    client.post('https://api.openai.com/v1/engines/davinci/search', data)
      .then(result => {
        console.log(result.data);
      }).catch(err => {
        console.log(err);
      });
    
  8. 就这样。现在,当您在 replit 中点击运行按钮时,您应该会从搜索端点获得类似以下截图的结果:

图 5.11 – 来自 search.js 的结果

图 5.11 – 来自 search.js 的结果

我们在本节中讨论的所有 JavaScript 示例都相当简单。但是,它们应该给您一个使用 JavaScript 和 Node.js 开始调用 OpenAI API 的一般思路,这正是我们的目标。在接下来的章节中,我们将更深入地讨论,但现在我们将转向我们的下一个语言–Python。

使用 Python 中的 OpenAI API

Python 是另一种流行的编程语言,在机器学习社区中尤其受欢迎。 这是一种强大的语言,但也非常适合初学者。 如果你是第一次编程,那么 Python 可能是最容易入门的语言之一。 与 JavaScript/Node 一样,Python 是开源的,可以在 Linux、macOS 或 Windows 上使用。 它还包含在许多操作系统中,包括 macOS 和大多数 Linux 发行版。 但由于我们将在 replit 中工作,所以不需要担心 Python 是否安装在我们的本地机器上。 也就是说,我们将要编写的代码中没有任何依赖于 replit 特定内容的地方。 因此,我们将在任何正确配置用于 Python 开发的计算机上完成所有工作。

对于我们的第一个示例,我们将看一下如何使用 Python 调用 OpenAI Engines 端点。

调用 engines 端点

我们将通过为本章中即将开发的 Python 代码设置一个新文件夹开始。 然后,我们将添加一个文件作为我们的第一个示例,并更新.replit文件,以便 replit Run 按钮可执行我们的新文件。 应按照以下步骤操作:

  1. 打开你的exploring-gpt3-python replit。

  2. 点击导航窗格右上角的添加文件夹图标。

  3. 将文件夹命名为chapter05

  4. 选择chapter05文件夹,然后点击engines.py

  5. 编辑.replit文件,使得chapter05/engines.py使用以下文本:

    run = "python chapter05/engines.py"
    
  6. 现在,通过导航窗格中点击文件名,在 replit 编辑器中打开chapter05/engines.py文件。 您的 replit 编辑器应该看起来类似于以下截图:图 5.12 – 在 Replit 编辑器中编辑 engines.py

    图 5.12 – 在 Replit 编辑器中编辑 engines.py

  7. 现在,我们将编写一些 Python 代码,以向https://api.openai.com/v1/engines端点发出 HTTP 请求。 有许多方法可以使用 Python 发出 HTTP 请求。 我们不会深入探讨所有不同的选项,或者一种方法胜过另一种方法的利弊。 我们只是将使用流行的requests库。

    重要提示

    包装和共享的代码库在大多数现代编程语言中很常见。 在 Python 中,包(或库)通常使用一个名为 PIP 的软件包管理器进行共享。 要了解有关 PIP 的更多信息,您可以访问pypi.org/project/pip/。 replit 自动管理 Python 项目的软件包依赖关系。 但是,在本地开发环境中,常用的是使用 PIP 命令行工具来管理 Python 包。

  8. 简而言之,requests库最大程度地减少了我们需要编写的代码,以使用 Python 进行 HTTP 请求。 因此,我们将在我们的engines.py文件的第一行包含对requests库的引用,代码如下所示:

    import requests
    
  9. 你可能还记得第四章使用 OpenAI API,OpenAI API 的所有端点都需要授权。所以下一步我们将添加一些代码来获取我们在.env文件中设置的 API 密钥,并将其保存到一个变量中。我们将使用以下行来做到这一点:

    import os
    apiKey = os.environ.get("OPENAI_API_KEY")
    
  10. 接下来,我们将创建一个名为headers的变量来保存我们的授权信息,这些信息将被用于发起 HTTP 请求:

    headers = {
        'Authorization':'Bearer ' + apiKey
        }
    
  11. 现在我们所需要做的就是发起请求。我们将使用以下代码来做到这一点,并将响应保存到一个名为result的变量中:

    result = requests.get('https://api.openai.com/v1/engines'
    ,headers=headers)
    
  12. 为了在控制台中显示 JSON 结果,我们将添加最后一行,如下所示:

    print(result.json())
    
  13. 在这一点上,你应该能够在 replit 中点击Run按钮,在 replit 控制台中看到结果,并看到一个类似以下截图的输出:

图 5.13 – 运行 engines.py 代码的结果

图 5.13 – 运行 engines.py 代码的结果

所以,用 12 行代码(实际上是 9 行,因为有三行是空白行),我们已经使用 Python 发起了我们的第一个 API 请求。现在让我们来看一下调用 Completions 端点。这个端点需要更多的代码,因为我们需要向端点发送数据。但正如你将看到的,这还是相当简单的。

调用 completions 端点

我们将从在chapter05文件夹中创建一个名为completions.py的新文件开始。然后我们将编辑我们的.replit文件,使chapter05/completions.py。要做到这一点,请按照以下步骤操作:

  1. 打开你的exploring-gpt3-python repl。

  2. 在导航窗格中选择chapter05文件夹。

  3. 点击completions.py

  4. 编辑.replit文件,使chapter05/completions.py使用以下文本:

    run = "python chapter05/completions.py"
    
  5. 接下来,我们将添加以下代码。它与chapter05/engines.py中的起始代码非常相似,但我们需要添加json库和Content-Type头。所以,你的completions.py文件应该以以下代码开头:

    import requests
    import os
    import json
    apiKey = os.environ.get("OPENAI_API_KEY")
    headers = {
        'Content-Type': 'application/json',
        'Authorization':'Bearer ' + apiKey
        }
    
  6. 对于 completions 端点,我们将发送参数。所以下一步我们要做的就是添加即将成为发送到 HTTP 主体的 JSON 对象。回想一下第四章使用 OpenAI API,completions 端点接受许多参数。但是对于这个示例,我们只会发送prompt参数和max_tokens参数。代码如下所示:

    data = json.dumps({
        "prompt":"Once upon a time",
        "max_tokens":15
        })
    

    为了使代码更易读,我们还将使用以下代码创建一个端点 URL 的变量:

    url = 'https://api.openai.com/v1/engines/davinci/completions'
    
  7. 唯一剩下的就是实际发起请求并打印出结果。这次,我们将进行 HTTP POST,并传递我们的参数。所以,代码与上一个示例略有不同,但看起来像这样:

    result = requests.post(url,headers=headers,data=data)
    print(result.json())
    
  8. 就这样。现在当你点击 replit 中的Run按钮时,你应该会从 completions 端点得到一个结果,类似于以下截图所示:图 5.14 – completions.js 的输出

    图 5.14 – completions.js 的输出

  9. 正如我们在Chapter 4中讨论的,使用 OpenAI API,从端点返回的响应是 JSON 格式的。但是如果你想格式化输出,你可以从 JSON 中提取你想要显示的内容。例如,你可以使用以下代码更新 console.log(result.data),以显示 API 返回的原始提示文本 Once upon a time 和完成文本:

    console.log(completionParams.prompt + result.data.choices[0].text);
    
  10. 如果您进行了这些更改并再次运行代码,则控制台输出应该与以下截图中的输出类似:

图 5.15 – completions.py 的格式化结果

图 5.15 – completions.py 的格式化结果

好的,让我们看一个更多的例子。这次我们将使用 Python 调用搜索端点。

调用搜索端点

对于我们的搜索示例,我们将在 chapter05 文件夹中创建一个名为 search.py 的新文件,并且我们将编辑我们的 .replit 文件,以便 chapter05/search.py。要做到这一点,请按照以下步骤进行:

  1. 打开你的 exploring-gpt3-python repl。

  2. 在导航面板中选择 chapter05 文件夹。

  3. 点击 search.py

  4. 编辑 .replit 文件,使运行按钮执行 chapter05/search.py,使用以下 run 命令:

    run = "python chapter05/search.py"
    
  5. 接下来,将 chapter05/completions.py 中的前九行代码复制到 chapter05/search.py 中,这样你的 search.py 文件将以以下代码开头:

    import requests
    import os
    import json
    apiKey = os.environ.get("OPENAI_API_KEY")
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + apiKey
    }
    
  6. 对于搜索端点,我们将像在 chapter05/completions.py 中那样发送参数。所以,我们接下来要做的就是添加将成为 HTTP 正文中发送的 JSON 对象。在Chapter 4中,使用 OpenAI API,我们涵盖了搜索端点的参数,我们将使用相同的示例 – 这是我们将使用的代码:

    data = json.dumps({
        "documents": ["plane", "boat", "spaceship", "car"],
        "query": "A vehicle with wheels"
    })
    
  7. 我们将添加一个变量来存储端点 URL,以便代码更容易阅读一些:

    url = 'https://api.openai.com/v1/engines/davinci/search'
    
  8. 最后,我们将添加代码来发起请求并打印结果:

    result = requests.post(url, headers=headers, data=data)
    print(result.json())
    
  9. 就这样。现在,当你点击 replit 中的 Run 按钮时,你应该会从完成端点得到一个类似以下截图的结果:

图 5.16 – search.py 的结果

图 5.16 – search.py 的结果

本节的目标是提供一些简单的 Python 示例,调用 OpenAI API。到目前为止,我们已经涵盖了基础知识,但在接下来的章节中,我们将看到更深入的例子。

使用其他编程语言

在本章中,我们只看了使用 JavaScript 和 Python 的代码示例。但再次强调,几乎任何现代编程语言都可以使用。OpenAI API 是一个基于标准的 HTTP API,所以你只需要一种能够发起 HTTP 请求并处理 JSON 的语言,而这几乎包括所有现代编程语言。

此外,在本章的示例中,我们直接使用通用的 HTTP 库调用 API。我们也可以使用专为 OpenAI API 构建的库。JavaScript、Python 和其他语言包括 C#/.NET、Go、Java 和 Unity 都存在多个库。您可以在beta.openai.com/docs/developer-quickstart/community-libraries找到社区维护的库列表。

库可以简化与 OpenAI API 的使用。然而,了解如何直接调用端点以及 API 的使用相当简单是很有帮助的。出于这些原因,我们将在本书的所有示例中直接使用 API。

总结

在本章中,我们在代码中使用了 OpenAI API。我们首先介绍了在浏览器中使用的集成开发环境 replit。然后,我们看了一下调用引擎端点、完成端点和搜索端点的代码示例,使用了 Node.js/JavaScript 和 Python。最后,我们讨论了其他可以使用的语言和可以简化与 OpenAI API 集成工作的库。

在下一章中,我们将讨论内容过滤,并查看使用 JavaScript 和 Python 实现内容过滤的代码示例。

第三部分:使用 OpenAI API

本节提供了使用 OpenAI API 与 Node.js/JavaScript 和 Python 的实际示例。然后,它通过指导您构建一个完全功能的 GPT-3 驱动的 Web 应用来结束。

本节包括以下章节:

  • 第六章内容过滤

  • 第七章生成和转换文本

  • 第八章文本分类和分类

  • 第九章构建一个由 GPT-3 驱动的问答应用

  • 第十章使用 OpenAI 驱动的应用上线

第六章:内容过滤

第一章中,介绍 GPT-3 和 OpenAI API,我们简要提到了一个内容过滤模型,用于识别潜在的冒犯或有害语言。我们还讨论了 GPT-3 有时会生成一些可能被一些人认为不当或伤害的完成。在本章中,您将学习如何实现内容过滤,以防止您的应用程序用户看到冒犯性或可能有害的完成。

本章我们将涵盖以下主题:

  • 预防不当和冒犯性结果

  • 了解内容过滤

  • 测试内容过滤过程

  • 使用 JavaScript 进行内容过滤

  • 使用 Python 进行内容过滤

技术要求

本章要求您能够访问OpenAI API。您可以通过访问openapi.com来请求访问权限。

预防不当和冒犯性结果

有时,GPT-3 会生成一些被一些用户认为不当的文本。这可能是粗话、含有不当的种族、宗教或政治用语,或者性不当/露骨的内容,或者性质黑暗或暴力的文本。这并不是因为 GPT-3 试图恶意或伤害别人——它只是一个根据统计概率生成文本的语言模型——它没有恶意不当的概念。但 GPT-3 是使用互联网数据进行训练的,而互联网上不幸存在大量冒犯性内容。因此,模型有时会生成不适当的内容。值得庆幸的是,作为开发者,我们可以采取措施防止用户看到 GPT-3 可能生成的不适当响应。

避免不适当内容的最简单方法是利用您的提示文本来引导模型避免生成可能不适当的结果。一般来说,GPT-3 会模仿提示的结构和内容。因此,您可以通过告诉模型完成应该友好或礼貌,来引导模型远离可能的不适当结果,例如。但是无论如何,您都需要测试。例如,“友好”这样的词也可能导致性内容。因此,请使用提示来引导模型,并根据您看到的结果来精确控制措辞。

为了说明,这里有两个假设客服问题的示例提示和相关完成。在示例中,#$%@! 用于代替原始提示和完成中使用的脏话(诅咒词)。

  • 示例 1:

    提示:

    Customer: Where the #$%@! is my order! I placed the order more than three days ago. How long can it take to package and ship a #$%@! tee-shirt?
    Response: 
    

    完成:

    I don't know. This is my first #$%@! day on the job. If you want, I can call you a #$%@! taxi so you can come pick up your #$%@! Order.
    
  • 示例 2:

    提示:

    Customer: Where the #$%@! is my order! I placed the order more than three days ago. How long can it take to package and ship a #$%@! tee-shirt?
    Polite Response: 
    

    完成:

    It can take up to 5 business days for in stock t-shirts to be processed. You ordered three t-shirts and each shirt takes a different amount of production time to be produced. There were some complications with your order but as of today your t-shirts should be fully prepared for shipping. 
    

两个提示之间的唯一区别是,第二个示例末尾包含Polite Response:,而不仅仅是Response:。这足以指导模型生成更适当语言的回应。为了进一步指导模型,您还可以提供一个或多个对于攻击性或不礼貌客户问题的样本,以便提供有礼貌回应。

这里的关键是提示是最小化不适当回应的第一种,也是最容易的方法。

另一种防止不当完成的方法是限制完成的返回内容。例如,如果你正在对文本进行分类或总结,模型将在结果中包含的内容方面受到限制。

在不受约束的完成情况下,例如,如果你为聊天机器人生成回应,你将希望使用内容过滤,这将在接下来进行讨论。此外,零-shot 提示,没有示例,很可能会导致不可预测的完成。

了解内容过滤

内容过滤是指阻止或隐藏可能被视为冒犯、不当或甚至危险的内容。在我们的情况下,我们谈论的是 GPT-3 生成的内容,我们不希望我们的应用用户看到的内容。

为了过滤潜在的冒犯或不安全的文本,我们需要编写一小段代码来评估 GPT-3 生成的文本,并对其进行安全、敏感或不安全的分类。Cool 的地方在于我们可以使用 GPT-3 来进行分类。因此,这有点像自我管理,但在一定程度上依靠我们的代码进行辅助。

从高层次上看,这是我们如何使其工作的方式:

  1. GPT-3 对提示生成一个完成。

  2. 完成的文本被提交回 GPT-3 过滤引擎。

  3. 过滤引擎返回一个分类(安全、敏感、不安全)。

  4. 根据分类,原始完成文本被屏蔽或发送回用户。

  5. 可选地,如果完成文本是敏感的或不安全的,可以生成一个新的安全完成并发送,而用户并不知道某些内容被屏蔽了。

内容过滤是使用完成的端点进行的。然而,需要使用专门的内容过滤引擎以及一些特定设置和特殊格式的提示。

在撰写本文时,可用的内容过滤引擎为content-filter-alpha-c4。因此,我们将在该引擎的 URL 中使用用于完成的端点,如api.openai.com/v1/engines/content-filter-alpha-c4/completions

重申一遍,需要在 API 请求中包含一些特定参数的具体要求。具体来说,我们需要包括以下参数和相关数值:

  • 1

  • 0.0

  • 0

最后,内容过滤的提示必须以特定方式格式化。提示格式为"<|endoftext|>[prompt]\n--\nLabel:"[prompt]部分将被替换为我们希望内容过滤器评估的文本。

重要说明

在发布时,内容过滤处于 beta 阶段。很有可能引擎 ID 在您阅读此文时已更改。因此,请务必查看位于 beta.openai.com/docs/engines/content-filter 的 OpenAI 内容过滤器文档。

因此,这是我们将发布到完成端点的 JSON 的一个示例。在此示例中,我们正在评估的文本是 从前有座山

{
    "prompt": "<|endoftext|>Once upon a time\n--\nLabel:",
    "max_tokens": 1,
    "temperature": 0.0,
    "top_p": 0
}

可以相当肯定地假设 从前有座山 会被视为安全的。因此,如果那是我们要应用过滤器的文本,我们可以期望得到类似以下示例的响应,显示文本是 0 - 安全的:

{
    "id": "cmpl-2auhZQYDGJNpeyzYNwMEm5YsAAUEK",
    "object": "text_completion",
    "created": 1615150445,
    "model": "toxicity-double-18",
    "choices": [
        {
            "text": "0",
            "index": 0,
            "logprobs": null,
            "finish_reason": "length"
        }
    ]
}

注意,在 JSON 响应对象中,有一个名为choices的元素。该元素包含一个对象的 JSON 数组。每个对象都包含一个文本属性,该属性将表示一个完成的内容过滤分类。其值始终是以下之一:

  • 0 – 安全:文本中似乎没有任何可能引起冒犯或不安全的地方。

  • 1 – 敏感:敏感话题可能包括具有政治、宗教、种族或国籍相关内容的文本。

  • 2 – 不安全:文本包含一些人认为是刻薄的、伤人的、明确的、冒犯的、亵渎的、偏见的、仇恨的语言,或者大多数人认为不适合工作NSFW)的语言,或者可能以有害方式描绘某些群体/人的语言。

一个数组被发送回 choices 元素,因为可能一次发送多个提示。例如,如果您想要查看句子中的任何单词是否不安全,您可能会将句子拆分为一个单词的数组,并将每个单词作为提示发送。以下是将 Oh hi 作为两个提示发送 - 每个单词一个的请求的示例:

{
    "prompt": [
"<|endoftext|>Oh\n--\nLabel:",
"<|endoftext|>hi\n--\nLabel:"
],
    "max_tokens": 1,
    "temperature": 0.0,
    "top_p": 0
}

鉴于前面的示例,使用提示数组,您将看到类似以下的响应。现在请注意,choices 数组中有多个对象 - 每个单词/提示一个:

{
    "id": "cmpl-2bDTUPEzoCrtNBa2gbkpNVc1BcVh9",
    "object": "text_completion",
    "created": 1615222608,
    "model": "toxicity-double-18",
    "choices": [
        {
            "text": "0",
            "index": 0,
            "logprobs": null,
            "finish_reason": "length"
        },
        {
            "text": "0",
            "index": 1,
            "logprobs": null,
            "finish_reason": "length"
    ]
}

choices 数组具有从零开始的索引值,该值对应于传入的提示数组中项目的索引,这意味着第一个提示/单词(在我们的示例中是“Oh”)的 choices 对象具有索引值 0。在此示例中,我们只发送了两个单词(“Oh”和“hi”),并且两者都被分类为 0(安全)。但是,如果您将其中一个单词更改为您喜欢的(或最不喜欢的)脏话,您会看到分类将更改为 2(不安全),其索引对应于您更改的单词(假设您使用的脏话大多数英语为母语的人会觉得冒犯)。

另一件需要牢记的事情是,过滤引擎并不是 100%准确,而是更倾向于谨慎。因此,您可能会看到误报 - 一些实际上是安全的单词被标记为敏感或不安全的情况。这可能是您在 Playground 中已经看到的情况。甚至提及政治或宗教等话题通常会被标记。小心总比后悔要好,但您需要考虑这可能如何潜在影响到您的应用程序。

因此,简要总结一下,您可以使用 OpenAI API 完成端点来对潜在的敏感或不安全文本进行分类。您只需要执行以下操作:

  1. 使用内容过滤引擎。

  2. max_tokens设置为1temperature设置为0.0top_p设置为0

  3. 将您的提示格式化为"<|endoftext|>your text here\n--\nLabel:"

好了,让我们使用 Postman 熟悉一下内容过滤的工作原理。

测试内容过滤流程

在本章后面,我们将会在代码中创建一个简单的内容过滤。但在此之前,让我们使用 Postman 测试一下通用的内容过滤方法:

  1. 登录Postman.com

  2. 打开我们在第四章中创建的 Exploring GPT-3 工作空间,使用 OpenAI API

  3. 创建一个名为第六章的新 Postman 集合。

  4. 创建一个名为内容过滤 - 示例 1的新请求。

  5. 将请求类型设置为POST,并将请求 URL 设置为api.openai.com/v1/engines/content-filter-alpha-c4/completions,如下面的屏幕截图所示:图 6.1 - 在 Postman 中设置过滤端点

    图 6.1 - 在 Postman 中设置过滤端点

  6. 将请求主体设置为原始,并将主体类型设置为JSON,如以下屏幕截图所示:图 6.2 - Postman 中的过滤参数

    图 6.2 - Postman 中的过滤参数

  7. 将以下 JSON 对象添加到请求主体中:

    {
      "prompt" : "<|endoftext|>Are you religious?\n--\nLabel:",
      "max_tokens" : 1,
      "temperature" : 0.0,
      "top_p" : 0
    }
    
  8. 单击发送按钮并查看 JSON 响应。响应将类似于以下屏幕截图:

图 6.3 - Postman 过滤结果

图 6.3 - Postman 过滤结果

在响应中,您会注意到索引为0的选择项的文本值为1(敏感)。正如您所猜的那样,这很可能是因为文本Are you religious? 可能被视为敏感话题。

在继续之前,尝试将提示文字更改为您认为可能被视为敏感或不安全的内容,并查看其分类情况。熟悉内容过滤流程后,继续下一节,在 JavaScript 中尝试应用。

使用 JavaScript 过滤内容

在本节中,我们将使用 JavaScript 看一下一个简单的内容过滤代码示例。我们可以自己编写所有代码,但是 Postman 中有一个很酷的功能,可以为我们创建的请求生成代码片段。所以,让我们试试看:

  1. 要查看 Postman 生成的代码片段,请单击右侧菜单上的代码按钮。以下截图中的箭头指向要单击的</>图标:图 6.4 – 打开代码窗格的代码按钮

    图 6.4 – 打开代码窗格的代码按钮

  2. 单击代码按钮后,Postman 将打开一个代码片段窗格。从下拉列表中选择NodeJs – Axios,将代码片段类型更改为该选项。然后,单击以下截图中显示的复制按钮。这将复制代码片段到您的剪贴板:图 6.5 – 适用于 Node.js – Axios 的 Postman 代码片段

    图 6.5 – 适用于 Node.js – Axios 的 Postman 代码片段

  3. 将代码片段复制到剪贴板后,请执行以下步骤:

    a) 登录 replit.com,并打开您的chapter06

    c) 在名为filter.jschapter06文件夹中创建一个文件。

    d) 将来自 Postman 的代码片段粘贴到filter.js文件中。

  4. 最终生成的代码应该看起来像以下截图。但是,在运行文件之前,我们需要做一个小改变:图 6.6 – 从 Postman 代码片段复制到 replit.com 文件

    change we need to make is on the line that contains Authorization – *line number 8* in the screenshot shown in *Figure 6.6*. We need to change it to pick up our environment variable in repl.it. To do that, we will replace the text 'Bearer {{OPENAI_API_KEY}}' from the code snippet with `Bearer ${process.env.OPENAI_API_KEY}`. Note that backticks are used rather than single quotes. This is because we're using a JavaScript template string as the value. This lets us merge in the ${process.env.OPENAI_API_KEY}, which will be replaced with the value of the OPENAI_API_KEY environment variable. For details about template literals/strings, visit the following link:[`developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals).
    
  5. 因此,在更新授权行之后,最终代码应该如下所示:

    var axios = require('axios');
    var data = JSON.stringify({
      "prompt": "<|endoftext|>What religion are you?\n--\nLabel:",
      "max_tokens": 1,
      "temperature": 0,
      "top_p": 0
    });
    var config = {
      method: 'post',
      url: 'https://api.openai.com/v1/engines/content-filter-alpha-c4/completions',
      headers: { 
        'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`, 
        'Content-Type': 'application/json'
      },
      data : data
    };
    axios(config)
    .then(function (response) {
      console.log(JSON.stringify(response.data));
    })
    .catch(function (error) {
      console.log(error);
    });
    
  6. 以下截图显示了replit.com中的先前代码:

图 6.7 – 修改后适用于 replit.com 的 Postman 代码片段

图 6.7 – 修改后的适用于 replit.com 的 Postman 代码片段

此时,代码与我们在第五章中所写的代码非常相似,在代码中使用 OpenAI API,当我们讨论调用完成端点时。我们只需要编辑.replit文件中的run命令,以运行我们的chapter06/filter.js文件中的代码。然后我们可以进行测试:

  1. 因此,将.replit文件更新为以下内容:

    Run "node chapter06/filter.js"
    
  2. 更新.replit文件后,单击绿色的运行按钮,您应该在控制台窗口中看到类似以下截图的结果:

图 6.8 – 运行 chapter06/filter.js 的结果

图 6.8 – 运行 chapter06/filter.js 的结果

这是一个简单的示例,将单个提示中的所有文本分类。让我们看另一个示例,该示例将字符串中的每个单词进行分类,并将每个单词分类为安全、敏感或不安全。

使用 Node.js/JavaScript 标记不安全的词汇

作为示例,我们将从创建一个名为chapter06/flag.js的新文件开始,并将chapter06/filter.js中的代码复制到其中作为起点。然后,我们将修改chapter06/flag.js中的代码,将每个单词列出并附带一个分类值(0 = 安全,1 = 敏感,2 = 不安全)。首先,执行以下步骤创建我们的起点:

  1. 登录到replit.com,打开您的exploring-gpt3-node repl。

  2. chapter06文件夹中创建一个名为flag.js的文件。

  3. chapter06/filter.js的整个内容复制并粘贴到chapter06/flag.js中。

  4. 编辑.replit文件以使用以下命令运行chapter06/flag.js

    Run = "node chapter06/flag.js"
    
  5. 我们将首先添加一个变量来保存我们要过滤的文本。我们将在第一行下面添加这段代码。因此,前两行将如下所示:

    var axios = require('axios');
    const textInput = "This is some text that will be filtered";
    
  6. 接下来,我们将添加一个变量来保存一个提示数组,并将初始值设置为空数组。这将用文本输入的每个单词的提示填充:

    const prompts = [];
    
  7. 现在,我们将把我们的textInput拆分成一个单词数组,并用每个单词的提示填充prompts数组。由于我们将提示发送到过滤引擎,我们还需要正确格式化每个提示项。因此,我们将在我们的prompts变量后添加以下代码。此代码将文本输入拆分为单个单词,循环遍历每个单词以创建提示项,然后将提示项添加到prompts数组中:

    const wordArray = textInput.split(' ');
    for (i = 0, len = wordArray.length, text = ""; i < len; i++) {
      text = `<|endoftext|>${wordArray[i]}\n--\nLabel:`;
      prompts.push(text);
    }
    
  8. 现在我们将更新由 Postman 创建的 data 变量。我们将使用我们的prompts数组作为提示值,而不是来自 Postman 的硬编码值。因此,我们将数据变量更改为以下内容:

    var data = JSON.stringify({"prompt": prompts,"max_tokens":1,"temperature":0,"top_p":0});
    
  9. 最后,我们将通过循环遍历单词数组并使用过滤器结果对每个单词进行分类来修改输出。为此,请将包含console.log(JSON.stringify(response.data));的行替换为以下代码:

        response.data.choices.forEach(item => {
          console.log(`${wordArray[item.index]} : ${item.text}`);
    

    在进行最后一次代码编辑之后,我们可以再次运行代码,这次我们将看到以下响应:

图 6.9 – 文本输入中每个单词的内容过滤器结果

图 6.9 – 文本输入中每个单词的内容过滤器结果

现在您会注意到单词(religion)的文本值为1(敏感)。如果您将textInput值更改为包含更具攻击性单词的文本,则可以再次运行代码以查看每个单词的分类方式。在实际实施中,您可能会替换或删除敏感或不安全的单词,现在可以轻松地通过 API 的结果使用类似的方法来完成。我们将在第七章中研究这样做,生成和转换文本,但现在,让我们来看看使用 Python 进行内容过滤。

使用 Python 过滤内容

现在让我们看看如何使用 Python 实现内容过滤。除非你跳过了“使用 JavaScript 过滤内容”,否则你可能能够猜到我们要如何开始使用 Python 实现内容过滤的示例——我们会使用由 Postman 生成的代码片段:

  1. 因此,首先需要在 Postman 中打开代码片段窗格。然后,点击右侧菜单中的代码按钮。箭头指向的即为代码按钮,如下面的截图所示:图 6.10 – 打开代码窗格的代码按钮

    图 6.10 – 打开代码窗格的代码按钮

  2. 单击代码按钮后,代码片段窗格会打开。更改代码片段类型为 Python – Requests,方法是从下拉列表中选择它,然后单击下面截图中所示的复制按钮。这将将代码片段复制到你的剪贴板:图 6.11 – 用于 Python – requests 的 Postman 代码片段

    图 6.11 – 用于 Python – requests 的 Postman 代码片段

  3. 将代码片段复制到剪贴板后,执行以下步骤:

    a) 登录 replit.com,并打开你的 chapter06

    c) 创建一个在 chapter06 文件夹中命名为 filter.py 的文件。

    d) 将 Postman 代码片段粘贴到 filter.py 文件中。

  4. 最终代码应该如下截图所示。但是你会发现你的 API Key 是硬编码的 —— 它在截图中被模糊处理了。硬编码的 API Key 是我们要更改的第一项内容:图 6.12 – 从 Postman 代码段复制到 repl.it 文件

    图 6.12 – 从 Postman 代码段复制到 repl.it 文件

  5. 为了从我们的代码文件中删除硬编码的 API Key,在 filter.py 文件的第一行添加以下代码,这样我们就可以读取在使用 OpenAI API 进行代码编写中设置的 .env 文件中的 OPENAI_API_KEY 环境变量了:

    import os
    
  6. 导入 Python 的 os 库后,我们可以从环境变量获取授权头的 API Key 值。在先前的 图 6.12 中,你需要将 第 7 行 编辑为以下内容:

    'Authorization':'Bearer ' + os.environ.get("OPENAI_API_KEY")
    
  7. 更新授权行后,最终代码应如下所示:

    import os
    import requests
    import json
    url = "https://api.openai.com/v1/engines/content-filter-alpha-c4/completions"
    payload = json.dumps({
      "prompt": "<|endoftext|>What religion are you?\n--\nLabel:",
      "max_tokens": 1,
      "temperature": 0,
      "top_p": 0
    })
    headers = {
      'Authorization':'Bearer ' + os.environ.get("OPENAI_API_KEY"),
      'Content-Type': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload)
    print(response.text)
    
  8. 下面的截图展示了前面章节中修改的 Postman Python 代码片段在 replit.com 中的效果:图 6.13 – 修改后的用于 repl.git.com 的 Postman Python 代码片段

    图 6.13 – 修改后的用于 repl.git.com 的 Postman Python 代码片段

  9. 此时,代码与我们在前一章“使用 OpenAI API 进行代码编写”中编写的代码非常相似,那时我们讨论了使用 Python 调用完成端点。我们只需编辑 .replit 文件中的 run 命令,以运行我们的 chapter06/filter.py 文件中的代码。然后我们可以进行测试。因此,请将 .replit 文件更新为以下内容:

    Run "python chapter06/filter.py"
    
  10. 更新.replit文件后,单击绿色的Run按钮,您应该会在控制台窗口中看到类似以下截图的结果:

图 6.14-运行 chapter06/filter.py 的结果

图 6.14-运行 chapter06/filter.py 的结果

这是一个简单的示例,它将一个单一提示中的所有文本进行分类。让我们现在看另一个例子,它将对字符串中的每个单词进行分类并替换不安全的单词。

使用 Python 标记不安全的单词

对于这个例子,我们将首先创建一个名为chapter06/flag.py的新文件,并将chapter06/filter.py中的代码复制到其中作为起点。从那里开始,我们将修改chapter06/flag.py中的代码,列出每个具有分类值的单词(0 = 安全,1 = 敏感,2 = 不安全)。开始之前,请执行以下步骤创建起点:

  1. 登录到 replit.com 并打开your exploring-gpt3-pythonrepl。

  2. chapter06文件夹中创建一个名为flag.py的文件。

  3. 复制并粘贴chapter06/filter.py的全部内容到chapter06/flag.py中。

  4. 编辑.replit文件,使用以下命令运行chapter06/flag.py

    Run = "python chapter06/flag.py"
    
  5. chapter06/flag.py文件中,我们将添加一个变量来保存我们要过滤的文本。我们将在第三行下面(最后一个以import开头的行之后)添加以下代码:

    textInput = "What religion are you?"
    
  6. 接下来,我们将添加一个变量来保存提示数组,并将初始值设置为空数组。这将从我们的文本输入中为每个单词填充一个提示:

    prompts = []
    
  7. 现在,我们将把textInput拆分为单词数组,并用每个单词的提示填充prompts数组。由于我们将提示发送到 filter engine,因此还需要正确格式化每个提示项。所以,在prompts变量之后添加以下代码。此代码将文本输入拆分为单个单词,循环遍历每个单词以创建提示项,并将提示项添加到prompts数组中:

    wordArray = textInput.split()
    for word in wordArray:
      prompts.append("<|endoftext|>" + word + "\n--\nLabel:")
    
  8. 现在,我们将把由 Postman 创建的payload变量更新为 Python 对象而不是字符串。这使它更容易读取和包含我们的prompts数组。因此,请将payload变量替换为以下代码:

    payload = json.dumps({
      "prompt" : prompts,
      "max_tokens" : 1,
      "temperature" : 0.0,
      "top_p" : 0
      })
    
  9. 最后,我们将用下面的代码替换最后一行代码print(response.text),通过循环遍历结果并为每个单词添加分类(0 = 安全,1 = 敏感,2 = 不安全):

    for word in response.json()['choices']:
      print(wordArray[word['index']] + ' : ' + word['text'])
    
  10. 在进行最终代码编辑后,我们可以点击Run按钮,这次我们将看到类似以下的响应:

图 6.15-使用 Python 显示文本输入中每个单词内容过滤结果

图 6.15-使用 Python 显示文本输入中每个单词内容过滤结果

您会注意到在控制台中,单词(religion)的文本值为1(敏感)。在实际应用中,您将使用类似的方法来编辑或替换不安全和敏感的单词。但请记住,没有任何内容过滤过程是完美的。语言不断发展,单词的上下文可能会改变含义,这可能会导致内容过滤器漏掉或错误地标记内容。因此,在设计您的过滤方法时考虑到这一点很重要。

摘要

在本章中,我们讨论了 GPT-3 有时可能生成不适当内容的情况。我们还讨论了我们可以采取的措施来预防和检测不适当内容。您学会了如何使用提示来防止生成不适当内容的可能性,以及如何使用内容过滤将内容分类为安全、敏感或不安全。

我们回顾了如何使用完成端点进行内容过滤,以及如何使用 JavaScript 和 Python 实现内容过滤。

下一章,我们将利用本章学到的知识,以及第五章在代码中调用 OpenAI API 中学到的知识,来构建一个由 GPT-3 驱动的聊天机器人。

第七章:生成和转换文本

虽然我们在前几章中已经看过一些文本生成和转换的例子,但在本章中,我们将看到更多。文本生成和转换有很多可能的用途,包括文章写作,纠正语法,生成列表,将文本从一种语言翻译成另一种语言,提取关键词和总结文本等等。虽然我们甚至不会接近涵盖所有可以使用 GPT-3 生成和转换文本的不同方式,但我们将看一下 15 个有趣的例子,让你的想象力发挥。

我们将要讨论的主题如下:

  • 使用示例

  • 生成内容和列表

  • 翻译和转换文本

  • 提取文本

  • 创建聊天机器人

技术要求

让我们来看看本章需要的要求:

  • 访问 OpenAI API

  • replit.com 上的一个账户

使用示例

在本章中,我们将看到很多例子 - 具体说来有 15 个。我们将为本章中的所有示例使用完成端点 - 因此,大多数示例的代码都类似。主要区别将是提示文本和端点参数的值。为了节省空间,我们将查看第一个示例的完整 JavaScript 和 Python 代码。之后,我们将只需复制第一个示例并编辑端点和参数。

为了开始我们的事情,我们将看一下生成原创内容和列表的例子。

生成内容和列表

让我们从几个例子开始创建原创内容和生成列表。在所有 GPT-3 可以做的事情中,内容和列表生成的可能性可能是最令人印象深刻的,也是最有趣的。GPT-3 可以撰写原创故事,创建产品描述,制作学习笔记,帮助你 brainstorm 创意,或者创建食谱 - 这只是个开始。

笨笑话生成器

我们将以一个例子开始,让气氛轻松一下 - 一个愚蠢的笑话生成器。剧透警告:并不是所有的笑话都可能那么好笑,但谁的都是呢?好吧,这是我们将使用的提示:

Dumb Joke: I'm not a vegetarian because I love animals. I'm a vegetarian because I hate plants.
###
Two-Sentence Joke: Parallel lines have so much in common. It's a shame they'll never meet.
###
Dumb Joke: Someone stole my mood ring. I don't know how I feel about that.
###
Dumb Joke:

我们将以一个使用 Node.js/JavaScript 的例子开始。记住,对于这个第一个例子,我们将逐步创建所有代码。对于接下来的例子,我们只需修改此第一个示例的副本。

Node.js/JavaScript 示例

要在 replit.comexploring-gpt3-node repl 中创建此示例,完成以下步骤:

  1. 登录 replit.com,打开你的 exploring-gpt3-node repl。

  2. 在项目根目录中创建一个名为 chapter07 的新文件夹。

  3. 创建一个名为 dumb-joke-generator.js 的新文件。

  4. 将以下代码添加到 dumb-joke-generator.js 文件中:

    //chapter07/dumb-joke-generator.js
    const axios = require('axios');
    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
      headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    const endpoint = "https://api.openai.com/v1/engines/davinci/completions";
    const params = {
      prompt: "Dumb Joke: I'm not a vegetarian because I love animals. I'm a vegetarian because I hate plants.\n###\nDumb Joke: Parallel lines have so much in common. It's a shame they'll never meet.\n###\nDumb Joke: Someone stole my mood ring. I don't know how I feel about that.\n###\nDumb Joke:",
      temperature: 0.5,
      max_tokens: 100,
      top_p: 1,
      frequency_penalty: 0.5,
      presence_penalty: 0.5,
      stop: ["###"]
    }
    client.post(endpoint, params)
      .then(result => {
        console.log(params.prompt + result.data.choices[0].text);
        // console.log(result.data);
      }).catch(err => {
        console.log(err);
      });
    
  5. 在根文件夹中更新 .replit 文件,加入以下代码:

    run = "node chapter07/dumb-joke-generator.js"
    
  6. 点击 chapter07/dumb-joke-generator.js,你应该会看到一个类似下面截图的结果。有多有趣?对吧?

图 7.1 - 来自 chapter07/dumb-joke-generator.js 的示例输出

图 7.1 - 来自 chapter07/dumb-joke-generator.js 的示例输出

现在让我们用 Python 看同一个示例。

Python 示例

要在 Python 中创建愚蠢笑话生成器,请完成以下步骤:

  1. 登录到 replit.com 并打开你的 exploring-gpt3-python repl。

  2. 在项目根目录中创建一个名为 chapter07 的新文件夹。

  3. 创建一个名为 dumb-joke-generator.py 的新文件。

  4. 将以下代码添加到 dumb-joke-generator.py 文件中:

    import requests
    import os
    import json
    apiKey = os.environ.get("OPENAI_API_KEY")
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + apiKey
    }
    endpoint = 'https://api.openai.com/v1/engines/davinci/completions'
    params = {
        "prompt": "Dumb Joke: I'm not a vegetarian because I love animals. I'm a vegetarian because I hate plants.\n###\nDumb Joke: Parallel lines have so much in common. It's a shame they'll never meet.\n###\nDumb Joke: Someone stole my mood ring. I don't know how I feel about that.\n###\nDumb Joke:",
        "temperature": 0.5,
        "max_tokens": 100,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0.5,
        "stop": ["###"]
    }
    result = requests.post(endpoint, headers=headers, data=json.dumps(params))
    print(params["prompt"] + result.json()["choices"][0]["text"])
    
  5. 将你根文件夹中的 .replit 文件更改为以下内容:

    run = "python chapter07/dumb-joke-generator.py"
    
  6. 点击 chapter07/dumb-joke-generator.py,你应该会看到类似以下截图中的控制台输出结果。你笑了吗?

图 7.2 - 来自 chapter07/dumb-joke-generator.py 的示例输出

图 7.2 - 来自 chapter07/dumb-joke-generator.py 的示例输出

让我们停止开玩笑,转而进行一个更为严肃的示例。

火星事实(在大多数情况下)

对于我们的下一个示例,我们将使用 GPT-3 来学习一些关于火星的知识。在大多数情况下,我们会得到一些事实,但请回想前几章中的内容,你不能一直相信它们是真实的。我们将使用以下提示生成关于火星的 10 条事实列表:

I'm studying the planets. List things I should know about Mars.
1\. Mars is the nearest planet to Earth.
2\. Mars has seasons, dry variety (not as damp as Earth's).
3\. Mars' day is about the same length as Earth's (24.6 hours).
4.

从这个示例开始,我们不会逐行走过所有的代码。我们将只复制我们的愚蠢笑话生成器的代码并对其进行修改。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建 Mars 事实示例,请按照以下步骤进行:

  1. 登录到 replit.com 并打开你的 exploring-gpt3-node repl。

  2. chapter07 文件夹中创建一个名为 mars-facts-list.js 的新文件。

  3. dumb-joke-generator.js 文件中的代码复制到 mars-facts-list.js 中。

  4. mars-facts-list.js 中的 params 变量替换为以下代码:

    const params = {
      prompt: "I'm studying the planets. List things I should know about Mars.\n\n1\. Mars is the nearest planet to Earth.\n2\. Mars has seasons, dry variety (not as damp as Earth's).\n3\. Mars' day is about the same length as Earth's (24.6 hours).\n4.",
      temperature: 0,
      max_tokens: 100,
      top_p: 1.0,
      frequency_penalty: 0.5,
      presence_penalty: 0.5,
      stop: "11."
    }
    
  5. 将你根文件夹中的 .replit 文件更改为以下内容:

    run = "node chapter07/mars-facts-list.js"
    
  6. 点击 chapter07/mars-facts-list.js,你应该会看到类似以下截图中的控制台输出结果。你知道关于火星的所有这些事情吗?

图 7.3 - 来自 chapter07/mars-facts-list.js 的示例输出

图 7.3 - 来自 chapter07/mars-facts-list.js 的示例输出

让我们来看看 Python 中的火星事实列表示例。

Python 示例

要在 Python 中创建 Mars 事实示例,请按照以下步骤进行:

  1. 登录到 replit.com 并打开你的 exploring-gpt3-python repl。

  2. chapter07 文件夹中创建一个名为 mars-facts-list.py 的新文件。

  3. dumb-joke-generator.py 文件中的代码复制到 mars-facts-list.py 中。

  4. mars-facts-list.py 中的 params 变量替换为以下代码:

    params = {
        "prompt": "I'm studying the planets. List things I should know about Mars.\n\n1\. Mars is the nearest planet to Earth.\n2\. Mars has seasons, dry variety (not as damp as Earth's).\n3\. Mars' day is about the same length as Earth's (24.6 hours).\n4.",
        "temperature": 0,
        "max_tokens": 100,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0.5,
        "stop": ["11."]
    }
    
  5. 将你根文件夹中的 .replit 文件更改为以下内容:

    run = "python chapter07/mars-facts-list.py"
    
  6. 点击 chapter07/mars-facts-list.py,你应该会看到类似以下截图中的控制台输出结果。一些有趣的事实,不是吗?

图 7.4 - 来自 chapter07/mars-facts-list.py 的示例输出

图 7.4 - 来自 chapter07/mars-facts-list.py 的示例输出

我们已经看过娱乐和教育示例,现在让我们用一个业务示例来完成一些工作 - 一个网络研讨会描述生成器。

网络研讨会描述生成器

在这个示例中,我们将使用 GPT-3 来帮助编写一个活动描述。我们将使用以下提示来为一个正念网络研讨会写一个描述:

Write a description for the following webinar:
Date: Monday, June 5, 2021
Time: 10 AM PT
Title: An introduction to mindfulness
Presenter: Gabi Calm
Event Description:

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建网络研讨会描述生成器,请按照以下步骤操作:

  1. 登录replit.com,并打开你的exploring-gpt3-node repl。

  2. chapter07文件夹中创建一个名为webinar-description-generator.js的新文件。

  3. 将代码从dumb-joke-generator.js文件复制到webinar-description-generator.js中。

  4. webinar-description-generator.js中的params变量替换为以下代码:

    const params = {
      prompt: "Write a description for the following webinar:\n\nDate: Monday, June 5, 2021\nTime: 10 AM PT\nTitle: An introduction to mindfulness\nPresenter: Gabi Calm\n\nEvent Description:",
      temperature: 0.7,
      max_tokens: 100,
      top_p: 1.0,
      frequency_penalty: 0.5,
      presence_penalty: 0.0,
      stop: ".\n"
    }
    
  5. 将你的根文件夹中的.replit文件更改为以下内容:

    run = "node chapter07/webinar-decription-generator.js"
    
  6. 点击chapter07/webinar-description-generator.js,你应该会看到与以下截图中控制台输出类似的结果:

图 7.5 - 来自 chapter07/webinar-description-generator.js 的示例输出

图 7.5 - 来自 chapter07/webinar-description-generator.js 的示例输出

现在让我们用 Python 创建网络研讨会描述生成器示例。

Python 示例

要创建 Python 中的网络研讨会描述生成器示例,请按照以下步骤操作:

  1. 登录replit.com,并打开你的exploring-gpt3-python repl。

  2. chapter07文件夹中创建一个名为webinar-description-generator.py的新文件。

  3. 将代码从dumb-joke-generator.py文件复制到webinar-description-generator.py中。

  4. webinar-description-generator.py中的params变量替换为以下代码:

    params = {
        "prompt": "Write a description for the following webinar:\n\nDate: Monday, June 5, 2021\nTime: 10 AM PT\nTitle: An introduction to mindfulness\nPresenter: Gabi Calm\n\nEvent Description:",
        "temperature": 0.7,
        "max_tokens": 100,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0,
        "stop": [".\n"]
    }
    
  5. 将你的根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/webinar-description-generator.py"
    
  6. 点击chapter07/webinar-description-generator.py,你应该会看到与以下截图中控制台输出类似的结果:

图 7.6 - 来自 chapter07/webinar-description-generator.py 的示例输出

图 7.6 - 来自 chapter07/webinar-description-generator.py 的示例输出

让我们继续,从 GPT-3 获取一些关于我们可能考虑阅读的书籍的建议。

书籍建议

你想读的书有哪些?让我们试试。我们将使用以下提示。这个提示将被完成为一个编号列表的书籍建议:

Suggest a list of books that everyone should try to read in their lifetime.
Books:
1.

现在让我们在代码中实现书籍建议提示。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建书籍建议列表示例,请按照以下步骤操作:

  1. 登录replit.com,并打开你的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/book-suggestions-list.js

  3. 将代码从dumb-joke-generator.py文件复制到chapter07/book-suggestions-list.js中。

  4. chapter07/book-suggestions-list.js中的params变量替换为以下代码:

    const params = {
      prompt: "Suggest a list of books that everyone should try to read in their lifetime.\n\nBooks:\n1.",
      temperature: 0.7,
      max_tokens: 100,
      top_p: 1,
      frequency_penalty: 0.5,
      presence_penalty: 0,
      stop: [".\n"]
    }
    
  5. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "node chapter07/book-suggestions-list.js"
    
  6. 点击chapter07/book-suggestions-list.js,您应该看到类似于以下截图中控制台输出的结果:

图 7.7 – 第七章/book-suggestions-list.js 的示例输出

图 7.7 – 第七章/book-suggestions-list.js 的示例输出

正如您在图 7.7中所看到的,完成是一系列书籍建议。现在让我们继续,看看使用 Python 的相同示例。

Python 示例

要在 Python 中创建书籍建议列表示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/book-suggestions-list.py

  3. 将代码从dumb-joke-generator.py文件复制到chapter07/book-suggestions-list.py中。

  4. chapter07/book-suggestions-list.js中的params变量替换为以下代码:

    params = {
        "prompt": "Suggest a list of books that everyone should try to read in their lifetime.\n\nBooks:\n1.",
        "temperature": 0.7,
        "max_tokens": 100,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0,
        "stop": [".\n"]
    }
    
  5. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/book-suggestions-list.py"
    
  6. 点击chapter07/book-suggestions-list.py,您应该看到类似于以下截图中控制台输出的结果:

图 7.8 – 第七章/book-suggestions-list.py 的示例输出

图 7.8 – 第七章/book-suggestions-list.py 的示例输出

现在让我们来看另一个例子。

儿童书籍生成器

现在让我们为孩子们做一些有创意的事情。要不我们来做一个定制的睡前故事书?以下是我们将使用的提示:

Write a short story for kids about a Dog named Bingo who travels to space.
---
Page 1: Once upon a time there was a dog named Bingo.
Page 2: He was trained by NASA to go in space.

在我们接下来的代码示例中,我们将只实现生成书籍的提示。然而,在实际版本中,您也会希望包含我们在第六章中讨论的内容过滤。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建儿童书籍生成器示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/childrens-book-generator.js

  3. 将代码从dumb-joke-generator.py文件复制到chapter07/childrens-book-generator.js中。

  4. chapter07/childrens-book-generator.js中的params变量替换为以下代码:

    const params = {
      prompt: "Write a short story for kids about a Dog named Bingo who travels to space.\n---\n\nPage 1: Once upon a time there was a dog named Bingo.\nPage 2: He was trained by NASA to go in space.\nPage 3:",
      temperature: 0.9,
      max_tokens: 500,
      top_p: 1,
      frequency_penalty: 0.7,
      presence_penalty: 0,
      stop: ["Page 11:"]
    }
    
  5. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "node chapter07/childrens-book-generator.js"
    
  6. 点击chapter07/childrens-book-generator.js,您应该看到类似于以下截图中控制台输出的结果:

图 7.9 – 第七章/childrens-book-generator.js 的示例输出

图 7.9 – 第七章/childrens-book-generator.js 的示例输出

让我们来看看 Python 版本。

Python 示例

要在 Python 中创建儿童书籍生成器示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/childrens-book-generator.py

  3. 将代码从dumb-joke-generator.py文件复制到chapter07/childrens-book-generator.py中。

  4. 用以下代码替换chapter07/childrens-book-generator.py中的params变量:

    params = {
        "prompt": "Write a short story for kids about a Dog named Bingo who travels to space.\n---\n\nPage 1: Once upon a time there was a dog named Bingo.\nPage 2: He was trained by NASA to go in space.\nPage 3:",
        "temperature": 0.9,
        "max_tokens": 500,
        "top_p": 1,
        "frequency_penalty": 0.7,
        "presence_penalty": 0,
        "stop": ["Page 11:"]
    }
    
  5. 将根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/childrens-book-generator.py"
    
  6. 点击chapter07/childrens-book-generator.py,你应该看到类似于以下屏幕截图中的控制台输出结果:

图 7.10 – 来自的示例输出

图 7.10 – 来自chapter07/childrens-book-generator.py的示例输出

现在让我们继续看一些将文本进行翻译和转换的示例。我们将看到一些你期望的示例,比如将口语翻译成为其他语言。我们还将看到一些带有变化的翻译。

文本的翻译和转换

当你考虑将文本进行翻译时,可能会想到如 Google 翻译这样的系统。但使用 GPT-3,你不仅可以进行口语翻译,还可以进行几乎任何内容的翻译。让我们来看看。

缩写译者

对于我们的第一个翻译示例,我们将把缩写词转换为它们的含义。以下是我们将使用的提示文本:

Provide the meaning for the following acronym.
---
acronym: LOL
meaning: Laugh out loud
acronym: BRB
meaning: Be right back
acronym: L8R
meaning:

提示中提供了一些缩写词及其含义的示例。尝试使用以下 Node.js/JavaScript 代码。

Node.js/JavaScript 示例

要创建 Node.js/JavaScript 的缩写译者示例,请按照以下步骤进行:

  1. 登录replit.com并打开你的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/acronym-translator.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/acronym-translator.js中。

  4. 用以下代码替换chapter07/acronym-translator.js中的params变量:

    const params = {
      prompt: "Provide the meaning for the following acronym.\n---\n\nacronym: LOL\nmeaning: Laugh out loud\nacronym: BRB\nmeaning: Be right back\nacronym: L8R",
      temperature: 0.5,
      max_tokens: 15,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      stop: ["acronym:"]
    }
    
  5. 将根文件夹中的.replit文件更改为以下内容:

    run = "node chapter07/acronym-translator.js"
    
  6. 点击chapter07/acronym-translator.js,你应该看到类似于以下屏幕截图中的控制台输出结果:

图 7.11 – 来自的示例输出

图 7.11 – 来自chapter07/acronym-translator.js的示例输出

让我们看看 Python 示例。

Python 示例

要创建 Python 的缩写译者示例,请按照以下步骤进行:

  1. 登录replit.com并打开你的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/acronym-translator.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/acronym-translator.py中。

  4. 用以下代码替换chapter07/acronym-translator.py中的params变量:

    params = {
        "prompt": "Provide the meaning for the following acronym.\n---\n\nacronym: LOL\nmeaning: Laugh out loud\nacronym: BRB\nmeaning: Be right back\nacronym: L8R",
        "temperature": 0.5,
        "max_tokens": 15,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
        "stop": ["acronym:"]
    }
    
  5. 将根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/acronym-translator.py"
    
  6. 点击chapter07/acronym-translator.py,你应该看到类似于以下屏幕截图中的控制台输出结果:

图 7.12 – 来自的示例输出

图 7.12 – 来自chapter07/acronym-translator.py的示例输出

让我们看看另一个示例。

英语到西班牙语

现在让我们来看看口语翻译。在这个示例中,我们将创建一个简单的翻译器,将英语文本转换为西班牙语:

Translate from English to Spanish
---
English: Where is the bathroom?
Spanish:

GPT-3 在语言之间的翻译方面非常出色。当在流行语言之间进行翻译时,如英语和西班牙语,尤其如此。因此,即使像这样的简单提示通常也足以获得准确的完成。

Node.js/JavaScript 示例

要创建 Node.js/JavaScript 中的英语到西班牙语翻译器示例,请按照以下步骤进行:

  1. 登录 replit.com,并打开你的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/english-spanish-translator.js

  3. dumb-joke-generator.py 文件中的代码复制到 chapter07/english-spanish-translator.js 中。

  4. chapter07/english-spanish-translator.js 中的 params 变量替换为以下代码:

    const params = {
      prompt: "Translate from English to Spanish\n---\n\nEnglish: Where is the bathroom?\nSpanish:",
      temperature: 0.5,
      max_tokens: 15,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      stop: ["---"]
    }
    
  5. 将你的根目录中的 .replit 文件更改为以下内容:

    run = "node chapter07/english-spanish-translator.js"
    
  6. 点击 chapter07/english-spanish-translator.js,你应该看到类似于以下截图中的控制台输出结果:

图 7.13 – 来自 chapter07/english-spanish-translator.js 的示例输出

图 7.13 – 来自 chapter07/english-spanish-translator.js 的示例输出

让我们使用 Python 来查看相同的示例,从英语翻译成西班牙语。

Python 示例

要创建 Python 中的英语到西班牙语翻译器示例,请按照以下步骤进行:

  1. 登录 replit.com,并打开你的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/english-spanish-translator.py

  3. dumb-joke-generator.py 文件中的代码复制到 chapter07/english-spanish-translator.py 中。

  4. chapter07/english-spanish-translator.py 中的 params 变量替换为以下代码:

    params = {
        "prompt": "Translate from English to Spanish\n---\n\nEnglish: Where is the bathroom?\nSpanish:",
        "temperature": 0.5,
        "max_tokens": 15,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
        "stop": ["---"]
    }
    
  5. 将你的根目录中的 .replit 文件更改为以下内容:

    run = "python chapter07/english-spanish-translator.py"
    
  6. 点击 chapter07/english-spanish-translator.py,你应该看到类似于以下截图中的控制台输出结果:

图 7.14 – 来自 chapter07/english-spanish-translator.py 的示例输出

图 7.14 – 来自 chapter07/english-spanish-translator.py 的示例输出

正如图 7.14所示,GPT-3 将英文文本翻译成了西班牙文。但更令人印象深刻的是,GPT-3 还能在计算机编程语言之间进行翻译。我们接下来将使用一个提示来查看将 JavaScript 代码翻译为 Python。

JavaScript 到 Python

翻译不仅仅需要在人类语言之间进行。由于 GPT-3 是使用互联网数据进行训练的,它还可以在编程语言之间进行翻译。以下提示提供了一个示例,显示了如何将 JavaScript 代码转换为 Python:

Translate from JavaScript to Python
JavaScript:
const request = require("requests");
request.get("https://example.com");
Python:

这是一个相当简单的代码转换示例,但它很好地展示了潜力。更复杂的代码转换可能需要更多样本的 few-shot 提示,但让我们尝试一下使用 Node.js/JavaScript。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建 JavaScript 到 Python 的翻译器示例,请按照以下步骤进行:

  1. 登录 replit.com,并打开你的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/javascript-python-translator.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/javascript-python-translator.js中。

  4. chapter07/javascript-python-translator.js中的params变量替换为以下代码:

    const params = {
      prompt: "Translate from JavaScript to Python\n---\n\nJavaScript:\nconst request = require(\"requests\");\nrequest.get(\"https://example.com\");\n\nPython:\n",
      temperature: 0.3,
      max_tokens: 15,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      stop: ["---"]
    }
    
  5. 将根目录中的.replit文件更改为以下内容:

    run = "node chapter07/javascript-python-translator.js"
    
  6. 单击chapter07/javascript-python-translator.js,您应该会看到类似于以下屏幕截图中控制台输出的结果:

图 7.15 – 来自 chapter07/javascript-python-translator.js 的示例输出

图 7.15 – 来自 chapter07/javascript-python-translator.js 的示例输出

让我们看一下 Python 版本。

Python 示例

要在 Python 中创建 JavaScript 到 Python 的转换器示例,请按照以下步骤进行:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/javascript-python-translator.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/javascript-python-translator.py中。

  4. chapter07/javascript-python-translator.py中的params变量替换为以下代码:

    params = {
        "prompt": "Translate from JavaScript to Python\n---\n\nJavaScript:\nconst request = require(\"requests\");\nrequest.get(\"https://example.com\");\n\nPython:\n",
        "temperature": 0.3,
        "max_tokens": 15,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
        "stop": ["---"]
    }
    
  5. 将根目录中的.replit文件更改为以下内容:

    run = "python chapter07/javascript-python-translator.py"
    
  6. 单击chapter07/javascript-python-translator.py,您应该会看到类似于以下屏幕截图中控制台输出的结果:

图 7.16 – 来自 chapter07/javascript-python-translator.py 的示例输出

图 7.16 – 来自 chapter07/javascript-python-translator.py 的示例输出

在下一个示例中,我们将看一下总结文本。我们在Chapter 7生成和转换文本中使用 TLDR 总结文本,但这不是总结文本的唯一方法。您还可以根据提供的阅读水平/年级提供文本摘要。

第五年级总结

GPT-3 可以为给定的年级或阅读水平总结文本。虽然年级水平不是完全精确的,可能是主观的,但您会注意到随着年级水平的降低,文本变得更简单。以下提示提供了一个示例,您可以用这种方式来处理:

Summarize the following passage for me as if I was in fifth grade:
"""
Quantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles. It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science.
Classical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.
Quantum mechanics differs from classical physics in that energy, momentum, angular momentum, and other quantities of a bound system are restricted to discrete values (quantization), objects have characteristics of both particles and waves (wave-particle duality), and there are limits to how accurately the value of a physical quantity can be predicted prior to its measurement, given a complete set of initial conditions (the uncertainty principle).
"""
Here is the fifth-grade version of this passage:
"""

让我们在 Node.js/JavaScript 中尝试这个示例,并审查结果。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建第五年级总结示例,请按照以下步骤进行:

  1. 登录replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/fith-grade-summary.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/fith-grade-summary.js中。

  4. chapter07/fith-grade-summary.js中的params变量替换为以下代码:

    const params = {
      prompt: "Summarize the following passage for me as if I was in fifth grade:\n\"\"\"\nQuantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles. It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science.\n\nClassical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.\n\nQuantum mechanics differs from classical physics in that energy, momentum, angular momentum, and other quantities of a bound system are restricted to discrete values (quantization), objects have characteristics of both particles and waves (wave-particle duality), and there are limits to how accurately the value of a physical quantity can be predicted prior to its measurement, given a complete set of initial conditions (the uncertainty principle).\n\"\"\"\nHere is the fifth-grade version of this passage:\n\"\"\"",
      temperature: 0,
      max_tokens: 100,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      stop: ["\"\"\""]
    }
    
  5. 将根目录中的.replit文件更改为以下内容:

    run = "node chapter07/fith-grade-summary.js"
    
  6. 单击chapter07/fith-grade-summary.js,您应该会看到类似于以下屏幕截图中控制台输出的结果:

图 7.17 – 来自 chapter07/fith-grade-summary.js 的示例输出

图 7.17 – 来自 chapter07/fith-grade-summary.js 的示例输出

让我们来看看 Python 代码。

Python 示例

要在 Python 中创建第五年级摘要示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/fith-grade-summary.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/fith-grade-summary.py中。

  4. chapter07/fith-grade-summary.py中的params变量替换为以下代码:

    params = {
        "prompt": "Summarize the following passage for me as if I was in fifth grade:\n\"\"\"\nQuantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles. It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science.\n\nClassical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.\n\nQuantum mechanics differs from classical physics in that energy, momentum, angular momentum, and other quantities of a bound system are restricted to discrete values (quantization), objects have characteristics of both particles and waves (wave-particle duality), and there are limits to how accurately the value of a physical quantity can be predicted prior to its measurement, given a complete set of initial conditions (the uncertainty principle).\n\"\"\"\nHere is the fifth-grade version of this passage:\n\"\"\"",
        "temperature": 0,
        "max_tokens": 100,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
        "stop": ["\"\"\""]
    }
    
  5. 将根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/fith-grade-summary.py"
    
  6. 单击chapter07/fith-grade-summary.py,您应该看到类似于以下截图中控制台输出的结果:

图 7.18 - 来自的示例输出

图 7.18 - 来自chapter07/fith-grade-summary.py的示例输出

让我们看另一个例子。 这次我们将看看 GPT-3 如何进行语法纠正。

语法纠正

英语语法纠正可以通过非常简单的提示来完成,例如以下内容:

Original: You be mistaken
Standard American English:

让我们使用 Node.js/JavaScript 来测试这个语法纠正提示。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建语法纠正转换器示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/grammar-correction-converter.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/grammar-correction-converter.js中。

  4. chapter07/grammar-correction-converter.js中的params变量替换为以下代码:

    const params = {
      prompt: "Original: You be mistaken\nStandard American English:",
      temperature: 0,
      max_tokens: 60,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      stop: ["\n"]
    }
    
  5. 将根文件夹中的.replit文件更改为以下内容:

    run = "node chapter07/grammar-correction-converter.js"
    
  6. 单击chapter07/grammar-correction-converter.js,您应该看到类似于以下截图中控制台输出的结果:

图 7.19 - 来自的示例输出

图 7.19 - 来自chapter07/grammar-correction-converter.js的示例输出

让我们来看看 Python 代码。

Python 示例

要在 Python 中创建语法纠正转换器示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/grammar-correction-converter.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/grammar-correction-converter.py中。

  4. chapter07/grammar-correction-converter.py中的params变量替换为以下代码:

    params = {
        "prompt": "Original: You be mistaken\nStandard American English:",
        "temperature": 0,
        "max_tokens": 60,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
        "stop": ["\n"]
    }
    
  5. 将根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/grammar-correction-converter.py"
    
  6. 单击chapter07/gramar-correction-converter.py,您应该看到类似于以下截图中控制台输出的结果:

图 7.20 - 来自的示例输出

图 7.20 - 来自chapter07/grammar-correction-converter.py的示例输出

好了,我们在本章中涵盖了很多例子,但我们还没有完成。让我们继续前进,看看如何从文本中提取信息。

提取文本

您还可以使用 GPT-3 从较大的文本中提取文本值。这通常称为实体提取,其中实体是您要提取的项或模式。或者您可能想要提取关键字。为此,您可以使用以下提示。

提取关键字

以下提示提供了如何从文本中提取关键字的示例。在本例中,文本来自en.wikipedia.org/wiki/Quantum_mechanics,但当然,这可以用任何文本来完成:

Quantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles. It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science.
Classical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.
Quantum mechanics differs from classical physics in that energy, momentum, angular momentum, and other quantities of a bound system are restricted to discrete values (quantization), objects have characteristics of both particles and waves (wave-particle duality), and there are limits to how accurately the value of a physical quantity can be predicted prior to its measurement, given a complete set of initial conditions (the uncertainty principle).
Keywords:

现在尝试使用 Node.js/JavaScript 提取关键词。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建关键词提取器示例,请按照以下步骤操作:

  1. 登录 replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/keyword-extractor.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/keyword-extractor.js中。

  4. chapter07/keyword-extractor.js中的params变量替换为以下代码:

    const params = {
      prompt: "Quantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles. It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science.\n\nClassical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.\n\nQuantum mechanics differs from classical physics in that energy, momentum, angular momentum, and other quantities of a bound system are restricted to discrete values (quantization), objects have characteristics of both particles and waves (wave-particle duality), and there are limits to how accurately the value of a physical quantity can be predicted prior to its measurement, given a complete set of initial conditions (the uncertainty principle).\n\nKeywords:",
      temperature: 0.3,
      max_tokens: 60,
      top_p: 1,
      frequency_penalty: 0.8,
      presence_penalty: 0,
      stop: ["\n"]
    }
    
  5. 更改根文件夹中的.replit文件为以下内容:

    run = "node chapter07/keyword-extractor.js"
    
  6. 点击chapter07/keyword-extractor.js,您应该会看到类似于以下截图中的控制台输出的结果:

图 7.21 – 来自章节 07/keyword-extractor.js 的示例输出

图 7.21 – 来自章节 07/keyword-extractor.js 的示例输出

现在是 Python 示例。

Python 示例

要在 Python 中创建关键词提取器示例,请按照以下步骤操作:

  1. 登录 replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/keyword-extractor.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/keyword-extractor.py中。

  4. chapter07/keyword-extractor.py中的params变量替换为以下代码:

    params = {
        "prompt": "Quantum mechanics is a fundamental theory in physics that provides a description of the physical properties of nature at the scale of atoms and subatomic particles. It is the foundation of all quantum physics including quantum chemistry, quantum field theory, quantum technology, and quantum information science.\n\nClassical physics, the description of physics that existed before the theory of relativity and quantum mechanics, describes many aspects of nature at an ordinary (macroscopic) scale, while quantum mechanics explains the aspects of nature at small (atomic and subatomic) scales, for which classical mechanics is insufficient. Most theories in classical physics can be derived from quantum mechanics as an approximation valid at large (macroscopic) scale.\n\nQuantum mechanics differs from classical physics in that energy, momentum, angular momentum, and other quantities of a bound system are restricted to discrete values (quantization), objects have characteristics of both particles and waves (wave-particle duality), and there are limits to how accurately the value of a physical quantity can be predicted prior to its measurement, given a complete set of initial conditions (the uncertainty principle).\n\nKeywords:",
        "temperature": 0.3,
        "max_tokens": 60,
        "top_p": 1,
        "frequency_penalty": 0.8,
        "presence_penalty": 0,
        "stop": ["\n"]
    }
    
  5. 更改根文件夹中的.replit文件为以下内容:

    run = "python chapter07/keyword-extractor.py"
    
  6. 点击chapter07/keyword-extractor.py,您应该会看到类似于以下截图中的控制台输出的结果:

图 7.22 – 来自章节 07/keyword-extractor.py 的示例输出

图 7.22 – 来自章节 07/keyword-extractor.py 的示例输出

让我们看看另一个示例。

HTML 解析

在此示例中,我们将从 HTML 中提取文本。具体来说,以下提示提取标题标签的值(在<title></title>之间的文本)。正如您所看到的,提示非常简单。它只提供了一些简单的指示、要从中提取的 HTML 和标题的标签:

Extract the title, h1, and body text from the following HTML document:
<head><title>A simple page</title></head><body><h1>Hello World</h1><p>This is some text in a simple html page.</p></body></btml>
Title:

现在,让我们尝试使用 Node.js/JavaScript 进行 HTML 解析。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建来自 HTML 示例的文本,请按照以下步骤操作:

  1. 登录 replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/text-from-html.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/text-from-html.js中。

  4. chapter07/text-from-html.js中的params变量替换为以下代码:

    const params = {
      prompt: "Extract the title, h1, and body text from the following HTML document:\n\n<head><title>A simple page</title></head><body><h1>Hello World</h1><p>This is some text in a simple html page.</p></body></html>\n\nTitle:",
      temperature: 0,
      max_tokens: 64,
      top_p: 1,
      frequency_penalty: 0.5,
      presence_penalty: 0
    }
    
  5. 将根文件夹中的 .replit 文件更改为以下内容:

    run = "node chapter07/text-from-html.js"
    
  6. 单击 chapter07/text-from-html.js,您应该会看到类似以下截图中控制台输出的结果:

图 7.23 – 来自 chapter07/text-from-html.js 的示例输出

图 7.23 – 来自 chapter07/text-from-html.js 的示例输出

让我们来看看 Python 代码。

Python 示例

要在 Python 中创建来自 HTML 的文本示例,请按照以下步骤进行:

  1. 登录 replit.com,打开您的 exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/text-from-html.py

  3. dumb-joke-generator.py 文件中的代码复制到 chapter07/text-from-html.py 中。

  4. chapter07/text-from-html.py 中的 params 变量替换为以下代码:

    params = {
        "prompt": "Extract the title, h1, and body text from the following HTML document:\n\n<head><title>A simple page</title></head><body><h1>Hello World</h1><p>This is some text in a simple html page.</p></body></html>\n\nTitle:",
        "temperature": 0,
        "max_tokens": 64,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0
    }
    
  5. 将根文件夹中的 .replit 文件更改为以下内容:

    run = "python chapter07/text-from-html.py"
    
  6. 单击 chapter07/text-from-html.py,您应该会看到类似以下截图中控制台输出的结果:

图 7.24 – 来自 chapter07/text-from-html.py 的示例输出

图 7.24 – 来自 chapter07/text-from-html.py 的示例输出

让我们看看另一个示例。

提取邮政地址

让我们看一个从电子邮件中提取邮政地址的示例。以下提示显示了您如何完成此操作。

重要说明

此示例使用的是davinci-instruct-beta引擎,在发布时处于测试阶段。

您可以看到提示提供了基本说明,电子邮件中的邮政地址以标准方式提供,因此 GPT-3 可能能够识别出该地址:

Extract the postal address from this email:
Dear Paul,
I'm in the market for a new home and I understand you're the listing agent for the property located at 2620 Riviera Dr, Laguna Beach, CA 92651.
Is the seller flexible at all on the asking price?
Best,
Linda
Property Address:

现在尝试使用 Node.js/JavaScript 进行此提示。

Node.js/JavaScript 示例

要创建 Node.js/JavaScript 中提取邮政地址的示例,请按照以下步骤进行:

  1. 登录 replit.com,打开您的 exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/extract-postal-address.js

  3. dumb-joke-generator.py 文件中的代码复制到 chapter07/extract-postal-address.js 中。

  4. chapter07/extract-postal-address.js 中的 params 变量替换为以下代码:

    const params = {
      prompt: "Extract the postal address from this email:\n\nDear Paul,\n\nI'm in the market for a new home and I understand you're the listing agent for the property located at 2620 Riviera Dr, Laguna Beach, CA 92651.\n\nIs the seller flexible at all on the asking price?\n\nBest,\n\nLinda\n\nProperty Address:\n",
      temperature: 0,
      max_tokens: 64,
      top_p: 1,
      frequency_penalty: 0.5,
      presence_penalty: 0,
      stop: [""]
    }
    
  5. 将根文件夹中的 .replit 文件更改为以下内容:

    run = "node chapter07/extract-postal-address.js"
    
  6. 单击 chapter07/extract-postal-address.js,您应该会看到类似以下截图中控制台输出的结果:

图 7.25 – 来自 chapter07/extract-postal-address.js 的示例输出

图 7.25 – 来自 chapter07/extract-postal-address.js 的示例输出

现在让我们尝试使用 Python 相同的示例。

Python 示例

要创建 Python 中提取邮政地址的示例,请按照以下步骤进行:

  1. 登录 replit.com,打开您的 exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/extract-postal-address.py

  3. dumb-joke-generator.py 文件中的代码复制到 chapter07/extract-postal-address.py 中。

  4. chapter07/extract-postal-address.py 中的 params 变量替换为以下代码:

    params = {
        "prompt": "Extract the postal address from this email:\n\nDear Paul,\n\nI'm in the market for a new home and I understand you're the listing agent for the property located at 2620 Riviera Dr, Laguna Beach, CA 92651.\n\nIs the seller flexible at all on the asking price?\n\nBest,\n\nLinda\n\nProperty Address:\n",
        "temperature": 0,
        "max_tokens": 64,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0,
        "stop": [""]
    }
    
  5. 在您的根文件夹中更改.replit文件为以下内容:

    run = "python chapter07/extract-postal-address.py"
    
  6. 单击chapter07/extract-postal-address.py,您应该看到类似于以下截图中控制台输出的结果:

图 7.26 – 来自 chapter07/extract-postal-address.py 的示例输出

图 7.26 – 来自 chapter07/extract-postal-address.py 的示例输出

让我们看一个类似的例子 – 提取电子邮件地址。

提取电子邮件地址

这个提示与邮政地址示例类似,但这次我们指示 GPT-3 提取电子邮件地址:

Extract the email address from the following message:
Dear Paul,
I'm in the market for a new home and I understand you're the listing agent for the property located at 2620 Riviera Dr, Laguna Beach, CA 92651.
Can you send details to my wife's email which is beth@example.com?
Best,
Kevin
Email Address:

现在,让我们尝试用 Node.js/JavaScript 运行这个提示。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建提取电子邮件地址的示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/extract-email-address.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/extract-email-address.js中。

  4. 用以下代码替换chapter07/extract-email-address.js中的params变量:

    const params = {
      prompt: "Extract the email address from the following message:\n\nDear Paul,\n\nI'm in the market for a new home and I understand you're the listing agent for the property located at 2620 Riviera Dr, Laguna Beach, CA 92651.\n\nCan you send details to my wife's email which is beth@example.com?\n\nBest,\n\nKevin\n\nEmail Address:\n",
      temperature: 0,
      max_tokens: 64,
      top_p: 1,
      frequency_penalty: 0.5,
      presence_penalty: 0,
      stop: [""]
    }
    
  5. 在您的根文件夹中更改.replit文件为以下内容:

    run = "node chapter07/extract-email-address.js"
    
  6. 单击chapter07/extract-email-address.js,您应该看到类似于以下截图中控制台输出的结果:

图 7.27 – 来自 chapter07/extract-email-address.js 的示例输出

图 7.27 – 来自 chapter07/extract-email-address.js 的示例输出

让我们看看 Python 代码。

Python 示例

要在 Python 中创建提取电子邮件地址的示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/extract-email-address.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/extract-email-address.py中。

  4. 用以下代码替换chapter07/extract-email-address.py中的params变量:

    params = {
        "prompt": "Extract the email address from the following message:\n\nDear Paul,\n\nI'm in the market for a new home and I understand you're the listing agent for the property located at 2620 Riviera Dr, Laguna Beach, CA 92651.\n\nCan you send details to my wife's email which is beth@example.com?\n\nBest,\n\nKevin\n\nEmail Address:\n",
        "temperature": 0,
        "max_tokens": 64,
        "top_p": 1,
        "frequency_penalty": 0.5,
        "presence_penalty": 0,
        "stop": [""]
    }
    
  5. 在您的根文件夹中更改.replit文件为以下内容:

    run = "python chapter07/extract-email-address.py"
    
  6. 单击chapter07/extract-email-address.py,您应该看到类似于以下截图中控制台输出的结果:

图 7.28 – 来自 chapter07/extract-email-address.py 的示例输出

图 7.28 – 来自 chapter07/extract-email-address.py 的示例输出

对于我们的最后一个示例,我们将以一个聊天机器人结束。

创建聊天机器人

对于最后一组示例,我们将看看如何创建聊天机器人。从技术上讲,这将被分类为生成文本,因此它可以被归类为生成内容和列表。但是使用 GPT-3 创建聊天机器人是如此有趣,它值得拥有自己的一节。我们将从一个简单的对话式聊天机器人开始。

一个简单的聊天机器人

对于我们的简单聊天机器人,我们将使用以下提示。我们将分别查看 Node.js/JavaScript 和 Python 的代码,但两者的提示是相同的。

提示的第一部分提供了有关机器人应如何响应以及一般对话风格的指导。通过更改指导和示例对话,您可以改变机器人响应的许多方面。例如,您可以通过将词语友好和礼貌更改为粗鲁和讽刺来改变对话语气。

这是我们简单机器人的提示文本:

The following is a conversation with an AI bot. The bot is very friendly and polite.
Human: Hello, how are you?
AI: I am doing great, thanks for asking. How can I help you today?
Human: I just wanting to talk with you.
AI:

现在,让我们看看如何在 Node.js/JavaScript 中实现一个简单的机器人。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建简单的聊天机器人示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-node repl。

  2. 创建一个新文件:chapter07/simple-chatbot.js

  3. dumb-joke-generator.py文件中的代码复制到chapter07/simple-chatbot.js中。

  4. chapter07/simple-chatbot.js中用以下代码替换params变量:

    const params = {
      prompt: "The following is a conversation with an AI bot. The bot is very friendly and polite.\n\nHuman: Hello, how are you?\nAI: I am doing great, thanks for asking. How can I help you today?\nHuman: I just wanting to talk with you.\nAI:",
      temperature: 0.9,
      max_tokens: 150,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0.6,
      stop: ["\n, Human:, AI:"]
    }
    
  5. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "node chapter07/simple-chatbot.js"
    
  6. 点击chapter07/simple-chatbot.js,你应该会看到类似以下截图中的控制台输出:

图 7.29 – 来自 chapter07/simple-chatbot.js 的示例输出

图 7.29 – 来自 chapter07/simple-chatbot.js 的示例输出

现在是 Python 版本。

Python 示例

要在 Python 中创建简单的聊天机器人示例,请按照以下步骤操作:

  1. 登录replit.com,并打开您的exploring-gpt3-python repl。

  2. 创建一个新文件:chapter07/simple-chatbot.py

  3. dumb-joke-generator.py文件中的代码复制到chapter07/simple-chatbot.py中。

  4. chapter07/simple-chatbot.py中用以下代码替换params变量:

    params = {
        "prompt": "The following is a conversation with an AI bot. The bot is very friendly and polite.\n\nHuman: Hello, how are you?\nAI: I am doing great, thanks for asking. How can I help you today?\nHuman: I just wanting to talk with you.\nAI:",
        "temperature": 0.9,
        "max_tokens": 150,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0.6,
        "stop": ["\n, Human:, AI:"]
    }
    
  5. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "python chapter07/simple-chatbot.py"
    
  6. 点击chapter07/simple-chatbot.py,你应该会看到类似以下截图中的控制台输出:

图 7.30 – 来自 chapter07/simple-chatbot.py 的示例输出

图 7.30 – 来自 chapter07/simple-chatbot.py 的示例输出

这是我们的最后一个例子。让我们用一个快速总结结束。

摘要

在本章中,我们介绍了生成和转换文本的内容。我们讨论了 15 个示例,涵盖了 Node.js/JavaScript 和 Python 两种语言。示例包括生成内容和列表、翻译和转换文本、提取文本以及创建简单的聊天机器人。

在下一章中,我们将介绍分类和归类文本的示例。

第八章:分类和归类文本

在上一章中,我们探讨了生成文本的不同方法。在本章中,我们将讨论文本分类和 OpenAI API 分类端点。我们将从快速概述文本分类和分类端点开始,然后进行实施情感分析、为文本分配 ESRB 评级、通过语言对文本进行分类以及从关键词对文本进行分类,这些都是常见的文本分类示例。

本章将涵盖以下主题:

  • 理解文本分类

  • 介绍分类端点

  • 实施情感分析

  • 为文本分配 ESRB 评级

  • 通过语言对文本进行分类

  • 从关键词对文本进行分类

技术要求

本章需要您访问 OpenAI API。您可以通过访问openapi.com来请求访问权限。

理解文本分类

文本分类任务接受文本并返回标签。将电子邮件分类为垃圾邮件或确定推文的情感都是文本分类任务的例子。使用 OpenAI API 进行文本分类有多种方法,我们已经看过其中一些。但我们还没有涵盖的一种方法是使用完成端点。然而,在我们深入研究完成端点之前,让我们快速回顾一下我们已经涵盖的一些不同的文本分类方法。

使用完成端点进行文本分类

你可以使用完成端点来执行分类任务,只需在提示中描述任务。例如,下面的提示可用于对社交媒体发布进行分类:

Social media post: "My favorite restaurant is opening again Monday. I can't wait!"
Sentiment (positive, neutral, negative):

以往的提示可能会根据发布返回积极,自然或消极,但很可能是积极的。

内容过滤是一个文本分类任务

内容过滤也是一种文本分类任务。回想一下第六章中的内容过滤,当我们使用内容过滤引擎时,返回的结果是0 = 安全1 = 敏感2 = 不安全,这就是文本分类。

虽然可以使用 OpenAI API 进行多种文本分类的方法,但有一个端点专门设计用于分类任务。该端点就是分类端点,接下来我们将讨论这个内容。

介绍分类端点

OpenAI API 还为文本分类任务提供了分类端点。分类端点简化了许多分类任务。它使用语义搜索和完成引擎的组合,根据您提供的样本对文本进行分类。您可以在 HTTP 请求中提供最多 200 个示例,或者可以提前上传包含示例数据的文件。

分类端点的 URL 是api.openai.com/v1/classifications。它期望使用包含输入参数的 JSON 主体的 HTTP POST。其中一个必需的参数是query参数。query参数的值是要分类的文本。query值首先用于进行语义搜索,以从提供的示例中找到相关示例。然后,这些示例连同查询一起用于创建一个定义的完成引擎的提示,该引擎将对文本进行分类。

以下代码块显示了分类端点的简单请求主体。请注意,此请求与示例一起提供,并且将用于执行分类的模型是curie模型:

{
  "query": "That makes me smile",
  "examples": [
    ["That is awesome", "Happy"],
    ["I feel so sad", "Sad"],
    ["I don't know how I feel", "Neutral"]
  ],
  "model": "curie"
}

正如前面提到的,你也可以上传示例数据,并使用file参数引用上传的示例数据。当你有大量示例时,这是很有用的 – 超过 200 个。让我们来看看如何上传文件。

上传文件

可以使用 OpenAI API 文件端点上传分类端点的示例数据。文件应该基于 JSON 行文本格式进行格式化,基本上就是每行一个有效的 JSON 对象,这些对象之间用换行符分隔。

重要提示

您可以在jsonlines.org了解更多关于 JSON 行格式的信息。

以下代码块提供了一个分类样本文件所需的格式示例。text属性和label属性是必需的,但metadata是可选的。元数据属性可以包含一个 JSON 对象,其中包含您想要的任何信息。然后这些数据可以选择性地随查询结果返回:

{"text": "that is awesome", "label": "Happy", "metadata": {"id":"1"}}
{"text": "i feel so sad", "label": "Sad", "metadata": {"id":"2"}}
{"text": "i don't know how i feel", "label": "Neutral", "metadata": {"id":"3"}}

要上传一个样本文件,您可以使用 OpenAI API 的文件端点。在本章的示例中,我们不会使用文件。但是,在第九章中,我们将更仔细地研究文件端点,构建一个 GPT-3 支持的问答应用

实施情感分析

常见的分类任务是情感分析。使用情感分析,您可以根据文本的一般语气进行分类 – 例如,快乐,悲伤,愤怒或中性。这在许多应用中都很有用;例如,如果您是餐馆老板,您希望能够迅速对不满意的顾客评论做出回应。让我们来看看如何使用 OpenAI API 分类端点来实现这一点。

在此示例中,我们将对餐厅评论进行分类。我们将使用分类端点进行此示例,并且我们将在请求中提供一些示例评论。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建评论分类器示例,请按照以下步骤进行:

  1. 登录到replit.com,并打开你的exploring-gpt3-node REPL。

  2. 创建一个新文件 – chapter08/reviews-classifier.js

  3. 将以下代码添加到reviews-classifier.js文件的开头:

    const axios = require('axios');
    const client = axios.create({
      headers: {
        'Authorization': 'Bearer ' + process.env.OPENAI_API_KEY
      }
    });
    const endpoint = "https://api.openai.com/v1/classifications";
    
  4. 然后,添加将与请求一起使用的示例评论:

    const examples = [
      ["The service was super quick. I love that.","Good"],
      ["Would not go back.","Poor"],
      ["I tried the chicken and cranberry pizza...mmmm!","Good"],
      ["There were no signs indicating cash only!","Poor"],
      ["I was disgusted. There was a hair in my food.","Poor"],
      ["The waitress was a little slow but friendly.","Neutral"]
    ]
    
  5. 接下来,为分类端点添加请求参数:

    const params = {
      "query": "I'm never going to this place again",
      "examples": reviews,
      "model": "curie"
    }
    
  6. 最后,添加以下代码将结果记录到控制台:

    client.post(endpoint, params)
      .then(result => {
        console.log(params.query + '\nLABEL:' + result.data.label);
      }).catch(err => {
        console.log(err);
      });
    
  7. 将你的根文件夹中的 .replit 文件更改为以下内容:

    run = "node chapter08/reviews-classifier.js"
    
  8. 单击 chapter08/reviews-classifier.js 文件,你应该会看到类似于以下截图中控制台输出的结果:

图 8.1 – 来自 chapter08/reviews-classifier.js 的示例输出

图 8.1 – 来自 chapter08/reviews-classifier.js 的示例输出

接下来,让我们使用 Python 来看一下相同的示例。

Python 示例

要创建 Python 中的在线评论分类器示例,请按照以下步骤操作:

  1. 登录到 replit.com,并打开你的 exploring-gpt3-python REPL。

  2. 创建一个新文件 – chapter08/reviews-classifier.py

  3. 将以下代码添加到 reviews-classifier.py 文件的开头:

    import requests
    import os
    import json
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + os.environ.get("OPENAI_API_KEY")
    }
    endpoint = "https://api.openai.com/v1/classifications"
    
  4. 为评论示例创建一个数组:

    examples = [
      ["The service was super quick. I love that.","Good"],
      ["Would not go back.","Poor"],
      ["I tried the chicken and cranberry pizza...mmmm!","Good"],
      ["There were no signs indicating cash only!","Poor"],
      ["I was disgusted. There was a hair in my food.","Poor"],
      ["The waitress was a little slow but friendly.","Neutral"]
    ]
    
  5. 为端点设置请求参数:

    params = {
      "query": "I'm never going to this place again",
      "examples": examples,
      "model": "curie"
    }
    
  6. 进行 HTTP 请求并将结果打印到控制台:

    result = requests.post(endpoint, headers=headers, data=json.dumps(params))
    print(params["query"] + '\nLABEL:' + result.json()["label"])
    
  7. 将你的根文件夹中的 .replit 文件更改为以下内容:

    run = "python chapter08/reviews-classifier.py"
    
  8. 单击 chapter08/online-review-classifier.py 文件,你应该会看到类似于以下截图中控制台输出的结果:

图 8.2 – 来自 chapter08/online-review-classifier.py 的示例输出

图 8.2 – 来自 chapter08/online-review-classifier.py 的示例输出

现在让我们看另一个示例。

为文本分配 ESRB 等级

在上一个示例中,我们提供了样本数据来帮助我们的分类任务。但 GPT-3 是预先训练的,具有大量数据集,这意味着它可以执行令人惊讶的数量的分类任务,而无需提供任何示例数据。让我们看另一个使用完成端点的示例。在这个示例中,我们将研究使用 娱乐软件评级委员会 (ESRB) 等级对文本进行分类。

在这个示例中,我们将使用完成端点为文本分配 ESRB 等级,而不需要任何示例数据。

Node.js/JavaScript 示例

要创建 Node.js/JavaScript 中的 ESRB 等级分类器示例,请按照以下步骤操作:

  1. 登录到 replit.com,并打开你的 exploring-gpt3-node REPL。

  2. 创建一个新文件 – chapter08/esrb-rating-classifier.js

  3. 将以下代码添加到 esrb-rating-classifier.js 文件的开头:

    const axios = require('axios');
    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
      headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    const endpoint = "https://api.openai.com/v1/engines/davinci/completions";
    
  4. 使用以下代码将端点参数添加到 esrb-rating-classifier.js 文件中:

    const params = {
      prompt: "Provide an ESRB rating for the following text:\n\n\"i'm going to hunt you down, and when I find you, I'll make you wish you were dead.\"\n\nESRB rating:",
      temperature: 0.7,
      max_tokens: 60,
      top_p: 1,
      frequency_penalty: 0,
      presence_penalty: 0,
      stop: ["\n"]
    }
    
  5. 将以下代码添加到将端点响应记录到控制台的文件中:

    client.post(endpoint, params)
      .then(result => {
        console.log(params.prompt + result.data.choices[0].text);
        // console.log(result.data);
      }).catch(err => {
        console.log(err);
      });
    
  6. 将你的根文件夹中的 .replit 文件更改为以下内容:

    run = "node chapter08/esrb-rating-classifier.js"
    
  7. 单击 chapter08/esrb-rating-classifier.js 文件,你应该会看到类似于以下截图中控制台输出的结果:

图 8.3 – 来自 chapter08/esrb-rating-classifier.js 的示例输出

图 8.3 – 来自 chapter08/esrb-rating-classifier.js 的示例输出

现在,让我们来看一下 Python 中的 ESRB 等级分类器。

Python 示例

要在 Python 中创建 ESRB 分级分类器示例,请按照以下步骤操作:

  1. 登录到 replit.com 并打开你的 exploring-gpt3-python REPL。

  2. 创建一个新文件 – chapter08/esrb-rating-classifier.py

  3. esrb-rating-classifier.py 文件的开头添加以下代码:

    import requests
    import os
    import json
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + os.environ.get("OPENAI_API_KEY")
    }
    endpoint = 'https://api.openai.com/v1/engines/davinci/completions'
    
  4. 使用以下代码将端点参数添加到 esrb-rating-classifier.js 文件中:

    params = {
      "prompt": "Provide an ESRB rating for the following text:\n\n\"i'm going to hunt you down, and when I find you, I'll make you wish you were dead.\"\n\nESRB rating:",
      "temperature": 0.7,
      "max_tokens": 60,
      "top_p": 1,
      "frequency_penalty": 0,
      "presence_penalty": 0,
      "stop": ["\n"]
    }
    
  5. 添加以下代码将端点响应记录到控制台:

    result = requests.post(endpoint, headers=headers, data=json.dumps(params))
    print(params["prompt"] + result.json()["choices"][0]["text"])
    
  6. 更改你根目录下的 .replit 文件为以下内容:

    run = "node chapter08/esrb-rating-classifier.js"
    
  7. 点击 chapter08/esrb-rating-classifier.js 文件,你应该看到类似于以下截图中控制台输出的结果:

![图 8.4 – 来自 chapter08/esrb-rating-classifier.py 的示例输出]

](https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/expl-gpt3/img/B16854_08_004.jpg)

图 8.4 – 来自 chapter08/esrb-rating-classifier.py 的示例输出

现在让我们看另一个例子。

文本分类为语言

现在,让我们考虑一个例子。假设我们需要根据消息所写的语言将支持消息路由到一个跨国支持中心。在这种情况下,我们可以使用 GPT-3 来按语言分类消息,例如英语、法语、印地语、西班牙语和俄语。让我们看看我们如何去做。

在此示例中,我们将使用分类端点和每种语言的示例来按语言分类支持消息。

Node.js/JavaScript 示例

要在 Node.js/JavaScript 中创建电子邮件分类器示例,请按照以下步骤操作:

  1. 登录到 replit.com 并打开你的 exploring-gpt3-node REPL。

  2. 创建一个新文件 – chapter08/language-classifier.js

  3. language-classifier.js 文件的开头添加以下代码:

    const axios = require('axios');
    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
      headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    const endpoint = "https://api.openai.com/v1/classifications";
    
  4. 为语言示例创建一个数组:

    const examples = [
      ["Hello, I'm interested in applying for the prompt designer position you are hiring for. Can you please tell me where I should send my resume?","English"],
      ["Здравствуйте, я хочу подать заявку на должность быстрого дизайнера, на которую вы нанимаете. Подскажите, пожалуйста, куда мне отправить резюме?","Russian"],
      ["Hola, estoy interesado en postularme para el puesto de diseñador rápido para el que está contratando. ¿Puede decirme dónde debo enviar mi currículum?", "Spanish"],
      ["Bonjour, je suis intéressé à postuler pour le poste de concepteur rapide pour lequel vous recrutez. Pouvez-vous me dire où je dois envoyer mon CV?","French"],
      ["नमस्कार, मैं उस त्वरित डिज़ाइनर पद के लिए आवेदन करने में रुचि रखता हूं, जिसके लिए आप नौकरी कर रहे हैं। क्या आप मुझे बता सकते हैं कि मुझे अपना रिज्यूम कहां भेजना चाहिए?","Hindi"]
    ]
    

    如果需要,你可以使用 translate.google.com 创建示例数据。

  5. 使用以下代码添加端点参数:

    const params = {
      "query": "¿Con quién debo comunicarme sobre ofertas de trabajo técnico?",
      "examples": examples,
      "model": "curie"
    }
    
  6. 添加以下代码将端点响应记录到控制台:

    client.post(endpoint, params)
      .then(result => {
        console.log(params.query + '\nLABEL:' + result.data.label);
      }).catch(err => {
        console.log(err);
      });
    
  7. 更改你根目录下的 .replit 文件为以下内容:

    run = "node chapter08/language-classifier.js"
    
  8. 点击 chapter08/email-classifier.js 文件,你应该看到类似于以下截图中控制台输出的结果:

![图 8.5 – 来自 chapter08/language-classifier.js 的示例输出]

](https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/expl-gpt3/img/B16854_08_005.jpg)

图 8.5 – 来自 chapter08/language-classifier.js 的示例输出

接下来让我们看看 Python 版本。

Python 示例

要在 Python 中创建语言分类器示例,请按照以下步骤操作:

  1. 登录到 replit.com 并打开你的 exploring-gpt3-python REPL。

  2. 创建一个新文件 – chapter08/language-classifier.py

  3. language-classifier.py 文件的开头添加以下代码:

    import requests
    import os
    import json
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + os.environ.get("OPENAI_API_KEY")
    }
    endpoint = "https://api.openai.com/v1/classifications"
    
  4. 为语言示例创建一个数组:

    examples = [
      ["Hello, I'm interested in applying for the prompt designer position you are hiring for. Can you please tell me where I should send my resume?","English"],
      ["Здравствуйте, я хочу подать заявку на должность быстрого дизайнера, на которую вы нанимаете. Подскажите, пожалуйста, куда мне отправить резюме?","Russian"],
      ["Hola, estoy interesado en postularme para el puesto de diseñador rápido para el que está contratando. ¿Puede decirme dónde debo enviar mi currículum?", "Spanish"],
      ["Bonjour, je suis intéressé à postuler pour le poste de concepteur rapide pour lequel vous recrutez. Pouvez-vous me dire où je dois envoyer mon CV?","French"],
      ["नमस्कार, मैं उस त्वरित डिज़ाइनर पद के लिए आवेदन करने में रुचि रखता हूं, जिसके लिए आप नौकरी कर रहे हैं। क्या आप मुझे बता सकते हैं कि मुझे अपना रिज्यूम कहां भेजना चाहिए?","Hindi"]
    ]
    

    如果需要,你可以使用 translate.google.com 创建示例数据。

  5. 使用以下代码添加端点参数:

    const params = {
      "query": "¿Con quién debo comunicarme sobre ofertas de trabajo técnico?",
      "examples": examples,
      "model": "curie"
    }
    
  6. 添加以下代码将端点响应记录到控制台:

    result = requests.post(endpoint, headers=headers, data=json.dumps(params))
    print(params["query"] + '\nLABEL:' + result.json()["label"])
    
  7. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "python chapter08/language-classifier.py"
    
  8. 单击chapter08/language-classifier.py文件,您应该看到与以下截图中的控制台输出类似的结果:

图 8.6 - 来自 chapter08/language-classifier.py 的示例输出

图 8.6 - 来自 chapter08/language-classifier.py 的示例输出

现在让我们看另一个例子。

基于关键字分类文本

另一个常见的文本分类任务是基于关键字对文档进行分类。为此,我们可以使用 GPT3 创建一个与文档内容相关的关键字列表。然而,GPT3 不仅仅是从文档中提取关键字。它根据文档内容确定相关的关键字。让我们尝试一个例子。

在这个例子中,我们将使用完成端点来基于相关关键字对文档进行分类。

Node.js/JavaScript 示例

要在Node.js/JavaScript中创建关键词分类器示例,请按照以下步骤进行:

  1. 登录到replit.com,然后打开您的exploring-gpt3-node REPL。

  2. 创建一个新文件 - chapter08/keywords-classifier.js

  3. keywords-classifier.js文件的开头添加以下代码:

    const axios = require('axios');
    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
      headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    const endpoint = "https://api.openai.com/v1/engines/davinci/completions";
    
  4. 使用以下代码将端点参数添加到keywords-classifier.js中:

    const params = {
      prompt: "Text: When NASA opened for business on October 1, 1958, it accelerated the work already started on human and robotic spaceflight. NASA's first high profile program was Project Mercury, an effort to learn if humans could survive in space. This was followed by Project Gemini, which used spacecraft built for two astronauts to perfect the capabilities needed for the national objective of a human trip to the Moon by the end of the 1960s. Project Apollo achieved that objective in July 1969 with the Apollo 11 mission and expanded on it with five more successful lunar landing missions through 1972\. After the Skylab and Apollo-Soyuz Test Projects of the mid-1970s, NASA's human spaceflight efforts again resumed in 1981, with the Space Shuttle program that continued for 30 years. The Shuttle was not only a breakthrough technology, but was essential to our next major step in space, the construction of the International Space Station.\n\nKeywords:",
      temperature: 0.3,
      max_tokens: 60,
      top_p: 1,
      frequency_penalty: 0.8,
      presence_penalty: 0,
      stop: ["\n"]
    }
    
  5. 添加以下代码以将端点响应记录到控制台:

    client.post(endpoint, params)
      .then(result => {
        console.log(params.prompt + result.data.choices[0].text);
        // console.log(result.data);
      }).catch(err => {
        console.log(err);
      });
    
  6. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "node chapter08/keywords-classifier.js"
    
  7. 单击chapter08/keywords-classifier.js文件,您应该看到与以下截图中的控制台输出类似的结果。请注意,在结果中识别出的一些关键字可能不存在于原始文本中:

图 8.7 - 来自 chapter08/keywords-classifier.js 的示例输出

图 8.7 - 来自 chapter08/keywords-classifier.js 的示例输出

好了,接下来,让我们看一下 Python 版本。

Python 示例

要在 Python 中创建关键词分类器示例,请按照以下步骤进行:

  1. 登录到replit.com,然后打开您的exploring-gpt3-python REPL。

  2. 创建一个新文件 - chapter08/keywords-classifier.py

  3. keywords-classifier.py文件的开头添加以下代码:

    import requests
    import os
    import json
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + os.environ.get("OPENAI_API_KEY")
    }
    endpoint = 'https://api.openai.com/v1/engines/davinci/completions'
    
  4. chapter08/keywords-classifier.py中添加一个params变量,其中包含以下代码:

    params = {
      "prompt": "Text: When NASA opened for business on October 1, 1958, it accelerated the work already started on human and robotic spaceflight. NASA's first high profile program was Project Mercury, an effort to learn if humans could survive in space. This was followed by Project Gemini, which used spacecraft built for two astronauts to perfect the capabilities needed for the national objective of a human trip to the Moon by the end of the 1960s. Project Apollo achieved that objective in July 1969 with the Apollo 11 mission and expanded on it with five more successful lunar landing missions through 1972\. After the Skylab and Apollo-Soyuz Test Projects of the mid-1970s, NASA's human spaceflight efforts again resumed in 1981, with the Space Shuttle program that continued for 30 years. The Shuttle was not only a breakthrough technology, but was essential to our next major step in space, the construction of the International Space Station.\n\nKeywords:",
      "temperature": 0.3,
      "max_tokens": 60,
      "top_p": 1,
      "frequency_penalty": 0.8,
      "presence_penalty": 0,
      "stop": ["\n"]
    }
    
  5. 添加以下代码以将端点响应记录到控制台:

    result = requests.post(endpoint, headers=headers, data=json.dumps(params))
    print(params["prompt"] + result.json()["choices"][0]["text"])
    
  6. 将您的根文件夹中的.replit文件更改为以下内容:

    run = "python chapter08/keywords-classifier.py"
    
  7. 单击chapter08/keywords-classifier.py文件,您应该看到与以下截图中的控制台输出类似的结果:

图 8.8 - 来自 chapter08/keywords-classifier.py 的示例输出

图 8.8 - 来自 chapter08/keywords-classifier.py 的示例输出

再次注意,返回的一些关键字并不出现在提供的文本中,但它们仍然相关。这是可能的,因为 GPT3 正在使用其语言模型来考虑最合适的关键字,即使它们不包含在文本中。

摘要

在本章中,我们介绍了理解文本分类和分类 API 端点。然后,我们通过实例来实现情感分析,为文本分配 ESRB 等级,语言分类和关键字文本分类。

在下一章中,我们将了解如何使用语义搜索 API 端点。

第九章:构建一个由 GPT-3 提供动力的问答 app

到目前为止,我们已经查看了(并编写了)很多代码。但我们实际上还没有创建一个完全可用的 app。那就是我们将要做的事情。在本章中,我们将构建一个简单但功能强大的 Web app,让用户提出问题,由 GPT-3 从我们提供的知识库中回答。该 app 可用于回答任何类型的问题,但我们将用它来回答人们可能对我们有的问题 - 一个 问我任何事 的 app。所以,想象一个招聘专员或潜在雇主可以用来询问你的技能、成就和经验的网站。不想找新工作?没问题。同样,这个 app 可以用于任何类型的问答应用 - 所以可能是一个由 GPT-3 动力驱动的产品 FAQ,或一个由 GPT-3 动力驱动的教学助手 - 这完全取决于你。我们将从 app 将如何工作的快速概述开始,然后逐步介绍构建过程。

我们将涵盖的主题如下:

  • 介绍 GPT Answers

  • 介绍 Answers 端点

  • 设置和测试 Express

  • 为 GPT Answers 创建 API 端点

  • 创建 GPT Answers 用户界面

  • 整合 Answers 端点

  • 生成相关且准确的答案

  • 使用带有 Answers 端点的文件

技术要求

本章需要您访问 OpenAI API。您可以通过访问 openapi.com 来请求访问权限。

介绍 GPT Answers

在本节中,我们将构建一个由 GPT-3 提供动力的 Web app,让用户提出任何问题并从我们提供的数据知识库中获取答案。我们将称该 app 为 GPT Answers。是的,这个名称有点平淡,但我们可以随时使用 GPT-3 来帮助我们思考一个更好的名称。

以下是完成时 app 外观的截图。是的,用户界面可能像名称一样平淡,但其背后的功能一定令人印象深刻!

图 9.1 – GPT Answers 用户界面

图 9.1 – GPT Answers 用户界面

现在让我们深入了解 UI 的后台以及 app 将如何构建。

GPT Answers 技术概述

GPT Answers 将使用 Node.js、JavaScript 和 HTML 构建。我们还将使用一个名为 Express 的 Web 框架来简化开发。

重要提示

该 app 也可以使用 Python 构建,但对于本章,与之前的章节不同,我们只会介绍使用 Node.js/JavaScript 创建 app 的步骤。

问题将通过一个简单的网页表单提交,该表单将使用 JavaScript 向 app 也暴露的 API 端点发送请求。该 app 的 API 主要作为与 OpenAI API 交互的代理,但也将提供异常处理和响应格式化。

托管该 app

到目前为止,我们只使用replit.com来编写和测试代码。但是,replit.com还支持托管应用程序,并且使用起来非常容易。对于 Web 应用程序,您甚至可以使用自己的域名。因此,replit.com将成为我们的托管环境以及开发环境。

重要说明

由 GPT-3 支持的应用程序需要经过 OpenAI 批准才能向公众展示。我们在本章不会详细讨论此事,但我们将在第十章中涵盖应用程序批准流程,与 OpenAI 技术的应用上线

应用程序将使用的主要 OpenAI 端点是答案端点。但是由于我们尚未涵盖答案端点,请在开始编码之前快速介绍一下。

介绍答案端点

OpenAI Answers 端点专为问答任务而设计。它通过启用用于答案的真实来源而比 Completions 端点提供更多控制。对于我们的 GPT Answers 应用程序,这个真实来源将是用于回答问题的知识库。知识库(即文档)可以通过端点请求提供,也可以通过引用包含数据的预先上传的文件来提供。

答案端点的 URL 为 api.openai.com/v1/answers,该端点接受 HTTP POST 请求和一些输入参数。以下是可用输入参数的简要描述,但有关更完整的详细信息,请参阅位于 beta.openai.com/docs/api-reference/answers 的 OpenAI 文档的答案端点。

以下是必填参数:

  • model(必填,字符串) - 将用于完成的模型的 ID。

  • question(必填,字符串) - 要回答的问题。

  • examples(必填,数组) - 问题列表,带有答案,以帮助引导模型朝着答案的语气和格式前进。

  • examples_context(必填,字符串) - 包含用于为您提供的示例生成答案的上下文信息的文本片段。

  • documents(数组) - 应从中提取输入问题的答案的文档列表。如果documents参数是空列表,则将根据问题 - 答案示例来回答问题。另外,仅在不使用file参数时才需要documents参数。

  • file(字符串) - 包含要从中提取答案的文档的上传文件的 ID。如果未使用documents参数,则仅需要file参数。

可选参数如下:

  • search_model(字符串) - 用于搜索的引擎。默认为ada

  • max_rerank(整数)- 要处理的文档的最大数量。较高的值可以提高准确性,但会增加延迟和成本。默认为200

  • temperature(数字)- 默认为0,适用于定义明确答案,但较高的值可用于较不确定的答案。

  • logprobs(整数)- 默认为null。返回的可能标记数量。

  • max_tokens(整数)- 将用于生成答案的最大标记数量。默认为16

  • stop(字符串或数组)- 可选的最多四个模式序列,将导致 API 停止生成完成。默认为null

  • n(整数)- 为每个问题生成的答案数量。默认为1

  • logit_bias(映射)- 可以用于控制指定标记出现在完成中的可能性。

  • return_metadata(布尔值)- 如果使用了file参数并且文件引用包含元数据,则导致响应包含来自文件的元数据。

  • return_prompt(布尔值)- 导致将提示文本与响应一起返回。默认为false

  • expand(数组)- 导致响应包含关于完成或文件的详细信息。expand的值当前可以包括completionfile。默认为一个空数组。

    重要提示

    对于我们的 GPTAMA 应用程序,我们将不会使用所有可用的参数。

现在我们已经对 Answers 端点进行了快速介绍,让我们开始编写我们的 GPTAMA 应用程序!

设置和测试 Express

Express 是用于 Node.js 的轻量级但灵活的 Web 应用程序框架,我们将在应用程序中使用它。通过 Replit.com,它非常容易上手。所以,我们要做的第一件事是在 Replit.com 上设置 Express 并进行测试。我们将从头开始,因此我们将为 GPTAMA 创建一个新的 repl。

要创建一个新的 Node.js REPL 并设置 Express,请完成以下步骤:

  1. replit.com登录。

  2. 创建一个名为gptanswers-node的新 Node.js REPL。

  3. 在输出窗格中,单击Shell选项卡,然后输入此命令:

    npx express-generator --no-view --force .
    
  4. 通过按下Enter键运行上一个命令,您应该会看到一个类似以下截图的结果:图 9.2 - express-generator 的输出

    图 9.2 - express-generator 的输出

    重要提示

    npx命令包含在 NPM 中,NPM 与 Node.js 一起安装。它用于运行express-generator,该生成器将创建一个基本的 Express 应用程序作为起点。命令以句点结尾,以指示express-generator将文件添加到当前目录。--no-view开关告诉生成器我们只是使用纯 HTML 作为我们的 UI,--force开关告诉生成器覆盖当前目录中的任何现有文件。

  5. express-generator完成后,在 shell 中运行以下命令:

    npm update
    
  6. 现在创建一个名为.replit的文件,并将以下Run命令添加到其中:

    Run = "node ./bin/www"
    
  7. 最后,点击Run按钮启动 Express 服务器。如果一切顺利,您应该在 Replit.com 编辑器中看到一个打开的浏览器窗口,其中显示 Express 的欢迎消息。它应如下图所示:

图 9.3 – 在 Replit.com 中运行的 Express 服务器

图 9.3 – 在 Replit.com 中运行的 Express 服务器

需要注意的两件事是浏览器窗格中的 URL 以及Run按钮变成了Stop按钮。这是因为 Express 正在运行一个 HTTP 服务器,该服务器将持续运行,直到停止。因此,在 Express 服务器运行时,应用程序可在网上访问,并通过浏览器窗格中的 URL 访问。此外,当您进行更改时,您需要点击Stop按钮然后点击Run按钮来停止和重新启动 Express。

如果您遇到任何问题,并且看不到 Express 页面,您可以再次按照本节的步骤操作而不会损坏任何内容。当您看到 Express 的欢迎页面时,您就可以继续进行。接下来,我们将为我们的 GPT Answers 应用程序创建 API 端点。

为 GPT Answers 创建 API 端点

当我们的应用程序完成时,我们将拥有一个完全功能的 API 端点,可以返回由 OpenAI API 生成的答案。但现在,我们将只创建一个返回占位符响应的端点。然后,我们将使用 Postman 测试端点,稍后再回来完成编码。

创建 API 端点

要创建 API 端点,请执行以下操作:

  1. 打开由express-generator创建的app.js文件。该文件应如下图所示:图 9.4 – 由 express-generator 创建的默认 app.js 文件

    图 9.4 – 由 express-generator 创建的默认 app.js 文件

  2. 编辑第 7 行,将var usersRouter = require('./routes/users')更改为以下内容:

    var answerRouter = require('./routes/answer');
    
  3. 编辑第 18 行,将app.use('/users', usersRouter);更改为以下内容:

    app.use('/answer', answerRouter);
    

    编辑第 7行和18行后,app.js文件应如下图所示:

    图 9.5 – 编辑后的 app.js 文件

    图 9.5 – 编辑后的 app.js 文件

  4. 删除routes/users.js文件。

  5. 创建一个新文件routes/answer.js

  6. 添加以下代码到answers.js文件中:

    const axios = require('axios');
    const express = require('express');
    const router = express.Router();
    
    router.post('/', (req, res) => {
      res.send({answer:'placeholder for the answer'});
    });
    
    module.exports = router;
    
  7. 点击Stop按钮,然后Start。您应该再次看到Welcome to E****xpress的消息。

我们创建的 API 端点接受 HTTP/answer。但由于它接受 HTTP POST,我们需要通过进行 POST 请求来测试它。为了做到这一点,我们将使用 Postman。

使用 Postman 测试我们的 API

此时,我们应该能够向我们的/answer端点进行 HTTP POST 请求并获得响应。要完成测试,请将从Replit.com浏览器(显示 Express 欢迎消息的浏览器)复制到剪贴板的应用程序 URL:

  1. 打开一个新的浏览器选项卡并登录到postman.com

  2. 创建一个名为gptanswers-node的新集合。

  3. /answer 中创建一个名为 test-answer-api 的新请求。端点 URL 的格式如下,其中{username} 是你的 Replit.com 用户名(假设你将 repl 命名为 gptanswers-node):

    https://gptanswers-node.{username}.repl.co
    
  4. 在端点 URL 输入框下方,选择 Body 选项卡,选择 Raw 单选按钮,并从内容类型下拉列表中选择 JSON

  5. 最后,添加以下 JSON 请求体:

    {
        "question" : "How old are you?"
    }
    

    在设置 Postman 请求后,它应该像以下的屏幕截图:

    图 9.6 – 在 Postman 中测试 GPT-CV 应用程序 API 端点的请求。

    图 9.6 – 在 Postman 中测试 GPT-CV 应用程序 API 端点的请求。

  6. 点击蓝色 Send 按钮提交请求并查看响应,应如下所示:

    {
        "answer": "placeholder for the answer"
    }
    

现在,我们已经得到 API 端点的回应,接下来我们将创建一个 Web 表单来调用 API。

创建 GPT Answers 用户界面。

现在,让我们创建一个简单的 Web 表单界面,让用户提交问题以从我们的 API 获取答案。我们将从添加 UIkit 开始 – 这是一个流行的轻量级前端框架,你可以在 getuikit.com/ 了解更多信息。我们还将使用 Axios 使用一些 JavaScript 来对应用程序 API 进行 HTTP 调用。

UIkit 将使我们的应用程序拥有简单但干净和现代的外观。你可以从 getuikit.com 免费下载 UIkit,或者你可以使用一个托管版本,该版本可从 jsdeliver.com 获得,那就是我们将要使用的。

要添加 UIkit,请执行以下操作:

  1. 打开 public/index.html 文件。

  2. cdn.jsdelivr.net/npm/uikit@3.6.22/dist/css/uikit.min.css替换样式表的 URL。

  3. 使用以下代码替换 <body> 标签和 </body> 标签之间的所有内容:

      <div class="uk-section uk-section-large uk-height-viewport">
      <div class="uk-container uk-text-center uk-padding-large">
            <h1 class="uk-heading-medium"><strong>GPT</strong> Answers </h1>
            <p class="uk-text-lead">An Example Knowledge Base App Powered by GPT-3</p>
        </div>
        <div class="uk-container uk-text-center">
            <form class="uk-grid-collapse" uk-grid>
              <div class="uk-width-1-1 ">
                <input id="question" class="uk-input uk-width-1-3" type="text">
                <button type="submit" class="uk-button uk-button-default uk-width-1-5">Get Answer</button>
              </div>
            </form>
        </div>
        <div class="uk-container uk-text-center uk-padding">
          <div class="uk-inline">
            <div id="answer" class="uk-flex uk-flex-center uk-flex-middle uk-padding uk-width-expand"></div>
          </div>
        </div>
      </div>
    
  4. </body>标签上方添加以下代码。这将添加页面使用的 JavaScript 文件的引用。其中三个脚本将来自 CDN,一个 /javascripts/script.js,我们将在下一步中创建它:

    <script src="img/axios.min.js"></script>
    <script src="img/uikit.min.js"></script>
    <script src="img/uikit-icons.min.js"></script>
    <script src="img/script.js"></script>
    

    此时,public/index.html 文件的代码应如图所示:

    图 9.7 – 完成的  代码

    图 9.7 – 完成的 index.html 代码

    如果你点击 Stop 按钮然后点击 Run 按钮停止并重新启动 Express 服务器,你会看到主屏幕更新为如下屏幕截图的样子:

    图 9.8 – 问题输入表单

    图 9.8 – 问题输入表单

    现在我们需要添加一些 JavaScript 来调用应用程序 API。

  5. 创建 javascripts/script.js 文件并添加以下代码。

  6. 首先,我们将添加两个变量来保存 HTML 表单和答案 div

    const form = document.querySelector('form');
    const answer = document.querySelector('#answer');
    
  7. 接下来,我们将添加当提交表单时触发的代码:

    const formEvent = form.addEventListener('submit', event => {
      event.preventDefault();
      const question = document.querySelector('#question');
      if (question.value) {
        askQuestion(question.value);
      } else {
        answer.innerHTML = "You need to enter a question to get an answer.";
        answer.classList.add("error");
      }
    });
    
  8. 下面的代码将将文本附加到答案div中:

    const appendAnswer = (result) => {
      answer.innerHTML = `<p>${result.answer}</p>`;
    };
    
  9. 最后,我们将添加一个函数,使用 Axios 调用应用程序的 API 端点:

    const askQuestion = (question) => {
      const params = {
        method: 'post',
        url: '/answer',
        headers: {
          'content-type': 'application/json'
        },
        data: { question }
      };
      axios(params)
        .then(response => {
          const answer = response.data;
          appendAnswer(answer);
        })
        .catch(error => console.error(error));
    };
    
  10. 现在我们可以通过点击Stop按钮,然后点击Start按钮来进行测试。然后,在浏览器窗格中,在文本框中输入一个问题,然后点击GET ANSWER按钮。你应该会看到 API 回复的占位符答案,如下图所示:

图 9.9 – 使用占位符 API 代码测试 Web UI

图 9.9 – 使用占位符 API 代码测试 Web UI

在这一点上,我们已经搭建好了应用程序的基本框架。接下来,我们需要做的是写一些代码,将问题传递给 OpenAI API 答案端点。

集成答案端点

现在我们将返回到routes/answer.js文件中添加一些代码,以便调用 OpenAI Answers 端点来回答用户的问题,而不是返回占位符文本:

  1. 打开routes/answer.js文件并执行以下操作。

  2. 删除 第 5 行 之后的所有代码。

  3. 第 5 行 开始,添加以下代码,然后换行:

    const apiKey = process.env.OPENAI_API_KEY;
    const client = axios.create({
      headers: { 'Authorization': 'Bearer ' + apiKey }
    });
    
  4. 接下来,添加以下代码并在其后换行:

    const documents = [
      "I am a day older than I was yesterday.<|endoftext|>",
      "I build applications that use GPT-3.<|endoftext|>",
      "My preferred programming is Python.<|endoftext|>"
    ]
    
  5. 第 16 行 开始添加以下代码,然后换行:

    const endpoint = 'https://api.openai.com/v1/answers';
    
  6. 接下来,从 第 18 行 开始添加以下内容以完成代码:

    router.post('/', (req, res) => {
      // call the OpenAI API
        const data = {
        "documents": documents,
        "question": req.body.question,
        "search_model": "ada",
        "model": "curie",
        "examples_context": "My favorite programming language is Python.",
        "examples": [["How old are you?", "I'm a day older than I was yesterday."], ["What languages do you know?", "I speak English and write code in Python."]],
        "max_tokens": 15,
        "temperature": 0,
        "return_prompt": false,
        "expand": ["completion"],
        "stop": ["\n", "<|endoftext|>"],
      }
      client.post(endpoint, data)
        .then(result => {
          res.send({"answer" : result.data.answers[0]})
        }).catch(result => {
          res.send({"answer" : "Sorry, I don't have an answer."})
        });
    });
    module.exports = router;
    

    当你编辑完routes/answer.js文件后,文件应该像以下屏幕截图所示:

    图 9.10 – 编辑后的 routes/answer.js 文件

    图 9.10 – 编辑后的 routes/answer.js 文件

    我们快要完成了。在测试之前的最后一步是将我们的 OpenAI API 密钥添加为环境变量。

  7. 通过点击挂锁图标并添加一个名为OPENAI_API_KEY的密钥和您的 OpenAI API 密钥的值来将您的 OpenAI API 密钥添加为 REPL 的秘密,就像以下屏幕截图中的示例一样: 图 9.11 – 为 OpenAI API 密钥添加一个秘密

    图 9.11 – 为 OpenAI API 密钥添加一个秘密

  8. 点击Stop按钮,然后点击Run重新启动 Express,然后在问题文本框中输入你最喜欢的食物是什么?,然后点击GET ANSWER按钮。你应该会看到像以下屏幕截图展示的内容——来自 GPT-3 的答案:

图 9.12 – 来自 GPT-3 的答案

图 9.12 – 来自 GPT-3 的答案

现在我们有了一个简单但功能齐全的基于 GPT-3 的问答应用。然而,您可能想知道为什么我们在你最喜欢的食物是什么?这个问题上得到了回应(一个答案),当我们还没有给出那个答案。我们将在后面讨论这个问题。

生成相关且真实的答案

GPT-3 是一个语言模型 - 它预测应该跟随提供的提示文本的文本的统计可能性。从某种意义上说,它不是一个知识库,它并不太关心所生成的响应的事实准确性。这并不意味着它不会生成事实性答案;这只是意味着你不能指望所有时间答案都是准确的。但是 Answers 端点可以提供对所生成答案的准确性或相关性的很多控制。

正如我们之前在 介绍 Answers 端点 中讨论的那样,答案将从我们提供的文档中生成。在这一点上,我们是作为端点请求的一部分提供文档的。使用这种方法,如果答案无法从文档中推导出来,由 routes/answer.js 文件定义的引擎 - 我们使用了 Curie 引擎。但是假设我们只希望答案从我们的文档中推导出来,否则我们不希望返回答案。虽然我们无法完全控制这一点,但我们可以使用预先上传的文件使我们接近实现这一点。

当使用 Answers 端点时使用预先上传的文件时,与使用 HTTP 请求提供文档时一样,你不仅仅限于只有 200 个文档。事实上,预先上传的文件可能包含非常多的文档,因为每个组织可以拥有最多 1 GB 的文件空间。因为一个文件可能包含非常多的文档,所以对文件中的文档应用关键字过滤器以缩小可能用于答案的文档范围。从那里开始,文档被排名,然后由模型参数定义的引擎使用以生成答案。当你使用请求参数发送文档时,关键字过滤将被跳过,因为你可以发送的文档数量限制为 200 个。对于我们的 GPT Answers 应用程序,关键字过滤将帮助我们减少回答无关问题的可能性。所以,让我们看一下如何使用 Answers 端点中的文件。

使用 Answers 端点的文件

要使用文件中的文档,我们需要做的第一件事是将文件上传到 OpenAI,以便 Answers 端点可以使用它。该过程涉及创建一个包含我们文档的文件,然后使用 文件端点 将文件上传并获取可在对 Answers 端点发出请求时使用的文件 ID。要创建和上传答案文件,请完成以下步骤:

  1. 创建一个名为 answers.jsonl 的新的jsonl文件,并为文件中的一些答案编写如下格式的答案:

    {"text": "I am a day younger than I will be tomorrow"}
    {"text": "I like to code in Python."}
    {"text": "My favorite food is carrot cake."}
    
  2. 创建另一个名为 files-upload.js 的新文件。

  3. file-upload.js 中添加以下代码:

  4. 需要几个将要使用的模块:

    const fs = require('fs');
    const axios = require('axios');
    const FormData = require('form-data');
    
  5. 接下来,添加以下代码来读取请求的 jsonl 数据:

    const data = new FormData();
    data.append('purpose', 'answers');
    data.append('file', fs.createReadStream('answers.jsonl'));
    
  6. 添加一个变量用于 HTTP 请求参数:

    const params = {
    method: 'post',
    url: 'https://api.openai.com/v1/files',
    headers: { 
      'Authorization': 'Bearer ' + process.env.OPENAI_API_KEY, 
      ...data.getHeaders()
    },
    data : data
    }
    
  7. 最后,添加代码以进行 HTTP 请求并记录结果:

    axios(params)
      .then(function(response) {
        console.log(response.data);
      })
      .catch(function(error) {
        console.log(error);
      });
    

    当编辑完 files-upload.js 后,它应该像以下截图中的代码一样:

    图 9.13 – file-upload.js 的完成代码

    图 9.13 – file-upload.js 的完成代码

  8. 在输出窗格中,点击Shell选项卡。

  9. ~/gptanswers-node提示符处,输入以下命令并附上你的 OpenAI API 密钥:

    export OPENAI_API_KEY="your-api-key-goes-here"
    
  10. 接下来,在 shell 中输入以下命令:

    node files-upload.js
    

    运行上述 shell 命令后,你应该会看到类似以下截图的输出结果:

    图 9.14 – files-upload.js 的 Shell 输出

    图 9.14 – files-upload.js 的 Shell 输出

  11. 从 JSON 结果中复制id值(以file-开头的值)到剪贴板。

  12. 点击小锁图标并创建一个名为ANSWERS_FILE的新秘密/环境变量,并将你在上一步中复制的 ID 值粘贴到值输入中,然后点击添加新的秘密按钮。

  13. 打开routes/answer.js并将第 20 行documents参数重命名为file。然后用process.env.ANSWERS_FILE替换documents值。

    上一个更新后,第 20 行应该看起来像以下截图中的第 20 行

    图 9.15 – 使用文件参数的 Answers 端点参数

    图 9.15 – 使用文件参数的 Answers 端点参数

    此时,你已经准备好测试了。

  14. 点击运行按钮,然后在问题输入中输入你最喜欢的食物是什么?,然后点击获取答案按钮。这次你会注意到答案是从我们的答案文件中生成的,就像以下截图所示:

图 9.16 – 从答案文件生成的答案

图 9.16 – 从答案文件生成的答案

但是现在,如果你输入一个与你的文件中的数据完全无关的问题,响应将会是对不起,我没有答案。你可以尝试询问诸如你们有红色的这个吗?这样的问题。你应该会看到一个类似以下截图的结果:

图 9.17 – 无法回答的问题

图 9.17 – 无法回答的问题

一个重要的事情要记住的是,答案文件和完成引擎(在我们的案例中是Curie)都用于生成答案。因此,有可能得到一个在你的文件中没有定义的答案。但是,你的答案文件中的数据越多,这种可能性就越小。但是因为我们现在只有三个文档在我们的答案文件中,所以如果你问类似你最喜欢的度假地点是什么?这样的问题,你可能会看到一个在你的答案文件中没有定义的答案,就像以下截图所示:

图 9.18 – 不是来自答案文件的答案

图 9.18 – 不是来自答案文件的答案

因此,即使我们在答案文件中提供答案,也不能保证 GPT-3 不会生成不准确的答案。但我们稍后将在本章和第十章使用 OpenAI-Powered 应用程序上线中讨论这一点。

到目前为止,我们有一个完全功能的应用程序。当然,我们可以添加更多功能来完善我们的应用程序,但核心功能已经就位。你需要做的主要事情是向答案文件中添加更多文档。要做到这一点,每次想要添加新数据时,请完成以下步骤:

  1. answers.jsonl 文件添加新文档。

  2. 打开 shell。

  3. 运行以下 shell 命令将你的 API 密钥设置为 shell 可以访问的环境变量:

    export OPENAI_API_KEY="your-api-key-goes-here"
    
  4. 在 shell 中运行以下命令以执行 files-upload.js

    node files-upload.js
    
  5. 通过单击锁图标并替换值为 ANSWERS_FILE 机密,复制文件 ANSWERS_FILE 环境变量。

  6. 单击 停止 按钮,然后单击 运行 按钮重新启动 Express。

再次,你的答案文件中有更多数据将减少出现非事实性答案的机会。但 GPT-3 仍然可能生成明显不是来自你的答案文件的答案。因此,考虑内容过滤仍然很重要,这也是我们将在下一章中更详细介绍的原因。

概要

在本章中,我们介绍了答案端点,并使用 Node.js/JavaScript 构建了一个简单但功能齐全的 Web 应用程序,可以从我们提供的文档中回答问题。对于我们的应用程序,我们创建了一个充当 OpenAI API 代理的 API 和一个提供用户界面的 HTML 页面。

在下一章中,我们将讨论 OpenAI 应用程序审查流程,并根据 OpenAI 的建议实施一些修改。然后,我们将介绍上线所需的步骤!

第十章:使用 OpenAI 提供的应用程序上线

在使用 OpenAI API 的应用程序上线之前,它们必须经过 OpenAI 的发布批准。批准过程有助于防止 OpenAI API 被故意或意外地滥用。它也有助于应用程序提供者和 OpenAI 规划资源需求,以确保应用程序在推出时表现良好,并随着使用量的增长而增加。

在此章节中,我们将讨论 OpenAI 应用程序使用案例指南以及审查和批准过程。然后,我们将根据 OpenAI 的指南讨论对我们的 GPT Answers 应用程序所做的更改。最后,我们将实施建议的更新,并讨论提交我们的应用程序进行审查,并希望获得批准的过程!

我们将涵盖的主题如下:

  • 上线

  • 理解用例指南

  • 处理潜在的批准问题

  • 完成预上线审查请求

技术要求

本章需要您可以访问OpenAI API。您可以通过访问openai.com来请求访问权限。

上线

OpenAI 将活动的应用程序定义为向超过五个人提供 API 输出的任何应用程序。这包括您公司或组织中的人员。因此,即使一个私人测试版应用程序使用 OpenAI API 并拥有超过五个用户,它也被认为是活动的。要超出这一限制,您的应用程序需要经过 OpenAI 的审查和批准。

在未经 OpenAI 批准的情况下上线可能会导致您的 API 密钥立即被吊销,而且没有警告。此外,未经批准的上线可能导致您的账户被永久性地阻止进一步访问 API。因此,了解 OpenAI 使用案例指南和审查过程是一个好主意。

理解用例指南

可以使用 OpenAI API 的应用程序范围广泛。然而,并非所有用例都被允许,因此每个应用程序在上线之前都必须经过审查和批准。

每个应用程序都是根据特定情况进行评估的,因此了解您的应用程序是否允许的唯一方法是通过审查过程。特别是,OpenAI 发表了一些指南,您可以阅读和遵循,以使您的应用程序有最佳的批准机会。您可以在beta.openai.com/docs/use-case-guidelines找到这些指南。在大量投入应用程序之前,您应该先仔细阅读这些指南。

在本节中,我们不会涵盖所有应用程序指南。但主要是与安全相关的指南。OpenAI 定义的安全是摆脱可以对人们造成身体、心理或社会伤害的条件的自由,包括但不限于死亡、伤害、疾病、困扰、错误信息或激进化、财产或机会的损失或损害,以及对环境的损害

因此,作弊、欺骗、剥削、骚扰、伤害、恐吓、操纵、误导、盗窃、诈骗,或者在任何方式上可能造成伤害或损害的应用,无论是否有意,都是不允许的。大多数指南应该看起来相当明显。但有些指南并不那么明显。例如,在大多数情况下,你不能构建用于生成 Twitter 推文内容的应用。这是因为使用 AI 生成的内容违反了 Twitter 的可接受使用政策。因此,再次强调本节的重点不是覆盖具体的指南;重点是强调在构建应用之前审查和理解指南的重要性。通过在开始构建之前审查指南,你将能够专注于所有可接受的用例,并避免潜在的审批问题。我们将在审查流程之前看一些可能的问题。

处理潜在的审批问题

阅读完 OpenAI 用例指南后,我们可以考虑它们如何适用于我们的 GPT Answers 应用程序。我们的应用程序仅限于以我们在答案文件中提供的答案来回答问题。因此,它的范围非常有限,不会生成开放式的响应。基于此,指南建议我们的应用程序几乎总是可批准的。然而,再次强调,每个应用程序都是根据具体情况审批的,所以这并不是一个保证。

另外,作为开发人员,我们希望尽一切可能考虑安全最佳实践。OpenAI 在 beta.openai.com/docs/safety-best-practices 发布了安全最佳实践,这将有助于确保我们的应用程序是安全的,并且不容易被利用。这也将有助于增加我们的应用程序获得批准的机会。基于这些指南,我们将考虑对我们的 GPT Answers 应用程序进行一些修改。具体来说,我们将考虑以下内容:

  • 内容过滤

  • 输入和输出长度

  • 速率限制

让我们逐个讨论这些考虑因素,并讨论它们如何适用于我们的应用。

内容过滤

对于我们的 GPT Answers 应用程序,内容过滤可能是不必要的,因为完成是从我们提供的答案文件中生成的 - 这在某种程度上可以算作一种输出过滤。然而,我们可能不希望将不适当的问题发送到 OpenAI API,因为即使在我们的情况下响应是安全的,我们仍然会使用令牌。因此,我们将为问题实施内容过滤,以检查不适当的词语。

我们将要实现的内容过滤流程如下:

  1. 用户提出一个问题。

  2. 我们检查问题是否含有粗俗语言。

  3. 如果检测到粗俗语言,我们显示:这不是我们可以回答的问题

  4. 如果未检测到粗俗语言,我们将问题传递给 OpenAI API。

我们将使用一个名为 bad-wordsNode.js 库来检查问题文本中是否包含粗话,然后再将其发送到 OpenAI API。如果在文本中发现了粗话,我们将礼貌地回复一条消息,说这不是我们能回答的问题

要在问题文本上实现内容过滤,请执行以下操作:

  1. routes/answer.js 的第一行引入 bad-words 库,代码如下:

    const Filter = require(‘bad-words’);
    
  2. routes/answer.js 文件中,在以 const data 开头的行上面添加以下代码:

    let filter = new Filter();
    if (filter.isProfane(req.body.question)) {
        res.send({ “answer”: “That’s not a question we can answer.”});
        return;
    }
    
  3. 点击停止按钮,然后点击运行按钮,并通过输入包含粗话的问题来进行测试。你应该会看到以下截图中的结果:

图 10.1 – 过滤问题中的粗话

图 10.1 – 过滤问题中的粗话

现在我们已经为问题实现了内容过滤。如果我们要使用完成端点生成答案,我们还想使用我们在第六章中讨论过的内容过滤引擎来对答案应用内容过滤。但是,因为我们是从提供的文件中生成答案,所以对于 GPT Answers 应用来说可能并不必要。因此,让我们继续考虑输入和输出长度。

输入和输出长度

OpenAI 建议限制输入和输出长度。输出可以使用 max_tokens 参数轻松限制。我们已经将 GPT Answers 应用的 max_tokens 参数设为 150。这是推荐的范围输出长度 - 如来自答案文件的问题答案。这将支持约 6-8 个句子的答案文本。如果你有更短的答案,你可以减小 max_tokens 的长度。较少,只要你允许足够来完全回答问题。

注入攻击是一种利用允许执行不受信任或意外输入的 Web 应用程序的攻击。例如,在 GPT Answers 应用中 - 如果用户提交的内容不是问题,而我们的后端代码将其传递给 OpenAI API 会发生什么?记得了吗,输入输出?尽管我们的应用程序范围严格,并且除了相关问题以外的任何内容都不会返回任何东西,但是添加一些代码来防止非常大的文本输入仍然是值得的,因为输入仍然会使用标记。因此,我们将添加一些代码来限制输入长度。平均句子是 75-100 个字符,因此我们将限制输入为 150 个字符,以允许更长的句子。

要限制我们的 GPT Answers 应用中的输入长度,请执行以下操作:

  1. 打开 routes/answer.js 并在以 router.post 开头的行后面的新行上添加以下代码:

    if (req.body.question.length > 150) {
      res.send({ “answer”: “Sorry. That question is too long.” });
      return;
    }
    
  2. 点击停止按钮,然后点击运行按钮来停止和启动 Express 服务。

  3. 输入一个超过 150 个字符长的文本输入到问题框中,然后点击获取答案按钮。

    您现在会看到表单告诉用户他们输入的文本太长,如下截图所示:

图 10.2 – 长文本表单输出

图 10.2 – 长文本表单输出

再次强调,尽管我们的应用不应生成意外完成,但限制输入,以及请求速率限制,将有助于预防恶意尝试利用您的应用。接下来让我们来谈谈速率限制。

请求速率限制

速率限制防止用户在给定时间段内发出超过预定义数量的请求。这可防止恶意脚本潜在地向您的应用程序发出大量请求。我们将使用一个名为Express Rate Limit的可用于Node.js的库,根据 OpenAI 建议的指南将限制设置为每分钟最多六次请求。

要实现速率限制,请执行以下操作:

  1. 打开app.js,在行 9之后(或在var app = express();之后),添加以下代码:

    const rateLimit = require(“express-rate-limit”);
    const apiLimiter = rateLimit({
      windowMs: 1 * 60 * 1000,
      max: 6
    });
    app.use(“/answer/”, apiLimiter);
    
  2. 打开routes/answer.js,并在以router.post开头的行后添加以下代码:

    if (req.rateLimit.remaining == 0) {
      res.send({“answer” : “Ask me again in a minute.”});
      return;
    };
    

    之前的更改为每分钟六次请求设置了速率限制。当在向 OpenAI API 发出请求之前达到速率限制时,我们会以消息回应,并要求在一分钟内再试一次,如下截图所示:

图 10.3 – 请求速率超过时的消息

图 10.3 – 请求速率超过时的消息

由于我们以与答案相同的 JSON 格式发送消息,因此消息会显示在表单页面上。

重要提示

您可以通过访问www.npmjs.com/package/limiter了解使用的速率限制器库。

好的,现在我们已经审查了用例指南并实施了一些安全最佳实践,我们准备讨论 OpenAI 预发布审核和批准流程。

完成预发布审核请求

当您的应用准备好上线时,您可以通过填写位于beta.openai.com/forms/pre-launch-review预发布审核请求表单来开始批准流程。

该表单收集您的联系信息,以及您的领英资料链接、应用程序的视频演示,以及关于应用用例和增长计划的一系列特定问题的答案。在接下来的部分中,我们将列出当前问题并提供可能适用于 GPT Answers 应用程序的示例答案。

预发布审核请求表中有很多问题,建议先在 Google 文档(或其他应用程序)中完整回答问题,然后在准备就绪时将答案复制粘贴到表单中。

该表单首先收集您的联系方式。在提供联系信息后,第一组问题会就高级别的用例进行提问。

高级用例问题

高层次的用例问题非常直观。但是,其中一个问题要求提供视频演示。所以,您需要提供一个视频演示,并将其发布到 YouTube 等地方,以便提供链接。以下是问题和一些示例答案:

  • 问题:您是否已经审查过 OpenAI 的用例指南?

    答案:是的

  • 问题:请描述一下您的公司是做什么的。

    答案:我的公司提供技术学习资源。

  • 问题:请描述一下您的应用程序是做什么的。

    答案:它让用户获取关于我的问题的答案。

  • 问题:您的申请之前是否被 OpenAI 审核过?此次审核的结果如何?此次提交与之前的审核有何关联?

    答案:没有

  • 问题:请链接到您的应用程序的短视频演示。

    答案:这里放置一个视频演示的链接。

  • 问题:请分享一个 OpenAI 团队可以用来演示/测试您的应用程序的登录凭据。

    答案:不需要登录凭据。

接下来的一组问题与安全性和风险缓解相关。您可能会猜到,有很多关于安全性和风险缓解的问题。让我们来看一看。

安全和风险缓解问题

在编写本书时,有 14 个安全和风险缓解问题。您将看到其中一些问题涉及内容过滤、设置输入和输出长度以及请求速率限制等问题。这些问题对批准是重要的且必需的,这就是为什么我们在我们的 GPT Answers 应用中实现了它们:

  • 问题:用户可以在您的应用程序的输入文本框中插入的最大字符数是多少?

    答案:150

  • 问题:您的应用程序运行的最大输出标记是多少?

    答案:150

  • 问题:您的应用程序的典型用户是谁(例如,企业、研究实验室、企业家、学术界等)?您以某种方式验证或认证用户吗?如果是,如何?

    答案:最可能的用户是对我的专业背景感兴趣的招聘人员。用户未经验证,但使用用户的 IP 地址进行了速率限制。

  • 问题:用户需要支付才能访问您的应用程序吗?如果是,金额是多少?

    答案:没有

  • 问题:您是否为您的应用程序实现了速率限制?如果是,速率限制是多少,如何执行?

    答案:是的,速率限制由 IP 地址强制执行,请求限制为每分钟六次请求。

  • 问题:您是否为您的应用程序实现了某种形式的内容过滤?如果是,被过滤的内容是什么,通过什么手段进行过滤,以及如何执行?

    答案:所有答案都是从预先上传用于与答案端点一起使用的答案文件生成的。因此,不使用内容过滤。

  • 问题:您是否捕获用户对您的输出质量或其他细节(例如,返回不愉快的内容)的反馈?如果是,这些数据如何监控和处理?

    答案:提供了一个链接到 Google 表单,让用户报告他们可能遇到的任何问题。

  • 问题:您是否会监控您应用程序的特定用户的使用情况(例如,调查体积的激增,标记某些关键字等)?如果是,以什么方式和通过什么执行机制?

    答案:不,因为范围仅限于由我提供的答案文件中的数据。

  • 问题:您的应用程序是否清楚地披露了内容是由 AI 生成的?以什么方式?

    答案:是的,问题输入页面上的文字让用户知道答案是由 GPT-3 生成的。

  • 问题:您的应用程序中是否有人类介入的形式?如果有,请描述。

    答案:是的,所有问题的答案都来自一个最初由人类创建和更新的答案文件。

  • 问题:您是否为此项目实施了其他安全或风险缓解因素?请描述。

    答案:OpenAI 令牌使用将被密切监控异常使用模式。

  • 问题:您的应用程序与社交媒体之间有何关系(如果有的话)?

    答案:没有。

  • 问题:你的应用程序与政治内容有何关系(如果有的话)?

    答案:没有。

  • 问题:如果您的团队具有特定的资格或背景,可能有助于缓解上述任何风险,请在此处详细说明。

    答案:我们没有特定的资格。

在安全和风险缓解问题之后,你将被询问关于你的增长计划。

增长计划问题

为了管理资源需求并限制滥用的可能性,新的应用程序被授予了最大花费限制。这就限制了可以处理的令牌的最大数量,从而限制了可扩展性。然而,随着你的应用程序建立了一份可靠记录,最大花费限制可以随着时间的推移而增加。

你的初始花费限制需要经过批准才能上线,并且在应用程序上线后需要提交额外的表单来请求花费限制的增加。花费限制增加表单位于beta.openai.com/forms/quota-increase。要计算您的花费限制,请在 Playground 中输入一个典型的提示,并设置引擎和响应长度。然后将鼠标悬停在提示输入下方的数字上,您将看到一个估计的成本,如下面的屏幕截图所示:

图 10.4 – 估计成本

img/B16854_10_004.jpg

图 10.4 – 估计成本

通过 Playground 的成本,你可以按预估的用户数量和每月请求数量进行乘法运算。你需要对增长计划部分的问题提供一个估计。

以下是关于你的增长计划的问题:

  • 问题:您希望请求多少美元价值的每月配额?

    答案:$18

  • 问题:您预计每个月会消耗多少令牌?针对哪些引擎?

    答案:~ 1 Mn ada 代币和~1 Mn curie 代币。

  • 问题:您最初将向多少用户(大约)推出您的应用程序?您如何知道这些用户?/您将如何找到这些用户?

    答案:订阅我们 SaaS 服务的 5,000 名用户

  • 问题:请描述您在初始推出后的增长计划。

    答案:我们计划向我们服务的所有新用户推出该应用程序 - 每月约 500 个

  • 问题:如果获准,您打算在哪个日期启动您的应用程序?

    答案:2021 年 11 月 5 日

  • 问题:如果有用的话,您可以在上面的启动日期上进行详细说明。

    答案:我们希望尽快推出。

在成长规划问题之后,还有一些杂项问题要总结,然后您就完成了。

总结问题

总结问题请求您对应用程序开发过程以及构建应用程序的经验提供反馈。这是向 OpenAI 提供信息的机会,可以帮助他们改进其他开发者的开发体验:

  • 问题:我们很喜欢听取反馈!您是否想与 OpenAI 团队分享任何内容(例如,构建应用程序最困难的部分或您希望看到的功能)?

    答案:最困难的部分是找出最佳的请求速率限制方法。

  • 问题:如果我们批准您的应用程序,您是否希望添加任何合作者来访问 API?如果是,请以逗号分隔的形式列出他们的电子邮件。

    答案:不,目前只有我一个人。

  • 问题:我们对此过程的反馈特别感兴趣。您完成这个表单需要多长时间?您觉得最困难的是什么?

    答案:我花了大约 5 天时间。我对编码还很陌生,所以学习曲线很具挑战性。

  • 问题:您还有什么要分享的吗?

    答案:我非常喜欢与 API 合作!

  • 问题:表单提交日期

    答案:05/11/2021

在完成并提交“预发布审查请求”表单后,您应该在几天内收到回复。回复将是批准或拒绝,并附有拒绝的原因。根据拒绝原因,您可能能够解决任何指出的问题并重新提交进行另一次审查。然而,希望您的应用程序获得批准,并且您已经获得了上线的批准!

概要

恭喜,您已完成探索 GPT-3和您的第一个 OpenAI 驱动的应用程序!在这一点上,您的应用程序应该已经准备好进行审查流程了。请记住,所有应用程序都是根据具体情况逐案批准的。因此,仅仅完成本书中的步骤并不保证获得批准。但是,您现在了解了用例指南以及应用程序审查和批准流程。此外,您具备了处理 OpenAI 可能要求的任何更改所需的知识和技能。

posted @ 2026-03-25 10:26  布客飞龙II  阅读(0)  评论(0)    收藏  举报