尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

RAG-技术笔记 (二)

RAG-技术笔记 (二) 首先在检索过程中获取较小的块然后如果前 k 个检索到的块中有超过 n 个块链接到同一个父节点较大的块将这个父节点替换成给 LLM 的上下文——工作原理类似于自动将一些检索到的块合并到一个更大的父块中因此得名。请注意搜索仅在子节点索引中执行。2.5 融合检索或混合搜索这是一个很早以前的思路结合传统的基于关键字的搜索稀疏检索算法如 tf-idf 或搜索行业标准 BM25和现代语义或向量搜索并将其结果组合在一个检索结果中。这里唯一的关键是如何组合不同相似度分数的检索结果。这个问题通常通过 Reciprocal Rank Fusion 算法来解决该算法能有效地对检索结果进行重新排序以得到最终的输出结果。在 LangChain 中这种方法是通过 Ensemble Retriever 来实现的该类将你定义的多个检索器结合起来比如一个基于 faiss 的向量索引和一个基于 BM25 的检索器并利用 RRF 算法进行结果的重排。在 LlamaIndex 中这一过程也是以类似的方式 实现 的。混合或融合搜索通常能提供更优秀的检索结果因为它结合了两种互补的搜索算法——既考虑了查询和存储文档之间的语义相似性也考虑了关键词匹配。3. 重排reranking和过滤filtering使用上述任何算法获得了检索结果现在是时候通过过滤、重排或一些转换来完善它们了。在 LlamaIndex 中有各种可用的后处理器根据相似性分数、关键字、元数据过滤掉结果或使用其他模型如 LLM、sentence-transformer 交叉编码器Cohere 重新排名接口或者基于元数据重排它们。这是将检索到的上下文提供给 LLM 以获得结果答案之前的最后一步。现在将讨论更高级的 RAG 技术比如查询转换和路由。这些技术涉及到大语言模型的使用代表了一种更复杂的逻辑思维——在 RAG 流程中融合了 LLM 的推理能力。4. 查询转换查询转换是一系列技术使用 LLM 作为推理引擎来修改用户输入以提高检索质量。有很多技术实现可供选择。对于复杂的查询大语言模型能够将其拆分为多个子查询。比如当你问“在 Github 上Langchain 和 LlamaIndex 这两个框架哪个更受欢迎”一般不太可能直接在语料库找到它们的比较所以将这个问题分解为两个更简单、具体的合理的子查询“Langchain 在 Github 上有多少星”“Llamaindex 在 Github 上有多少星”这些子查询会并行执行检索到的信息随后被汇总到一个 LLM 提示词中。这两个功能分别在 Langchain 中以多查询检索器的形式和在 Llamaindex 中以子问题查询引擎的形式实现。Step-back prompting 使用 LLM 生成一个更通用的查询以此检索到更通用或高层次的上下文用于为原始查询提供答案。同时执行原始查询的检索并在最终答案生成步骤中将两个上下文发送到 LLM。这是 LangChain 的一个示例实现。查询重写使用 LLM 来重新表述初始查询以改进检索。LangChain 和 LlamaIndex 都有实现个人感觉LlamaIndex 解决方案在这里更强大。5. 聊天引擎关于构建一个可以多次用于单个查询的完美 RAG 系统的下一件工作是聊天逻辑就像在 LLM 之前时代的经典聊天机器人中一样考虑到对话上下文。这是支持后续问题、代词指代或与上一个对话上下文相关的任意用户命令所必需的。它是通过查询压缩技术解决的将聊天上下文与用户查询一起考虑在内。与往常一样有几种方法可以进行上述上下文压缩——一个流行且相对简单的 ContextChatEngine首先检索与用户查询相关的上下文然后将其与内存缓冲区中的聊天记录一起发送到 LLM以便 LLM 在生成下一个答案时了解上一个上下文。更复杂的情况是 CondensePlusContextMode——在每次交互中聊天记录和最后一条消息被压缩到一个新的查询中然后这个查询进入索引检索到的上下文与原始用户消息一起传递给 LLM 以生成答案。需要注意的是LlamaIndex 中还支持基于 OpenAI 智能体的聊天引擎提供更灵活的聊天模式Langchain 还支持 OpenAI 功能 API。还有像 ReAct 智能体 这样的其他聊天引擎类型但接下来将直接跳转到第 7 节讨论智能体本身。6. 查询路由查询路由是 LLM 驱动的决策步骤决定在给定用户查询的条件下下一步该做什么——选项通常是总结、对某些数据索引执行搜索或尝试许多不同的路由然后将它们的输出综合到一个答案中。查询路由器还用于选择数据存储位置来处理用户查询。这些数据存储位置可能是多样的比如传统的向量存储、图形数据库或关系型数据库或者是不同层级的索引系统。在处理多文档存储时通常会用到摘要索引和文档块向量索引这两种不同的索引。定义查询路由器包括设置它可以做出的选择。选择特定路由的过程是通过大语言模型调用来实现的其结果按照预定义的格式返回以路由查询指定的索引。如果是涉及到关联操作这些查询还可能被发送到子链或其他智能体如下面的多文档智能体方案所展示的那样。LlamaIndex 和 LangChain 都提供了对查询路由器的支持。7. 智能体Agent智能体 Langchain 和 LlamaIndex 均支持几乎从第一个 LLM API 发布开始就已经存在——这个思路是为一个具备推理能力的 LLM 提供一套工具和一个要完成的任务。这些工具可能包括一些确定性功能如任何代码函数或外部 API甚至是其他智能体——这种 LLM 链接思想是 LangChain 得名的地方。智能体本身就是一个复杂的技术不可能在 RAG 概述中深入探讨该主题所以我将继续基于 agent 的多文档检索案例并简要提及 OpenAI 助手因为它是一个相对较新的概念在最近的 OpenAI 开发者大会上作为 GPTs 呈现并在下文将要介绍的 RAG 系统中发挥作用。OpenAI 助手基本上整合了开源 LLM 周边工具——聊天记录、知识存储、文档上传界面。最重要的是函数调用 API 其提供了将自然语言转换为对外部工具或数据库查询的 API 调用的功能。在 LlamaIndex 中有一个 OpenAIAgent 类将这种高级逻辑与 ChatEngine 和 QueryEngine 类结合在一起提供基于识和上下文感知的聊天以及在一个对话轮次中调用多个 OpenAI 函数的能力这真正实现了智能代理行为。来看一下多文档智能体的方案—— 这是一个非常复杂的配置涉及到在每个文档上初始化一个AgentOpenAIAgent该智能体能进行文档摘要制作和传统问答机制的操作还有一个顶层智能体负责将查询分配到各个文档智能体并综合形成最终的答案。每个文档智能体都有两个工具向量存储索引和摘要索引它根据路由查询决定使用哪一个。对于顶级智能体来说所有文档智能体都是其工具。该方案展示了一种高级 RAG 架构其中每个智能体都做路由许多决策。这种方法的好处是能够比较不同的解决方案或实体在不同的文档及其摘要中描述以及经典的单个文档摘要和 QA 机制——这基本上涵盖了最常见的与文档集合聊天的用例。这种复杂配置的缺点可以通过图片发现 —— 由于需要在智能体内部的大语言模型之间进行多次往返迭代其运行速度较慢。顺便一提LLM 调用通常是 RAG 管道中耗时最长的操作而搜索则是出于设计考虑而优化了速度。因此对于大型的多文档存储我建议考虑对此方案进行简化以便实现扩展。8. 响应合成这是任何 RAG 管道的最后一步——根据检索的所有上下文和初始用户查询生成答案。最简单的方法是将所有获取的上下文高于某个相关性阈值与查询一起连接并提供给 LLM。但是与往常一样还有其他更复杂的选项涉及多个 LLM 调用以优化检索到的上下文并生成更好的答案。响应合成的主要方法有通过将检索到的上下文逐块发送到 LLM 来优化答案概括检索到的上下文以适应提示根据不同的上下文块生成多个答案然后将它们连接或概括起来。RAG 融合和其他软件世界的架构决策一样RAG融合也有权衡取舍你需要清楚它们以便为具体情境做出最好的决定。不过首先看一下RAG融合的优缺点。优点提供多样化的上下文因为你可以从不同的角度查看用户的查询所以顶级结果里会出现更多样化的内容片段。与专注于单一视角的内容段落相比你更有可能看到能够涵盖话题多个方面的内容作为顶级结果出现。额外的控制层面像其他机器学习解决方案一样RAG融合提供了额外的控制手柄让你可以微调你的应用并让它更加符合你的期望目标。自动校正通过使用LLM作为用户在文本框中输入内容与实际在数据库中搜索内容之间的中间人你可以纠正拼写错误添加与用户查询相关的上下文信息关于用户的信息、时间、他们的账户状态等以及/或潜在地筛选特定类型的内容。成本这是一个有些争议的问题因为成本既是RAG融合的优点也是缺点让我来解释一下。你大概知道向量搜索比LLMs要便宜得多那么用于RAG融合的额外LLM调用是不是应该会增加应用的整体成本呢不过……让再来看看LLM的成本。你大概也知道你可能使用的大多数主流LLMs都采用基于token的计费模式。即使是自己托管LLM你的成本也会与处理的token数量大致成正比。基本上在这儿向LLM发送两次请求一次大概有100个token用来生成相似的查询另一次则会有数千个token提供相关文本块并希望从LLM那里得到适当的回应。所以基本上第一次对LLM的调用要比第二次便宜10到100倍。所以即使RAG融合每10次查询节省一次后续问题你在成本上还是能领先的。缺点延迟:正如你现在可能知道的LLMs需要大量的计算资源因此它们的速度相对较慢(相对于应用程序中的其他部分)。根据你的应用程序向LLM发送一次额外的请求可能会让用户的体验变得糟糕因为他们可能需要等待几百毫秒的时间。自动纠错:是的这是一个优点但是当它不起作用时也可能是一个缺点。这通常发生在你的内容包含内部术语或行话而这些术语或行话没有出现在LLM学习过的数据中。在这种情况下LLM可能会出现困惑并生成完全无关的查询从而影响到最后的结果。成本:正如之前讨论的如果RAG融合对你应用程序的整体效益贡献不大你最终可能会花费更多的费用但收益却很有限。有了以上的介绍接下来讨论一下在什么情况下最有可能通过实现RAG融合得到好的效果。如果你的应用程序的内容主要基于常见概念那么你更有可能从使用RAG融合中获益良多。RAG融合n不适用场景如果您拥有的内容包含大量内部行话或与知名品牌重复的词语则您可能需要调整RAG融合提示以获得良好的效果或者最好避免使用。以下是一个例子来说明这一点。如今所有的知名LLMs都是基于“注意力就是你所需要”的论文中首次引入的transformer架构这是一种根据语境中其他单词对生成下一个token的重要性的度量方法。现在如果我在该论文的基础上构建一个RAG应用并添加RAG融合功能其工作方式可能是这样的(绿色文字表示对RAG融合有贡献的LLM生成的查询)由于在这个语境下理解“注意力”的含义依赖于上下文LLM对这个含义产生了误解并生成了一些与之完全无关的搜索查询。这可能导致您的应用得出糟糕的结果。现在来看一下通过更改系统提示将其改为“您是一个有用的助手可以根据单一输入查询为试图解释transformer架构概念的应用生成多个搜索查询”是如何在这个特定例子中解决这个问题的。根据您的具体情况微调提示可能有用也可能没用。您也可以试试以下技巧然后才放弃使用语义搜索找到相关的查询这个选项适合较为成熟的使用场景但是如果你有很多用户基础你可以尝试搜索一个相似的查询数据库利用它们来寻找相关的内容。通过少量示例学习实现上下文理解有时候在给出提示前先给LLM展示几个例子也许能帮助提升效果。微调小型LLM如果上述方法对你特定的使用场景都没有用而测试这些方法相对较快那么你可以考虑微调自己的LLM。这样可能会有效果因为即使是很小的LLM即使只有几百万个参数也有可能足够好到能在特定模板下生成几个相似的查询。请注意这种方法相比于前面提到的方法会花费更多的成本和时间但可能会给你带来最好的效果代价是增加了复杂性。正如您所见在这种情况下(像HyDe、TF-IDF、BM25或混合搜索等许多其他方法一样)不清楚这种方法是否会胜过针对您具体用例的基本语义搜索功能。但是就像人们常说的那样“如果你不衡量你就无法改进”。因此我的建议是一旦构建了基本的RAG应用程序就要立即创建一个评估过程。在这一过程中你会有大量的想法去优化你的提示或搜索功能而每一种改变所带来的附带影响是不清楚的。有时候提升某一组查询的效果会以牺牲另一组查询为代价。在这种情况下最好的办法就是把它当作另一种机器学习问题看看数据告诉你什么。编码器和 LLM 微调这种方法主要是对 Transformer 编码器 和 LLM 进行微调。其中编码器影响嵌入质量从而影响上下文检索质量。LLM 负责最好地使用提供的上下文来回答用户查询。如今的一大优势是可以使用像 GPT-4 这样的高端 LLM 来生成高质量的数据集。但是必须清楚使用小型合成数据集进微调基础模型可能会降低基础模型的通用能力。编码器微调作者进行了一项测试对 bge-large-en-v1.5 编码器进行微调发现对于检索效果提升影响有限。因为针对搜索优化的最新 Transformer 编码器已经非常高效。排序器微调如果不完全信任基础编码器可以使用交叉编码器对检索到的结果进行重排。这个过程是这样的你把查询和每个前 k 个检索到的文本块一起送入交叉编码器中间用 SEP (分隔符) Token 分隔并对它进行微调使其对相关的文本块输出 1对不相关的输出 0。LLM 微调最近OpenAI 开始提供 LLM 微调 APILlamaIndex 有一个关于在 RAG 设置中微调GPT-3.5-turbo的教程。RAG 管道评估的 ragas 框架显示忠实度指标增加了 5%这意味着微调后的 GPT 3.5-turbo 模型比原始模型更好地利用了提供的上下文来生成答案。Meta AI Research 最近的论文 RA-DIT Retrieval Augmented Dual Instruction Tuning 展示了一种更复杂的方法提出了一种同时调整 LLM 和 Retriever 的技术原始论文中的双编码器关于查询、上下文和答案的三元组。该技术被用于通过微调 API 微调 OpenAI LLM。也被用于微调了Llama2 开源模型在原始论文中结果与带有 RAG 的 Llama2 65B 相比知识密集型任务指标增加 ~5%和常识推理任务增加几个百分点。评估RAG 系统性能评估的多个框架都包含了几项独立的指标例如总体答案相关性、答案基础性、忠实度和检索到的上下文相关性。在之前章节提到的 Ragas使用真实性和答案相关性来评价生成答案的质量并使用经典的上下文精准度和召回率来评估 RAG 方案的检索性能。最近推出的课程构建和评估高级 RAG中以及 LlamaIndex 和评估框架Truelens他们提出了RAG 三元组评估模式 — 分别是对问题的检索内容相关性、答案的基于性即大语言模型的答案在多大程度上被提供的上下文的支持和答案对问题的相关性。最关键且可控的指标是检索内容的相关性 — 实际上是上述高级 RAG 管道的前 1-7 部分加上编码器和排名器的微调部分这些都是为了提高这个指标。而第 8 部分和大语言模型的微调则专注于提高答案的相关性和基于性。简单有效的检索器评估管道可以应用于编码器的微调部分。一个更高级的方法不仅考虑命中率还包括了常用的搜索引擎评估指标平均倒数排名 (Mean Reciprocal Rank)以及生成答案的质量指标如真实性和相关性这在 OpenAI 的实用指南中有所展示。LangChain 提供了一个颇为先进的评估框架 LangSmith。在这个框架中你不仅可以实现自定义的评估器还能监控 RAG 管道内的运行进而增强系统的透明度。如果你正在使用 LlamaIndex 进行构建可以尝试 rag_evaluator llama pack。总结本文概述 RAG 的核心算法并举例说明其中的一些方法。RAG融合是一个强大的功能能够提高RAG应用的语义搜索效率。通过使用语言模型生成多个查询并对搜索结果进行重新排序RAG融合可以呈现更丰富多样的内容并提供了一个额外的层次用于调整应用。此外RAG融合还可以实现自动纠正、节省成本以及增加内容多样性。但是需要注意一些权衡比如潜在的延迟问题、自动纠正的挑战以及成本影响。对于依赖常见概念但可能出现内部行话或重叠词汇的应用来说RAG融合尤其有用。重要的是要评估RAG融合的表现并测量其影响以确定它是否适合特定应用场景。还有很多其他的事情需要考虑比如基于网络搜索的 RAGLlamaIndex 的 RAG、webLangChain 等更深入地研究智能体架构以及关于 LLM 长期记忆的一些想法。除了答案相关性和忠实度之外RAG 系统的主要生产挑战是速度。ChatGPT 和大多数其他助手使用的这种流式特性不是随机的赛博朋克风格而只是一种缩短感知答案生成时间的方法。这就是为什么我认为小参数规模的 LLM 有一个非常光明的未来最近发布的 Mixtral 和 Phi-2 正在引领朝着这个方向前进。
返回列表