Jan 5, 2025, 4:52 PM

简介

 
到目前为止,我们在项目中一直使用 ChatGPT 现有的知识和推理能力。例如,当我们向 ChatGPT 提出一个医学问题时,我们不需要教 ChatGPT 任何东西,因为它已经被大量医学知识和问题训练过了。

然而,在许多应用中,ChatGPT 的知识可能不够

  • 首先,ChatGPT 不知道在其知识截止日期(其最新训练数据的时间)之后发生的事件。
  • 此外,ChatGPT 只记住下一个单词出现的概率,而不记住任何来源的确切内容。假设我们希望 ChatGPT 仅根据特定的医学书籍回答问题,那么它很可能会失败或产生幻觉(进行猜测)。

在本教程中,您将学习一项非常有用的技能:如何教 ChatGPT 一些新知识。具体来说,您将构建一个可以回答有关 CreatiCode 问题的聊天机器人。由于 CreatiCode 在撰写本文时(2023 年 11 月)还相当新,因此 ChatGPT 对 CreatiCode 一无所知。我们将教 ChatGPT 一些关于 CreatiCode 的新知识,以便它可以根据这些知识帮助回答有关 CreatiCode 的问题。

 
 

语义搜索

 
在开始编码之前,让我解释一下我们将使用的关键方法:语义搜索。“语义”的意思是“含义”,因此“语义搜索”的意思是“按含义搜索”

例如,假设我有一个关于一本书的 5 个问题的列表:

  • 这本书叫什么名字?
  • 这本书有多少页?
  • 这本书叫什么名字?
  • 这本书多少钱?
  • 我在哪里可以买到这本书?

现在我有一个新问题“这本书的价格是多少?”,我想找出这 5 个问题中哪个与这个新问题相似。

如果我们使用传统的搜索方法,我们需要找出哪个现有问题与新问题具有最多的共同词。显然,这两个问题具有最多的共同词(6 个中的 5 个):

  • 这本书的 名字 是什么?
  • 这本书的 价格 是多少?

 
然而,由于大型语言模型的发展,现在我们有了一个全新的工具,称为“语义搜索”,它允许我们这样搜索:这 5 个已知问题中哪个与新问题的含义最相似?使用语义搜索,我们将得到一个更好的答案:“这本书多少钱?”

本质上,“语义搜索”允许我们找到含义最相似的句子,即使这些句子中的单词非常不同。正如您将在下面看到的,这将对我们的项目非常有用。


 
 

[高级主题] 语义搜索如何工作?

 
如果您对语义搜索的工作原理感到好奇,这里有一个简单的解释。

让我们仍然使用上面的例子。对于这 5 个问题中的每一个,我们将首先将它们转换为一个向量,就像 XY 轴上的一个箭头:

  • 这本书叫什么名字? -> (x = 0.9, y = 0.1)
  • 这本书有多少页? -> (x = 0.3, y = 0.8)
  • 这本书叫什么名字? -> (x = 0.4, y = 0.2)
  • 这本书多少钱? -> (x = 0.5, y = 0.5)
  • 我在哪里可以买到这本书? -> (x = 0.15, y = 0.9)

我们可以像这样说明这 5 个箭头:

83d6b769-416a-4d9b-b2c8-24a93cc5921c-image.png

 
现在,当我们得到一个查询问题“这本书的价格是多少?”时,它也将被映射到一个向量,例如 (x=0.45, y=0.4)。我们也可以将这个新向量绘制成一个箭头:

ed87cca2-4809-4fac-a865-4dfef1869ac3-image.png
 
接下来,我们只需要比较所有 5 个蓝色箭头,并找到与红色箭头夹角最小的那个。如图所示,“这本书多少钱?”的箭头与红色箭头夹角最小,这意味着这两个箭头的方向最相似。因此我们可以将该问题作为搜索结果。

5a52d20b-5162-4ba4-b37d-b65cff7bba12-image.png

 
将句子映射到向量的过程称为“嵌入”,因为它就像将每个句子作为一块石头放置在墙上的正确位置。实际上,向量通常具有数千个维度,最好的嵌入模型可以很好地衡量两段文本之间的相似性。

 
 

步骤 1 - 启动项目

现在让我们开始我们的 QA 机器人项目。我们将使用以下项目作为起点。请在您的帐户中打开它并重新混合它:

https://play.creaticode.com/projects/65544f377f7509db74c436c7

 
 

