plan-sess_4d6aa46c-0157-4a26-9add-313e05e615c3.md 5.2 KB

PDF 解析双引擎方案:本地 PaddleOCR + 远程 MinerU

目标

ocr_extract.py 增加 --engine 参数,支持在本地 PaddleOCR(原方案)和远程 MinerU(高精度云端解析)之间切换,两种引擎输出统一 JSON 格式供下游消费。


涉及文件(6 个文件变更)

文件 操作 说明
scripts/mineru_parser.py 新建 MinerU 云端解析模块
scripts/ocr_extract.py 修改 增加 --engine / --mineru-token / --mineru-mode 参数,路由分发
scripts/requirements.txt 修改 增加 langchain-mineru + python-dotenv(可选依赖)
scripts/deploy.md 修改 增加 MinerU 部署配置章节
SKILL.md 修改 阶段 2 补充 --engine 用法说明
.env.example 新建 MinerU 配置模板
.gitignore 修改 增加 mineru_cache/

详细设计

1. scripts/mineru_parser.py(新建,约 180 行)

配置加载(优先级:CLI arg > 环境变量 > .env 文件):

  • MINERU_TOKEN:MinerU API 令牌
  • MINERU_MODE:解析模式,默认 "precision"
  • MINERU_MAX_PAGES:单次 API 最大页数,默认 20
  • MINERU_CACHE_DIR:缓存目录,默认 ./mineru_cache/

核心函数

get_file_hash(file_path) → md5 hex
_cache_path_for(file_hash) → Path
_read_cache(path) / _write_cache(path, content)
count_pdf_pages(file_path) → int
clean_mineru_text(markdown_text) → str
sanitize_text(text) → str
mineru_pdf(pdf_path, out_dir, pages_spec, token, mode) → (result_dict, json_path)

mineru_pdf() 流程

  1. 检查缓存(基于 PDF 的 MD5 hash)
  2. 命中缓存 → 直接返回
  3. 未命中 → 分片调 MinerULoader(source, mode, token, pages="start-end")
  4. 每页 doc.page_contentclean_mineru_text() 清洗
  5. 拼接全文 → 写缓存
  6. 输出统一 JSON,type: "mineru", avg_confidence: 0.98

输出 JSON 格式(与 PaddleOCR 兼容):

{
  "source": "/path/to/file.pdf",
  "engine": "mineru",
  "total_pages": 15,
  "from_cache": false,
  "pages": [
    {
      "page": 1,
      "type": "mineru",
      "text": "## 配风计划表\n| 地点 | 风量 |\n...",
      "avg_confidence": 0.98,
      "item_count": 0,
      "items": []
    }
  ]
}

缓存策略

  • 缓存 key = PDF 文件 MD5(文件内容不变则命中缓存)
  • 缓存内容 = 清洗后的全文 markdown
  • 缓存目录 mineru_cache/.gitignore 排除)

2. scripts/ocr_extract.py(修改)

新增 CLI 参数

--engine {local,mineru}    解析引擎,默认 local
--mineru-token TOKEN       MinerU API Token(可选,优先级最高)
--mineru-mode {precision,fast}  MinerU 模式,默认 precision

main() 路由逻辑

if args.engine == "mineru":
    from mineru_parser import mineru_pdf
    result, json_path = mineru_pdf(
        args.pdf, args.out, args.pages,
        token=args.mineru_token, mode=args.mineru_mode
    )
else:
    result, json_path = ocr_pdf(args.pdf, args.out, args.dpi, args.pages)

输出时标注 engine 字段

  • ocr_pdf() 结果自动补 "engine": "local"

3. scripts/requirements.txt(修改)

新增(注释标为可选):

# === MinerU 云端解析(可选,仅 --engine mineru 时需要)===
# pip install langchain-mineru python-dotenv
# langchain-mineru
# python-dotenv

4. scripts/deploy.md(修改)

新增章节"六、MinerU 云端解析(可选)":

  • 申请 Token 地址
  • 安装依赖:pip install langchain-mineru python-dotenv
  • 配置 .env 文件
  • 用法示例
  • 费用/速率限制说明
  • 与本地 PaddleOCR 对比表(精度/速度/费用/离线能力)

5. SKILL.md(修改)

阶段 2 第 2 步增加 --engine 选项说明:

**引擎选择**:
- `--engine local`(默认):本地 PaddleOCR,无需网络,适合离线环境
- `--engine mineru`:MinerU 云端解析,精度更高,适合扫描质量差的 PDF

6. .env.example(新建)

# MinerU 云端解析配置(可选,仅 --engine mineru 时需要)
MINERU_TOKEN=your_token_here
MINERU_MODE=precision
MINERU_MAX_PAGES=20
MINERU_CACHE_DIR=./mineru_cache

7. .gitignore(修改)

新增两行:

# MinerU 缓存
mineru_cache/
.env

兼容性保证

关注点 措施
向下兼容 --engine 默认 local,不传时行为完全不变
输出格式 MinerU 输出 JSON 与 PaddleOCR 结构一致,type: "mineru" 区分
依赖隔离 langchain-mineru 仅在 --engine mineru 时才 import,不用不装
容错 MinerU 网络异常时明确报错,不静默失败;缓存损坏自动清除重建

CLI 用法示例

# 本地 PaddleOCR(默认,与原行为一致)
python scripts/ocr_extract.py --pdf 配风计划.pdf --out output/ --pages 3,8,9

# MinerU 云端解析
python scripts/ocr_extract.py --pdf 配风计划.pdf --out output/ --engine mineru

# MinerU + 指定 Token + 快速模式
python scripts/ocr_extract.py --pdf 配风计划.pdf --out output/ --engine mineru --mineru-token xxx --mineru-mode fast