向量相似性搜索毫无希望

B站影视 2025-01-23 09:45 3

摘要:大约两年前,作为一名机器学习顾问,我曾多次参与项目,试图让 GPT 变得有用且知识渊博。在一个案例中,我试图让它扮演客户支持的角色,另一个案例是让它担任销售工程师的角色,第三个案例是实现一个用于医疗入院访谈的诊断助手。

预先形成的相似性概念本身就存在缺陷,注定会失败。我们可以做得更好。


https://medium.com/@urimerhav?source=post_page---byline--7251a855b4bd

https://medium.com/@urimerhav/vector-similarity-search-is-hopeless-7251a855b4bd

大约两年前,作为一名机器学习顾问,我曾多次参与项目,试图让 GPT 变得有用且知识渊博。在一个案例中,我试图让它扮演客户支持的角色,另一个案例是让它担任销售工程师的角色,第三个案例是实现一个用于医疗入院访谈的诊断助手。

在所有情况下,要求 GPT 使用其一般知识回答问题最初都令人印象深刻,但最终还是有局限性。该模型的一般知识已经过时且不完整,并且很难区分事实和想象。在客户支持方面,它会很乐意为您的产品编造一个功能,或者无法了解其详细工作原理等。询问它不断发展的产品的复杂性,您不可能仅靠希望模型的一般知识能够涵盖该主题而正确回答。

解决方案当然是 RAG:检索增强生成。这是一个非常简单的术语。RAG 只是“查看问题,复制并粘贴一些相关知识文章以及问题,然后告诉模型根据粘贴的文章提供答案。”

让我们举一个具体的例子。假设我正在构建一个自动化的房地产支持代理。我拥有所有租户的租赁合同,他们会发送电子邮件提出问题和投诉。

显然,如果你只是询问 ChatGPT,它根本不知道如何回答这些问题——模型权重中没有任何地方说明我的租赁合同中有什么,或者适用于该租赁合同的城市法令。

嗯?稍后我们会深入研究这个奇怪且肯定是错误的答案是如何得出的

好吧,GPT 有点失控了,它没有说“我不知道”,而是选择寻找答案,找到了一个完全不相关的来源,然后编造了一些内容。如果我们不进行互联网搜索,你就会得到典型的 4 段长的“我不知道”,这是 LLM 喜欢生成的。

那么,如果我在粘贴租赁合同宠物部分的纯文本的同时问同样的问题,会发生什么?我首先粘贴了租赁合同中的相关页面,然后提出了我的问题。奇迹发生了。

这是一个完美的答案。如果您获取相关的城市条例、建筑许可语言等,您也会得到同样出色的答案。

所以 RAG 很棒。如果我们找到一段具体有助于回答问题的文本,像 ChatGPT 这样的 LLM 可以推断和调整知识源以给出权威答案。请注意,除了房地产支持机器人之外,它还支持许多其他用例:

只要您知道如何获取相关手册,您就可以帮助技术人员找到解决复杂机器故障的相关步骤。您可以帮助保险裁决者根据保单文件的相关部分和相关的医疗发票来决定是否报销费用。您可以下载有关您正在研究的主题的最新研究论文,以便为您的问题解答或实验规划提供参考。

现在,棘手的问题仍然存在——我们如何提取能够回答当前问题的文本片段?请记住,我们的上下文长度有限——我们不能将世界上所有的文档都粘贴为上下文。那么我们如何选择在其中放入哪些支持文本呢?

向量嵌入来救援(?)

向量嵌入的想法非常吸引人。它的工作原理如下:在底层,大型语言模型 (LLM) 会为您输入的每段文本生成一个抽象表示。您可以选取一个单词、一个句子或一份 50 页的文档,并将它们中的每一个转换为单个向量。文本输入后,输出数字列表。

举一个具体的例子,你可以将整篇博文插入 OpenAI 的Ada Embedding,得到一个包含 1,536 个数字的列表,从某种意义上说,这些数字代表了这篇博文。然后你可以将它与其他 Medium 博文进行比较,它们可能会涵盖类似的主题。

如果您想了解如何测量这些向量之间的距离,我们通常只计算向量之间的距离 - 它很简单,例如,取这两个数字列表,减去它们,然后对它们的平方求和。

有了向量嵌入,搜索变得异常简单。索引所有租赁合同、城市法令、建筑许可证以及您拥有的有关问题空间的任何其他信息,并将每个文档转换为向量。当出现新问题时,将整个问题或对话嵌入到相同的向量空间中,并找到最接近的文档。现在将这些文档作为上下文复制并粘贴到您的 LLM 中,放在用户输入之前(“这是一些支持文档,您可以使用它们来回答问题”),您就大功告成了。

