跳转到内容
PDF转文本——3000份合同45分钟跑完
·灿海星图指南

PDF转文本——3000份合同45分钟跑完

返回博客
金柘
#MinerU#RAG#文档解析#AI工具#教程

我运营API中转站这几个月,被问最多的问题不是模型选哪个,不是价格多少——是"金哥,我们公司有3000份PDF合同,能不能让AI帮我分析条款?"

每次我都不太好意思回答。不是不能,是太麻烦了。3000份PDF→手动转文本→清洗格式→分段→存向量库→RAG查询。每一步都在掉数据。一份带表格的合同,转文本后表格变成谁也看不懂的乱码。

MinerU解决的就是这个——把任何文档变成LLM能直接吃的结构化数据。上海AI实验室出品,做到了"doc to LLM-ready data"。

快速开始

bash
# 安装
pip install magic-pdf

# 转单个文件
magic-pdf -p "合同文件.pdf" -o "output/"

# 批量处理
magic-pdf -p "documents/" -o "output/" --batch

默认输出到output/目录,包含.md文件和对应图片文件夹。

用公司一份30页产品手册试了试。原来PDF里的表格、流程图、多级标题,全部正确转成Markdown。表格变成| 列1 | 列2 |格式,LLM能直接理解。

详细步骤

1. 单文件处理

bash
magic-pdf -p "2026年采购合同.pdf" -o "output/"

输出结构:

output/ 2026年采购合同/ full.md # 完整Markdown images/ # 提取的图片 tables/ # 表格的JSON格式

2. 批量处理(企业场景)

bash
magic-pdf -p "./company_docs/" -o "./rag_data/" --batch --workers 4

--workers 4用4个进程并行处理。实测3000份PDF用4个worker,约45分钟跑完。

3. 接入RAG管道

python
from magic_pdf import MagicPdf
import chromadb

# 解析
docs = MagicPdf.parse_dir("./documents/")

# 分块
chunks = []
for doc in docs:
    chunks.extend(doc.to_chunks(chunk_size=512))

# 向量化并存入向量库
client = chromadb.Client()
collection = client.create_collection("company_docs")
collection.add(
    documents=[c.text for c in chunks],
    ids=[c.id for c in chunks]
)

4. 指定输出格式

bash
magic-pdf -p "合同.pdf" --format json  # 输出JSON(适合API)
magic-pdf -p "合同.pdf" --format md    # 输出Markdown(适合RAG)
magic-pdf -p "合同.pdf" --format both  # 两种都要

踩坑实录

坑1:扫描件PDF识别差。 MinerU对原生数字PDF效果好,图片型PDF不行。解法:先用PaddleOCR预处理,再喂MinerU。

坑2:超大PDF内存爆。 500页产品手册(200MB),默认配置吃2GB内存。解法:加--chunk-size 50分批处理。

坑3:中文手写体完全无法识别。 手写签名、手写批注显示为空白。暂时无解,建议提前预处理。

效果验证

bash
magic-pdf -p "test_contract.pdf" --format both

验证清单:

  • Markdown文件正常打开
  • 表格数据完整(对比原文)
  • 多级标题层级正确
  • 图片已单独提取
  • JSON格式的表格可代码读取

延伸思考

为什么MinerU要维护两套解析后端(PyMuPDF和pdfplumber)? 文档里说是"为了高保真",但两套后端各管什么场景?一个处理文字、一个处理表格和图片?这跟PaddleOCR的后端策略有什么区别——PaddleOCR也分检测、识别、表格三个子模型。如果MinerU的两个后端是互补的,那有没有自动切换逻辑,还是需要手动选?

chunk_size到底跟什么有关? 文档推荐合同用512字符,技术手册用256-384,论文用768-1024。但这串数字是怎么测出来的?有没有量化标准(比如每个chunk包含的token数不应该超过embedding模型的输入限制)?还是纯经验值?如果我的文档类型不在这个列表里——比如双语合同、或者技术文档混着代码和文本——怎么定chunk_size?

常见疑问

Q1:扫描件PDF真的完全不能用?

能用,但需要预处理。MinerU本质是PDF内容提取器而非OCR引擎。先用PaddleOCR或Tesseract将扫描件转成可搜索PDF,再喂MinerU。识别率取决于原稿清晰度,80%-95%不等。

Q2:512字符的chunk大小固定吗?

不是。技术手册类段落短、代码块多,建议256-384字符;长段落文档放宽到768-1024字符。核心原则:每个chunk包含一个完整语义单元,别把一句话切成两半。

Q3:JSON和Markdown输出什么时候用哪个?

Markdown更适合直接喂RAG系统,LLM对Markdown表格和标题层级理解最好。JSON保留完整结构化信息,适合二次开发——比如提取表格数据做统计分析,或接入自己的数据处理管线。选both兼顾两种场景。

下一步

  • MinerU GitHub:https://github.com/opendatalab/MinerU
  • 想搭完整RAG系统?看《OpenWebUI接入灿海星图》
  • 企业级方案:MinerU → 向量库 → 灿海星图API → 企业AI助手

本文数据来源于互联网公开信息(GitHub opendatalab/MinerU),仅供行业趋势参考。