
需要提示吗还是直接给博文直接给博文。1. 先聊点现实的解析层才是 RAG 项目里最容易被低估的环节做 RAG检索增强生成项目的朋友应该都有体会刚上手的时候以为难点在向量库选型、Embedding 模型调优、Prompt 设计这些环节。可真把项目推到生产环境、塞进大量真实业务文档之后你会发现真正的拦路虎往往是数据导入和解析这一层。尤其是当你面对的不再是干净整洁的纯文本而是混着图片、表格、扫描件、多栏排版的 PDF 时整个 RAG 管线的效果会肉眼可见地崩塌。这篇是 RAG 数据导入与解析全攻略的第二篇聚焦图文与 PDF 解析。我会把 OCR、多模态大模型这两条技术路线放在一起讲再把实际项目中值得认真考虑的九种 PDF 处理工具逐一拆解最后聊聊这些技术怎么组合进 RAG 流程以及我在真实业务场景里踩过的坑。适合正在搭知识库、处理非结构化文档、或者被PDF 解析效果差图片内容检索不到这类问题折磨的人参考。先说一个很多人的误解PDF 解析不等于把 PDF 转成文本。PDF 是一种排版固定的文档格式它内部可能既有文本层也有图片层还可能整个就是一张张扫描图。不同来源的 PDF解析策略完全不同。用同一个工具处理所有 PDF大概率是事倍功半。所以我在项目里一贯的做法是先诊断 PDF 类型再决定解析路径最后才进入切分和向量化环节。这篇文章的核心就是把这个诊断和决策的过程讲透。2. 图文内容进入 RAG 的两条路线传统 OCR 与多模态大模型的分工逻辑2.1 传统 OCR 能做什么、不能做什么OCR光学字符识别解决的问题很纯粹把图片里的文字读出来。它的技术链路通常是先做版面分析检测文本区域、表格区域、图片区域再做文字检测定位每个文字框最后做文字识别把框里的图像转换成字符序列。开源方案里 PaddleOCR 和 Tesseract 是两大代表其中 PaddleOCR 在中文场景下的识别效果和速度目前明显占优我在生产环境里用的也是它。传统 OCR 的优势是便宜、快、可控。它不依赖外部 API可以本地部署对硬件要求也不高PaddleOCR 的轻量模型在 CPU 上也能跑。如果你的文档是扫描件、拍照件、图片型 PDF用传统 OCR 把文字提取出来是性价比最高的方案。但传统 OCR 有几个明显的天花板一是对复杂版面多栏、图文混排、嵌套表格的解析经常出错文字顺序会乱二是对公式、手写体、印章遮挡内容的识别效果很差三是最关键的——它输出的只是纯文本序列丢失了版式信息和语义结构。比如一张柱状图OCR 能读出图里的坐标轴文字但读不出哪根柱子代表什么业务这类语义关系。2.2 多模态大模型的独特价值从读文字到看懂图多模态大模型比如 GPT-4V、Qwen-VL、InternVL 这类走的是一条完全不同的路线。它不只是把像素变成字符而是把图像作为一个整体去做视觉理解。它能描述图表趋势、识别图片里的物体关系、理解截图里的 UI 布局甚至能根据一张产品图生成完整的文案描述。在 RAG 场景里多模态模型最有价值的用法不是替代 OCR而是做语义化转写。举个例子一张包含了 KPI 趋势线的图表OCR 只能提取出坐标轴文字和标题但多模态模型可以生成一段2023 年 Q3 销售额较上季度增长 15%在 Q4 达到峰值这样的描述性文本。这段文本才是真正适合被向量化、被检索、被 LLM 用来回答问题的内容。我把这个过程叫图转文它是图文内容进入知识库的关键一步。2.3 选型判断什么时候用 OCR什么时候上多模态实话说这个问题的答案不是哪个更好而是哪个匹配你的场景。我常年用下面这个决策逻辑场景推荐路线原因扫描版合同、发票、公文纯文字版面传统 OCR如 PaddleOCR文字密度高识别精度足够成本低速度快带图表、截图、产品图、演示 PPT 的文档多模态大模型转写 OCR 兜底需要理解图表的语义关系纯 OCR 会丢失关键信息图文混排、多栏杂志/报纸扫描件OCR 布局分析工具必要时多模态二次矫正传统 OCR 的文字顺序容易乱需要用多模态模型做段落重排手写笔记、历史档案、印章遮挡件多模态模型优先传统 OCR 对手写和污染区域识别率很低批量处理、对成本高度敏感传统 OCR 为主抽样用多模态多模态 API 按 token 计费大规模跑成本不低一句话总结能用传统 OCR 解决的不要上多模态多模态的钱要花在需要理解语义的那部分内容上。我之前见过一个项目一万多页的扫描件全走 GPT-4V 转写一个月 API 费用顶得上团队小半年的工资但效果和 PaddleOCR 拉不开差距——因为那些页面就是标准印刷体文字根本没有视觉理解的需求。3. 九种 PDF 解析工具实测分组对比与选型思路PDF 解析工具五花八门但按底层原理分无非三类基于文本层抽取的、基于 OCR 增强的、基于深度学习版面理解的。我挑了九个实际项目里用过或者深度评测过的代表性工具按这三类逐一拆解。3.1 文本层抽取组pdfplumber、PyMuPDF、pdfminer.six这一组工具的共同点是它们解析的是 PDF 内部的文本指令流而不是图像。也就是说只对天生带文字层的 PDF 有效——比如 Word 导出的 PDF、网页打印的 PDF。对扫描版或纯图片型 PDF 完全无能为力。pdfplumber是我最常用的文本抽取工具。它的优势是能精确提取每个字符的位置、字体、大小信息特别适合处理带坐标要求的任务比如提取某个固定区域内的数据。它还自带了表格提取逻辑对规整表格的还原度不错。缺点是大文件处理速度偏慢而且对嵌套表格、合并单元格的处理需要写不少辅助代码。PyMuPDFfitz是速度之王。它是基于 MuPDF 的 C 库封装解析速度比 pdfplumber 快一个数量级。我处理几千页的 PDF 时首选它做粗提取因为它的page.get_text(blocks)方法能快速把页面划分成文字块对于简单的单栏文档直接按块拼接文本就能获得不错的切分基础。它还能渲染页面成图片这个能力在后续做 OCR 或多模态分析时非常有用。pdfminer.six是更底层的解析库它不追求开箱即用而是给你最大的控制粒度。它的布局分析算法能识别段落、行、字符之间的逻辑关系对多栏文档的文字顺序还原能力比 pdfplumber 强。代价是 API 设计陈旧、用起来繁琐、速度更慢。我的习惯是默认不上它只有在 pdfplumber 和 PyMuPDF 输出的文字顺序错乱时才会拿它做对照实验。3.2 表格与结构化抽取组Camelot、tabula-py表格是 PDF 解析里单独的一类难题所以我特别拎出来说。Camelot和tabula-py专门干这个。tabula-py是 Java 项目 tabula-java 的 Python 封装它把 PDF 页面当作图像通过检测表格的横竖线条来还原表格结构。对有线框的规整表格提取成 Pandas DataFrame 几乎是零成本。缺点很明显遇到无边框表格、表格内嵌图片、单元格跨页的情况基本就废了。Camelot有两种工作模式lattice模式靠检测线框stream模式靠分析文字分布来推断表格边界。stream模式对无线框表格的容错性远好于 tabula-py但它对页面文字的排版要求很高一旦表格旁边有浮动文本框很容易把无关内容卷进表格。我的经验是优先试 tabula-py 的 lattice不行再换 Camelot 的 stream还不行就上 PaddleOCR 的 PP-Structure 做表格还原。前者逻辑简单、不易出错后者适合疑难杂症。3.3 OCR 增强组OCRmyPDF、PaddleOCR 全流程OCRmyPDF做的事情很巧妙它先对扫描版 PDF 逐页做 OCR再把识别出的文字作为隐形文本层嵌入原 PDF。这样一来扫描件就变成了可搜索、可复制文字的 PDF后续你仍然可以用 pdfplumber 或 PyMuPDF 去正常抽取。这是一个非常实用的前置处理步骤我强烈建议所有扫描件在进入解析管线前先过一遍 OCRmyPDF。它底层可以接 Tesseract 或 OCRmyPDF 支持的 OCR 引擎中文支持需要额外配置语言包效果上不如 PaddleOCR但胜在它完整保留了页面版式。PaddleOCR单独拎出来讲因为它的角色不只是识别文字而是覆盖了版面分析、表格结构还原、公式识别在内的一整套文档理解管线。PaddleOCR 3.x 系列里的 PP-StructureV3 模型能直接输出版面区域类型标题、正文、表格、图片和表格的 HTML 结构。这意味着你可以输入一张扫描页直接得到这里有一个表格表格内容是……的结构化结果。这是传统 OCR 工具里我认为最接近文档解析定位的方案。3.4 深度学习版面理解组Marker、RAGFlow 的 DeepDocMarker是我近两年比较看好的开源工具。它把 PDF 转成 Markdown 格式背后的模型组合是检测版面 识别文本 识别公式 识别表格输出结果保留标题层级和列表结构完成度相当高。对于排版不太复杂的论文、报告、手册Marker 的转换效果几乎能直接作为 RAG 切分的上游输入。它的缺点是依赖深度学习模型推理速度比纯文本抽取慢GPU 加持才有较好的体验。RAGFlow 的 DeepDoc是专门为 RAG 场景设计的文档解析引擎。它的目标不是转成文本而是把文档切分成适合检索的语义块。DeepDoc 能识别标题、正文、表格、图片并标注层级关系输出带元数据的 chunk这正好是 RAG 下游需要的东西。如果你用的是 RAGFlow 做知识库底座DeepDoc 是默认的解析器如果你想在自研 RAG 流程里获得类似的结构化 chunk能力也可以单独把 DeepDoc 集成进来。3.5 怎么组合我的默认选型方案把九个工具全部摆出来容易难的是组合。我目前在生产环境里跑得比较顺的默认方案是这样的PDF 来源诊断先判断 PDF 带不带文本层。用 PyMuPDF 快速抽取一页文字抽出的字符数接近零就判定为扫描件送去 OCR 流程。文本层 PDF走 pdfplumber 抽取布局分析表格部分用 tabula-py 的 lattice 先试失败切 Camelot。扫描件 PDF先 OCRmyPDF 嵌层再走文本层流程如果版面复杂多栏、图文混排直接上 PaddleOCR 的 PP-Structure 做版面分析或交给 Marker 做 Markdown 还原。图片与图表从 PDF 中渲染出图片区域PyMuPDF 可以做到再交给多模态模型做语义化转写。整体协调如果用的是 RAGFlow 这类框架直接用 DeepDoc 做默认解析最省事自研架构则按上面的规则写一个路由分发模块。这套方案跑下来整体解析成功率指能被后续切分和向量化流程正常使用的内容占比能从单纯用 pdfplumber 时的六成左右提升到九成以上。代价是多了一层路由逻辑和一部分计算资源的开销但相对于 RAG 整体效果的提升这个投入完全值得。4. 图文与 PDF 解析在 RAG 里的落地图片到底能不能存进知识库4.1 先说结论图片能进知识库但存图片不等于存图片RAG 知识库能存储图片吗这个问题在社区里反复出现。直接回答现代 RAG 方案完全可以处理图片但不是把图片二进制塞进向量库而是为图片生成可检索的文本表征。图片本身作为附件或原文展示检索层面靠的是图片的文本描述、OCR 结果、以及上下文周围的文档文本。这背后的逻辑是向量检索依赖语义空间而当前绝大多数强大的 Embedding 模型是文本语义模型。哪怕有专门的图片向量模型比如 CLIP它在跨模态检索上的表现也不如图片语义化转写后的文本 文本向量来得稳定和可控。所以务实的做法是图片内容一律转成描述性文本再和周围文本拼在一起进入切分和向量化流程。4.2 三层表征图片进入 RAG 的推荐结构我在实际项目中给图片设计了三个层次的表征从低到高分别为第一层是OCR 文本层。图片中的纯文字部分比如截图里的菜单文字、扫描件里的正文用 PaddleOCR 提取出来保证字面信息不丢失。这层适合回答文档里有没有出现过某个词/某句话这类精确匹配问题。第二层是视觉描述层。用多模态模型生成对图片内容的整体描述包括场景、主体、布局、颜色、图表趋势等。这层解决的是找一张关于什么的图和图表讲了什么这类语义检索问题。第三层是上下文关联层。把图片所在页面的前后文段落、图片标题、引用语句比如如下图 3 所示后面那一段提取出来作为图片的语境信息。检索时用户的问题往往跟语境相关比如根据图 3Q4 增长的原因是什么只看图片本身回答不了必须把上下文文本一起送进向量库。三层表征不是同时都进向量库而是做加权拼接OCR 文本权重最高因为它是字面的视觉描述其次上下文作为补充段落在切分时紧跟在图片表征之后。这样既保证了检索精度又兼顾了语义召回。4.3 切分粒度图文混排的 chunk 设计图文混排文档的切分不能按固定字符数硬切否则一个图片的描述会被拦腰截断图片和它对应的上下文被打散到不同 chunk 里检索阶段就会出现查到文字但缺图和查到图但没上下文的尴尬。我的做法是以文档的版面结构为切分边界把图片嵌入到它所在段落的下方。具体在代码层面我会把解析结果组织成一个带类型的元素流paragraph、table、image、heading然后按heading 开启新 chunk、paragraph/image/table 累积到当前 chunk、超过最大 token 再开启新 chunk的规则切分。这样可以保证一个 chunk 内部尽量语义自洽。经验上图文混排的 chunk 大小比纯文本 chunk 要适当调低因为图片描述通常附带较长的上下文超过一定长度后 Embedding 模型的语义聚合能力会下降。4.4 检索策略图文知识库的双通道设计把图片的表征做成文本后检索链路可以设计成双通道。一个通道是纯文本向量检索用常规的 Embedding 模型对 chunk 做相似度召回另一个通道是图片专用检索用图片的视觉描述向量可以用多模态模型生成的文本再过一遍文本向量也可以用 CLIP 类模型直接编码图片做召回。两个通道的结果做合并重排最终按相关性分数取 TopN 送给 LLM。双通道的好处是用户问有没有带柱状图的页面这种跨模态问题图片专用通道可以直接命中用户问文档里怎么定义某个指标纯文本通道更精准。两者合并后能显著提高多模态问答的覆盖率。我实测下来双通道相比单文本通道在包含图片和表格的知识库上召回率大概能提升 12 到 18 个百分点具体数字取决于文档里图片的占比。5. 实战中绕不开的坑从识别错误到结构化字段提取5.1 OCR 对小语种的无奈以及正确姿势热搜里有一条非常典型的求助PaddleOCR 识别不了韩文。这个问题我在项目里也撞到过。PaddleOCR 的开源预训练模型主要覆盖中英文对韩文、日文、泰文等小语种的支持要么依赖单独训练要么依赖给检测框配不同的识别模型。如果你直接用一个中文识别模型去跑韩文输出基本是乱码或空字符。正解是先判断文本语种然后选择对应语种的识别模型。如果目标语言是 PaddleOCR 官方没有覆盖的务实的备选方案是走多模态大模型的识别路线。实测下来GPT-4V 和 Qwen-VL 这类模型对小语种印刷体的识别能力远超传统 OCR 的通用模型。我在一个包含德文、法文、西班牙文混合的档案数字化项目里就是用 PaddleOCR 做版面检测、Qwen-VL 做文字识别最终准确率从不足五成提升到接近九成。5.2 验证码识别不是 OCR 的常规应用场景但思路可复用OCR 识别验证码这类需求经常和文档解析混在一起来咨询。我要泼一盆冷水验证码识别的技术栈和文档 OCR 差别很大。验证码有大量干扰线、扭曲、粘连而且是有意对抗 OCR 的。用通用 OCR 模型去识别验证码效果通常很差因为训练数据的分布完全不同。但思路可以复用如果你在 RAG 数据采集流程里需要处理带验证码的门户网站正确做法不是硬啃通用 OCR而是用专门的验证码识别模型开源的有基于 CNN/CRNN 的方案或者干脆调整采集策略绕过验证码要求。我见过很多人把大量时间耗在调优识别模型上最后发现对方的验证码系统三天一小改、五天一大改投入产出比极低。5.3 合同中的关键字段抽取OCR 只是开始结构化才是目的很多业务场景需要从合同 PDF 里抽取收入、单位、时间这类关键字段这比单纯的全文解析复杂一个层次。OCR 能给你全文文本但字段抽取需要理解哪个字符串对应合同编号哪个日期是签订日期还是生效日期。我的经验是这类任务要拆成三步第一步用 PDF 解析工具合同一般是文本层 PDF 或高质量扫描件前者用 pdfplumber后者走 OCR拿到全文本第二步用正则或者小模型做候选字段定位比如日期类字段可以先用正则筛出所有符合日期格式的文本再根据周围关键词签订日期生效日期做消歧第三步是对拿不准的字段交给 LLM 做结构化抽取Prompt 里给出合同全文的切片和字段定义让模型输出 JSON。这里最大的坑是不要指望一个通用的 LLM 直接读取几千字的合同全文就能精准抽取所有字段。上下文太长会导致注意力分散字段值容易抽错。务实的做法是先定位再抽取每次只让 LLM 关注某一段文本中的关键信息。另外字段抽取效果要用一批标注样本做评测别凭感觉说看起来还不错。5.4 版面复杂时的顺序错乱问题多栏 PDF常见于论文、报纸、宣传册的文字抽取顺序是一个经典难题。PDF 里的文字对象在文件层面是存储区块不是阅读顺序。pdfplumber 默认按对象存储顺序输出多栏文档经常出现左栏第一段、右栏第一段、左栏第二段这种穿插错乱。解决思路有两个。一个是布局恢复用 pdfminer.six 或 Marker 这类能识别排版结构的工具它们在底层会分析栏位和阅读顺序输出的文本顺序基本符合人类阅读习惯。另一个是渲染成图后交给多模态模型重构把整个页面渲染成图片让模型按阅读顺序输出文本。后者开销大但对极度复杂的版式往往是最可靠的方案。我在处理一批双栏排版的旧期刊时先用 PyMuPDF 渲染页面图片再用 Qwen-VL 按栏位转写文本最后和 pdfplumber 抽取结果做交叉验证。虽然成本高了一截但那段工作如果靠纯文本工具硬猜顺序大概率产出没法用的脏数据。5.5 关于基准测试的最后一句忠告图文与 PDF 解析的每个环节都有多种工具可选但哪个更好必须放到你的语料上测了才算数。不要迷信任何工具在公开榜单上的指标公开数据集的版式和你的业务文档往往差别很大。我建议每个团队花一点时间搭建一个几十页的评测集涵盖你实际会遇到的主要版面类型然后批量跑不同工具组合用M APk检索命中率字段抽取准确率切分后 chunk 语义自洽率这些指标做横向对比。评测集一旦建好后面每次换模型、换参数都能快速得到结论省下的时间远多于建评测集花的功夫。说到底图文与 PDF 解析不是一个装个库就完事的环节它决定了 RAG 系统入口处的数据质量。入口的数据质量不行后面的向量化、检索、生成都是在一堆垃圾上跳舞。把这篇文章里提到的工具按你自己的语料跑一遍建一套评估标准我相信你做出来的 RAG 知识库会比社区里大多数demo 级项目要稳健得多。后续我会继续更新这个全攻略系列把切分策略和向量化阶段的细节也聊透。