
前几天有朋友跟我吐槽说他们公司那个 RAG 知识库问答系统老答错问题。团队把大模型从 A 换到 B、再换到 Cembedding 模型也来回折腾甚至把 prompt 抄了各种模板结果准确率还是上不去。测试集里那些简单问题明明文档里都有答案系统就是答不对。我让他把知识库里的原始文件发我看看一眼就看出问题了PDF 解析出来全是乱码表格内容整段丢失长文本被硬切成一堆没有上下文的碎片。答案出错从文档进入系统的那一刻就已经注定了跟模型几乎没有关系。这种情况在 RAG 项目里太常见了。大家默认“答错了就是模型不行”但 RAG 系统是一个完整链路文档解析、文本切分、向量索引、召回排序、模型生成每一环都会影响最终答案。假如前面几环把信息弄丢了、切碎了、标错了后面再强的模型也没法凭空答对。这篇文章我会从实际排查的角度把“文档进入系统之前”最容易踩的坑拆开讲清楚包括具体表现、根因、排查方法和可直接照做的处理方案适合正在做 RAG 应用、知识库问答或者被“模型答不对”问题折磨得想骂人的朋友参考。1. 先把“锅”找对RAG 答错究竟是哪一环的错1.1 RAG 系统的三道关口进得来、找得着、答得对我一直喜欢用一个图书馆管理员做类比RAG 系统干的事本质上就是“管理员拿着你的问题去仓库找资料找到资料再组织语言回答你”。整个过程分三道关口。第一道关是“进得来”对应文档解析和索引。你扔一批 PDF、Word、扫描件进来系统要把它们变成干净、完整、有结构的文本再按合理粒度切成一块块建立索引。这道关出了岔子文本在源头上就缺胳膊少腿后面什么都谈不上。第二道关是“找得着”对应检索召回。用户问一个问题系统要在海量文本块里找出最相关的几块。这里涉及向量化、相似度计算、召回策略。第一道关不干净第二道关找回来的内容自然就是“垃圾进、垃圾出”。第三道关是“答得对”对应大模型生成。模型读到你召回来的文本块再结合指令组织答案。模型负责的是“读懂并复述”它不会知道文档里本来就没写什么。很多人把宝全押在这一关其实前两道关不牢第三道关再努力也是白费。1.2 为什么“换模型”常常是无效操作我见过太多团队在模型选型上反复横跳今天觉得 Qwen 不行换 Llama明天觉得 Claude 贵换回来甚至有人把“换模型”当成唯一调优手段。真的如果你连续换了三个模型正确率都纹丝不动那几乎可以断定问题不在模型而在它之前。原因很简单大模型的能力边界只作用于“给定材料后如何组织语言”。它不会自动修正检索结果里的错误也不会脑补出文档里根本不存在的细节。极端情况下它还会把检索来的半截话“圆”成一个通顺但错误的答案——这正是 RAG 答错里最迷惑人的一种。所以遇到“答错”我强烈建议先做一次最小化验证把系统实际召回的文本块直接打印出来看不看最终答案。如果召回内容本身就是错的、不完整的、不可读的那你换一百个模型也没用。这一步能帮你迅速分清楚问题到底出在生成端还是检索端免得白花冤枉钱、白烧 GPU。2. 文档进入系统之前三个高频问题根源2.1 文档解析从 PDF 到文本信息在这条路上丢了文档解析是 RAG 系统的第一铲土也是坑最多的环节。很多人拿到 PDF 直接调用现成库三行代码解析看起来没问题实际上问题全埋在“看起来没问题”里。最典型的是扫描版 PDF。它本质上是图片普通文本解析器提取出来是空文本必须过 OCR光学字符识别。OCR 没配或者没做校正中文错字、词被拆得零碎检索根本命中不了。其次是表格。很多解析器会把表格拆成一行行乱序文本数字和表格标题对不上业务数据问答直接崩塌。还有多栏排版学术论文常见两栏排版按行读取会把左右两栏内容交叉混在一起答案自然牛头不对马嘴。页眉页脚混入正文、目录被当成正文、代码块和缩进丢失这些都是高频问题。我建议在解析链路里增加一个“输出检查”步骤抽样 5 到 10 页文档人工核对解析后的文本。别嫌麻烦这个步骤能帮你筛掉绝大多数低级错误。很多团队连原始 PDF 是什么样都没仔细看过就跑去调模型属实是开了个头就去修车。2.2 切分Chunking一刀切下去语义被切碎了解析完文档下一步是切分。切分太粗或太细都会让答案“找不到北”。最常见的错误是固定长度硬切比如每 512 个字符一切切完也不管句子是不是断在中间、语义是不是完整。用户问“这个项目的预算上限是多少”文档里那句话恰好被切到两个 chunk 中间向量化后两个片段都不完整top-k 召回要么找不着要么匹配错。另一个常见问题是忽略段落和标题结构。说明书里一个小节明明是一个完整操作流程硬切法可能把操作步骤和结果分开标题“安全性说明”和正文被拆到不同块检索时只召回正文却不带标题系统连这段在说什么主题都不知道。更隐蔽的是重叠率没设好chunk 之间没有字符重叠前后句被截断丢失上下文设了重叠又设得过大索引体积膨胀检索噪声上升。切分的核心不是找个标准参数而是“跟着文档结构走”。有标题按标题切有段落按段落切尽量让每个 chunk 在语义上独立完整。后面第 4 节我会讲具体怎么切更合理。2.3 元数据与索引能检索到但检索到的内容“看不全”第三个高频根源是元数据和索引设计。很多团队切完 chunk 直接扔进向量库最多带一个 document_id其他信息一概不存。这就导致检索结果只有一段干巴巴的文本没有标题、页码、来源、时间、权限。上线后业务方问“这答案是从哪份文档来的”系统答不上来用户在对话里问“根据最新的 XX 文件”系统因为不知道文档版本把旧版内容也召回进来答案自然出错。索引设计不合理也会引发“看不到”问题。比如只嵌入正文不嵌入标题和上下文关键词一个关于“合同违约条款”的 chunk连“违约”二字都没出现在向量化文本里检索相关度自然低。再比如没有做知识库分类或元数据过滤一个十万份文档的混合库里找运维手册的答案时把财务制度也召回来了和关键词高度相关但与用户意图毫不相干。做知识库前先想清楚内容到底适合放哪种形态。文档类、非结构化的说明文件适合 RAG 向量库精确数值、记录类的结构化数据更适合走表格检索或数据库查询实体关系复杂、需要多跳推理的领域可能要引入知识图谱。不是所有内容塞进“RAG 知识库”就是一个合格知识库形态选错了答错是必然。3. 一张排查路径图从错误答案倒推到问题点3.1 第一步把检索结果暴露出来判断是“没找到”还是“找错了”排查 RAG 问题第一件事永远是“拆开系统看中间产物”。直接调一个 debug 接口把最终回答和检索到的 top-k 文本块一起返回到前端或者日志里。之后对每个错误样本做分类。如果是“没找到”意味着文档里明明有答案但召回结果的 top-k 里根本没有和答案相关的 chunk。问题大概率在文档处理或检索策略上。如果属于“找错了”说明召回的 chunk 有涉题内容但不精准或者相关 chunk 排名太靠后被不相关的片段挤掉了问题可能出在 embedding 质量、切分粒度或者 top-k 设置过小。我见过一个案例用户问“设备维护周期”系统召回的是“设备保修政策”因为两者文本向量距离很近但语义实际上不同。这明显是 embedding 区分度不够。可如果文档解析时根本没有把“维护周期”所在的表格内容提取出来那系统连“找错”的机会都没有直接就是“没找到”。所以归因顺序必须先看有没有、再看好不好。3.2 第二步从召回质量反推文档处理而不是继续调模型拿到检索引擎的召回结果后反推几个关键问题这个 chunk 本身读起来通顺吗内容完整吗它有上下文吗如果你发现 chunk 里全是乱码、表格被拆成碎片、句子断在奇怪的地方那恭喜你根因找到了。常见的一个误判是某次召回结果不好有人立刻去换 embedding 模型或者调相似度算法。但你把召回结果打印出来发现召回出来的内容全是“半个句子”或者“无意义表格碎片”——换 embedding 有用吗没用。你把世界上最好的向量模型拿来它也无法让乱码变通顺、让碎片变完整。这就是我反复强调“文档进入系统之前”的原因chunk 本身就是脏的检索和生成端永远在啃一块馊了的馒头。另外我习惯用一个简单指标做验证定义“golden chunk”即对测试集里每个问题人工标注哪几个 chunk 应该被召回。然后看系统最终有没有把这些 chunk 召回到 top-k。如果 golden chunk 在 top-k 之外满分概率再高检索也没法生效这时候直接调切分和 embedding 策略方向才正确。4. 文档进入系统前的实操要领4.1 文档解析实操不同文档类型的处理方式先给一份“先判断再解析”的 checklist拿到文档看它是原生 PDF、扫描版 PDF、Word 还是 PowerPoint看里面有没有表格、图片、多栏文本再看是中文还是多语言混合。这三步直接决定解析方案。原生文本型 PDF 可以直接用解析库输出带结构的文本扫描版必须先过 OCR中文语境下建议用支持中文的 OCR 引擎识别出来后最好再做一轮常用错别字校正。表格是重灾区建议用带表格识别能力的解析器把表格转换成 Markdown 表格或者结构化记录不要放任它变成纯文本流失信息。多栏排版要用“栏检测”能力按栏切分而不是按行读。页眉页脚要去掉目录要跳过代码块要保留原始缩进。Word 文档比 PDF 友好但也要注意如果里面有嵌入图片、文本框、公式解析时这些内容容易被跳过。PowerPoint 则要按幻灯片拆成条目别把所有页连成一篇没有边界的长文本。如果你处理的是网页或者 Markdown 文档尽量保留标题标签、列表、链接这些结构信息它们是切分时最值钱的线索。本地处理这些解析、预览、筛查可以找开源的“文本拆解工具”组合来做不一定非得上在线服务。4.2 切分策略实操按结构切、加重叠、分层级解析干净之后切分依然有讲究。我最推荐“结构优先 父子分块”的方式。结构优先遇到有清晰标题的文档按标题层级把内容切到二级或三级标题下每个标题下的几段内容作为一个大块再对这个大块做进一步的子块拆分。这样每个子块不仅有自己的向量还能附带父块的标题和上下文摘要检索时既精准又保留足够的语义背景。父子分块的做法是大块父块通常是 800 到 2000 个字子块 200 到 500 个字子块之间保留一定重叠率10% 到 20% 比较稳。检索时先命中子块再把父块的标题、摘要、上下文一起送进大模型。这个模式能明显缓解“答案被切断”的问题代价是多写一点索引逻辑但效果对比非常值。另一种做法是“语义切分”按段落主题边界来判断在哪里断句而不是机械按字符数切。很多文本拆解工具都能做句子向量相似度比较发现前后句语义距离大了就切一下。这种方式适合论文、合同、说明书等逻辑清晰的文档能在不过度依赖标题的情况下做到相对合理的边界。还补充一个场景超长文档比如几百页的产品手册全部塞进一个索引会导致太多内容参与召回。我建议先做一个“文档摘要层”每个大章节生成摘要并建索引用户提问先用摘要层粗召回再用原文层细查效果比硬塞一个巨型 chunk 好得多。这个技巧很多人忽略但在处理长文档时属于标准解法。4.3 元数据与知识库结构设计让每个 chunk 有“身份”切分完成后不要急着灌库。给每个 chunk 打上元数据这是一项投入低、回报极高的工作。必要字段至少包括文档标题、一级/二级标题、页码或章节号、来源路径、文档版本、日期、所属业务领域、权限级别。有了这些检索时可以做过滤比如“只看 2024 年后的文档”“只看操作手册”回答时也可以引用来源方便用户核对。在知识库结构上我强烈建议按业务域或用途来区分集合collection比如“产品手册库”“售后工单库”“制度文件库”不要全部混在一个库。混合库里不同语言、不同文风、不同粒度的内容相互污染检索精度往往惨不忍睹。分开后用统一的检索入口再按业务路由到不同集合或者在不同集合间做加权检索这样“找不着”的概率会明显下降。索引时还有其他细节是否做粗排和精排是否有 filter 字段的倒排索引是否需要给标题额外加权这些都会显著影响最终效果。不要默认向量库的默认配置就是最优配置花点时间做一次检索效果评估比盲目换模型有用得多。5. 常见 RAG 答错问题速查表与避坑经验5.1 排查速查表现象、根因与解决方向我把实际踩过或见人踩过的高频问题整理成一张速查表建议直接贴在工位边。问题现象很可能根因优先排查点解决方向回答内容明显缺细节解析时表格、注释被丢弃打印解析文本对比原文档换带表格识别能力的解析器回答张冠李戴牛头不对马嘴多栏 PDF 按行交叉读取抽样查看解析文本排版启用栏检测按栏切分答案断在句子中间固定长度硬切未按句子/段落查看 chunk 源码是否有半截句结构切分 父子分块答非所问召回全是噪声chunk 粒度太小或太大打印 top-k 文本块调整切分宽度与重叠率最新文档内容答不出来未设置版本/日期元数据检查文档元数据字段增加日期过滤保留版本标记特定领域问题召回差知识库未分层内容互相干扰检查 query 命中的集合按业务域拆分集合同一问题不同时间答案不稳未做精排或相似度算法不透明对比多轮召回排名引入粗排精排管道文档明明有答案但始终答不对解析错、切分碎、索引弱叠加做 golden chunk 召回验证从头检查文档处理链路这张表不覆盖所有可能性但能覆盖我见过的 80% 的“模型背锅”场景。当团队里有人再次提出“要不要换模型”先对着表做一轮排查会有意外收获。5.2 几个值得长期坚持的避坑习惯第一建立“回归测试集”。选 100 道业务真实问题人工标注标准答案和期望召回的 chunk。每改动一次文档处理或检索策略就跑一遍这套回归对比之前你的指标是涨是跌。没有评估集的调优等于拍脑袋。我见过很多团队调了半天模型最后连“原来效果什么样”都说不清。第二把“文档进入系统前”的质检纳入工作流。解析、清洗、切分、元数据录入每一步结束后都设一个输出检查节点。用脚本自动检查乱码比率、句子不完整比率、chunk 重复率每隔几天抽样人眼复核一次。这个习惯能让你在问题发生第一天就察觉而不是等到产品上线后被用户骂了才知道。第三不要把“本地文本拆解工具”和“线上发布”对立起来。本地先做一轮快速实验看看解析出来效果如何、切分边界是否合理确认稳定后再灌入知识库。相比直接在线上反复调试线下验证的成本低得多而且能避免污染正式索引。第四记得保存“处理前”的文档。拿一个出问题的明确示例把原始 PDF、解析后的文本、切分后的 chunk 三样放在同一个 trace 里。出问题时对照这三样东西几分钟就能定位是解析、切分、还是索引的锅不用每次都把整套链路重跑一遍。最后再分享一个小技巧遇到“模型答非所问”时先别急着看大模型输出直接把检索到的 top-5 文本块拼在一起模仿大模型的“阅读理解”复述一遍。如果你自己读这段文本都觉得没法回答用户问题那大模型答错就一点也不冤。这个五分钟的“人肉 check”能帮你准确判断到底是模型不够聪明还是压根没喂对料。我自己的习惯是每接到一个新的 RAG 需求先花 40% 的精力在文档处理和切分策略上剩下的时间才用来调检索和模型。过去一年多帮团队排障的经验反复印证一件事只要“文档进入系统之前”这片土壤是干净健康的后面的模型哪怕是中规中矩的开源模型也能给出立得住脚的答案。下次再想换模型的时候先回头看看你的 PDF 解析和切分代码也许答案就在那份你从来没打开检查过的文档里。