← Back to home@TianzeLuo

dsh-paper-reader

DSH 插件:论文解读模式。精读单篇论文并生成证据可追溯的中文解读报告,按图注自动裁出图表,并基于同一份解析产物回答关于这篇论文的问题。速览 / 解读 / 深读三档可选,以 agent preset 隔离,只在选中该模式时可见。

Stars
0
Language
JavaScript
Created
Sep 29, 2026
Updated
Oct 2, 2026

Introduction

dsh-paper-reader

DSH 插件:论文解读模式。精读一篇具体论文并生成解读报告,同时基于同一份解析产物回答关于这篇论文的问题。

这个插件解决什么

三件事,都放在一个只在需要时出现的模式里:

  1. 解读报告 —— 给定一篇论文,产出结构固定、证据可追溯的中文报告。解读深度分 速览 / 解读 / 深读 三档,由输入框旁的档位控件选定(不是让模型自己猜);图表自动裁好,嵌在第一次提到它的位置; 报告头写清原文路径与 docId,读者把报告交给自己的 agent 提问时能直接定位同一份解析产物。
  2. 论文问答 —— 针对同一篇论文提问,答案带页/章节锚点,并分清作者主张与推断;默认一次检索 就带约两段上下文,多数问题不必再读整页。
  3. 输出风格 —— 术语首现给中英对照加白话解释、缩写首现展开、同一概念只用一个名字、指标首现 说清「它在算什么」、公式写成 LaTeX、不写空转句。

档位控件

进入「论文解读」模式的会话后,输入框工具行左侧会出现一个三档段控件:

档位篇幅(参考,不设上限)读到什么程度交付文件名
速览通常 800–1500 字主智能体自己顺序读 3–5 页(摘要、引言、方法开头、主结果),不起并行编排<简称>-速览.md
解读(默认)通常 3000–6000 字并行分节读正文,附录只读与主张相关处<简称>-解读报告.md
深读参考 8000 字以上并行读全文 + 附录的超参 / 梯度 / 算力 / 数据配比<简称>-深读报告.md

篇幅只用来校准基调,不是硬指标:该讲清楚的(指标在算什么、公式的符号、证据边界)不因为怕超字数而省, 内容紧凑时也不硬凑;写长了先检查是不是把更深档位的内容写了进来。

档位是每个会话独立的(同一工作目录里可以一个会话写速览、另一个写深读)。模型只看到自己这一档的 流程:技能正文按档位装配,系统提示里也只有当前档位那一段——没有另外两档的冗余。控件只在论文解读 模式出现,其他模式的会话里既不显示控件、也看不到这些技能。

档位不是模型判断的:模型只被要求照当前档写。用户的措辞看起来像另一档时,模型按当前档交付并在导读 里说明可以换档,不会自行改档。

为什么是 agent preset,而不是全局 skill

DSH 的 skill 目录只在上下文里放「名字 + 描述」,正文按需加载——但目录行、persona、工具仍然是每个 session 都要背的成本。本插件把这部分整个放进一个 agent preset:在 Web 的新任务模式选择器里选 「论文解读」才生效,其他模式(standard / ptc / …)的会话里看不到这些 skill、persona 和工具。

这不是约定,是 DSH 的原生隔离:ctx.skills.registerProvider 的注册落到调用上下文的 scope 层。 取舍与实测细节见 设计与取舍。

一处例外,值得明说:档位控件必须由 profile 根层的 bundle 提供——DSH 组装浏览器插件图时只扫描 根层 bundle 行,preset 的子行拿不到 UI(代码层面无解)。所以本包被挂两次:根层那一行 (role: control)只负责让控件进页面并注册档位端点,preset 里那一行(role: agent)注册技能、 五个工具与档位提示词段。模型可见面仍然全部落在 preset 的 scope 上,隔离是 DSH 原生的——包括 工具在内,别的模式一件都看不到。两行都由本包自己的 patch 提供,不需要手工改配置;取舍与实测 见 设计与取舍。

安装

本包自带运行时依赖(mupdf、yaml),且 node_modules/ 不入库,所以在装进 profile 之前必须先在 本包目录里装一次依赖:

cd <本包目录>
pnpm install

dsh plugin --profile web add <本包目录>

装完重启 dsh web:preset 与根层 bundle 都属启动期组装。本包同时出现在两处—— cordis.patch.yml 插根层 bundle 行(role: control,让控件进页面),presets/paper.patch.yml 插 preset 行(role: agent,提供模式身份与模型可见面)。dsh plugin add 会自动带上这两层, 不需要手工改 profile 配置,也不要删掉其中任何一行:少了根层那行没有控件,少了 preset 那行则论文 模式没有技能和工具。

别用 scp 风格的 URL 让 pnpm 去装(git@github.com:...)——pnpm 会把它误解析成「包名 git + 版本」,插件不会生效。本插件目前只验证过本地路径安装;远端安装的写法与注意事项见 开发文档。

Windows 与 Linux 都能用:preset 里 bash / pwsh 两行按平台互相 disabled,与官方 preset-standard 的写法一致。

五个工具

