03. 文档解析 / OCR 链路通常怎么设计?
文档解析与 OCR 链路的典型设计方法。
简单回答
文档解析链路的目标是从 PDF、扫描件、图片等非结构化文档中提取出结构化的文本、表格和图片内容。典型流程是:文档分类(判断类型)→ 版面分析(Layout Analysis,识别页面中的文本块、表格、图片、标题等区域)→ 文本识别(OCR)→ 表格识别与结构化 → 阅读顺序排列 → 输出结构化结果(Markdown/HTML/JSON)。实际项目中这条链路的复杂度远超想象,是 RAG 系统中最容易出问题也最容易被低估的环节。
详细解释
为什么文档解析很重要
做 RAG 的人都知道"Garbage In, Garbage Out"——如果文档解析阶段就把内容搞乱了(表格丢列、OCR 识别错字、段落顺序搞反、标题层级搞错),后面的 Chunk 切分、Embedding、检索全都受影响。实际项目中,RAG 效果不好的根因有很大比例出在文档解析环节,而不是模型或检索策略。
文档类型决定了处理策略
文档大致分几类,每类的处理难度和方法完全不同。
原生数字 PDF——这类 PDF 是由 Word、LaTeX 等工具直接生成的,文字信息直接存在 PDF 的文本层里,不需要 OCR。用 PyMuPDF、pdfplumber 这类工具可以直接提取文字。难点在于表格的识别和还原(PDF 中表格只是"一堆线条和文字",没有语义上的"行列"概念)、多栏排版的阅读顺序判断、以及页眉页脚的过滤。
扫描件 PDF / 图片——这类文档的内容是图片形式的,必须用 OCR 识别文字。难度比原生 PDF 高得多——需要处理倾斜校正、噪声去除、手写识别、低分辨率等问题。
混合 PDF——部分页面是原生文本、部分页面是扫描件。需要自动判断每一页的类型,分别处理。这在实际业务中非常常见(比如一份合同,正文是电子版的,附件是扫描件)。
版面分析(Layout Analysis)
版面分析是文档解析中技术含量最高的环节——给一个文档页面图片,识别出其中的文本块、标题、表格、图片、公式、页眉页脚等区域的位置和类型。
传统方法用规则(比如按线条分割表格),但对复杂排版效果很差。现代方法用目标检测模型来做——把版面分析当作一个 object detection 任务,模型在页面图片上检测出各个区域的 bounding box 和类别标签。
常用模型有 LayoutLMv3(微软)、YOLO 系列的微调版本、DocTR 等。Marker 和 MinerU 等开源工具封装了完整的版面分析流程。
OCR
OCR 的技术已经相当成熟。PaddleOCR(百度开源)在中英文场景下表现很好,支持检测+识别的端到端流程。Tesseract 是老牌开源方案。各云平台(AWS Textract、Google Cloud Vision、Azure Document Intelligence)的 OCR API 在准确率和易用性上通常更好,但有成本和隐私考量。
对于高质量印刷文档,OCR 准确率可以到 99%+。但手写体、模糊图片、低分辨率、复杂排版(多栏、文字和图表交错)下准确率会明显下降。
表格识别与结构化
表格是文档解析的最大难点之一。表格在视觉上可能很清晰,但机器要理解它的行列结构、合并单元格、表头关系并不容易。
对于原生 PDF 中的表格,pdfplumber 和 camelot 通过分析 PDF 中的线条来提取表格结构,效果不错但对"无线条表格"(靠空白对齐的表格)无能为力。
对于扫描件中的表格,需要先用表格检测模型定位表格区域,再用表格结构识别模型分析行列结构,最后用 OCR 识别每个单元格的内容。Table Transformer(微软)是目前效果比较好的表格识别模型。
提取出的表格通常转成 Markdown 或 HTML 格式保存——这比纯文本更好地保留了结构信息,LLM 也能理解。
阅读顺序
对于多栏排版的文档,按从左到右、从上到下的简单顺序读取会导致内容错乱——左栏第一段后面应该接左栏第二段,而不是右栏第一段。阅读顺序的判断需要结合版面分析的结果,理解页面的逻辑布局。
端到端的文档解析方案
近年来出现了一些用 VLM 直接做文档解析的方案——不再分步做版面分析+OCR+表格识别,而是直接让 VLM "看"文档页面的截图,输出结构化的 Markdown。
Nougat(Meta)专门针对学术论文做端到端的 PDF 转 Markdown。GOT(General OCR Theory)是更通用的 OCR 方案。还有前面提到的 ColPali 直接对文档截图做 Embedding 跳过解析。
这些端到端方案的优势是流程简单、对复杂排版的适应性更好。劣势是对硬件要求高(需要 GPU 推理)、在精确结构化(特别是表格)上的准确率还不如专门的管线。
实际项目中的建议
不要指望一套方案适配所有文档。按文档类型做差异化处理——结构化好的原生 PDF 用 pdfplumber/PyMuPDF 直接提取,复杂排版的用 Marker/MinerU,扫描件用 PaddleOCR + 表格识别模型。
一定要人工抽检解析结果。文档解析的错误往往很隐蔽——看起来文字都提取出来了,但表格多了一列、段落顺序反了、公式变成乱码了。这些错误会在下游造成严重但很难定位的问题。
面试时可以这样答
文档解析链路通常分几步:先判断文档类型(原生 PDF 还是扫描件),然后做版面分析识别页面中的文本块、表格、图片区域,接着对文本区域做 OCR(扫描件)或直接提取(原生 PDF),表格区域做专门的结构识别和结构化,最后按阅读顺序排列输出 Markdown 或 HTML。
实际项目中这条链路的复杂度远超预期。表格是最大的难点——无线条表格、合并单元格、跨页表格都很难处理。多栏排版的阅读顺序判断也容易出错。工具选择上,原生 PDF 用 pdfplumber/PyMuPDF,扫描件用 PaddleOCR,复杂排版考虑 Marker 或 MinerU。
近年来也有用 VLM 做端到端文档解析的方案——直接让模型看页面截图输出 Markdown,流程简单但精度上还比不过专门的解析管线,特别是表格。
做 RAG 的时候,文档解析的质量直接决定了后面所有环节的上限。我见过不少效果不好的 RAG 系统,回头一查根因就在解析环节——表格切碎了、段落顺序乱了。
常见追问
- 你实际项目中用的什么文档解析方案?遇到过什么坑?
- 无线条表格怎么识别?
- 文档解析的质量你是怎么检验的?