如果您想要更精确地定位相关文本片段,您可以选择嵌入文档,也可以单独嵌入其组成部分、段落等。这样,您就可以找到广泛相关的文档,并深入到似乎相关的特定段落或部分。听起来很神奇,对吧?

事实上,这个解决方案非常神奇。你一下子就从零搜索能力跃升到非常细致的搜索。在拆解它之前,让我们先惊叹一下它的神奇之处:

我可以嵌入以下问题:“嗨,我住在 31A 公寓,我可以带一只宠物鳄鱼吗?”将每一段嵌入我 52 页的合同中,您会立即看到这部分作为顶部部分:

您可以询问您的存款情况,果然,最上面的结果之一就会回答其金额。

当我们问一些更细致的问题时,问题就开始显现。如果我问:“你们什么时候可以用完我的押金?你们花掉我的押金的流程是什么?”顶级搜索结果实际上并没有说明具体内容。

但如果我们深入研究第二和第三个结果,我们最终会找到相关的文本跨度,我不会给你这个,因为它很长而且很无聊。

那么模型为什么会失败呢?简单来说,它嵌入信息的方式没有预测到回答的确切背景。

向量搜索测量文本跨度之间的相似性,但不知道哪种相似性是关键的,哪种相似性是偶然的

这是一个极端的例子。假设我有同一位租户的多份租赁文件,其中一些已经过期。相似性搜索可以轻松找到正确的段落——来自错误的合同。

您可以尝试一些技巧,例如在问题文本前面加上“该问题将于 2024 年 12 月 2 日提出”。但这不会显示最新的文档,因为不幸的是,已过期的租赁合同提到其将于 2024 年 12 月 1 日到期,这在向量空间中非常接近 2024 年 12 月 2 日。在房地产法律世界中,距离应该是无穷大——合同只是到期了。但在向量空间中,日期看起来很接近,因此它看起来像是一份相关文档。

检索不相关的文档并将其用作上下文是让原本很棒的 RAG 系统发疯的原因。还记得我们的第一个示例显示 ChatGPT 给出了关于我公寓的肯定错误的答案,因为它进行了互联网搜索并获取了一些不相关的来源吗?事实上,这是 RAG 非常常见的故障模式。你从错误的合同中获得正确的金额,从错误的手册中获得正确的说明,等等。

好的检索是索引检索

在实际文档中,通常有明确定义的业务逻辑来说明如何检索该文档。您可以提取租赁合同中指定的入住和退房日期。更妙的是,您不仅可以索引这些类型的项目来获取相关文档,还可以索引文档以预先回答大多数常见问题,例如租金金额、押金金额或自由格式文本中的宠物政策摘要等。

让我们来看一个具体的例子。我可以复制并粘贴我的整个租赁租约(全部 53 页),并提示 GPT 提取我感兴趣的字段。

如果我们将这些信息转换为 JSON 格式并一致地提取相同的字段,我们就可以免费获得一堆东西:

我们获得一致、可预测的检索。我们可以使用相同的字段(入住日期等)索引所有文档,然后运行 ​​SQL 或 MongoDB 查询来获取相关文档。更好的是,我们可以让我们的人工智能知道我们如何索引文档,并让它自动编写相关查询来获取相关文档。有时我们不需要获取整个文档,因为我们在索引中预测了答案,因此索引中已经包含了答案。例如,租赁租约问题通常会涉及文档理解的几个方面——租金金额、付款时间表、入住日期、宠物政策等。这使得我们致电 LLM 的成本更低、速度更快。我们无需阅读文档的整个部分,只需引用索引结果即可。

我相信这种模式非常强大。我对此深信不疑,因此我创建了一家名为DocuPanda.io的公司来支持这种方法。

我们可以轻松定义一组字段,并在数百万个文档中大规模提取具有一致数据类型和定义的字段。即使文档包含表格、手写、复选标记等,它也能正常工作。

这是 DocuPanda 中的输出内容(我隐藏了一些字段以节省空间)。

一旦你标准化了许多文档,你就可以提出自由形式的问题,并依靠人工智能自动生成相关查询

这个问题触发了一个链条,其中人工智能会反省我们的模式中有哪些字段(例如,租户姓名、允许携带宠物(真/假布尔值)、允许携带宠物的详细信息(短文本跨度)。然后,人工智能会编写一个数据库查询来获取相关结果,阅读返回的记录(例如,租户姓名 ==“Meital Bendet”),最后对结果进行推理,可能需要参考原始文档文本。

这给出了最终结果。

我希望您能考虑一下,您可以花一点时间思考您的企业需要如何理解其文档,并以一种符合您搜索文档方式的方式一劳永逸地索引您的文档,从而构建更强大的管道。还可以考虑试用DocuPanda。它是多年来在这个领域不断尝试和犯错的成果,可能会帮助您更快地执行。

快乐索引!

来源:想吃烤地瓜

相关推荐