上个月一个做企业知识库的朋友跟我吐槽。
他们给一家律所做了RAG系统,把几千份合同、法律意见书全灌进去了。演示的时候很顺利,随便问一个问题,Agent都能引经据典。
结果上线之后,律师反馈:“我问‘这份合同里关于知识产权归属的条款在哪’,它给我的内容是空的。我手动翻了合同,明明白白写着。”
排查了一周才发现问题:合同里有一页是扫描件,那页内容在RAG的知识库里完全是空白。因为他们的文档解析流程没有区分“文字版PDF”和“扫描版PDF”,直接跳过OCR,把扫描件当空白页处理了。
他说:“我们花了一个月做RAG,输在了一页扫描件上。”
这问题挺普遍的。很多RAG项目在真实环境里遇到的第一个坑,往往不是模型不够强、不是检索不够准,而是文档解析这步就没做好。入口没打通,后面再折腾也是白搭。
Gartner 2026年的企业AI调研也提到,文档解析环节的缺陷是RAG项目从POC走向生产的主要障碍之一。
先给个比喻。RAG的文档解析,就像医院挂号处的病历录入。 护士把病历本上的信息录进系统,如果录错了——姓名写错了、过敏史漏了——后面医生水平再高,开的药也是错的。解析这一步的质量,很大程度决定了整个RAG系统的体验上限。
第一步:需求定义——先搞清楚你的文档长什么样
做文档解析之前,先弄清楚你要对付的是什么类型的文档。
我们内部有个“文档体检”流程:拿到一批文档后,先抽一部分样本,逐份记录格式、结构、质量。PDF还是Word?文字版还是扫描版?有没有表格?有没有多列排版?字体清晰度如何?
做完体检,你才知道该用什么策略。
我见过一个团队,花了三周调PDF解析工具,最后发现90%的文档是Word格式。提前做一次文档分类,三小时就能搞清楚。
这个环节最容易踩的坑是“默认所有文档都一样”。 PDF不是只有一种,文字版和扫描版的处理方式完全不同。怎么避:项目启动时做一次文档分类——文字版PDF、扫描版PDF、Word文档、其他格式——针对每种类型选不同的解析方案。
第二步:方案设计——6个技巧
技巧一:PDF的文字是“画”上去的
PDF里的一段文字,底层可能不是连续的文本流,而是一个个字符“画”在页面上的。你复制PDF里的一段话,粘贴出来变成乱码——就是这个原因。
解析的时候,需要处理字体映射和编码识别。工具选型上,PyPDF2和pdfplumber在处理复杂字体时的表现差异很大——我们测过一份带特殊字体的PDF,前者提取出来是乱码,后者能正常识别。如果你的场景涉及Word文档,用python-docx处理时要注意中文字体编码。
技巧二:表格——别让“一行数据”变成“孤立的词”
表格是PDF解析的重灾区。一个三行五列的表格,解析工具可能把它拆成15个独立的文本块,行列关系完全丢失。检索时问“第二季度营收”,表格里有答案,但拆散了就找不到。
用专门的表格解析工具处理。pdfplumber有.extract_table()方法,规整表格效果不错。复杂表格可以用Camelot或TableTransformer。Word的表格用python-docx能直接读,相对简单。如果表格特别复杂——合并单元格、跨页、嵌套——可以考虑截图+OCR+多模态模型识别,虽然成本高但比硬解析靠谱。
技巧三:多列排版——学术论文的常见坑
学术论文、年报经常用双栏排版。解析工具默认按页面从左到右读,会把左栏第一行、右栏第一行、左栏第二行混在一起,顺序完全乱掉。
用支持版面分析的解析工具。Marker和Unstructured.io能识别多列排版,按阅读顺序重组文本。如果工具不支持,就按坐标位置手动分栏——先按x坐标把页面切成左右两半,分别提取再合并。我们做学术论文RAG时遇到过,用户问“方法论”,Agent把结论部分误读成方法论,就是因为双栏排版解析错位。
技巧四:图片PDF必须走OCR
PDF分两种——文字版(可以直接选中文字)和扫描版(本质是图片)。扫描版PDF必须通过OCR把图片转成文字。
但OCR不是万能的。字体不清晰、盖章遮挡、手写批注都会影响识别准确率。文字版PDF用pdfplumber直接提取就行;扫描版PDF先走OCR再提取;纯图片(JPG/PNG)直接走OCR。关键是:在流程设计上就要区分对待,而不是把所有PDF都扔进同一个解析管道。
技巧五:元数据是文档的“身份证”
解析不只是提取正文。文档的元数据——文件名、创建日期、作者、页数、章节标题——跟正文一样重要。
解析的时候把元数据也提取出来单独存储。检索时元数据可以作为过滤条件——用户说“找去年的合同”,系统直接按年份过滤,不用在全部文档里搜“2025”。标题层级尤其重要,从PDF的目录或大纲里提取标题层级,可以按章节做分块,语义连贯性会好很多。
技巧六:按语义边界切分,别按固定字数切
分块策略直接决定检索质量。按固定字数切最简单,但容易切断完整的语义单元。
按段落边界切——段落结束、表格结束、章节结束。段落太长的再按句子切。Word文档可以直接用“段落”作为最小单位。PDF要先还原阅读顺序,再按语义边界切。不同文档类型用不同的分块策略——短文档(<5页)可以整体作为一个单元不分块;长文档按章节边界切;表格单独处理,不混入正文。
第三步:开发验证——用“盲测”验证解析质量
这一步很多人跳过。
从文档库里随机抽一批不同类型的文档,把解析后的文本和原始文档逐页对比。重点看三个地方:乱码、顺序错乱、表格行列关系。
我们第一次做盲测的时候,发现一份年报的表格解析结果里,数字全乱了——第二列的数据跑到了第三列。排查发现是表格里有一个合并单元格,解析工具没处理好。
这个环节最容易踩的坑是“抽样只看两三页”。 怎么避:抽样覆盖不同类型的文档——文字版、扫描版、带表格的、带多列的——每类至少选2份做全文对比,而不是只看前几页。
第四步:上线迭代——文档健康档案得建起来
解析不是跑一次就完事。新文档进来、新格式出现、解析工具升级,都得重新验证。
建立一个“文档健康档案”,记录每次解析的文档类型、解析工具版本、解析成功率、主要错误类型。新文档格式出现时,先跑一次小样本验证再全量处理。工具升级后,跑一遍标准测试集确认质量没下降再切过去。
这个环节最容易踩的坑是“工具升级了也不影响我”。 新版处理逻辑变了,以前能正常解析的文档可能变差。怎么避:工具升级前先跑测试集对比再决定。
检查清单
□ 做过“文档体检”了——抽样检查过文档的格式、结构、质量?
□ 文字版PDF和扫描版PDF有分别的处理策略?
□ 表格内容用了专门的解析工具?
□ 多列排版做了版面分析?
□ 元数据(文件名、创建日期、标题层级)单独提取存储了?
□ 分块策略是按“语义边界”切的,不是按“固定字数”?
□ 用“盲测”验证过至少一批不同类型文档的解析质量?
□ 有“文档健康档案”记录每次解析的文档类型和解析成功率?
三个常见坑
坑一:用处理标准文档的流程去处理边缘文档。
90%的文档跑得很顺,剩下10%——特殊字体、复杂表格、混合排版——全卡住了。怎么避:把边缘文档单独挑出来,用专门流程处理。复杂表格用TableTransformer,多列排版用Unstructured.io。10%的文档可能花掉50%的解析时间,但缺失这10%,RAG就永远有盲区。
坑二:不保留解析的原始记录。
解析完直接把文本存进向量库,原始解析记录扔了。出了问题想排查,找不到“原始文档在解析这一步变成了什么”。怎么避:保留解析后的原始文本和解析日志,出了问题能回溯是解析环节的问题还是检索环节的问题。
坑三:所有文档用同一个分块策略。
短文档切成一块,长文档切成几十块,检索质量时好时坏。怎么避:根据文档类型调整分块策略。短文档(<5页)整体作为一个单元;长文档按段落+章节边界切;表格单独处理不混入正文。
最后一个问题:你现在的RAG系统,如果来了一份“带表格的年报PDF”和一份“带特殊字体的扫描合同”,你的解析流程能保证它们的内容完整进入知识库吗?
今天就去跑一遍文档体检。
行动指南:
第一步,从文档库里抽5份不同类型的文档,跑一遍现在的解析流程。输出结果和原始文档逐页对比。
第二步,挑出解析质量最差的那一份,专门调试它的解析流程——换工具、调参数、加预处理。跑通了就把经验固化成这一类型文档的标准处理流程。
第三步,建一个“文档健康档案”,记录每次解析的文档类型、解析成功率、主要错误类型。每周更新一次,清楚你的RAG系统在“吃”什么质量的文档。
夜雨聆风