
1. RAG 问答准确度到底卡在哪儿做过 RAG 应用的人大概都有过这种体验Demo 阶段效果惊艳一旦上了真实业务数据回答就开始胡言乱语。用户问“A 产品的保修期是多久”系统检索回来三段文档一段讲 A 产品的安装步骤一段讲 B 产品的保修政策还有一段是客服话术模板。大模型拿着这三段互相矛盾的材料硬生生编出一个“A 产品保修三年”的答案——而真实文档里写的是两年。这不是模型不够聪明而是整个检索增强生成链路的某个环节出了问题。RAG 的核心逻辑说起来简单用户提问 → 检索相关文档 → 把文档和问题一起塞给大模型 → 生成回答。但每一个箭头背后都藏着大量可以优化的细节。检索回来的内容对不对、全不全、有没有噪声直接决定了大模型是在“开卷考试”还是在“闭卷瞎编”。我前后经手过七八个 RAG 项目从企业内部知识库到电商客服问答从法律文书检索到技术文档助手踩过的坑基本覆盖了这条链路的每一个环节。这篇文章不聊空泛的概念只讲一件事当你的 RAG 应用回答不准的时候到底该从哪里下手每一步怎么调调完怎么验证。适合已经跑通过基础 RAG 流程、但效果不达预期的开发者也适合正在选型阶段、想提前避开常见陷阱的技术负责人。2. 先搞清楚准确度问题的根源在哪一层2.1 检索层、生成层、数据层的问题特征对比RAG 回答不准症状看起来都是“答非所问”但病因可能完全不同。我的经验是先把问题定位到具体层级再对症下药否则很容易在错误的方向上浪费大量时间。问题层级典型症状根因方向排查优先级数据层检索结果里根本没有正确答案文档切分不合理、元数据缺失、知识覆盖不全最高检索层检索到了相关文档但排序靠后或混入大量噪声嵌入模型不适配、检索策略单一、缺少重排序高生成层检索内容正确但模型回答跑偏提示词设计差、上下文组织混乱、模型能力不足中交互层多轮对话中意图理解错误查询改写缺失、历史上下文未正确传递中这个表格不是理论分类而是我实际排查时的顺序。很多人一上来就想着换更大的模型、调更复杂的提示词但十次里有六次问题出在数据层——文档切分把一段完整的说明拦腰截断或者 PDF 里的表格转成文本后格式全乱检索再厉害也捞不出正确内容。2.2 用“检索命中率”和“回答忠实度”两个指标定位问题定位问题不能靠感觉得有可量化的指标。我通常用两个核心指标来切分检索命中率Hit Rate对于一组标注了标准答案的问题检索结果中是否包含能回答该问题的文档片段。这个指标衡量的是“找没找到”。回答忠实度Faithfulness模型生成的回答是否完全基于检索到的内容没有编造信息。这个指标衡量的是“有没有胡说”。实操中我会准备 50 到 100 条测试问题每条标注好标准答案所在的文档片段。然后分别计算检索命中率低于 80%优先优化数据层和检索层检索命中率正常但忠实度低优先优化生成层两个都低先解决数据层问题再逐层往上调注意测试问题一定要覆盖真实用户的各种问法包括口语化提问、错别字、多意图混合提问。我见过太多团队用自己写的“标准问法”测试命中率 95%一上线真实用户提问直接掉到 40%。3. 数据层优化切分策略决定检索上限3.1 文档切分的三种策略与适用场景文档切分是 RAG 链路里最容易被忽视、但对最终效果影响最大的环节。切分粒度太粗检索回来的内容包含大量无关信息噪声干扰大模型判断切分太细一个完整的知识点被拆散检索只能捞到碎片。我常用的三种切分策略固定长度切分按 token 数或字符数硬切比如每 500 个 token 一段重叠 50 个 token。优点是实现简单、速度快适合格式统一的文档如日志、聊天记录。缺点是经常在句子中间切断语义不完整。语义切分基于段落、标题、列表项等自然边界切分。Markdown 文档按标题层级切PDF 按段落切HTML 按 DOM 结构切。这是我最推荐的方式因为大多数知识库文档本身就有清晰的逻辑结构顺着结构切分能最大程度保留语义完整性。递归切分先按大边界如章节切如果某段仍然超过长度限制再按小边界如段落、句子递归切分。LangChain 的 RecursiveCharacterTextSplitter 就是这种思路适合结构不规整的混合文档。实际项目中我通常组合使用先按文档的自然结构做语义切分对超长段落再用递归切分兜底。切分后的每个片段控制在 200 到 500 个 token 之间这个范围是实测下来检索效果和上下文完整性的平衡点。3.2 元数据补全让检索结果自带上下文光有文本内容还不够。一个文档片段被单独检索出来时往往丢失了它在原文中的位置信息。比如一段话写的是“该参数设置为 30”但“该参数”指的是什么如果没有元数据大模型根本不知道。我的做法是给每个片段附加以下元数据来源文档标题帮助模型理解片段所属的主题章节路径如“第三章 3.2 节 配置参数”提供层级上下文文档类型产品手册、FAQ、技术规范、会议纪要等更新时间用于处理多版本文档的冲突关联实体片段中提到的产品名、功能名等关键实体这些元数据在检索时可以作为过滤条件在生成时可以作为上下文补充。比如用户问“最新版的配置参数”检索时就可以按更新时间过滤只取最新文档的片段。3.3 处理表格、图片和结构化数据的特殊技巧真实业务文档里不可能只有纯文本。表格、流程图、架构图这些内容如果处理不好检索效果会大打折扣。表格的处理我的做法是把表格转成“表头 每行数据”的自然语言描述。比如一个产品参数表不要直接存 Markdown 表格而是转成“产品 A 的重量是 2.5kg尺寸是 30x20x10cm”这样的句子。这样嵌入模型才能理解语义用户问“产品 A 多重”时才能检索到。图片的处理如果图片中有文字先用 OCR 提取如果是流程图或架构图用多模态模型生成文字描述把描述文本存入向量库。图片本身可以存 URL在生成回答时如果需要展示原图再引用。结构化数据的处理对于数据库中的结构化数据不要直接转成文本塞进向量库。更好的做法是让 RAG 系统能够生成查询语句直接查数据库。这就是 Text-to-SQL 的思路适合数据频繁更新的场景。4. 检索层优化从“能查到”到“查得准”4.1 嵌入模型选型不是越大越好嵌入模型负责把文本转成向量它的质量直接决定了语义检索的准确性。选型时需要考虑几个维度模型类型代表模型优势劣势适用场景通用中文嵌入text-embedding-3-large、bge-large-zh语义理解强开箱即用对垂直领域术语不敏感通用知识库垂直领域微调基于 bge 微调的法律/医疗模型领域术语理解准确需要标注数据训练成本高专业领域多语言嵌入multilingual-e5、bge-m3支持跨语言检索单语言性能略低于专用模型多语言文档轻量级嵌入bge-small、text-embedding-3-small速度快成本低语义区分度稍弱大规模初筛我的经验是先用通用大模型跑 baseline如果垂直领域术语的检索效果差再考虑微调。微调不需要海量数据通常 500 到 1000 对“问题-相关文档”的标注数据就能带来明显提升。4.2 混合检索向量检索 关键词检索的互补纯向量检索有个致命弱点对精确匹配不敏感。用户搜“错误码 E5021”向量检索可能返回一堆讲“错误处理”的文档但就是找不到包含“E5021”的那一篇。这时候关键词检索BM25、TF-IDF就能补上。混合检索的做法是同时跑向量检索和关键词检索然后融合两路结果。融合策略有两种加权求和给两路结果分别打分按权重相加。权重需要根据业务数据调我通常从 0.7向量比 0.3关键词开始试。RRFReciprocal Rank Fusion不依赖分数只看排名。每个文档的最终得分是 1/(k排名)k 通常取 60。这种方式更鲁棒不需要调权重是我目前最常用的融合策略。4.3 重排序用交叉编码器精排 Top 结果检索回来的 Top 20 结果里真正相关的可能只有 3 到 5 条。重排序模型Reranker的作用就是把这 20 条重新打分排序把最相关的推到最前面。重排序模型通常是交叉编码器Cross-Encoder它把问题和文档一起输入模型直接输出相关性分数。相比嵌入模型的“双塔”结构交叉编码器的精度更高但速度慢所以只适合对少量候选做精排。我的标准流程是向量检索 关键词检索召回 Top 50 → RRF 融合取 Top 20 → 重排序模型精排取 Top 5 → 送入大模型生成。这个流程在多个项目中把检索命中率从 70% 左右提升到了 90% 以上。实操心得重排序模型的选择上bge-reranker-v2-m3 是我目前用得最多的中文效果好推理速度也能接受。如果对延迟极其敏感可以考虑用更小的重排序模型或者只对 Top 10 做重排。5. 生成层优化让大模型“有据可依”5.1 提示词工程约束模型不要自由发挥检索层做得再好如果提示词写得随意大模型照样会编。生成层的核心原则是把模型当成一个严格的阅读理解器而不是一个创意写手。我的提示词模板通常包含以下要素你是一个严谨的问答助手。请严格根据以下参考资料回答用户问题。 规则 1. 如果参考资料中没有相关信息直接回答“根据现有资料无法回答该问题”不要编造。 2. 回答时引用具体的参考资料编号如 [1]、[2]。 3. 如果不同参考资料存在矛盾指出矛盾并说明各自来源。 4. 回答要简洁不要重复参考资料中的无关内容。 参考资料 [1] {doc_1_content} [2] {doc_2_content} ... 用户问题{question}这个模板的关键在于明确告诉模型“不知道就说不知道”并且要求引用来源。实测下来加上引用要求后模型的编造率能降低一半以上。5.2 上下文组织把最相关的放在最前面大模型对上下文的注意力不是均匀分布的。研究表明模型对开头和结尾的内容注意力更集中中间部分容易被忽略。这就是所谓的“Lost in the Middle”现象。所以上下文组织策略很关键把重排序后最相关的片段放在最前面次相关的放在最后面中间放相对不那么关键的。如果片段之间有逻辑顺序比如操作步骤则按逻辑顺序排列不要机械地按相关性排序。另外每个片段前面加上来源标注比如“来自《产品手册》第三章”帮助模型理解片段的语境。5.3 模型选择大模型和小模型的配合策略不是所有环节都需要用最大的模型。我的做法是分层使用查询改写用小模型如 7B 级别做查询改写和意图识别速度快成本低重排序用专用的重排序模型不需要生成能力最终生成用能力最强的大模型确保回答质量和忠实度如果成本敏感可以先用大模型跑一批测试数据然后用这些数据微调一个小模型来替代。我做过一个项目用 70B 模型生成的 5000 条问答数据微调 7B 模型最终效果能达到原模型的 90%但推理成本降到了十分之一。6. 查询理解与改写别让用户的问题“原样”去检索6.1 多轮对话中的查询改写用户很少一次就把问题说清楚。多轮对话中后续问题往往依赖前面的上下文。比如用户A 产品的保修期是多久 系统A 产品保修期为两年。 用户那 B 产品呢如果直接把“那 B 产品呢”拿去检索肯定什么都查不到。需要先把查询改写成“B 产品的保修期是多久”再走检索流程。查询改写的实现方式有两种一种是用规则模板适合问法固定的场景另一种是用大模型改写适合开放场景。我通常用大模型做改写提示词大概是“根据对话历史将用户的最新问题改写成一个独立的、完整的检索查询”。6.2 意图识别与路由分发不是所有问题都需要走 RAG 检索。有些问题是闲聊有些是要求执行操作有些是问系统功能怎么用。如果全部走检索不仅浪费资源还可能因为检索到无关内容而降低回答质量。我的做法是在检索前加一个意图识别环节把用户问题分类知识问答类走 RAG 检索流程操作指令类路由到对应的功能模块闲聊类直接用大模型回答不检索敏感类走安全审核流程意图识别可以用小模型做分类也可以用大模型做 zero-shot 分类。实测下来用大模型做 few-shot 分类的准确率能到 95% 以上成本也不高。6.3 查询扩展用同义词和相关词提升召回用户的提问用词和文档中的用词往往不一致。用户问“怎么退钱”文档里写的是“退款流程”。如果只按字面检索很可能漏掉。查询扩展的思路是在检索前把用户查询扩展成多个相关查询。比如“怎么退钱”可以扩展成“退款流程”、“退货退款”、“申请退款”。这些扩展查询分别去检索然后合并结果。扩展的方式有几种用同义词词典、用大模型生成、用历史查询日志挖掘。我常用的是大模型生成提示词是“请生成与以下问题语义相同的 3 个不同问法”。7. 效果评估与持续迭代7.1 构建测试集覆盖真实场景的评估基准没有评估就没有优化。我每个 RAG 项目都会建一个测试集包含以下类型的问答对事实型问题答案在文档中有明确表述如“A 产品的重量是多少”推理型问题需要综合多个片段才能回答如“A 产品和 B 产品哪个更适合户外使用”否定型问题文档中没有答案如“A 产品支持太阳能充电吗”文档中未提及多轮问题需要结合对话历史理解的问题口语化问题用非正式表达提问如“这玩意儿咋用啊”每类问题至少 10 条总共 50 条以上。测试集要定期更新把线上发现的 bad case 加进去。7.2 自动化评估与人工评估的结合自动化评估用 RAGAS 这类框架可以计算忠实度、答案相关性、上下文精度等指标。但自动化评估有个问题它本身也是用模型来评判可能存在偏差。我的做法是自动化评估做日常监控人工评估做关键节点验收。人工评估时让评估者只看回答和参考资料判断回答是否准确、是否有编造、是否完整。每个版本至少人工评估 50 条确保没有系统性退化。7.3 线上反馈闭环从用户行为中挖掘优化点线上用户的真实行为是最好的评估数据。我会重点监控几个信号追问率用户得到回答后继续追问的比例高追问率说明首次回答不完整点踩率用户主动标记“回答不准”的比例复制率用户复制回答内容的比例高复制率说明回答质量好会话终止率用户得到回答后直接结束会话的比例高终止率说明问题被解决这些信号结合具体的用户问题能帮我快速定位问题类型。比如追问率高的问题往往是检索不完整点踩率高的问题往往是模型编造。8. 常见问题与排查技巧实录8.1 检索结果相关但回答跑偏这是最常见的问题之一。检索回来的文档确实和问题相关但模型就是不用这些内容回答或者回答得似是而非。排查思路先看提示词是否明确要求“仅根据参考资料回答”。如果提示词没问题再看上下文组织是否合理——最相关的片段是否放在了开头。如果都没问题可能是模型能力不足考虑换更大的模型或微调。我遇到过一个案例检索回来的文档是一段操作步骤用户问的是“怎么配置”模型却回答了一段原理说明。后来发现是文档片段里同时包含了原理和步骤模型被原理部分吸引了。解决办法是在切分时把原理和步骤分开检索时只取步骤部分。8.2 相似问题检索结果差异大用户问“A 怎么用”和“如何使用 A”语义几乎一样但检索结果可能完全不同。这通常是嵌入模型的问题——它对某些表达方式不够鲁棒。解决办法一是用查询扩展把两种问法都覆盖二是用混合检索关键词检索能兜住字面匹配三是考虑微调嵌入模型用相似问法的数据对做训练。8.3 长文档检索效果差长文档如 100 页的产品手册切分后片段很多检索时容易召回大量相似但不相关的片段。比如手册里每个章节都有“概述”部分检索“概述”时会召回一堆。解决办法在元数据中标注片段类型概述、步骤、参数、注意事项等检索时按类型过滤。另外长文档适合用层级检索——先检索到相关章节再在章节内做细粒度检索。8.4 多跳问题无法回答有些问题需要多步推理才能回答。比如“A 产品的保修期是否覆盖 B 配件”需要先查 A 产品的保修政策再查 B 配件是否在保修范围内最后综合判断。单次检索很难覆盖这种多跳需求。解决办法是用 Agentic RAG 的思路让模型先分解问题生成多个子查询分别检索后再综合。或者用 GraphRAG把文档中的实体和关系抽出来构建知识图谱通过图遍历来回答多跳问题。8.5 常见问题速查表问题现象可能原因排查动作解决方向检索不到相关内容切分粒度不当、嵌入模型不适配检查切分后片段是否完整、测试嵌入模型相似度调整切分策略、换嵌入模型检索结果噪声多缺少重排序、检索策略单一查看 Top 20 结果的相关性分布加重排序、混合检索回答编造信息提示词约束不足、模型能力不够检查提示词是否要求引用来源优化提示词、换更大模型多轮对话理解错误查询改写缺失检查历史上下文是否传入加查询改写环节精确匹配查不到纯向量检索对关键词不敏感测试包含错误码、型号的查询加关键词检索、混合检索长文档效果差片段过多、相似片段干扰检查元数据是否丰富加元数据过滤、层级检索9. 进阶方向从基础 RAG 到 Agentic RAG基础 RAG 的流程是线性的检索 → 生成。但真实场景中很多问题需要更复杂的处理逻辑。Agentic RAG 的思路是让模型自己决定什么时候检索、检索什么、检索几次。比如用户问“对比 A 产品和 B 产品的保修政策”Agentic RAG 会先检索 A 产品的保修政策再检索 B 产品的然后对比生成回答。如果第一次检索结果不完整它还会自动补充检索。实现 Agentic RAG 的关键是给模型提供工具调用能力检索工具、计算工具、数据库查询工具等。模型根据问题自主选择工具和调用顺序。这种方式的灵活度更高但延迟和成本也会增加适合对准确度要求极高的场景。另一个方向是 GraphRAG把文档中的实体和关系抽出来构建知识图谱检索时同时走向量检索和图检索。对于需要多跳推理的问题GraphRAG 的效果明显优于基础 RAG。不过构建知识图谱的成本较高适合知识结构相对稳定的领域。我在实际项目中的体会是不要一上来就追求最复杂的方案。先把数据层和检索层的基础打好用混合检索 重排序把命中率做到 90% 以上再考虑生成层的优化。很多团队跳过基础优化直接上 Agentic RAG结果因为底层数据质量差效果反而更不稳定。RAG 的准确度提升是个系统工程每一层都有优化空间但优先级不能乱。