步骤 2 - 填充“数据”表

 
在项目中,已经定义了一个名为“数据”的表。它有 2 个名为“键”和“答案”的列。我们的第一个任务是用一些问题和答案填充此表。我们的想法是,我们将向 ChatGPT 提供一些标准问题和答案作为新知识,以便它可以根据这些答案回答其他问题。

 
为了节省时间,我们准备了一个包含问题和答案的 CSV 文件。请在此处下载:

https://ccdn.creaticode.com/public/sampledata.csv

 
下载 sampledata.csv 文件后,将其导入到您的数据表中。您可以在舞台上的数据表上单击鼠标右键,选择“导入”,然后在您的计算机上找到 sampledata.csv 文件。

e3.gif

 
导入数据后,您可以将鼠标悬停在任何单元格上以查看其内容。对于每一行,“键”列是一个问题,“答案”列是相应的答案。

e3.gif

 
如果您正在构建另一个项目,您可以使用 Google 表格或 Excel 准备问题和答案,然后将表格导出为 CSV 文件。然后您可以将文件上传到“数据”表中。请注意,重要的是第一列名为“键”,因为这将是我们搜索的列。您可以在“键”列之后拥有任意数量的列。

 
 

步骤 3 - 创建语义数据库

 

接下来,我们将使用表中的数据构建一个“语义数据库”。请将此块单独拖到编辑器中,确保从下拉列表中选择“数据”表,然后单击它以运行它

25b71ca9-5be1-4ad7-a70a-b3c897ecf173-image.png

 
您不会注意到任何变化,但在幕后,发生了以下情况:

  • 表中的数据已发送到 CreatiCode 服务器。
  • 已根据数据创建了一个“语义数据库”,该数据库将用于语义搜索。

请注意,在撰写本文时,每个项目只能有一个语义数据库。如果您多次运行“创建语义数据库”块,则后续运行将首先删除任何现有的语义数据库。这对于大多数应用程序来说应该足够了。

此外,**对于所有没有订阅的用户,目前有一个限制,“数据”表最多可以有 100 行数据。对于有订阅的用户,限制为 1000 行。**如果您正在构建需要更高限制的应用程序,请联系 info@creaticode.com

 
 

步骤 4 - 查看聊天精灵

 

现在我们将构建一个利用此语义数据库的聊天机器人。在开始编码之前,请快速查看“聊天”精灵中的现有块。它们提供以下 2 个基本功能:

  • 当项目开始时,向 ChatGPT 发送初始请求并显示其响应;
  • 每当用户输入一些输入时,显示该输入,然后将其发送给 ChatGPT,然后也显示响应。

 
 

步骤 5 - 测试问题

 

现在我们将通过一个问题来验证 ChatGPT 对 CreatiCode 了解不多:creaticode 多少钱?

04ba77d1-f3ec-495f-949c-06752db1db72-image.png

 
如图所示,ChatGPT 不知道答案。我们需要“教”它,然后我们将再次提出相同的问题。

 
 

步骤 6 - 运行语义搜索

 

为了教 ChatGPT 更多关于 CreatiCode 的知识,基本思想如下:给定一个用户问题,我们首先在我们准备的问题中搜索,以找到一些相似的问题,然后我们告诉 ChatGPT 根据搜索结果回答用户问题。

您可能想知道:为什么我们不直接将我们准备的所有问题和答案提供给 ChatGPT?这种方法可能有效,但有几个原因说明这不是一个好主意:

  • 当我们有很多 QA 对时,它们可能会占用大量的令牌。它可能会超过 ChatGPT 的令牌限制,并且还会花费很多钱。
  • 当我们向 ChatGPT 提供大量信息时,它可能需要更长的时间来阅读所有信息,并且也可能找不到相关信息。

 
因此,我们将使用语义搜索仅查找与用户问题具有相似含义的问题,因此它们的答案将提供与回答用户问题最相关的信息。

我们需要在获得用户问题时添加“搜索语义数据库”块。现在让我们先单独添加此块以对其进行测试。

66f542a3-50f5-432a-b19d-fa6aa5bf7ee9-image.png

 
在这个新块中,指定了前 3 个输入:

  1. 查询:第一个输入指定我们要搜索的内容。在这种情况下,我们正在搜索测试问题“Creaticode 多少钱?”。
  2. 结果数:第二个输入指定搜索将返回多少项,例如 3。搜索结果将根据它们与查询的相似程度进行排名,因此我们将获得与用户输入最相似的前 3 个问题
  3. 结果表:第三个输入指定用于存储结果项的表。返回的每个项都将作为一行存储在此表中。

 
