1. 长 PDF 解析为什么总在 RAG 和 Agent 里翻车
如果你正在做 RAG 或 Agent 项目,大概率遇到过这种场景:一份 200 页的科研论文或企业年报丢进流水线,解析到一半超时,重跑一次又从第一页开始;或者解析"成功"了,但跨页表格被截成两半、公式编号丢失、双栏论文阅读顺序错乱,chunk 里混进页眉页脚,检索出来的证据链根本对不上原文。这不是模型不行,而是把长文档解析当成了"大文件上传",而不是"长任务编排"。
RAG 和 Agent 需要的不是手工拆 PDF 的脚本,而是一条可恢复、可追踪、可验收的解析流水线。核心思路是:用 MinerU 3.x 做结构化文档产出(Markdown、JSON、LaTeX、图片资产),通过 MCP 接入统一的 Key/API 通道 TaoToken,把解析能力变成 Agent 可调用的工具,同时用检查点机制保证中断后能续跑。这篇就给你一套可复制的config.toml与settings.json骨架,并演示中断续跑和结果校验的完整动作。
适合谁看:正在搭 RAG 知识库、做 Agent 工具链、或者被长 PDF 解析折磨过的工程师。读完你能拿到一套能直接改参数就跑的配置,而不是又一篇"注册即用"的注水教程。
2. TaoToken 前置:统一 Key 与 API 通道
在把 MinerU 接进流水线之前,先解决一个工程问题:解析服务、Agent 调用、模型对话往往散落在不同的 Key 和 endpoint 上,一旦要换通道或做审计,就得满项目改配置。TaoToken 在这里的角色是统一入口——你可以在一个控制台里管理 Key,把模型对话、编码任务、文档解析相关的调用收敛到同一条 API 通道上。
具体操作路径:
- 打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 了解整体能力;
- 进入控制台创建 API Key:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ;
- Key 管理页在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ;
- 接入文档参考 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ;
- API 基地址统一用 https://taotoken.net/api (不加 UTM)。
拿到 Key 之后,不要硬编码进脚本。正确做法是写进环境变量或配置文件,让 MinerU 的 MCP Server、Python SDK、以及后续的 Agent 调用都从同一处读取。这样做的直接好处是:解析任务失败时,你能快速判断是 Key 额度问题、通道问题,还是文档本身的问题,而不是在多个 token 之间来回猜。
注意:MCP Server 会把文件或 URL 发往解析服务,涉及未公开论文、合同、财务数据时,先确认外发权限,必要时走本地部署。
3. 可复制配置骨架:config.toml 与 settings.json
这一节是全文的核心。下面给出两份可直接落地的配置骨架,一份给 MinerU 解析流水线用(config.toml),一份给 MCP 客户端和 Agent 用(settings.json)。参数按你的实际环境替换即可。
3.1 config.toml:解析流水线与检查点
# config.toml —— MinerU 解析流水线配置骨架 [api] # 统一走 TaoToken 通道,Key 从环境变量读取,避免硬编码 base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" timeout_seconds = 600 max_retries = 3 [parse] # 输入与输出 input_dir = "./samples" output_dir = "./runs" # 页码范围支持断点续跑,中断后改这里即可 pages = "1-120" model = "vlm" ocr = true table = true formula = true language = "ch" extra_formats = ["docx", "html", "latex"] [checkpoint] # 检查点文件,记录已完成页、失败页、task_id enabled = true path = "./runs/checkpoint.json" # 每完成 N 页写一次盘,防止长任务全丢 flush_every_pages = 10 resume = true [review] # 抽样验收配置 sample_pages = [1, 18, 19, 35, 36] high_risk_types = ["cross_page_table", "formula", "scanned_page"] fail_log = "./runs/failures.jsonl"关键点说明:pages字段是续跑的抓手,中断后不用从头再来;checkpoint.flush_every_pages控制写盘频率,长文档建议 10 页一次,太频繁伤 IO,太稀疏丢进度;review.sample_pages把高风险页固定下来,每次回归都查这几页。
3.2 settings.json:MCP 客户端与 Agent 接入
{ "mcpServers": { "mineru": { "command": "uvx", "args": ["mineru-open-mcp"], "env": { "MINERU_API_TOKEN": "${TAOTOKEN_API_KEY}", "MINERU_BASE_URL": "https://taotoken.net/api", "OUTPUT_DIR": "/absolute/path/to/mineru-runs", "CHECKPOINT_FILE": "/absolute/path/to/mineru-runs/checkpoint.json", "MAX_PAGES_PER_TASK": "120" } } }, "agent": { "tool_timeout_seconds": 900, "allow_local_paths": ["./samples"], "allow_urls": [], "auto_write_to_kb": false } }auto_write_to_kb设为false是刻意的:解析成功不等于适合入库,半成品 Markdown 直接进生产知识库,后面检索出来的答案会带着错误结构一起被 embedding 放大。allow_urls留空,避免 Agent 自动抓取未授权地址。
3.3 参数对照表
| 参数 | 作用 | 建议值 | 踩坑提示 |
|---|---|---|---|
pages | 页码范围 | 按检查点动态调整 | 续跑时只填未完成段 |
model | 解析模式 | vlm或pipeline | 扫描件优先 vlm |
ocr | 文字识别 | 扫描件必开 | 原生文本 PDF 可关省时间 |
table | 表格提取 | 有表格就开 | 跨页表需人工复核 |
formula | 公式识别 | 论文必开 | 输出 LaTeX 需抽样核对 |
flush_every_pages | 写盘频率 | 10 | 太小伤 IO,太大丢进度 |
max_retries | 重试次数 | 3 | 配合失败日志定位阶段 |
4. 验证请求与成功结果
配置写好后,先做小样本预检,再跑长任务。下面给出 CLI、Python SDK 和 MCP 三种入口的验证动作。
4.1 CLI 预检
# 先用单份小样本确认通道和参数没问题 export TAOTOKEN_API_KEY="你的Key" mineru -p ./samples/long-report.pdf -o ./runs/long-report -b pipeline跑通后检查./runs/long-report下是否同时生成了 Markdown、JSON 和图片资产目录。如果只有 Markdown 没有 JSON,说明结构化输出没开,回去检查extra_formats。
4.2 Python SDK 提交长任务并轮询
from mineru import MinerU import time, json, os client = MinerU(os.environ["TAOTOKEN_API_KEY"]) batch_id = client.submit( "./samples/long-report.pdf", model="vlm", ocr=True, table=True, formula=True, pages="1-120", extra_formats=["docx", "html", "latex"], ) while True: result = client.get_batch(batch_id)[0] print(result.state, result.progress) if result.state in ("done", "failed"): break time.sleep(10) if result.state == "done": result.save_all("./runs/long-report") # 写检查点,记录已完成页 with open("./runs/checkpoint.json", "w") as f: json.dump({"task_id": result.task_id, "pages_done": "1-120"}, f) else: raise RuntimeError(f"parse failed: {result.task_id}")成功结果的判断标准不是"state == done",而是三件事同时成立:Markdown 能正常渲染、JSON 里元素类型和页码对得上、图片资产路径在 Markdown 里可回溯。我试过只看 state 就入库,结果跨页表格缺表头,检索时证据链直接断掉。
4.3 MCP 调用验证
Agent 侧调用解析工具后,应该拿到的是任务句柄而不是阻塞等待:
{ "tool": "submit_parse_task", "args": { "file": "./samples/long-report.pdf", "pages": "1-120", "outputs": ["markdown", "json"] }, "returns": { "task_id": "task_20260721_001", "state": "running", "progress": 0.35 } }随后用get_parse_task(task_id)查询状态,拿到markdown_path、json_path、assets和failures。这样 Agent 不会因为一次长解析超时而卡死。
4.4 中断续跑演示
假设解析到第 60 页时进程被杀,检查点里记录了pages_done: "1-60"。续跑时只需把pages改成"61-120",重新提交:
# 读取检查点,只跑未完成段 python resume_parse.py --checkpoint ./runs/checkpoint.json --input ./samples/long-report.pdfresume_parse.py的核心逻辑就是读检查点、算剩余页、提交新任务、合并输出。这样一份 200 页文档中断三次也能拼回完整结果,而不是每次从第一页重来。
5. 本篇常见错排查
5.1 解析成功但表格错列
现象:JSON 里表格元素存在,但行列关系错乱,合并单元格被拆散。原因通常是跨页表格没开滑动窗口,或者table参数没生效。排查动作:检查config.toml里table = true,并在review.sample_pages里固定几个关键表格页做单元格级核对。跨页大表建议人工复核后再入库。
5.2 中断后重跑从头开始
现象:进程被杀后重新提交,进度从 0 开始。原因是没有启用检查点,或者resume = true没配。排查动作:确认checkpoint.enabled = true,检查checkpoint.json是否真的写入了pages_done。如果检查点文件为空,说明flush_every_pages设得太大,任务还没到写盘点就挂了。
5.3 MCP 调用超时
现象:Agent 调用解析工具后长时间无响应。原因是把长任务当成了短 RPC。排查动作:确认 MCP Server 返回的是task_id而不是阻塞结果,agent.tool_timeout_seconds设到 900 以上,并让 Agent 用轮询而不是同步等待。
5.4 Key 或通道报错
现象:提交任务返回鉴权失败或额度不足。排查动作:确认TAOTOKEN_API_KEY环境变量已导出,base_url用的是https://taotoken.net/api。如果 Key 没问题,去控制台核对额度和调用记录。接入细节参考接入文档,Key 管理在 API Keys 页面。
5.5 扫描件 OCR 漏字
现象:扫描页文字可读但关键数字或单位错误。原因是低清扫描或特殊字体。排查动作:把该页加入high_risk_types的scanned_page,人工标注错字漏字,必要时换更高分辨率重扫。OCR 结果不要直接进 RAG,先过抽样验收。
5.6 版本漂移导致输出结构变化
现象:升级 MinerU 或 SDK 后,同样的文档输出结构变了。排查动作:保留解析版本号,升级前重跑固定回归集(就是review.sample_pages那几页),对比 JSON 元素类型和 Markdown 结构。许可证和页数上限也要逐项核对,以当前官方文档为准。
6. 把解析能力接进你的 Agent 工具链
配置和验证都跑通之后,下一步是让这套流水线真正为 RAG 和 Agent 服务。如果你主要在做模型对话相关的调试,可以先用模型对话入口验证通道是否顺畅;如果长期跑编码任务或 Agent 工作流,建议了解 Coding Plan 的额度与调用方式;接入和排障过程中遇到 Key、通道、参数问题,直接查接入文档和 API Keys 页面最快。
回到工程本身:长文档解析的稳定性,不取决于你把页数上限调多大,而取决于任务是否可恢复、失败是否可定位、结果是否可验收。MinerU 负责结构化产出,TaoToken 负责统一通道,检查点负责续跑,抽样验收负责质量。这四件事凑齐,RAG 的上下文质量才有底。最后留一个实用习惯:每次升级解析组件或改切块逻辑,先跑一遍失败集回归,别让版本漂移悄悄污染你的知识库。