15种高级RAG技术
15种高级RAG技术检索增强生成 RAG 是一种强大的技术它将信息检索与生成式 AI 相结合以产生更准确、上下文更丰富的响应。本文将探讨 15 种高级 RAG 技术以提高生成式 AI 系统的输出质量和整体性能的鲁棒性。这样做使本文能够测试和识别从预检索到生成的适当优化本文所提到的优化点大多数基于下图的流程。一般来说传统的 RAG 系统经常会遇到以下问题信息密度检索到的文档可能不包含足够的相关信息。检索准确性系统可能无法检索最相关的文档。响应质量生成的响应可能不准确或缺少上下文。先进的 RAG 技术通过优化 RAG 管道的每个阶段来应对这些挑战从而实现更高的系统效率、更好地满足用户需求、最优语义搜索以及更相关准确的回复。RAG 中召回是一个核心步骤按照不同优化策略和召回的前后关系优化策略可分以下几类预检索优化检索/召回策略检索后优化生成优化一、预检索优化预检索优化主要包括提高数据索引或知识数据库中信息的质量和可检索性。由于每个系统依赖于不同性质的信息预检索优化策略不一定是万能的。比如为金融系统设计的优化策略在旅游机器人中可能不太有效。预检索优化包括以下方法。使用 LLM 提高信息密度使用分层索引检索创建假设性问答对使用 LLM 对信息进行去重测试并优化最优分块1、使用 LLM 提高信息密度在存储数据前使用 LLM 处理、清洗以及对数据进行打标。这种改进是因为来自异构数据源例如 PDF、抓取的网页数据、音频转录的非结构化数据不一定是为 RAG 系统构建的导致信息密度低、噪声数据、信息重复等信息密度低迫使 RAG 系统在 LLM 上下文窗口中插入更多的块以正确回答用户查询从而增加了 token 的使用和成本。此外信息密度低会稀释相关信息以至于 LLM 可能会给出错误的回答。GPT-4 在使用少于 70,000 个 token 时似乎对这个问题有相对的抵抗力但其他模型可能没有那么强的鲁棒性。比如当原文本来源于网页时原始 HTML 包含了大量无关信息例如 CSS 类、页眉/页脚导航、HTML 标签等冗余信息。即使在程序化地剥离了 CSS 和 HTML 之后信息密度仍然很低。因此为了提高块中的信息密度本文尝试使用 GPT-4 作为事实提取器从文档中提取相关信息。对应的 prompt 中system 指令为You are a data processing assistant. Your task is to extract meaningful information from a scraped web page from XYZ Corp. This information will serve as a knowledge base for further customer inquiries. Be sure to include all possible relevant information that could be queried by XYZ Corps customers. The output should be text-only (no lists) separated by paragraphs.以上流程中原始 HTML 约有 55000 tokens而使用 GPT4 提取后的信息约有 330tokens在降低噪声的同时大大提高了信息密度。值得注意的是使用 LLM 提高信息密度是伴随着风险的即可能导致部分关键信息丢失。2、使用分层索引检索由 LLM 生成摘要并对摘要进行检索可以使得检索过程更为高效。上节使用 LLM 提高信息密度的方法类似于无损压缩而使用 LLM 生成摘要更像有损压缩。在大型数据库的情况下一种有效的方法是创建两个索引 — 一个由摘要组成另一个由文档块组成并分两步进行搜索首先通过摘要过滤掉相关文档然后在此相关组内进行搜索。3、创建假设性问答对在数据准备阶段embedding 的对象是原始文本answer而在请求阶段embedding 的对象是用户 query。这使得查询的 embedding 和结果的 embedding 是“不对称”的。一种方法是使用 GPT-4 为每个文档生成一系列假设/可能的问题和答案对然后使用生成的问题作为嵌入检索的块。在检索时系统将检索问题及其对应的答案并提供给 LLM。因此查询的嵌入与生成问题的嵌入的余弦相似度可能会更高。例如在文档中某段话的内容可能是从多个角度介绍了 xx 技术的特点但是未显式地提到特点、有缺点二词。传统 RAG 情况下当用户问到 xx 技术的优缺点时难以匹配到此段落。而如果为这个段落生成假设性问题“xxx 技术的优缺点是什么有什么特点”此时 embedding 方法就能准确匹配到此段落。上图展示了对 HTML 提取的信息生成的问答对示例。值得注意的是提取问答对仍然可能造成一定的数据信息丢失。4、使用 LLM 对信息进行去重使用 LLM 作为信息去重器可以提高数据索引的质量。LLM 通过将块提炼成更少的块来去重信息从而提高获得理想响应的几率。根据具体情况数据索引中的信息重复可能有助于或阻碍 RAG 系统的输出。一方面如果生成响应所需的正确信息在 LLM 的上下文窗口内被重复它会增加 LLM 做出理想响应的可能性。另一方面假设重复的程度稀释甚至完全挤出了 LLM 上下文窗口中的所需信息那么用户可能会收到一个无关的回答。本方案通过在 embedding 空间中对块进行 k-means 聚类来去重信息以便每个块聚类中的总 token 数在 LLM 的有效上下文窗口内。然后本文可以任务 LLM 从原始聚类中输出一组新的提炼块去除重复信息。如果一个给定的聚类包含 N 个块本文期望这个去重提示输出 N 个新块其中任何冗余信息都被去除。值得注意的是这种方法可能会使得从块到原文的引用这一信息丢失。5、测试并优化最优分块上述技术强调了分块策略的重要性。但最优的分块策略是特定于具体使用场景的并且有许多因素会影响它。找到最优分块策略的唯一方法是对你的 RAG 系统进行广泛的 A/B 测试。以下是测试时需要考虑的一些最重要因素。embedding 模型的最优输入长度不同的模型具备不同的最优的输入长度。例如来自 sentence transformers 的 embedding 模型在处理单个句子时表现出色而 text-embedding-ada-002 则可以处理更大的输入。chunk 的大小应理想地根据所使用的特定 embedding 模型进行调整反之亦然。文档的语义信息根据文档的信息密度、格式和复杂性chunk 可能需要达到一定的最小尺寸以包含足够的上下文信息从而对 LLM 有用。然而这是一种平衡的艺术。如果 chunk 过大可能会在 embedding 中稀释相关信息从而降低在语义搜索中检索到该 chunk 的几率。如果文档没有自然的分割点例如用子标题分段的教科书章节并且文档是基于任意字符限制例如 500 字符进行 chunk 分割的那么关键的上下文信息可能会被拆分开。在这种情况下应考虑重叠。例如采用 50%重叠率的 chunking 策略意味着文档中两个相邻的 500 字符 chunk 将有 250 字符的重叠。在决定重叠率时应考虑信息重复和 embedding 更多数据的成本。模型的总结能力虽然 GPT-4 似乎能够处理许多大块内容但小模型可能表现不佳。此外在许多大块内容上运行推理可能成本高昂。存储成本embedding 向量必须存储在某个地方而较小的块大小会导致相同数据量下更多的嵌入这意味着增加的存储需求和成本。更多的嵌入也可能增加语义搜索所需的计算资源这取决于语义搜索的实现方式精确最近邻 vs. 近似最近邻。通过对本 RAG 进行 A/B 测试本文可以评估每个用例的最佳分块策略。本文主要在由 GPT-4 处理的改进信息密集型文档上测试了以下分块策略1,000 字符的分块带有 200 字符的重叠500 字符的分块带有 100 字符的重叠段落处理后的文档中存在段落分隔句子使用 spaCy 进行分割假设性问题生成从上文详细描述的生成的假设性问题索引中嵌入问题在构建 AI 助手时本文发现分块策略的选择并没有太大影响见下表结果。1,000 字符的分块策略带有 200 字符的重叠表现略优于其他策略当然构建不同的应用可能会出现不同的测试结果。二、检索/召回优化检索优化涵盖了高级 RAG 技术和策略目标是在推理时提高搜索性能和检索结果并在检索发生之前进行优化本质上也可以是认为检索过程中的优化。这些策略包含以下几种使用 LLM 优化搜索请求HyDE假设性文档 embedding使用查询路由1、使用 LLM 优化搜索请求搜索系统在搜索查询以特定格式呈现时往往能达到最佳效果。LLM 是一种强大的工具可以为特定的搜索系统定制或优化用户的搜索查询。为了说明这一点本文来看两个例子优化一个简单的搜索查询和一个面向对话系统的查询。假设一个用户想要搜索 example-news-site.com 上所有关于比尔·盖茨或史蒂夫·乔布斯的新闻文章。他们可能会在 Google 中输入如下内容次优的 Google 搜索查询Articles about Bill Gates or Steve Jobs from example-news-site。可以使用 LLM 来优化这个搜索查询具体针对 Google通过利用 Google 提供的一些高级搜索功能。最优的 Google 搜索查询Bill Gates OR Steve Jobs -site:example-news-site.com。这种方法对于简单的查询是有效的但对于对话系统本文需要进一步提升。尽管上述简单的搜索查询优化可以视为一种增强本文发现使用 LLM 来优化对话系统中的 RAG 搜索查询是至关重要的。对于一个只能进行单轮对话的简单问答机器人用户的问题同时也是检索信息以增强 LLM 知识的搜索查询。但在对话系统中情况会变得更加复杂。以下是一个示例对话客户“你们的定期存款利率是多少” 助手“我们的利率是 XYZ。” 客户“哪种信用卡适合旅行” 助手“XYZ 信用卡适合旅行原因是 ABC。” 客户“告诉我更多关于那个利率的信息。”为了回答用户的最后一个问题可能需要进行语义搜索以检索有关特定 XYZ 旅行信用卡的信息。那么搜索查询应该是什么呢仅仅使用最后一条用户消息是不够具体的因为金融机构可能有许多产品会产生利息。在这种情况下语义搜索可能会产生大量潜在的无关信息这些信息可能会挤占 LLM 上下文窗口中的实际相关信息。那么使用整个对话记录作为语义搜索查询怎么样呢这可能会产生更好的结果但仍然可能包括关于定期存款的信息这与用户在对话中的最新问题无关。本文发现的最佳技术是使用 LLM 根据对话生成最优的搜索查询。此场景中用到了一下 promptYou are examining a conversation between a customer of Example bank and an Example bank chatbot. A documentation lookup of Example banks policies, products, or services is necessary for the chatbot to respond to the customer. Please construct a search query that will be used to retrieve the relevant documentation that can be used to respond to the user.这种技术的一个变体是查询扩展其中由 LLM 生成多个子搜索查询。这种变体在具有混合检索系统的 RAG 系统中特别有用该系统结合了来自不同结构的数据存储例如SQL 数据库独立的向量数据库的搜索结果。其他提示工程技术如step-back prompting和HyDE也可以与这种方法结合使用。2、HyDE假设性文档 embedding预检索优化策略中提到了查询和文档内容的 embedding 可能存在不对称的问题。通过应用 HyDE我们还可以在检索阶段实现更大的语义相似性。预检索优化中的方法是为每个段落生成对应的问答对。而在 HyDE 中我们预先为用户的问题生成多个假设性的回答再用假设性回答去进行检索而不是使用用户查询。这个想法是在具有查询-文档不对称的 RAG 系统中假设文档或片段将比用户查询本身具有更大的语义相似性。用到的 prompt 如下Please generate a 1000 character chunk of text that hypothetically could be found on Example banks website that can help the customer answer their question.3、使用查询路由查询路由器是我们见过的更受欢迎的高级 RAG 技术之一。其思想是当 RAG 系统使用多个数据源时利用 LLM 将搜索查询路由到适当的数据库。这涉及在提示中预定义路由决策选项并解析 LLM 的路由决策输出以便在代码中使用。为了降低成本并提高 RAG 的质量本文开发了一种 RAG 决策模式因为并非所有查询都需要 RAG 查找。因此识别何时 LLM 可以独立回答查询而无需外部知识可以提高效率。一个不太明显的例子是当回答用户查询所需的所有信息已经存在于最近的对话历史中。在这种情况下LLM 只需重复或稍微改述之前所说的内容。例如你能把你最后的信息翻译成西班牙语吗或请像我五岁一样解释最后的信息。这两种查询都不需要新的检索因为 LLM 可以简单地使用其内置功能回答这些查询。在实现的过程中只需要对不同的分支采用不同的 prompt 即可。