paint-brush
用于查找 ChatGPT 上下文的语义与关键字搜索经过@tsg
2,408 讀數
2,408 讀數

用于查找 ChatGPT 上下文的语义与关键字搜索

经过 Tudor Golubenco8m2023/03/15
Read on Terminal Reader

太長; 讀書

上周我们添加了一个问答机器人来回答 [我们的文档] 中的问题这利用 ChatGPT 技术来回答 Xata 文档中的问题。我们这样做的方法是使用 Simon Willison 建议的方法。同样的方法也可以在 OpenAI 食谱中找到。
featured image - 用于查找 ChatGPT 上下文的语义与关键字搜索
Tudor Golubenco HackerNoon profile picture
0-item
1-item


上周我们添加了一个问答机器人来回答我们文档中的问题。这利用 ChatGPT 技术来回答 Xata 文档中的问题,即使 OpenAI GPT 模型从未在 Xata 文档上训练过。


我们这样做的方法是使用 Simon Willison 在这篇博文中建议的方法。同样的方法也可以在OpenAI 食谱中找到。这个想法如下:


  1. 针对文档运行文本搜索以查找与用户提出的问题最相关的内容。

  2. 使用这种一般形式生成提示:

     With these rules: {rules} And this text: {context} Given the above text, answer the question: {question} Answer:
  3. 将提示发送到 ChatGPT API,让模型完成回答。


我们发现这非常有效,并且结合相对较低的模型温度(温度的概念在这篇 博文中进行了解释),这往往会产生正确的结果和代码片段,只要可以在文档。


这种方法的一个关键限制是您在上面第二步中构建的提示最多需要 4000 个标记(约 3000 个单词)。这意味着第一步,即文本搜索以选择最相关的文档,变得非常重要。如果搜索步骤做得很好并提供了正确的上下文,ChatGPT 往往也能很好地生成正确且中肯的结果。


那么在文档中找到最相关内容的最佳方法是什么? OpenAI 食谱以及 Simon 的博客使用所谓的语义搜索。语义搜索利用语言模型为问题和内容生成嵌入。嵌入是数字数组,表示多个维度上的文本。具有相似嵌入的文本片段具有相似的含义。这意味着一个好的策略是找到与问题嵌入最相似的内容片段。


另一种可能的策略,基于更经典的关键字搜索,如下所示:


  • 让 ChatGPT 从问题中提取关键字,提示如下:

     Extract keywords for a search query from the text provided. Add synonyms for words where a more common one exists.
  • 使用提供的关键字运行自由文本搜索并选择最重要的结果


将其放在一张图中,这两种方法如下所示:

我们已经在我们的文档中进行了尝试,并注意到了一些优点和缺点。


让我们从比较几个结果开始。两者都针对同一个数据库运行,并且都使用 ChatGPT gpt-3.5-turbo模型。由于涉及随机性,我将每个问题都回答了 2-3 次,然后选择了我认为最好的结果。

问题:如何安装 Xata CLI?

用矢量搜索回答:

用关键字搜索回答:

结论:两个版本都提供了正确答案,但是矢量搜索版本更完整一些。他们都找到了正确的文档页面,但我认为我们基于突出显示的启发式方法在关键字策略的情况下选择了较短的文本块。


赢家:矢量搜索。

比分:1-0

问题:你如何将 Xata 与 Deno 一起使用?

用矢量搜索回答:

用关键字搜索回答:

结论:向量搜索的结果令人失望,不知何故错过了我们文档中的专用 Deno 页面。它确实找到了一些其他 Deno 相关内容,但没有找到包含非常有用示例的页面。


赢家:关键字搜索。

比分:1-1

问题:如何导入具有自定义列类型的 CSV 文件?

使用矢量搜索:

使用关键字搜索:

结论:两者都找到了正确的页面(“导入 CSV 文件”),但关键字搜索版本设法获得了更完整的答案。我确实多次运行它以确保它不是侥幸。我认为不同之处在于文本片段的选择方式(在关键字搜索的情况下与关键字相邻,在矢量搜索的情况下从页面的开头开始)。


赢家:关键字搜索。

比分:1-2

问题:如何按电子邮件列过滤名为 Users 的表?

使用矢量搜索:

使用关键字搜索:

结论:矢量搜索在这方面做得更好,因为它找到了“过滤”页面,其中有更多示例可供 ChatGPT 用来编写答案。关键字搜索答案被巧妙地破坏了,因为它使用“query”而不是“filter”作为方法名称。


赢家:矢量搜索。

比分:2-2

问题:Xata 是什么?

使用矢量搜索:

使用关键字搜索:

结论:这个是平局,因为两个答案都很好。两人选择了不同的页面来总结答案,但都做得很好,我无法选出获胜者。


比分:3-3

配置和调整