现在让我们通过单击单独运行此块。要查看结果,我们需要查看“结果”表。由于舞台窗口被聊天小部件占用,我们还需要使用“删除所有小部件”块删除该小部件:

b1bf29d1-9eed-4d0d-89f0-6b829291b0e5-image.png

 
在我们运行“搜索语义数据库”和“删除所有小部件”块之后,将“结果”表添加到舞台,并隐藏“数据”表:

16dd89af-0c30-42b0-b341-eb21bec6497a-image.png

 
您现在应该看到“结果”表包含 3 行。第一列“分数”表示该项与查询的相似程度。它通常介于 0 和 1 之间。第二列和第三列是“键”和“答案”,这是我们之前添加到语义数据库中的问题和答案。这很有效,因为第一行是问题“CreatiCode 可以免费使用吗?”,这与我们的查询“Creaticode 多少钱?”密切相关。

e3.gif

 
注意:如果您得到一个空的“结果”表,这意味着您在步骤 3 中没有成功创建语义数据库,因此请再次尝试该步骤。

 
 

步骤 7 - 使用用户输入进行搜索

 

现在让我们将“搜索语义数据库”块添加到我们的程序中,以便它使用用户输入作为查询。我们还分离了它下面的 ChatGPT 块,因为我们需要在将其发送给 ChatGPT 之前改进我们的提示。

364a3938-5a28-41ae-9d22-e3bad05a9068-image.png

 
在此更改之后,无论用户说什么,都将用于运行搜索,并且结果将存储在“结果”表中。

 
 

步骤 8 - 从“结果”表中读取第一行

 

接下来,我们将从“结果”表中提取数据,并将它们嵌入到我们发送给 ChatGPT 的请求中。首先,创建 2 个名为“键”和“答案”的变量,并尝试从结果表中读取第一行的内容,如下所示:

58bdf0e1-974d-424a-be14-6192698c7f5a-image.png

 
单击这两个块以运行它们,您可以在舞台上查看这两个变量的值:

d4e6d4a5-17e4-445f-b83e-83ca6357cfa2-image.png
 

82e1cc48-8a3f-48d8-a481-88d4314e25f8-image.png

 
 

步骤 9 - 从“结果”表中读取所有行

 

接下来,让我们从结果表中读取所有行。我们可以使用“for 循环”,它将索引变量设置为从 1 到总行数,如下所示:

81f71a6d-a475-4ed2-bb2e-5ef503d6cf8b-image.png

 
在我们的例子中,“结果”表的行数为 3,因此这个 for 循环将运行 3 次迭代。

 
 

步骤 10 - 将所有问题和答案连接到一个参考中

 

当我们遍历结果表的每一行时,我们可以使用“连接”块将该行的内容连接到一个“参考”变量中。参考变量将以“”开头,我们将每行的新内容附加到此变量中。我们将使用“\n”字符连接问题和答案,这将在它们之间添加一个新行。循环完成后,我们可以打印出参考以查看其值。

a505ff5b-b0b0-4d75-bfd9-b160f068d103-image.png

 

如果您运行这组块,参考应该在控制台面板中打印出来,如下所示:

a7b4eab2-d3cc-4e00-988b-f6d4928f9ca4-image.png

 
 

步骤 11 - 使用参考向 ChatGPT 组成一个新的请求

 

现在我们准备使用此新的参考信息向 ChatGPT 创建一个新的请求。基本思想是向 ChatGPT 说以下内容:嘿,ChatGPT,我们需要你回答这个问题,顺便说一下,这里有一些你可以用作参考的信息

更具体地说,我们需要使用 3 个部分组成一个“请求”:用户输入、一个“[参考]”标签来指示参考部分,以及我们上面检索到的参考。

8b7168c2-65bc-4f8b-8608-156e926c200b-image.png

 
现在如果我们运行该程序,我们可以在控制台面板中看到打印出的以下请求:

e3.gif

 
 

步骤 12 - 获取 ChatGPT 的响应

 

现在让我们将**“请求”变量的值**发送给 ChatGPT 并显示其响应:

676dbecb-2214-4005-8451-933f068cc333-image.png

 
这是您应该从 ChatGPT 获得的内容:

46652e6d-b5a7-4d7f-b571-97792c800deb-image.png

 
与我们在步骤 5 中的初始测试结果相比,这显然是一个显着的改进。ChatGPT 似乎对 CreatiCode 非常了解。

 
 

步骤 13 - 使 ChatGPT 的响应更具体。

 