工具做什么关键参数
paper_import把 PDF 导入本地缓存,返回 docId 与论文地图(章节树 + 图表清单)source(绝对路径)
paper_search检索词句,返回命中片段与 [p.7 §3.2] 锚点docId query limit(默认 6,≤30) context(默认 window)
paper_read按页读正文,超出字符预算就如实报告截断docId pages(如 3,7,9-11) maxChars(默认 24000)
paper_figure渲染整页,或按 bbox 只裁一块区域docId pages(单次≤8 页) dpi(默认 120) bbox outputDir
paper_figures按图注自动裁出全部图与表,一张一个 PNGdocId pages dpi(默认 200) max(默认 24) outputDir

paper_search 的 context 有三档:snippet(命中处前后各 70 字,最省)、block(命中所在块)、 window(默认,命中块连同前后各最多两块,约 700 字符)。默认档就是照着「一次检索够回答、 不必再读整页」选的。

设计上值得说明的四点:

  • 一次导入,多处复用。 报告与问答共用同一份解析产物,所以锚点在同一篇论文里始终一致。 docId 是 PDF 字节的 sha256 前 12 位,同一份文件换路径导入仍然命中同一份缓存。
  • 检索优先于通读。 paper_search 先按短语匹配,一个都不中才退化成「所有词都出现」的宽松匹配, 并在结果里标明是哪种模式——避免模型把宽松命中当成精确依据。
  • 锚点是算出来的。 每个文本块带 bbox 与「是否标题」判定,命中项因此能给出 [p.7 §3.2] 这种 可核查的位置。判定同时看文本形态与排版特征(加粗,或字号大于全篇正文基准字号),宁可漏判 让锚点变粗,也不误判让锚点指错章节。算法与失败模式见 设计与取舍。
  • 图是按图注找出来的。 paper_figures 走一遍页面的 display list 收集矢量图元与位图的 bbox, 按「图注所在栏 + 正确一侧」认领,再用墨迹分布收紧。因此裁出来的是图本身,不是整页截图; 并排的两张图各自成图。裁切框不与图注文字相交:渲染前按图注块的 bbox 再削一遍,图注原文 单独返回,报告把它写在图片下方。启发式会失败,失败项如实列出并可用 bbox 手动裁,取舍见 设计与取舍。

数据放在哪

缓存默认落在 $DSH_HOME/paper-reader/:

paper-reader/
├── levels.json        档位:{ "version": 1, "levels": { "<sessionId>": "brief|standard|deep" } }
└── <docId>/
    ├── meta.json        页数、源路径、导入时间、PDF 内嵌标题/作者(常常没有)
    ├── source.pdf       源文件副本——缓存因此自包含,原文件被移走也能继续渲染
    ├── pages/001.txt    分页正文
    ├── pages/001.json   结构化块(bbox / 行数 / text / heading),锚点由图注分侧都由它算出来
    ├── figures.json     图形区域检测结果(图注 → 裁切矩形),首次检测时写入
    └── figures/p002@120.png

meta.json 最后写,所以它存在就意味着这次导入完整;中断的导入不会留下「看起来能用」的半份 缓存。缓存根可以在代理面那一行(presets/paper.patch.yml 的 paper-reader-agent)加 config.cacheRoot 覆盖;档位文件也在同一个根下,控制面那一行必须给同一个值(控制面默认值与 代理面一致,所以只在两边都改时才需要动):

- id: paper-reader-agent
  name: 'dsh-paper-reader'
  config:
    role: agent
    cacheRoot: /path/to/paper-cache

它里面的 format 是缓存格式版本:抽取逻辑改进后旧缓存里的页码与块结构就不再可信,版本对不上会 重新解析并覆盖。因此改了抽取逻辑必须抬 CACHE_FORMAT,见 维护纪律。

档位写的是文件而不是会话事件:DSH 的持久化读到未知事件类型会拒绝整条会话日志,而仓库外插件 无法给事件打 ignorable 标记。取舍与替代做法见 设计与取舍。

技能

skills/<name>/SKILL.md 三个技能包,随模式一起生效:

技能什么时候用按档位装配
paper-report要求解读、精读、写阅读报告是(工作流与各节重心来自 levels/<档位>.md)
paper-qa针对某一篇论文提问否(问答与档位无关)
paper-verify成稿自审(报告或较长答案交付前)是(第 10 项按档位核对,来自 levels/verify.md)

技能名刻意保持稳定(不按档位拆成三个技能):/paper-report 这类手势与「用户自己的同名技能覆盖 本插件版本」都依赖名字稳定,而技能目录的每一行都是每个会话的固定成本。代价是目录行看不出档位差异, 所以系统提示里的档位段会明说「以 paper-report 正文为准」。

技能名的来源、frontmatter 约定与「改正文不需要重载」的机制见 开发文档。

验证

node --test          # 132 条:provider / preset / client 契约 + levels 装配 + pdf 行为 + tools 行为

不改任何 profile、验证 bundle 与 preset 组装的方法见 开发文档。

已知限制

首次导入会把每页解析两遍(实测 17 页约 127ms、31 页约 247ms,之后命中缓存);图形区域检测是启发式 的,会漏也会多框(唯一硬保证是裁切框不含图注文字),自动裁不出来的项会如实列出;公式的上下标在 纯文本抽取里会丢,本包不做公式 OCR,改为要求写成 LaTeX 并回原页核对;章节锚点的粒度取决于论文模板。 逐条说明与实测记录见 已知限制。

许可证

MIT,见 LICENSE。仓库:https://github.com/s11phere/dsh-paper-reader(私有)。