
PDF转文本——3000份合同45分钟跑完
我运营API中转站这几个月,被问最多的问题不是模型选哪个,不是价格多少——是"金哥,我们公司有3000份PDF合同,能不能让AI帮我分析条款?"
每次我都不太好意思回答。不是不能,是太麻烦了。3000份PDF→手动转文本→清洗格式→分段→存向量库→RAG查询。每一步都在掉数据。一份带表格的合同,转文本后表格变成谁也看不懂的乱码。
MinerU解决的就是这个——把任何文档变成LLM能直接吃的结构化数据。上海AI实验室出品,做到了"doc to LLM-ready data"。
快速开始
# 安装
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. 单文件处理
magic-pdf -p "2026年采购合同.pdf" -o "output/"
输出结构:
output/
2026年采购合同/
full.md # 完整Markdown
images/ # 提取的图片
tables/ # 表格的JSON格式
2. 批量处理(企业场景)
magic-pdf -p "./company_docs/" -o "./rag_data/" --batch --workers 4
--workers 4用4个进程并行处理。实测3000份PDF用4个worker,约45分钟跑完。
3. 接入RAG管道
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. 指定输出格式
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:中文手写体完全无法识别。 手写签名、手写批注显示为空白。暂时无解,建议提前预处理。
效果验证
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),仅供行业趋势参考。