高级RAG优化实战:从查询改写、混合检索到Agentic RAG与RAGAS评估
1. 从“能用”到“好用”RAG到底卡在哪里1.1 naive RAG的四个瓶颈前面十几章把朴素RAG的完整链路走了一遍文档加载、切块、向量化、建索引、向量检索、拼上下文、交给LLM生成。这套流程跑通不难本地用Ollama跑个小模型几百行代码就能搭一个简易本地RAG知识库零基础照着教程也能复制出来。但一旦进入真实业务场景你会发现“跑通”和“好用”之间隔着一条鸿沟。我把这条鸿沟总结成四个绕不开的瓶颈第一是检索精度不够。向量检索本质上是在做“语义近似匹配”它擅长找“相似”但不擅长找“正确”。比如用户问“公司今年Q3的营收预期”知识库里恰好有一段话讲了“Q3指引区间”措辞完全不同但语义相关向量检索大概率能召回可如果用户问的是“老王上次说的那个方案后来定了没”这种高度依赖指代和上下文的query纯向量检索基本抓瞎。第二是上下文窗口浪费严重。在naive RAG里我们要把检索回来的top_k文档全部塞给LLM。top_k设大了塞进去一堆不相关片段模型注意力被稀释回答质量直线下降top_k设小了又怕漏掉关键证据。实际测试里很常见的一种情况是5个召回片段里只有1个是有用的但另外4个占据了上下文长度——如果再用上重排序还好没用重排序的话LLM经常会被那4个没用的片段带着跑偏。第三是知识割裂。大部分知识库里的文档是孤立的文本块块与块之间没有关系。用户问“A产品降价对B产品线的影响”这种跨文档、跨实体的推理问题普通切片检索根本答不上来。这也是为什么GraphRAG、ontology RAG本体RAG这半年突然热起来——因为它们解决的是关系建模问题而不是单纯的文本匹配问题。第四个瓶颈容易被忽略就是评估缺失。很多团队把RAG项目上线了但问一句“现在的hit rate是多少”“答案忠实度怎么样”答不上来。没有量化指标优化就只能靠感觉这也是很多RAG项目后期迭代不下去的根本原因。1.2 高级RAG的定位不是算法炫技是把链路拆开逐个优化高级RAG技术的本质不是某个惊艳的算法横空出世而是把整个RAG链路拆成“查询侧—检索侧—上下文组织侧—生成侧—评估侧”然后针对每个环节做专项优化。这也是第14章要讲透的思路。我在实际项目里的体感是query没改写好后面检索、重排、生成做得再好都白搭。反过来也一样检索链路已经做到位了结果生成阶段模型还是被无关片段带偏那就得上Self-RAG、CRAG这类带“自我反思”能力的方案。整条链路的优化是系统性的单点发力效果有限。所以这一章的核心内容我会按“优化顺序”来展开先优化检索前的查询再优化检索和重排然后优化上下文组织最后用评估体系把效果固化下来。这套思路适合任何阶段的RAG项目——哪怕你已经上线了也可以拿来做诊断和迭代。那个被问了很多次的问题——“RAG和LLM Wiki有什么区别”其实也可以在这个框架里回答Wiki是静态知识组织RAG是动态知识接入而高级RAG技术就是让这个“接入”变得更精准、更可控、更可解释。2. 检索链路优化让“找到”变成“找对”2.1 查询改写把用户的模糊表述变成检索器喜欢的问题做RAG项目时间久了你会发现一个规律线上很多query的质量是“差”的。用户不会按照RAG系统的喜好去提问题他们可能只说半句话、带口误、用口语化表达、甚至query里一半内容跟真正想找的东西无关。这时候直接把原始query丢给向量检索召回质量一定不好。查询改写就是解决这个问题的。核心思路很简单在检索之前先用一个小模型或LLM把用户query转成更适合检索的形式。实操中我比较常用两类改写策略一类是关键词扩展。用LLM把用户问题拆解出若干个关键实体和同义说法。比如用户问“笔记本开不了机怎么办”扩展成“笔记本电脑 无法开机 故障 原因 电源 电池 显示器”——多路关键词分别去检索合并结果召回率会明显提升。另一类是假设性问题生成。比如用户问“X产品的退换货政策”改写为“X产品 退换货 条件 流程 时间限制 售后政策”这种显式地列出检索实体的改写对向量模型和稀疏检索BM25都有帮助。还有一种改写思路是拆解复合query。用户有时候一口气问了两个问题比如“杭州和上海的分公司分别在什么位置哪个离高铁站近”这种query必须拆成两条子query分别检索再在生成阶段汇总。不拆的话向量检索会返回一个“语义均值”两边都靠一点两边都不精。我在部署改写模块时的经验是改写任务用7B级别的小模型就够不一定非要上大模型。因为改写不要求高深推理关键是稳定输出。要用提示词把输出格式锁死成JSON强制返回{rewritten_query: ...}方便下游直接解析。另外要设置改写失败时的兜底策略——解析不出来就用原query去检索不要因为改写模块崩了导致整个链路不可用。2.2 HyDE用“假设答案”去检索HyDEHypothetical Document Embeddings是我认为性价比极高的一种检索增强方案它不改变检索器本身只改查询端。思路是先让LLM根据用户问题生成一个“假设性答案”不要求准确只要求风格和结构像真实文档然后用这个假设答案的向量去做相似度检索。为什么这招有效因为向量检索的核心是“语义空間里的相近”。用户query通常只有一句话信息量少而知识库里的文档是长段落这两者的向量表示天然不在一个量级上。但如果你先让LLM把query扩写成一段“像文档一样”的文本生成的向量就更靠近文档空间检索命中率自然会提升。我之前在本地RAG项目里实测过同样的知识库和query直接用query向量检索的hit rate在62%左右换成HyDE后能到78%上下。代价是多了一次LLM调用延迟大概增加300~500ms对于内部知识库场景完全可以接受。不过HyDE有个需要注意的坑它假设LLM生成的“假设答案”在风格上和真实文档接近。如果知识库是高度专业化的比如法律条文、医疗指南通用LLM生成的假设答案风格差异会很大效果可能不升反降。这种情况建议在prompt里注入几条知识库的真实片段作为few-shot示例让模型模仿它们来写假设答案。另一个小经验HyDE的输入是“生成文本”实际控制的是生成结果的“长度”。我习惯把假设答案限制在80~150字之间太长会稀释语义重心太短又起不到扩写效果。2.3 混合检索稠密向量 稀疏关键词先明确一个概念纯向量检索有盲区。它擅长语义相似匹配但对精确关键词、专有名词、ID编号、缩写这类信息反而不敏感。比如用户搜“Bug修复记录编号BUG-2024-0917”向量模型大概率把这个编号当成语义的一部分模糊掉了但BM25这类稀疏检索能精确匹配这个token。混合检索Hybrid Search就是同时跑两路一路用稠密向量embedding模型做语义召回一路用BM25/Splade等稀疏检索做关键词精确匹配最后把两路结果合并去重。这是目前工业界RAG项目的主流做法也是LangChain里RetrieverType.HYBRID背后做的事情。合并策略上我推荐RRFReciprocal Rank Fusion公式很朴素score(d) Σ 1 / (k rank_i(d))其中rank_i(d)是文档d在第i路检索结果里的排名k是一个平滑常数通常取60。RRF的好处是不需要对两路分数做归一化向量距离和BM25分数不是一个量纲直接用排名计算融合分数简单稳定效果在绝大多数场景下都好过加权分数合并。实操中的一个细节两路检索的top K取值要分开设。我一般让向量路召回50条关键词路召回30条RRF融合后统一取前10条给重排序。如果你的知识库规模特别大百万级文档可以再加一层“按知识库类别预过滤”比如先限定产品线或文档类型再做混合检索能显著提升精度。2.4 重排序Rerank把Top50召回变Top5重排序是我反复跟团队强调“绝对不能省”的一步。原因很简单召回阶段要的是“找全”所以阈值必须放松宁可多召回不相干的也不要漏掉真正有用的但生成阶段LLM的上下文窗口有限不能把几十条结果全塞进去所以需要在“找全”之后再做一次“找对”的筛选。具体做法召回阶段返回Top50候选然后用一个更精细的排序模型cross-encoder对每条候选逐条计算与query的相关性分数统一排序最后取Top5作为最终上下文。Cross-encoder比双塔式的向量模型更准因为它把query和文档拼接在一起送入模型能充分建模交互信息。代价是计算量大但只对50条候选做重排的话完全可接受。模型选型上中文场景我推荐BAAI/bge-reranker系列英文场景Cohere Rerank或者开源的路如bge-reranker-v2-m3都可以。本地方案用Ollama跑不了轻量重排器但可以单独部署一个FastAPI服务挂载bge-rerankerCPU也能跑单条重排耗时大概在几十毫秒量级。这里有个容易踩的坑重排序的输入长度有限制超长文档会被截断而很多知识库片段恰恰比较长。建议在重排前先把候选片段按照语义边界切成不超过512 token的块重排后再把命中的块还原成完整上下文。另外重排序分数本身可以用来做“相关性阈值过滤”低于某个分数的候选直接丢弃宁可让LLM说“知识库中未找到相关信息”也不要硬编答案。3. 生成增强与自我反思从“单次对话”到“迭代循环”3.1 Self-RAG让模型自己判断要不要检索、检索结果可不可信普通RAG的工作流是线性的用户提问 - 检索 - 拼上下文 - 生成。它默认每一步都是必要的、结果都是可信的。但实际运行里很多query根本不需要检索比如用户问“你是什么模型”“帮我算一下35等于多少”反过来有些query第一次检索结果质量很差需要进一步细化检索才能找到答案。Self-RAG的思路是给生成过程加一个“反思”环节。具体分两步第一步用一个判别器判断当前query是否需要检索如果不需要就直接用LLM自身知识回答第二步检索结果返回后再判断检索到的片段是否与query相关、是否能支撑最终答案。这个技术落地起来有几条路径。最轻量的是prompt级实现在提示词里要求LLM先输出一个需检索/不需检索的判断再输出检索计划或者直接回答问题。我实测这种方案在7B模型上的判断准确率不够稳定但对于简单query够用。更稳的方案是微调一个小型判断模型专门做“检索必要性判断”和“相关性判断”不过成本较高一般业务项目没必要。我在生产项目里的折中做法是不做模型微调但用“规则 小模型”搭一个判断层。规则判断优先级最高——问时间、问计算、问身份类query直接走LLM回答拿不准的再交给一个分类模型判断模型也拿不准就默认走完整RAG链路。这套方案不需要额外微调稳定性和可控性都很好。3.2 CRAG检索质量低时怎么修正CRAGCorrective RAG解决的是另一个场景不是“要不要检索”而是“检索结果质量不行时怎么办”。我们都有过这种经历query已经写好检索也跑了但召回结果跟问题驴唇不对马嘴。传统RAG会把垃圾上下文直接塞给LLM模型被误导的可能性很大。CRAG的核心是增加一个“检索质量评估器”。拿到召回结果后先打分分数分三档确认Confirm、模糊Ambiguous、不正确Incorrect。确认的话直接进入生成模糊的话改用检索词重写再查一轮或者从互联网/另一个知识库补充检索不正确的直接丢弃检索结果改用LLM自身知识回答。在本地RAG项目里实现完整版CRAG可能有点重但可以做一个简化版用LLM对召回片段做一个二分类判断相关/不相关只把“相关”的片段拼进上下文并且要求LLM在回答末尾标注信息来源片段ID。简化版不需要额外训练模型成本就是一次额外的LLM调用但效果提升非常明显。这里补充一个经验很多RAG项目上下文质量差的根源不是检索器不好而是从来不检查检索结果。甚至有的上线项目已经在跑“无检索失败兜底”即检索结果为空或完全不相关时直接让模型回答“暂未找到相关信息”但模型还是会根据自身知识强行编一个答案。引入CRAG或者简化的相关判断后这类问题能大幅减少。3.3 长上下文下的切片策略与知识压缩高级RAG处理长文档时很多人第一反应是“直接把整个文档塞给LLM现在模型上下文窗口都很大”。这个思路在token成本低、文档量小的场景下可行但在知识库场景下不现实——你不可能每次都给模型喂几万字延迟和成本都受不了。所以切片的策略依然重要只是可以做得更聪明。先说切片粒度。我见过很多项目的经验值中文场景下chunk_size在300~500字比较合适英文场景按token算大概200~400。但按固定字数切的问题是容易切断句子结构和语义所以更推荐用递归字符切分RecursiveCharacterTextSplitter用分隔符优先级逐级切分优先在段落、句子边界处切。再进一步可以按文档结构感知切分先识别Markdown标题、PDF章节结构、表格区域然后在结构边界处切分并把标题信息作为元数据拼到块内容里。比如一个块的内容是“Q3收入下降原因分析”如果把所属章节标题“财务报告-Q3-收入分析”也拼进embedding内容检索命中率会高很多。知识压缩是我在长上下文场景下的一个“小秘密”检索回Top10候选后不让LLM直接读这10段原文而是先让一个轻量模型把每段压缩成“信息密度更高的摘要”再把摘要拼进上下文。实测在上下文窗口有限的情况下这种做法能保留更多关键信息减少被无关细节干扰的概率。代价是延迟增加一次轻量模型调用如果预算敏感的团队可以用规则摘要代替。4. 结构化知识与多源组织解决知识割裂4.1 GraphRAG与ontology RAG从“文本块”到“关系网”传统RAG把知识库当成一堆割裂的文本块这样做语义理解有余、关系推理不足。举个例子一个公司知识库里有很多文档A文档说“A产品线营收占比40%”B文档说“A产品线隶属于事业群X”C文档说“事业群X的战略重心是AI”——用户问“公司AI业务大概占多少营收”纯文本检索很难把三个文档的知识串联起来但人类能轻松推理出来。这就是“知识割裂”。GraphRAG的解法是把文档先抽成实体和关系实体A产品线、事业群X、AI业务关系隶属、战略重心、营收占比构建成图结构存入图数据库或者用图算法处理检索时通过query相关的实体节点做“社区检测”和“邻居扩展”把局部知识子图连同原文片段一起送给LLM。它在处理“跨文档聚合归纳类问题”时明显优于普通RAG微软开源的GraphRAG项目已经把这套流程封装成了文档索引pipline可以直接跑。ontology RAG更进一步在GraphRAG的“实体-关系”基础上引入本体层Ontology。本体定义了领域内的概念、属性和关系类型比如“产品”可以有“所属事业部”“营收”“发布时间”这些属性可以被“促销”这类事件修改状态。有了本体约束构建图的时候不会把“营收”和“负责人”这种不同类型的属性混在一起检索时也能按本体路径做定向查询。如果知识库涉及大量标准化实体比如电商商品库、法律条款库、医疗指南库ontology RAG的价值会更明显。不过要泼一盆冷水GraphRAG/ontology RAG的部署成本不低。索引阶段需要大量调用LLM做实体抽取一个百万字的知识库可能要跑上百万token抽完还要清洗、去重、建图查询阶段也不是一个向量检索能搞定的要走实体链接、路径检索、社区摘要多个环节。所以我给团队的建议是当普通RAG在“关系推理类问题”上反复失败且这类问题占比高时再考虑GraphRAG如果只是偶尔几个跨文档问题用多文档RAG加一点手工规则就能覆盖。4.2 多文档RAG架构不让知识库变成“信息孤岛”聊GraphRAG可能有人觉得距离自己太远那多文档RAG就是所有人都绕不开的课题。很多知识库项目是“把一堆文档灌进去就完事”结果用户问一个需要两个文档交叉印证的问题系统给不出好答案。多文档RAG的核心挑战有两点一是证据分散答案可能需要从文档A拿数据、文档B拿结论、文档C拿背景二是矛盾处理不同文档对同一事实的描述可能不一致。解决思路通常分两类。简单方案是预建跨文档摘要索引离线对每个文档生成结构化摘要包括文档观点、关键实体、统计口径、结论把摘要作为单独的检索入口。在线查询时先检索摘要层定位到最相关的2~3个文档再去文档内部做细分检索最后把细粒度证据汇总给LLM。这个方案实现成本低大部分“跨文档归纳”场景都能覆盖。进阶方案是文档路由 动态组合用路由模型判断query属于哪个文档域把候选文档集缩小到2~3个再在这些文档上执行“多轮检索”——第一轮粗定位第二轮精检索最后汇总生成。这种思路其实已经有点Agentic RAG的味道了后面会细讲。4.3 本地RAG知识库的常见落地形态在高级RAG的语境下本地知识库依然是很多人的首选场景——数据不出域、可控性强。配套Ollama 本地embedding 本地LLM的组合已经能跑出一整套零基础可复制的RAG知识库。这里聊聊落地形态因为高级RAG不是只能跑在云端的。第一种形态是单机All-in-One一台带GPU的机器部署Ollama跑LLM、部署embedding服务、挂一个重排序模型、再用FastAPI/Dify搭一个Web UI。知识库文档用Unstructured或OpenParse做解析配合递归切分和元数据提取。这个形态适合个人知识库和小团队内部问答延迟200ms~1s可接受。第二种形态是**“向量库关系库”混合存储**向量库存文本块关系库/图库存文档之间的关系如引用、版本、同主题。查询时向量检索先召回候选块再用关系库扩一圈“相关文档”把它们的关键摘要一并塞进上下文。这个形态能缓解知识割裂问题但架构上多了一个存储组件适合知识库文档之间关系复杂、需要频繁交叉引用的场景。这里回应一个高频问题RAG知识库能存图片吗能但不能走文本embedding。图片文本信息可以用OCR提取后混入文本索引要支持视觉问答就需要CLIP类多模态模型走图像向量。Ollama目前有支持视觉的模型例如llava类但整个链路会更复杂。如果是普通文本知识库建议优先把图片中的文字信息OCR出来进索引图片本身只做附件展示即可。5. Agentic RAG智能体化的RAG工作流5.1 为什么需要Agentic RAG聊到Agentic RAG先别被名词吓到。它本质上是对RAG工作流程的一次“去线性化”传统RAG是“问题-检索-生成”一条直线Agentic RAG则是让LLM扮演一个调度者自主决定“什么时候检索、检索几轮、每轮用什么工具、结果怎么验证”。为什么要这样设计因为真实问题远没有“给定query找出答案”这么简单。比如用户问“对比A方案和B方案哪个更适合我们公司”系统需要先检索A方案资料再检索B方案资料再检索公司背景信息最后综合对比。一步检索搞不定这就是Agentic RAG的用武之地把复杂任务拆成子任务每个子任务调用一次RAG工具最后汇总答案。RAG智能体RAG Agent在热搜词里的高热度不是偶然的。我观察到的核心驱动力是普通RAG在“需要多步推理的复杂问题”上确实吃力而把RAG封装成工具、让LLM自主调度正好补上了这块短板。5.2 规划-检索-验证的闭环设计一个Agentic RAG工作流通常包含四个核心模块规划器Planner收到用户query后决定要拆成几个子任务、每个子任务检索什么。它输出的是一个任务清单每个任务包含检索query和预期要获取的信息类型。工具执行器Executor执行规划器下发的检索任务。每个任务可以走混合检索、重排序、HyDE等不同配置这一层把高级RAG的所有优化技术都封装成工具接口。验证器Verifier检查每次检索的结果质量。如果发现检索结果不足以支撑回答就反馈给规划器让它重新规划下一步检索动作而不是硬着头皮生成。记忆器Memory记录已经检索过的信息避免重复检索同时把中间结果保留供最终汇总时使用。我在LangChain里实现过一个简化版用create_agent或者干脆手写一个ReAct风格的循环——LLM循环执行“思考-调用检索工具-观察结果-再思考”的流程直到收集到足够信息才回答。LangChain4j的Easy RAG也已经支持了类似的工具调用模式Java技术栈的团队可以直接参考。这里提个重要的架构决策Agent循环要不要开“无限步数”我强烈建议设置最大迭代次数比如6步和超时时间比如90秒。不是所有问题都值得Agent去反复探索超过阈值就直接用已有信息回答能显著控制成本和延迟。5.3 小成本实现方案不拼复杂框架Agentic RAG听起来高端但在小团队和本地环境里完全可以用低成本方案落地。核心思路是不要一上来就上重型Agent框架先用prompt驱动一个轻量调度循环。具体来说我推荐用Ollama LangChain的“Tool Calling”模式或LangChain4j的AiServiceContext实现第一版先定义好两个工具——search_knowledge_base(query)和search_web_for_supplementary(query)然后用一个支持工具调用的模型比如Qwen系列7B/14B、LLaMA 3.1 8B驱动循环。每轮循环里模型决定调哪个工具工具返回结果后模型决定继续还是回答。这套方案的优点是不需要额外写Agent框架LangChain/LangChain4j已经封装好了代码量几百行就够。我的一个具体实操建议是给工具加上明确的输入输出描述因为模型决定调哪个工具、传什么参数全靠工具描述。描述写得模糊模型就会乱传参、乱调用。比如RAG工具描述要写清楚“用于在内部产品知识库中检索技术文档、FAQ、操作指南输入应为自然语言关键词组合输出为相关文档片段列表”。实测中把工具描述写好后模型工具调用的准确率能从40%提升到80%。另外有条件的话推荐在Agent里面加一个人工反馈接口。用户对回答点“有帮助/没帮助”的反馈可以直接回灌到验证器里让Agent在后续轮次更加谨慎或更激进。这是Agentic RAG相比普通RAG一个很重要的差异化优势它可以在线调整自己的检索策略而不是每次都在同一套流程里死转。6. 评估与调优没有指标优化就是玄学6.1 RAGAS评估体系从生成结果倒推链路问题很多团队做完RAG项目就不知道下一步怎么优化了因为没有数据支撑。高级RAG的每一步改动查询改写、混合检索、重排序、Agent化都可能带来效果变化但没有评估指标你根本分不清是变好了还是变差了。所以评估体系必须是RAG项目的“标配组件”。我推荐用RAGAS这套开源框架来搭评估流水线。它把RAG的生成结果从四个维度打分忠实度Faithfulness答案是否严格基于检索到的上下文有没有脑补。答案相关性Answer Relevance生成答案是否回答了用户问题。上下文相关性Context Relevance检索到的上下文是否与问题相关。上下文召回率Context Recall参考答案里需要的信息是否都被检索出来了。这四个维度对诊断链路问题非常有用。我举几个真实的“病历”忠实度分数高、上下文相关性分数也高但最终答案不对——说明LLM推理能力弱换个模型就行。上下文相关性分数低——问题在检索侧优先优化query改写和重排序。上下文相关性分数高但忠实度低——问题在生成侧需要考虑模型对上下文的利用方式、或者上下文里相关的信息密度不够。上下文召回率低——问题的知识可能根本不在库里或者切分方式把有效信息切碎了。用这套诊断框架RAG项目的优化路径就清晰多了先看分数结构再决定动哪一段链路而不是拍脑袋改参数。6.2 hit rate / MRR / NDCG怎么用另一个面试里常聊、项目里却总被用错的指标是hit rate。我先说一个常见误区很多人把hit rate等同于“系统答对问题的比例”这是不对的。严格来说hit rate在RAG评估里通常指的是“检索结果里是否包含正确答案或相关文档”的比例——它是一个检索检全性质的指标不涉及生成质量。我习惯把评估拆成两层检索层评估和生成层评估。检索层看三个指标Hit RateK前K条检索结果里是否包含相关文档。适合快速评估检索器整体是否“找得到”。MRRMean Reciprocal Rank第一个正确答案排在第几位。如果MRR低但Hit Rate高说明检索结果里虽然有正确答案但排在很后面这时候重排序的价值就能体现出来。NDCGK按相关性等级排序的加权指标适合评估结构化相关性比如一个文档有“高度相关/部分相关/不相关”三级标签的场景。生成层则用RAGAS的忠实度、答案相关性和上下文相关性的组合来判断。这里给一个实操建议Blockbuster实验法。在评估集上固定生成层不变只改变检索层配置比如从纯向量改成混合检索观察Hit Rate和MRR的变化反过来固定检索层不变只改变生成提示词或模型观察忠实度变化。一次只动一个变量你才能知道是谁贡献了提升。6.3 离线评估与线上监控的落地离线评估的建设没有想象中复杂。我建议用一个月的时间逐步搭建第一步搜集真实query和答案对。从线上日志里抽取用户真实问题人工标注标准答案和来源文档ID。至少要攒200~500条覆盖知识库的主要业务场景。这个环节不可跳过RAG评估集的质量直接决定优化的方向是否正确。第二步建设回归测试流水线。每次改模型、改检索配置、改prompt都跑一遍同样的评估集输出各维度分数变化。我习惯用LangSmith或者自建一个简单的数据表记录每次跑的配置和分数方便对比。第三步上线后的线上监控。线上流量的真实反馈比离线指标更宝贵。至少要埋三个点检索链路时延、无结果率检索相关性全低的情况、用户对回答的反馈赞/踩。线上一旦出现“忠实度问题”反馈率飙升优先排查最近一次链路改动是否有回归。关于评估我想再聊一个很多人不知道的细节。RAG评估集里的query必须包含一定比例的“无答案问句”——就是知识库里根本没有对应答案的问题。因为“找不到时就该说找不到”这种能力和“找得到时答得准”同样重要。没有这类样本你的评估会虚高上线后会猝不及防地被真实用户打脸。7. 几组高频问题的实操解答7.1 如何选择适合自己项目的“高级RAG”优化组合接触了太多团队之后我发现大家面对高级RAG技术时最大的困惑不是“东西好不好”而是“我该用哪个”。这里我给一个相对实用的选型逻辑如果项目刚从naive RAG起步别急着上GraphRAG、Agentic RAG。先把混合检索和重排序这两件性价比最高的事情做了把纯向量检索换成“BM25 向量”的混合检索再加一个cross-encoder重排hit rate和MRR通常就能涨一大截生成质量随之改善。这套优化只需要增加几百行代码不依赖大模型不增加太多延迟。如果发现用户query质量很差口语化、复合问题多再把查询改写加上。改写的收益在前置优化做完后会被放大——因为检索器本身已经很强了喂给它的query越精准效果就越爆炸。如果“跨文档关系推理类问题”比例高再考虑多文档RAG的摘要索引结构当这类问题成为核心需求且团队有算法能力再上GraphRAG。如果是复杂任务场景比如“写一份包含竞品分析、数据总结和风险提示的报告”上Agentic RAG让Agent自己拆解和调度。总的原则是复杂度要匹配问题复杂度。不要为了炫技把简单问题搞复杂也不要因为知识盲区把一个复杂系统做成不伦不类的简化版。7.2 为什么hit rate明明很高用户还是说答得不好这个现象太常见了值得单独说一下。Hit Rate高只说明“检索到了相关文档”但用户问的是“回答质量”。两者脱节的原因通常有三个第一检索到了但没用上。Top5候选里只有第1名相关其他4条都在稀释上下文。重排序和相关性过滤可以缓解。第二相关但不充分。候选文档提到了相关概念但没有包含用户提问角度的关键数字或结论。这是“知识库覆盖度”问题硬优化检索链路解决不了只能靠补充知识源。第三答案格式不符合预期。用户问的是一个开关机步骤结果系统回复了一大段理论原因用户问的是数字对比系统给了一段叙述性文字。这类问题跟检索无关要在prompt侧定义好输出格式必要时用few-shot引导。所以我的建议是不要用单一指标评价一个RAG系统。检索层指标hit rate、MRR 生成层指标忠实度、答案相关性 用户反馈赞踩、二次点击三个维度一起看才能定位到真正的问题节点。7.3 知识库持续更新后检索效果为什么会莫名变差还有一个高频问题知识库存量更新新增文档、修改原有文档之后检索效果反而变差了。这个现象背后的原因不复杂但经常被忽略。最常见的坑是embedding模型升级导致向量空间变化。如果你中途换了embedding模型新旧模型生成的向量不在同一个向量空间里旧索引里的向量无法与新增文档匹配。这种情况下必须全量重建索引不要混用。如果没有换模型但效果变差大概率是新增文档与旧文档之间存在语义冲突或者新增文档里的高频表达覆盖了旧文档的向量空间导致相关旧文档排名下降。另外还有一种隐蔽情况切分策略或元数据提取规则改了但旧的缓存索引没有及时重建。RAG项目的索引版本管理必须跟代码版本管理一样严谨——每次索引逻辑变化都要生成一个新的索引版本并在系统里记录对应版本号方便回溯。7.4 本地知识库部署踩坑整理最后把本地RAG知识库比如Ollama方案的常见坑集中列一下都是我实际踩过的Embedding模型和LLM不是同一个模型体系不代表不能配合使用。embedding选bge-m3这类双语模型LLM选Qwen或LLaMA系列完全没问题。但注意embedding模型一旦选定就别随意换换了一定要全量重建索引。chunk_size不是越小越好。切得太碎每块的信息量太小检索精度高但上下文碎片感强LLM拼不出完整答案切得太大会引入噪音。建议根据文档类型做A/B测试找到适合自己场景的粒度。重排序模型用CPU也能跑但不要跟embedding共用线程池。并行度高时互相争抢资源时延会不可控。最好独立部署或者做资源隔离。提示如果你用LangChain4j的Easy RAG起步注意观察默认实现里的embedding维度是否与你的向量库配置一致。有些向量库如Qdrant、Milvus对collection的向量维度有严格校验维度不匹配会直接报错或者静默插入失败。这些坑都不复杂但每一个都足以让一个看起来正常的RAG系统性能劣化。踩过之后回头看都是“规划和监控没到位”的问题。这也是为什么我在前文反复强调评估和监控不是附加功能是RAG项目能不能持续迭代的生命线。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →