RAG检索增强生成——让大模型学会“开卷作答”
前言在前面的文章中我们拆解了Embedding如何把文字变成向量Transformer如何理解词与词之间的关系以及大模型为什么会产生幻觉。这三条知识线最终汇聚到一个技术上——RAG检索增强生成。你可能会问RAG不就是“搜一下文档再喂给大模型”吗有什么好深究的但真正做过RAG应用的人知道这里面的坑比想象中多得多文档切多大一块检索出来的片段到底相不相关怎么知道模型是在引用文档还是在瞎编这些问题处理不好RAG的效果甚至不如直接问大模型。本文从原理到实践系统拆解RAG的每一个环节。读完这篇你将对简历上“基于LangChainRAG实现课程问答”这句话拥有完整的解释能力——面试官追问任何一个环节你都能从底层逻辑讲清楚。本文核心问题RAG解决的根本问题是什么为什么不能靠“增大上下文窗口”替代RAG的完整流程分几步离线索引和在线生成的职责如何划分文档怎么切分块多大最合适重叠窗口设多少检索策略怎么设计向量检索和关键词检索各自的优劣检索到的文档不相关怎么办如何量化“相关性”并做过滤Prompt怎么拼接检索结果上下文顺序、引用标注有什么讲究RAG和微调各适合什么场景什么情况下该选RAG而不是微调RAG的局限性在哪它不能解决什么问题一、RAG解决的根本问题疑问现在大模型的上下文窗口越来越大了直接把文档全丢进去不行吗为什么还需要RAG回答三个关键限制决定了“全量塞入”不可行——成本、注意力稀释、幻觉不降反升。1.1 成本问题GPT-4的输入价格为每百万token约30美元。一套课程文档高达20万字换算成token大约13万。每个学员每提一个问题就把整套文档全部输入一次——单次提问的成本约4美元。如果一个学员提问10次光API调用费就超过课程的售价了。问题在于课程文档中真正和当前问题相关的往往只有三五段。把整个文档全部送进去相当于花钱买了几百页不相关的信息。RAG每次只送入最相关的Top-K片段单次输入量从13万token降到1万token成本骤降90%以上。1.2 注意力稀释即使不考虑成本全部塞进去也有问题。大模型虽然支持长上下文但在长文档中的“注意力”并不均匀——它对开头和结尾的信息更敏感对中间的长段信息容易遗漏。这和人类读一份200页PDF时的体验类似翻到第80页时已经不记得第20页说过什么了。RAG通过检索把“大海捞针”变成了“拿着索引找答案”大模型只需要关注最相关的几段文字而不需要在200页中四处搜索。1.3 幻觉悖论直觉上给模型越多信息它应该越准确。但实际情况是长文档包含了大量不相关的信息、相互矛盾的说法、以及过时的内容。这些“噪音”混在检索结果中模型可能把噪音当成了事实依据反而产生了更隐蔽的幻觉。这种幻觉比凭空编造更危险——因为它“引用了原文”看起来可信度极高但引用的是无关片段。1.4 RAG的本质不用RAG 大模型 闭卷考试完全依赖“记忆”训练时见过的数据 问题记忆模糊、知识过时、容易编造 用RAG 大模型 开卷考试给参考资料让它“阅读理解总结” 优势知识实时更新、回答有据可查、幻觉大幅降低RAG不要求大模型“知道一切”只要求它“读懂几段话并回答”。这让大模型从“全知的神谕”变成了“认真的实习生”——给它资料它回答得很好不给资料它就会猜。这个类比在面试时非常管用。二、RAG的完整流程疑问RAG的流程到底分几步每个环节的职责是什么回答RAG分成两个阶段——离线索引和在线生成。前者是“把书放到书架上”后者是“根据问题从书架上拿书来答”。┌─────────────────────────────────────────────────────┐ │ 离线索引阶段 │ │ │ │ 课程文档(PDF) → 文本提取 → 文档切分(Chunk) │ │ ↓ │ │ Embedding向量化 │ │ ↓ │ │ 存入向量数据库 │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ 在线问答阶段 │ │ │ │ 用户提问 → 问题向量化 → 向量相似度检索 → Top-K片段 │ │ ↓ │ │ 构建Prompt(指令 检索片段 问题) → 调用LLM → 回答 │ └─────────────────────────────────────────────────────┘两个阶段的职责分离阶段做什么频率速度要求离线索引处理文档、生成向量、存入数据库文档更新时几天一次分钟级可接受在线生成检索 生成回答每次用户提问需秒级响应为什么分开因为Embedding向量化需要调用模型耗时较长。如果把文档处理放在每次提问时用户等不了。离线把向量算好存起来在线只做检索和生成延迟才可控。三、文档切分策略疑问文档切成多大一块为什么重叠这些问题有标准答案吗回答没有标准答案但有经验法则。核心权衡是“语义完整性”和“检索精度”之间的拉锯。3.1 切分大小的权衡切法优势劣势小块200字检索更精准召回的片段噪音少语义不完整一句话被截断大块2000字语义完整上下文充足检索不准包含很多无关信息中块500字精度和完整性的平衡点需要根据文档类型微调3.2 为什么需要重叠没有重叠时 块1: ......依赖注入的核心在于控制 块2: 反转。具体来说就是将对象的创建权...... 控制反转“这个完整概念被切断了检索时两块都可能召回不到——块1不够明确 块2开头缺少前文。两个歧义的片段送到模型手里模型的回答质量可想而知。 有100字重叠时 块1: ......依赖注入的核心在于控制反转。具体来说就是将...... 块2: ......控制反转。具体来说就是将对象的创建权交给容器...... 完整概念同时出现在两块中检索命中率大幅提高。即使用户的问题关键词只在某一块中 完全匹配相关概念不会因为切分点的位置而被遗漏。3.3 课程问答项目的实际设置// 课程文档切分配置TextSplittersplitternewRecursiveCharacterTextSplitter(500,// 每块500字——大约一段完整的技术说明的长度100// 重叠100字——确保关键概念不被切断);选择500/100的原因课程文档讲义、FAQ每个技术概念大约需要500字解释完毕。100字重叠覆盖了一个概念被拆分到两个块的边界情况。这个参数不是拍脑袋定的——试验过300/50太碎检索召回率高但回答质量差和800/200检索不准经常召回无关内容后500/100在准确率和召回率上达到了平衡。四、检索策略——向量检索 vs 关键词检索疑问向量检索和关键词检索各自的优劣实际项目中该选哪个回答两者互补实际项目建议混合使用。4.1 各自的原理和适用场景检索方式怎么做优势劣势向量检索问题→Embedding→余弦相似度找最近理解同义词、理解上下文对专有名词不敏感关键词检索BM25算法匹配单词专有名词精确命中不懂语义“线程”搜不到“多线程”4.2 实际项目中遇到的真实问题用户在课程问答项目中问“Java线程池的配置”向量检索返回的是“数据库连接池配置”相关的文档块。原因两个“池”的上下文语义相似——都是“配置参数”“大小设置”这类讨论。但用户的意图是锁定Java线程池不是数据库连接池。关键词检索能精确匹配到包含“Java线程池”的段落但对“多线程怎么配”这种同义表达就失效了。两种检索在不同维度上各有盲区这个问题天然适合用混合检索解决。4.3 混合检索方案1. 向量检索召回Top-20语义相关 2. 关键词检索召回Top-20精确匹配 3. 合并去重用RRF倒数排名融合重新排序 4. 取最终Top-5送入大模型RRF的直观理解如果一个文档在两种检索方式中都排名靠前那它大概率就是用户想找的。向量检索说第1名关键词检索说第3名——综合排名大概率最高。向量检索第1名但关键词检索根本没出现——可能只是语义模糊匹配价值有限。五、检索相关性过滤——挡住不相关的文档疑问混合检索召回了5个片段但有些还是不相关怎么办回答加一个相关性阈值过滤。检索完先判断相关性不相关的直接不送大模型。5.1 为什么需要过滤不管检索策略多优秀总有召回不相关内容的可能——用户问了一个课程里完全没有的话题向量数据库里找不到真正匹配的片段但余弦相似度还是会给出分数最高的几个结果。这些“伪相关”片段送到大模型面前模型可能拿它们当真实信息去回答产生一种“看起来引经据典但其实是张冠李戴”的幻觉。5.2 实现方式// 检索后、送大模型前加一道过滤publicListDocumentretrieveWithFilter(Stringquestion,intk,doubleminSimilarity){ListDocumentdocsvectorStore.similaritySearch(question,k*2);ListDocumentfilterednewArrayList();for(Documentdoc:docs){doublesimilaritycosineSimilarity(question,doc);if(similarityminSimilarity){// 余弦相似度 0.7 才要filtered.add(doc);}if(filtered.size()k)break;}returnfiltered;}阈值0.7是怎么定的做了一组人工标注测试50个问题标注“相关”或“不相关”。绘制余弦相似度分布发现在0.7以上时检出的片段大多是相关的低于0.7后不相关的比例急剧上升。这个阈值不是拍脑袋定的数字而是数据驱动的选择。不同业务场景的阈值可能不同需要用相同的标注方法做标定。5.3 过滤后的兜底if(relevantDocs.isEmpty()){return抱歉课程内容中未提及此问题。请换个方式提问或联系老师。;}对应的Prompt策略是“如果没有相关课程内容就说课程中未提及”。过滤层兜住了检索端的不确定性Prompt兜住了模型端的幻觉倾向。六、Prompt拼接——检索结果怎么喂进去疑问检索到的片段怎么组织顺序有讲究吗回答有讲究。顺序、标注、分隔符都影响模型的理解。6.1 最佳实践Stringprompt 你是一个课程答疑助手。请基于以下课程内容回答学生问题。 如果课程内容中没有相关信息请回答课程中未提及此内容。 ## 参考课程内容 [来源第3章] {chunk1} [来源第5章] {chunk2} [来源第2章] {chunk3} ## 学生问题 {question} ## 回答要求 - 引用来源标注章节名 - 涉及代码时使用代码块 - 回答不超过300字 ;6.2 设计要点来源标注让模型有机会区分“这是来自第3章的内容”和“这是来自第5章的内容”。用户追问时可以回溯原文位置做验证同时也方便后续做质量审查——如果你发现答案引用了第3章但引用错了可以精准定位是检索还是生成环节的问题。最相关的片段放前面大模型的注意力对开头信息更敏感。把相似度最高、最可能包含答案的片段放在第一位模型不会因为注意力漂移到后面的片段而漏掉关键信息。片段间有明显分隔防止两个片段在Prompt里拼接后被模型当作连续文本理解产生上下文串扰。七、RAG vs 微调——什么时候该选谁疑问我为什么选RAG而不是微调面试官追问这个你怎么回答回答在课程问答这个场景下RAG是更优的选择有三个理由。7.1 对比表维度RAG微调知识更新改文档即可秒级生效需要重新训练成本高可解释性可追溯到原文出处输出来自参数化记忆不可追溯幻觉控制靠外部文档约束效果明显微调后仍可能产生幻觉实现成本低不需GPU训练高需准备数据训练部署适用场景知识密集型、需要溯源风格调整、格式规范化7.2 课程问答场景选择RAG的理由课程内容会持续更新讲师会修订讲义、补充FAQ。如果用微调每次内容更新都需要重新准备数据、训练、部署一套新模型。RAG只需要更新向量数据库里的文档块后续的检索和生成流程完全不用动。回答需要溯源学生追问“你确定吗出自哪一节课”时RAG可以给出具体的引用来源——向量检索能找到原文片段Prompt里标注了章节名回答中可以引述出处。微调做不到这一点——知识融入了参数无法追溯具体的出处。Demo阶段的成本约束微调需要准备高质量问答对作为训练数据还需要GPU资源做训练。RAG只需要一个向量数据库和调用大模型API对Demo项目来说实现成本更低。7.3 微调适合什么如果未来项目需要定制特定的教学风格、统一回答的语气、或让模型遵循非常规范的输出模板可以考虑在RAG的基础上加微调。实际生产中的最佳实践往往是RAG 微调组合——RAG提供知识微调控制行为和风格。八、RAG的局限性疑问RAG能解决所有问题吗它不能做什么回答RAG能解决“知识”问题但解决不了“推理”问题。它的能力上限取决于被检索文档的质量。8.1 无法回答“超越文档”的问题如果用户问“这门课和另一门课相比哪个更适合零基础学习”RAG召回的是两门课各自的介绍但没有任何一段文档直接比较两门课。模型需要综合信息做推理——这类回答的质量很大程度上依赖模型本身的推理能力RAG提供了素材但提供了判断。8.2 无法纠正“文档中的错误”如果课程文档里本身就有一个错误比如版本号写错了RAG会忠实地把错误信息检索出来、送进Prompt、让模型基于这个错误信息回答。模型没有能力验证事实的正确性——它只是对着资料回答。8.3 检索失败时退化为基础模型当检索到的文档和问题完全不相关时如果你没有做过滤和兜底模型的行为就退化为不用RAG的基础模型——开始凭记忆编造。相关性过滤阈值和“课程未提及”的兜底策略本质上就是为这个退化路径设置的安全网。总结RAG的本质是把大模型从“闭卷考试”变成“开卷考试”——不要求它知道一切只要求它读懂几段资料文档切分是精度和完整性的拉锯500字/块100字重叠是课程内容的最佳平衡点需根据文档类型微调混合检索弥补了向量和关键词各自的盲区向量理解语义但不识专名关键词精确匹配但不懂同义相关性过滤是RAG的“安全阀”——相似度低于0.7的片段不送入模型从上游切断幻觉隐患Prompt拼接注明了来源章节让回答可回溯、可验证RAG vs 微调在课程问答场景下RAG优先知识实时更新、回答可溯源、实现成本低。生产最佳实践是RAG微调组合RAG不能解决推理问题和文档自身错误它的上限由检索库质量决定下一篇预告AI理论学习六——大模型的“记忆”从上下文窗口到会话管理。拆解大模型如何实现多轮对话ConversationBufferMemory和ConversationSummaryMemory的底层原理和各自优劣。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2587557.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!