这是用于关键字搜索的示例 Xata 请求:

 // POST https://workspace-id.eu-west-1.xata.sh/db/docs:main/tables/search/ask { "question": "What is Xata?", "rules": [ "Do not answer questions about pricing or the free tier. Respond that Xata has several options available, please check https://xata.io/pricing for more information.", "If the user asks a how-to question, provide a code snippet in the language they asked for with TypeScript as the default.", "Only answer questions that are relating to the defined context or are general technical questions. If asked about a question outside of the context, you can respond with \"It doesn't look like I have enough information to answer that. Check the documentation or contact support.\"", "Results should be relevant to the context provided and match what is expected for a cloud database.", "If the question doesn't appear to be answerable from the context provided, but seems to be a question about TypeScript, Javascript, or REST APIs, you may answer from outside of the provided context.", "If you answer with Markdown snippets, prefer the GitHub flavour.", "Your name is DanGPT" ], "searchType": "keyword", "search": { "fuzziness": 1, "target": [ "slug", { "column": "title", "weight": 4 }, "content", "section", { "column": "keywords", "weight": 4 } ], "boosters": [ { "valueBooster": { "column": "section", "value": "guide", "factor": 18 } } ] } }


这是我们用于矢量搜索的内容:

 // POST https://workspace-id.eu-west-1.xata.sh/db/docs:main/tables/search/ask { "question": "How do I get a record by id?", "rules": [ "Do not answer questions about pricing or the free tier. Respond that Xata has several options available, please check https://xata.io/pricing for more information.", "If the user asks a how-to question, provide a code snippet in the language they asked for with TypeScript as the default.", "Only answer questions that are relating to the defined context or are general technical questions. If asked about a question outside of the context, you can respond with \"It doesn't look like I have enough information to answer that. Check the documentation or contact support.\"", "Results should be relevant to the context provided and match what is expected for a cloud database.", "If the question doesn't appear to be answerable from the context provided, but seems to be a question about TypeScript, Javascript, or REST APIs, you may answer from outside of the provided context.", "Your name is DanGPT" ], "searchType": "vector", "vectorSearch": { "column": "embeddings", "contentColumn": "content", "filter": { "section": "guide" } } }

如您所见,关键字搜索版本有更多设置,配置模糊度和助推器以及列权重。矢量搜索仅使用过滤器。我认为这是关键字搜索的一个优势:你有更多的拨盘来调整搜索,从而得到更好的答案。但这也需要更多的工作,如果没有这种调整,向量搜索的结果也相当不错。


在我们的例子中,我们已经为我们的文档搜索功能调整了关键字搜索。因此,这不一定是额外的工作,在使用 ChatGPT 时,我们发现我们的文档和搜索也有所改进。此外,Xata 恰好有一个非常好的 UI 来调整您的关键字搜索,所以这项工作并不难开始(计划单独发布一篇关于它的博客文章)。


向量搜索没有理由不能也有助推器和列权重等,但我们在 Xata 中还没有它,我不知道有任何其他解决方案可以像我们制作关键字一样简单搜索调整。而且,一般来说,关键字搜索有更多的现有技术,但矢量搜索很可能会赶上来。


现在,我要称关键字搜索为赢家

比分:3-4

方便

我们的文档已经有一个搜索功能,狗食 Xata,所以它很容易扩展到聊天机器人。 Xata 现在也原生支持矢量搜索,但使用它需要为所有文档页面添加嵌入,并找出一个好的分块策略。我们使用 OpenAI 嵌入 API 来生成文本嵌入,成本最低。


获胜者:关键字搜索

得分 3-5

潜伏

关键字搜索方法需要额外往返 ChatGPT API。这会增加开始在 UI 中流式传输的结果的延迟。根据我的测量,这增加了大约 1.8 秒的额外时间。


使用矢量搜索:

使用关键字搜索:

注意:此处的总下载时间和内容下载时间无关,因为它们主要取决于生成的响应的长度。查看“等待服务器响应”栏(绿色栏)进行比较。


优胜者:矢量搜索

得分:4-5

成本

关键字搜索版本需要对 ChatGPT API 进行额外的 API 调用,另一方面,矢量搜索版本需要为数据库中的所有文档和问题生成嵌入。


除非我们谈论的是很多文件,否则我会称之为平局。


得分:5-6

结论

比分很紧!在我们的例子中,我们现在已经使用关键字搜索,主要是因为我们有更多的方法来调整它,因此它为我们的测试问题集生成了更好的答案。此外,我们对搜索所做的任何改进都会自动使搜索和聊天用例受益。随着我们通过更多调整选项改进矢量搜索功能,我们可能会在未来切换到矢量搜索或混合方法。


如果您想为自己的文档或任何类型的知识库设置类似的聊天机器人,您可以使用 Xata ask 端点轻松实现上述功能。免费创建一个帐户并加入我们的Discord 。我很乐意亲自帮助您启动并运行它!