PaperFlow项目进展记录:MinerU 全文精析与 Editor Pro 进展记录 1. 设计背景与阶段目标Daily Update 打通后系统已经可以从首页触发论文发现、审核和初步入库。但这个阶段生成的内容主要来自论文元数据、标题、摘要和 Agent 判断还不能充分利用论文全文。对于一个论文阅读系统来说只把标题和摘要入库是不够的Sage 回答需要正文证据PDF 阅读器需要页码和位置公式翻译需要 LaTeXEditor Pro 需要图片和图注后续可视化也需要更细粒度的结构化资源。因此 MinerU 在 PaperFlow 中的定位不是“把 PDF 转成一段文本”而是全文资源层。它应该把 PDF 中的正文、标题、公式、图片、表格、markdown 和 layout/json 都变成可索引、可访问、可复用的知识资源。Editor Pro 则建立在这一层之上它不再只基于摘要写一张卡片而是在全文解析和 MinerU 资产准备好之后选择合适的论文插图并生成更适合详情页展示的图文导读。这也是为什么系统区分 Editor Lite 和 Editor Pro。Lite 负责快适合 Daily Update 当场刷新和用户上传后的即时反馈Pro 负责深适合在 PDF 下载、MinerU 精析、资源入库之后异步补强。两者不是重复功能而是服务于不同延迟要求的两层编辑机制。2. MinerU 精准解析 API 接入当前实现已经把 MinerU 解析从本地命令行优先改成远程精准解析 API。Knowledge Engine 的 MinerUAdapter 会根据环境变量决定解析模式当 MINERU_PARSE_MODEapi 时会直接走 MinerU precise API不再尝试本地运行 MinerU。实际流程是先调用 MinerU 的批量上传 URL 接口为当前 PDF 申请上传地址然后把本地 PDF 二进制上传到返回的 URL上传完成后轮询 batch 解析结果解析成功后下载 full_zip_url 指向的 zip最后将 zip 解压到当前论文的解析目录。这个目录在服务器上位于/opt/paperflow-knowledge/data/parsed/paper_id/mineru_precise以已验证论文 2605.30345v1 为例MinerU 解包后能看到 full.md、content_list.json、content_list_v2.json、layout.json、model.json 和 images/*.jpg。这些文件是后续全文 chunks、公式资产、图片资产和 Editor Pro 插图选择的原始来源。这里有一个重要取舍系统没有把 MinerU 原始 zip 或全部 JSON 原封不动塞进 PostgreSQL。PDF 解析结果可能包含大量图片和结构文件如果直接塞进 pf_paper.metadata会让论文主表变重也不利于前端按需加载。当前采用的是“文件留磁盘数据库存索引”的方式。原始文件继续放在 data/parsed数据库只保存资源类型、路径、页码、bbox、caption、latex 等结构化索引。3. 正文 blocks 归一化与 chunks 入库MinerU 输出格式并不是直接等于 PaperFlow 的知识库格式所以中间增加了 flatten_blocks 归一化步骤。这个步骤会优先读取 MinerU 输出中的 pdf_info/preproc_blocks把其中的 text、title、interline_equation 转换为统一 block{ id: ..., page: 1, bbox: [x0, y0, x1, y1], text: ..., type: text|title|formula }如果某些 MinerU API 结果没有 pdf_info则 fallback 到 content_list、blocks 或 pages。对于 content-list 中缺少坐标的文本系统会保留文本并生成兜底 bbox这样至少不影响全文检索和 RAG 入库。这个策略的核心是坐标准确时用于 PDF 定位坐标缺失时仍然保留语义文本避免解析结果因为少字段而被全部丢弃。归一化后的 blocks 会通过 save_parsed_paper 写入 pf_paper_chunk。这些 chunk 的 metadata 标记为{ source: parsed-original, page: 1, bbox: [x0, y0, x1, y1], source_type: text, section_title: ..., paper_title: ... }这一步和 Editor Lite 的 agent-workflow chunks 是区分开的。agent-workflow 保存 Agent 对论文的总结和判断parsed-original 保存 MinerU 从论文全文中解析出的原文内容。Sage 检索时会优先奖励 parsed-original因为它更接近论文原始证据但 Agent summary 仍然保留用于快速理解和补充语义召回。4. 公式资源的处理方式公式目前有两条入库路径。第一条是作为 typeformula 的 parsed-original chunk 写入 pf_paper_chunk这样 Sage 和全文搜索可以检索到公式上下文。第二条是作为 asset_typeformula 写入 pf_paper_asset这样后续 PDF 阅读器和前端渲染可以按页码、bbox 和 LaTeX 精确定位公式。formula asset 不是独立图片文件而是从归一化 blocks 中提取出来的结构化资源。它会保存 page、bbox、latex/content 和原始 block id。这个设计是为后续公式渲染准备的当用户在 PDF 中选中含公式区域时系统可以先根据 page bbox 找到对应公式 asset再把 LaTeX 交给翻译模型或前端 KaTeX/MathJax 渲染而不是只依赖 OCR 后的纯文本。目前公式资产已经能进入资源表但前端 LaTeX 渲染还没有最终完成。也就是说数据基础已经准备好下一步要做的是在摘要、Sage 回答、PDF 选区翻译和 Editor Pro 中统一处理 $...$ 或 block formula 的渲染。5. pf_paper_asset 表的引入一开始考虑过把 MinerU manifest 放进 pf_paper.metadata。这个做法实现快但长期会有明显问题一篇论文可能有几十张图片、多个 JSON、markdown、公式和表格如果都放进 metadata论文详情接口会变重前端不能按需加载后续也很难按类型查询“某篇论文有哪些图片”或“第 3 页有哪些公式”。因此当前改为引入 pf_paper_asset把 MinerU 解析资源提升为系统的一等资源。文件本体仍然保存在 Knowledge Engine 的 data/parsed 目录资源表保存索引。当前字段包括资源 id、论文 id、来源、资源类型、相对路径、磁盘路径、公开访问 URL、content type、文件大小、页码、bbox、caption、latex、content 和 metadata。这张表的实际用途有三个。首先前端详情页不需要在论文主接口里拿到所有图片只需要按需请求 /assets?asset_typeimage。其次Editor Pro 可以直接从资源表读取图片候选而不需要每次重新扫磁盘目录。第三后续公式定位、图片引用、Sage 引用证据和对象存储迁移都有了统一索引层。当前 pf_paper_asset 由 Python Knowledge Engine 在写入解析结果时自动建表和补列。这是为了快速打通链路。更规范的做法是后续整理成正式 SQL migration避免长期依赖运行时代码修改 schema。6. MinerU 资产扫描与登记解析完成后系统会扫描当前论文的 mineru_precise 目录。扫描逻辑不是只看 images 文件夹而是结合 MinerU 的 content_list 信息。对于 content_list 中 typeimage 或 typetable 的对象系统会尝试读取 img_path、image_path、table_img_path、path、src 等字段并匹配真实文件路径。这样可以把图片文件和 MinerU 提供的 page、bbox、caption 联系起来。如果 content_list 中没有完整字段系统仍然会 fallback 扫描目录下的图片、markdown 和 json 文件。图片会登记为 asset_typeimagemarkdown 登记为 markdowncontent_list*.json 登记为 content_list_jsonlayout.json 登记为 layout_jsonmodel.json 登记为 model_json。公式则由正文 blocks 额外生成 formula asset。每个 asset 都会生成稳定 id。当前 id 基于相对路径 hash避免同一篇论文重复回填时不断生成新 id。asset 的 public_url 采用统一形式/api/v1/papers/{paper_id}/assets/{asset_id}这样前端不需要知道真实磁盘路径也不会暴露 /opt/paperflow-knowledge/data/parsed 这种服务器内部结构。7. 资源访问接口与 Java 代理Knowledge Engine 新增了资源列表和资源文件接口。列表接口返回 asset metadata但过滤掉 storage_path避免把服务器真实路径暴露给前端。单文件接口会根据 paper_id 和 asset_id 查询资源表确认文件路径仍位于该论文的 parsed 目录下然后用 FileResponse 返回文件。外部访问仍然经过 JavaGET /api/v1/papers/{paperId}/assets?asset_typeimage GET /api/v1/papers/{paperId}/assets/{assetId}content-service 中的 KnowledgeEngineClient 增加了对应代理方法PapersController 增加了列表和文件转发接口。单个图片文件通过 Java 返回时保留上游 content type例如 image/jpeg。这点很重要因为前端 img 标签需要直接加载图片资源不能依赖登录态和不能拿到错误 MIME。已在服务器用 2605.30345v1 验证过图片列表接口可以返回 MinerU 图片资产单图接口可以返回200 image/jpeg 632338. Editor Pro 的生成逻辑Editor Pro 的触发点在全文解析之后而不是 Curator 审核通过之后立即运行。原因是 Pro 需要依赖 MinerU 产出的全文 blocks 和 asset 列表尤其是图片、公式和 markdown/json 这些资源。如果 PDF 还没有下载或者 MinerU 还没有完成解析Editor Pro 就只能退化成和 Editor Lite 类似的摘要卡片无法体现“全文级编辑”的价值。当前代码路径中Daily Update 审核通过论文后会进入 ingest_approved_paper_pdf。这个函数先下载 PDF再调用 MinerU precise API随后执行三个关键步骤flatten_blocks(raw_data) 负责把 MinerU 输出归一化为统一正文 blocksbuild_mineru_assets(paper_id, output_dir, raw_data) 负责扫描 MinerU 解包目录并登记图片、markdown、json 等资源build_formula_assets(paper_id, output_dir, blocks) 负责从公式 blocks 中提取 formula asset。只有这些输入准备好以后系统才调用 build_editor_pro_card(paper, blocks, mineru_assets) 生成 Editor Pro。Editor Pro 的输入不是把整篇论文全文直接丢给模型。这样做会浪费 token也容易让模型被大量正文噪声淹没。当前采用的是压缩后的多源输入论文基础信息提供标题、摘要、标签、Editor Lite 已经整理过的贡献点和局限全文 blocks 中抽取若干较长文本片段作为论文方法和实验内容的语义样本MinerU asset 中筛出前若干张图片候选提供图片 id、文件名、页码、caption、文件大小和访问 URL。这个输入结构的目标是让模型既知道论文讲什么又能在有限候选图里做选择而不是重新完成全文阅读。全文样本的抽取也做了简化规则。系统不会把所有 chunk 都放进 prompt而是从 blocks 中选择长度足够的文本片段过滤掉过短、信息量低的内容并截断到固定长度。这种做法牺牲了一部分完整性但换来了稳定的模型调用成本和响应时间。对于 Editor Pro 第一版来说它的任务不是生成完整综述而是为详情页生成“足够帮助用户判断是否深入阅读”的图文导读因此这种采样是可接受的。图片候选的构造更依赖 MinerU asset 表。系统会优先选择 asset_typeimage 的资源并限制候选数量避免把几十张图全部放进模型输入。每张候选图传给模型的不是图片二进制而是结构化描述例如 asset id、文件名、页码、caption、size_bytes 和 public_url。这里的设计有一个明确限制当前模型并没有直接看图它依据的是 MinerU 解析出的 caption、图片所在页码、文件信息和论文文本上下文来判断哪张图更适合作为详情页插图。Prompt 对模型的要求也不是简单“总结论文”。它要求模型完成一个编辑决策从候选图中选择最适合详情页展示的一张并解释为什么这张图有助于读者理解论文。规则上会偏好方法框架图、系统结构图、流程图、结果总览图和具有明确 caption 的图片同时避免选择 logo、无意义裁剪、小尺寸图片、纯公式截图或装饰图。这让 Editor Pro 更像一个论文编辑而不是普通摘要器。模型调用走模型路由中的复杂任务 editor_summary。在当前 Sophnet 配置下这类任务会走 qwen3.7-max因为它需要做综合判断既要理解论文摘要和全文样本又要根据候选图信息做内容选择还要输出结构化 JSON。相比 DeepSeek Flash 这类简单任务模型复杂模型更适合做这种多约束编辑任务。Editor Pro 期待模型返回稳定 JSON而不是自由文本。当前结构包括 display_mode、hero_title、visual_summary、selected_figure_id、figure_reason、figure_caption、key_takeaways 和 limitations。这里最关键的是 selected_figure_id因为模型只能返回候选图 id系统再用这个 id 回连到真实 asset。也就是说模型不直接决定图片 URL模型只做选择后端负责把选择结果映射回数据库中的资源记录。回连 selected figure 之后系统会把完整的 selected_figure 写入 pf_paper.metadata.editor_pro。这里保留完整 asset 信息是为了让前端详情页可以直接读取 public_url、caption、page 和 rel_path不必再额外查一次 asset 列表。与此同时asset 本体仍然由 /api/v1/papers/{paperId}/assets/{assetId} 提供访问metadata 中只是保存对该资源的引用和必要展示信息。Editor Pro 还有 fallback 机制。如果模型不可用、模型没有返回合法 JSON、候选图为空或者返回的 selected_figure_id 无法匹配真实 asset系统不会让整篇论文入库失败。它会退化为 fallback card有图片时选择第一张图片作为插图没有图片时返回 no_figure 状态标题和摘要则回退到 Editor Lite 的 popular_headline、popular_summary 或论文摘要。这个设计是为了保证 Daily Update 的主链路稳定不能因为 Pro 阶段失败就影响论文全文入库。从数据流上看Editor Pro 的输出最终只写入论文 metadata而不是单独建一张 Editor Pro 表。这样做是为了第一版实现轻量因为 Editor Pro 当前是一篇论文的一组展示信息不涉及多版本对比、人工审核或历史回滚。后续如果要支持“重新生成”“人工修正”“爆款版/客观版多版本并存”就应该把 Editor Pro 从 metadata 中拆出来建立独立的 card/version 表。当前 Editor Pro 第一版已经形成了完整闭环MinerU 解析提供全文和资源asset 表提供图片索引复杂模型做图文导读决策后端把选择结果写回 metadata前端详情页读取 metadata.editor_pro 并展示插图和导读。但它仍然不是最终形态。最大限制是模型目前没有直接读取图片像素选图更像“基于 caption 和上下文的编辑判断”如果 MinerU 没有给出 caption模型只能依赖页码、文件名和文本样本。下一阶段如果接入视觉模型Editor Pro 就可以真正判断图片内容例如识别方法框架图、实验结果图、消融表格截图或无意义裁剪图从而显著提高插图选择质量。9. 前端详情页展示论文详情页现在会读取 metadata.editor_pro。如果存在 hero_title、visual_summary、selected_figure、key_takeaways 或 limitations页面会展示 Editor Pro 区块。展示内容包括图文标题、全文级摘要、选中插图、图片说明、选图理由、Pro takeaways 和 Pro limitations。图片使用 asset 的 public_url因此前端不需要额外拼接服务器地址也不需要知道图片实际保存在哪里。这使详情页从“论文标题 摘要 PDF 入口”进一步升级为“论文图文导读页”。从产品角度看Editor Lite 更像 Feed 里的摘要卡Editor Pro 更像进入详情页后真正帮助用户判断“这篇论文值不值得深入读”的编辑层。10. 摘要一键翻译详情页还新增了摘要一键翻译。这个能力独立于 Editor Pro但与论文导读体验相关。前端摘要区的按钮会调用POST /api/v1/papers/{paperId}/translate-summaryKnowledge Engine 会优先翻译 summary如果没有 summary 则 fallback 到 abstract再 fallback 到 editor_pro.visual_summary。当前翻译走简单任务 light_summary也就是使用低成本快速模型而不是每次都调用复杂模型。接口只返回翻译结果不写入数据库。不缓存的原因是当前阶段更关注链路验证。如果直接把每次翻译写入 metadata用户重复点击会产生状态污染也需要考虑不同目标语言、不同模型版本和缓存失效。后续可以单独设计 metadata.translations 或独立翻译缓存表。服务器已通过外部接口验证摘要翻译返回 200前端也已经有按钮入口。11. 与 Daily Update 入库链路的关系MinerU 和 Editor Pro 不是单独的离线功能而是 Daily Update 入库闭环的后半段。当 Curator 审核通过一篇论文后系统会下载 PDF然后调用 MinerU 精析随后保存 parsed chunks 和 assets最后生成 Editor Pro。这个顺序解决了实时性和完整性的矛盾。Daily Update 点击后可以先用 Editor Lite 给用户快速反馈全文解析完成后再补上 Editor Pro 和可访问的 MinerU 资源。对于用户上传论文也是类似逻辑上传后先有基本记录和解析状态完整解析完成后再逐步增强阅读页。因此后续如果做 Agent 可视化应该把这一段显示成状态链PDF downloaded - MinerU parsed - chunks indexed - assets registered - Editor Pro generated这样用户能知道论文不是“突然出现一张图”而是经过了可解释的全文资源处理流程。12. 当前完成度与限制当前已经完成全文精析的关键基础设施MinerU precise API 接入、正文 chunks 入库、公式资产登记、图片/markdown/json 资产登记、资源访问接口、Java 代理、Editor Pro 生成和详情页展示。也就是说系统已经具备把 MinerU 解析结果作为长期知识资源使用的基础。仍然需要注意的是Editor Pro 目前是第一版。它能选图和生成导读但选图依据还不是视觉模型直接理解图片。公式虽然已经入库为 chunk 和 asset但前端还没有统一 LaTeX 渲染。pf_paper_asset 目前由 Knowledge Engine 自动建表和补列后续应该整理成正式 migration。老论文也不会自动拥有完整 assets 和 Editor Pro需要重新解析或执行回填。下一步如果继续推进这一块优先级应该是公式渲染和 Editor Pro 模式增强。公式渲染可以直接利用现有 formula assetEditor Pro 模式增强可以在同一份全文和资产基础上生成“客观评论版”和“爆款导读版”并允许前端切换。再往后才是多图候选、人工改图和视觉模型理解图片。