目前,我们只是使用一个非常简单的请求,还有很大的改进空间。当前响应最明显的问题是它不够具体。显然,ChatGPT 正在使用我们参考中的所有 3 个问题/答案对来为用户撰写答案。

您能否尝试更改我们在请求中的说明,以便 ChatGPT 仅提供如下所示的具体和直接答案?

37af690c-a35a-4ef2-bfc7-093def3305bd-image.png

 
在您花一些时间在这个挑战上之前,不要查看下面的答案。这是关于如何微调提示以从 ChatGPT 获得所需响应的一个非常好的练习。

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

你找到解决方案了吗?如果没有,请不要查看答案!

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 

步骤 14 - 使 ChatGPT 的响应更具体的解决方案

 

好的。如果您已经弄清楚在提示中要说什么,那就太好了!这并非易事,因为 ChatGPT 可能非常“固执”,并且会坚持使用参考中的所有信息。

以下是使 ChatGPT 更具体的一种解决方案。我们将像这样撰写请求:

用户输入:
creaticode 多少钱?

说明:以下是一些常见问题/答案,但它们可能不是用户要问的内容。您能否撰写一个只回应用户问题的简明答案?
CreatiCode 可以免费使用吗?
大多数功能都是免费的
CreatiCode 的目标用户是谁?
CreatiCode 是一种适合所有年龄段学习者的简单语言
我可以在 CreatiCode 上编写 3D 程序吗?
可以

 
如您所见,我们正在进行以下 2 项更改:

  1. 我们将请求分为两个部分“用户输入”与“说明”。
  2. 在说明中,我们明确告诉 ChatGPT 一些问题/答案可能不是用户要问的内容,我们要求它撰写一个只回应用户问题的答案。

 
要撰写此新请求,我们可以按以下方式修改代码:

e3.gif

 
具体来说,这是您可以复制到代码中的请求的第三部分:

\n说明:以下是一些常见问题/答案,但它们可能不是用户要问的内容。您能否撰写一个只回应用户问题的简明答案?

 
现在请再次尝试测试您的程序。

 
 

步骤 15 - 改进我们的参考问题/答案

 

除了更新提示之外,我们还可以改进语义数据库中的问题/答案。

例如,目前在我们的数据库中,我们有这样一对问题/答案:

问:CreatiCode 可以免费使用吗?
答:大多数功能都是免费的

 
答案有点模糊,ChatGPT 将无法提供超出我们提供的答案的更好答案。

例如,让我们尝试将答案改进为以下内容:

大多数功能都是免费使用的。但是,对于非付费用户,某些高级块(例如 ChatGPT 块或文本到语音块)存在速率限制。

要进行此更改,您可以从舞台中删除所有小部件,更新“数据”表的内容(不是“结果”表),然后再次单独运行“创建语义数据库”块。

e3.gif

 
现在我们可以再次测试它。您将看到 ChatGPT 根据我们的新答案提供了更新后的答案:

3259d4ee-a437-403a-a318-197d3189c0a6-image.png

 
此外,我们可以验证我们提供给 ChatGPT 的参考信息确实包含更新后的答案:

35b5c43b-4673-4271-b4a5-7fe72e8bb2da-image.png

 
 

检索增强生成 (RAG)

 

现在您已经学习了一项非常强大的技术:我们首先使用语义搜索检索一些参考信息,然后在我们对 ChatGPT 的请求中使用该信息。这通常被称为“检索增强生成”,或简称为 RAG。那是因为我们正在使用我们检索到的信息来增强 ChatGPT 的响应生成。

这个项目只是一个关于如何使用 RAG 来增强 ChatGPT 响应的简单示例。您可以使用此技术实现更多目标。

 
 

构建您自己的 QA 机器人

 

现在尝试为您非常了解但 ChatGPT 不了解的内容构建另一个 QA 机器人。

例如,您可以创建一个关于您非常了解的人的 QA 机器人,或者关于特定地点(如餐厅或公园)的 QA 机器人,或者关于组织(如学校俱乐部或非营利组织(例如 https://visionsvcb.org/))的 QA 机器人,或者关于对象(如书籍或电子设备)的 QA 机器人。

您应该首先测试它以确保 ChatGPT 尚不了解该主题,否则不容易显示您教给 ChatGPT 多少新知识。

您可能已经猜到,成功的 QA 机器人最重要的因素是高质量的输入数据。准备此类数据需要大量工作。在这个项目上团队合作可能是一个好主意。