在这个由两部分组成的系列的第一部分中,我们将探讨次优的嵌入模型、低效的分块策略以及缺乏元数据过滤如何导致您很难从法学硕士那里获得相关回复。以下是如何克服这些挑战。
构建使用以下内容的生成式 AI 应用程序
我们将把这个过程分为两个主要部分。第一个,我们将在本系列的第一篇文章中讨论,是嵌入管道,它填充
在这里,我们将考虑可能导致不良结果的三个主要方面:次优的嵌入模型、低效的分块策略以及缺乏元数据过滤。 (在即将发表的文章中,我们将研究与法学硕士的实际互动,并检查其中突然出现并可能导致不良结果的一些常见问题。)
您选择的嵌入模型将对 RAG 应用程序的整体相关性和可用性产生重大影响。因此,它需要对每个模型的功能有细致入微的了解,并分析这些功能如何与您的应用程序的需求保持一致。
如果您对 RAG 和嵌入相对较新,那么您应该了解的最佳资源之一是
排行榜可以帮助您确定最适合您的特定用例的模型。
RAG 性能不佳的最常见原因之一是,刚接触该领域的开发人员会通过 Google 搜索来查找嵌入生成的示例。他们经常发现使用 Word2Vec、sBERT 和 RoBERTa 等嵌入模型的样本对于检索用例来说是糟糕的选择。
如果您发现这篇文章是因为您正在调试相关性较差的结果,并且使用 sBERT 之类的工具来生成嵌入,那么我们很可能已经确定了相关性问题的原因。
如果是这样,您可能会遇到的下一个问题是可以使用哪些嵌入模型来改进相似性搜索结果。在不知道您的用例的详细信息的情况下,我们建议的三个是:
最大输入序列长度高达 8,192 个标记,它还允许您为比替代模型更长的文本片段创建嵌入。这既是祝福也是诅咒。
拥有较大的序列大小可以简化为更多文本内容创建嵌入的过程,并且允许嵌入模型识别更大文本正文中单词和句子之间的关系。
然而,这也会导致相似性搜索在比较两个长文档的相似性时变得更加模糊,而您正在寻找的是相关的上下文块以促进生成过程。
Ada v2 有两大缺点。首先是它不能在本地运行。您必须使用 OpenAI 的 API 来创建嵌入。这不仅会在您想要为许多内容创建嵌入的情况下引入瓶颈,而且还会增加每 1,000 个令牌 0.0001 美元的成本。
第二个是,从开放 AI 模型创建的嵌入各有 1,536 维。如果您使用云矢量数据库,这可能会大大增加您的矢量存储成本。
何时选择:您想要一个仅需要 API 调用的简单解决方案,您可能需要对大型文档进行矢量化,并且成本不是问题。
Jina v2 是一种新的开源嵌入模型,它为您提供与 Ada v2 相同的 8,000 个输入序列支持,并且实际上在检索用例中得分略高。
Jina v2 为 Ada v2 的问题提供了解决方案。它是 Apache License 2.0 下的开源软件,可以在本地运行,当然,如果您不希望运行自己的代码来执行此操作,这也是一个缺点。它还生成一个维度为 Ada v2 一半的嵌入向量。
因此,您不仅可以在基准用例上获得稍微更好的检索性能,而且从矢量数据库的角度来看,您还可以以较低的存储和计算要求获得改进的结果。
何时选择:您想要使用开源解决方案,并且可能需要对大型文档进行矢量化,并且能够轻松地在本地运行嵌入管道。您希望通过较低维度的嵌入来降低矢量数据库成本。
bge-large-en-v1.5在 MIT 许可下开源,目前是 MTEB 检索用例排行榜上排名最高的嵌入模型。使用较小的输入序列,它需要您更多地考虑分块策略,但最终为检索用例提供最佳的全面性能。
何时选择:您想要使用开源解决方案,并且愿意花更多时间在分块策略上以保持在输入大小限制之内。您可以轻松地在本地运行嵌入管道。您需要针对检索用例使用性能最佳的嵌入模型。
虽然超出了本文的范围,但您可能希望更深入地研究 MTEB 排行榜中的 15 个基准,以确定最接近您的具体情况的一个。
虽然各种嵌入模型在不同基准上的表现肯定存在一定的模式,但每个模型中通常都有一些突出的特定模型。如果您需要进一步细化您的嵌入选择,这是一个可能需要进一步研究的领域。
输入文本的分段或“分块”是显着影响生成输出的相关性和准确性的关键因素。各种分块策略具有独特的优势,并且适合特定类型的任务。在这里,我们深入研究这些方法并为其应用提供指南,并纳入一些关键考虑因素:
何时使用- 除非您的内容本身是高度结构化且长度固定的,否则您通常需要依赖更有用的分块策略,例如下面的策略。
技术考虑- 虽然实施起来非常简单,但这种分块策略通常会导致 RAG 应用程序的结果不佳。
其他见解如果您在 RAG 应用程序中使用固定长度策略并且在检索相关上下文时遇到困难,则应考虑切换到不同的分块方法。
何时使用- 当输入文本中的每个句子都具有丰富的含义和上下文时,此策略非常有效。它允许模型专注于每个句子中的复杂性,从而生成更连贯且与上下文相关的响应。对于 RAG 用例,您很少会依赖句子级分块。
技术考虑-句子级分块通常涉及基于句子边界的标记化,这可以使用自然语言处理 (NLP) 库来实现。
其他见解-当您搜索特定语句时,例如在会议记录中,您试图查找与给定文本片段在语义上相似的语句,句子级分块尤其有用。
何时使用- 当输入文本被组织成不同的部分或段落,每个部分或段落封装一个单独的想法或主题时,采用此策略。这使得模型能够专注于每个段落中的相关信息。
技术考虑-识别段落边界通常涉及检测换行符或其他表示段落结束的分隔符。
其他见解-当您的文档涵盖同一主题的许多不同方面时,段落级分块可能会很有用。例如,一页产品文档可能会介绍产品功能,解释何时使用它,讨论如何配置它,并给出不同配置的示例。
使用段落级分块可以帮助您识别文档中最相关的部分,以作为上下文提供给法学硕士。
何时使用-当文本中特定部分的相关性至关重要时选择此策略。例如,在法律文件中,根据条款或章节对文本进行分段可以产生更多针对特定上下文的响应。
技术考虑-这种方法可能需要先进的 NLP 技术来理解文本内的语义边界。
额外的见解-内容感知分块在处理结构化或半结构化数据时特别有用,因为特定的块可以与元数据过滤相结合以实现更精确的检索。
例如,在法律文档中,您可能希望提取所有保修或赔偿条款,并且当您在向量数据库中存储块的嵌入时,您可以使用元数据,以便在构建文档时更轻松地搜索给定类型的内容。 RAG 用例。
何时使用-递归分块使用分层方法将数据分成越来越小的部分。例如,在对文本文档进行分块时,您可以先将文本分为段落,然后分为句子,最后分为单词。
一旦数据被划分为第一组块,您就可以递归地将分块过程应用于每个较小的块,重复直到达到您感兴趣的最小块大小。
技术考虑-实现递归分块可能涉及多级解析策略,其中根据附加标准将块进一步划分为子块。如果您正在使用
额外的洞察力-这种方法使模型能够理解多个级别的上下文,从高级主题到详细的细微差别,使其对于学术论文、技术手册或法律合同等复杂文档特别有用。这带来了灵活性优势,因为相似性搜索可以为更广泛和更短的查询识别相似的文本。
然而,这也意味着来自同一源文档的相似块最终也可能在相似性搜索中被过度代表,特别是如果您选择在文本拆分器配置中的块之间有更长的重叠。
作为一般方法,在尝试对大型语料库进行分块并将其矢量化之前,您应该考虑对数据进行一些临时实验。
手动检查您想要针对给定查询检索的文档,识别代表您想要为 LLM 提供的理想上下文的块,然后尝试分块策略,看看哪一种策略可以为您提供您认为最相关的块法学硕士拥有。
LLM 的可用上下文窗口是选择分块策略的重要因素。如果上下文窗口很小,您需要更有选择性地输入模型的块,以确保包含最相关的信息。
相反,较大的上下文窗口允许更大的灵活性,从而能够包含可以增强模型输出的附加上下文,即使并非全部都是严格必要的。
通过试验这些分块策略并考虑这些因素,您可以评估它们对生成输出的相关性的影响。关键是将所选策略与 RAG 应用程序的具体要求保持一致,保持输入的语义完整性,并提供对上下文的全面理解。
这将使您能够找到正确的分块过程以获得最佳性能。
随着搜索索引中嵌入数量的增加,在查找要包含在提示中的相关上下文时,近似最近邻 (ANN) 的帮助变得越来越小。假设您已为知识库中的 200 篇文章的嵌入建立了索引。
如果您能够以 1% 的准确度识别最接近的邻居,您可能会找到非常相关的结果,因为 1% 代表这 200 篇文章中的前两篇文章,并且您将获得这两篇文章中的一篇。
现在,考虑一个包含维基百科上每篇文章的搜索索引。这大约相当于 670 万篇文章。如果您最近的邻居位于最相似文章的前 1% 中,则意味着您正在获取 67,000 篇最相似文章中的一篇。
对于像维基百科这样的语料库,这意味着您最终仍然可能偏离目标。
元数据过滤为您提供了一种缩小内容范围的方法,首先过滤文档,然后应用最近邻算法。如果您要处理大量可能的匹配项,此初始预过滤可以帮助您在检索最近的邻居之前缩小可能的选项范围。
接下来,我们将深入探讨与法学硕士的互动,并检查一些可能导致不良结果的常见问题。
尝试
作者:DataStax 的 Chris Latimer
也发布在这里