dsh-paper-digest
每日论文日报插件。按设定的时间自动检索中英文高质量论文,按透明可审计的质量信号排序,生成一份按主题分组的 Markdown 日报写入工作区。全部配置在 DSH 设置 → 论文日报 中完成。
它解决什么
"每天自动送 10 篇好论文"的真正难点不是推送,而是判定质量与拿到中文文献:
- 知网、万方、维普都没有面向个人的公开 API;
- "北大核心"是《中文核心期刊要目总览》这本书目,不是可查询的数据库;
- 新发表的论文没有任何引用,所以"按引用排序"在 T+0 完全无效(OpenAlex 对新论文返回
fwci: null)。
因此插件的排序依据是当天就能算出来的信号:场所权威(核心库收录 / 期刊 / 已录用)、内容证据(方法·结果·局限·数据公开)、时效、作者机构,以及很小的社区关注度。每篇论文都会在日报里写出入选理由、命中关键词和评分构成,可直接审计。
日报会话(找得到)
每份日报除了写成文件,还会自动创建一个会话:以日期命名(如 2026-09-18 论文日报(10 篇)),会话根目录是日报目录,并挂到对应工作区上——因此在左侧会话列表里直接点开就能读,不必去翻文件夹。
打开后你会看到一轮正常的对话:你自己的请求「生成今天的论文日报(日期)」→ 助手读完报告后给出的分主题速览,并以交付文件卡片呈现日报本身(可直接点开或下载),末尾附本地全文路径与数据源失败情况。会话挂载的是部署默认的 agent 预设,所以能继续追问某篇论文的细节。
- 播种的那条消息必须用
source: { kind: 'user' }。用 plugin 源会被判为上下文注入,渲染成折叠的「上下文注入」行而不是对话(第一版就是这样,对照截图确认后修正)。
- 摘要轮次是真的模型轮次:创建会话后用
agent.followup(message)(等价于 send(msg, 'next-turn', true))排一轮,让助手真正读取文件并总结——这才产出你期望的"助手总结 + 文件"形态,而不是把整份 Markdown 塞进消息里。
- 提示词里明确要求调用
present:文件卡片由 present 工具产生,只在正文里写路径是不会有卡片的(这一点在我自己的回复里也踩过)。
- 零事件会话不会显示:
agents.create 建出来的是空日志(501 字节、零事件),侧边栏不渲染它——工作区展开后只有文件夹(已在真实 UI 上复现)。所以播种是必需的,不是可选项。
- 播种/追加失败会降级并如实报告:退回空会话并把原因写进日报诊断,不会因为会话问题丢掉日报。
- 日报目录只建一个工作区,后续每天复用(按路径匹配,避免侧边栏堆满每日工作区)。
- 设置页有「为上次日报新建会话」按钮,用于补救历史日报。
- 关掉开关即只写文件、不建会话。
实现上有几个只靠猜一定会踩的坑,均已写进代码注释:
resolveByPath() 定义在原型上(列服务自己的方法时看不到),且 Workspace 的目录是通过 path() 方法暴露的、不是 cwd 属性——按 cwd 匹配永远失败,会每天重复建一个工作区。
- 宿主服务必须每次运行惰性读取:插件加载得早、工作区平面挂载得晚,激活时读一次会把
undefined 永久缓存(ctx.get() 不会触发重新激活)。
- 会话事件有 surface 契约:
user/message 属于表面事件,必须带 surfaceOp(追加用 'append')并可引用来源事件序号;序号从 0 连续;且不能留下未闭合的轮次,所以 turn/end 是必需的。写错的代价由日志校验器当场拒绝(不会写坏会话)。
agent.followup() 是驱动一轮的官方原语,send(message, 'next-turn', true) 等价;只 append 到 inbox 不足以让轮次跑起来。
中文速览
每篇入选论文会由本机已配置的模型(读取 agentDefaultModel 的当前选择,无需另配 API Key)根据标题与摘要生成 2–3 句中文速览,在日报里以「📌 一句话速览」置顶;原文摘要折叠保留在下方可展开核对。提示词明确要求只使用给定信息、不得补充或推测,摘要未交代方法与结论时如实说明。
几个由实测得来的设计点:
- 默认输出上限 1500 tokens。思考型模型会先花预算思考:最初设 300 tokens 时 10 篇里有 9 篇返回空内容(预算被思考吃光)。
- 首次为空会自动加倍预算重试一次。实测仍有 3/10 篇首次为空、重试后成功,所以这不是冗余逻辑。
- 思考档位可调(继承 / minimal / low / medium / high / max)。速览只是归纳,嫌慢或嫌费可调
minimal 并相应调低输出上限。
- 单篇失败不影响整篇日报:失败原因(含 finish 与思考 token 数)写进「运行诊断 → 中文速览」,其余论文照常出速览。
- 关闭开关即完全不调用模型。
全文获取
只下载开放获取(OA)全文,插件从不尝试绕过付费墙:
| 通道 | 说明 |
|---|
| arXiv | 作者自存预印本,PDF 直链稳定可下 |
| PubMed Central(经 Europe PMC) | 有 pmcid 即代表全文开放,PDF 接口精确 |
| 出版商 OA 版本 | OpenAlex 的 best_oa_location.pdf_url 明确标注开放时才会使用 |
| Unpaywall(可选) | 留空邮箱即关闭;填入你自己的邮箱后,可为付费论文查找合法的 OA 副本 |
每个文件都先校验 %PDF- 魔数再落盘,所以验证码页 / HTML 错误页不可能被存成 .pdf;单文件上限 25MB,每轮下载数量可限。
中文订阅库(知网 / 万方 / 维普)不抓取全文,日报只给详情页链接。这不是技术限制而是刻意选择:其服务条款禁止批量下载,且从校园网跑脚本抓取一旦触发风控,受影响的是全校 IP 段。你在浏览器里用学校账号点开链接,一样省事但零风险。
产出位置:outputDir(日报 Markdown)与 pdfDir(默认 outputDir/pdf);默认根目录 ~/Documents/dsh-paper-digest,可用环境变量 DSH_PAPER_DIGEST_DIR 覆盖。
安装
1. 取得源码并构建
git clone https://github.com/juzikexue/dsh-paper-digest.git
cd dsh-paper-digest
pnpm install
pnpm build:client # 必须执行,原因见下
pnpm test # 可选:69 项回归单测
lib/client.js 不入库(esbuild 构建产物,见 .gitignore),所以克隆后必须自己构建一次。
跳过这一步插件仍能启动、日报也照常生成,但设置页会是空的——浏览器半加载不到,且没有任何报错。
这是装这个插件最容易漏掉的一步。
2. 以 link: 方式装入 web profile
// ~/.dsh/profiles/web/package.json
{
"dsh": {
"profile": {
"bundles": [ /* … */ "@dsh-local/dsh-paper-digest" ]
}
},
"dependencies": {
// 换成上一步克隆到的绝对路径
"@dsh-local/dsh-paper-digest": "link:/abs/path/to/dsh-paper-digest"
}
}
cd ~/.dsh/profiles/web && pnpm install
# 然后重启 dsh web
插件的 cordis.patch.yml 只在 Loader 树里插一行 host row:该行负责配置/状态路由、每日调度与产出;浏览器半由 package.json 的 dsh.client 声明被 dsh-client-modules 发现。
设置项(设置 → 论文日报)
| 设置 | 说明 |
|---|
| 启用每日自动检索 | 关闭后只保留手动运行 |
| 发送时间 | 每天此刻之后首次检查时生成;若运行时刻机器休眠,唤醒后自动补跑 |
| 每日篇数 / 中英配比 | 中文是软目标,中文源不足时由英文补齐到总篇数 |
| 回溯天数 | 只收最近 N 天发表的论文(期刊 RSS 除外,见下) |
| 输出目录 | 日报写入此处,建议填会话工作区 |
| 研究主题 | 每个主题含中文关键词与英文关键词 |
| CNKI 期刊监控 | 期刊代码 + 刊名 + 归属主题;中文主力通道 |
| 数据源开关 | 见下表 |
| 核心期刊表 | 可选,每行 刊名关键词 = 等级,命中即标记核心刊并提高评分 |
关键词写法(重要)
中英文的空格含义不同,这是刻意的:
- 中文:空格 = 或。
人工智能 教育 表示"人工智能"或"教育"。但 2 字通用词(教育、学习、技术)不单独作为证据,否则"义务教育"论文会灌进"人工智能教育"主题。请写 3 字以上的词组。
- 英文:空格 = 且。
computer-assisted language learning 是一个短语,所有词都必须在标题/摘要中出现。
日报会打印每篇论文的命中关键词,如果发现某篇不对口,照它去收紧关键词即可。
数据源与可靠性
| 源 | 语言 | 通道 | 状态 |
|---|
| CNKI 期刊 RSS | 中 | rss.cnki.net 的期刊最新目录(每刊约 20 条) | ✅ 稳定、免登录、无需验证码 |
| ChinaXiv | 中 | 中科院预印本公开 JSON API | ✅ 稳定;接口是全文检索,插件会自行做相关度过滤 |
| Europe PMC(中文) | 中 | LANG:chi 检索 | ⚠️ 仅医学(每两周约 35 条,几乎全是中华医学会系列),默认关闭 |
| NCPSSD | 中 | 站点为 Vue SPA,无公开检索 JSON 接口 | ⚠️ 实验性,默认关闭 |
| OpenAlex | 英 | 官方 API,primary_location.source.is_core 作核心库标记 | ✅ 稳定、免费、无需 key |
| Crossref | 英 | 官方 API,标题检索 | ✅ 稳定、免费 |
| arXiv | 英 | Atom API,arxiv:comment 里的 "Accepted at XXX" 是强质量信号 | ✅ 可用(偶发超时,已隔离) |
一个数据源失败不会中断日报:失败会记进「运行诊断」,剩余源继续,英文补齐篇数。
为什么中文主力是期刊 RSS 而不是检索
知网检索页有滑块验证码,且用校园 IP 批量抓取检索结果有连累全校封禁的风险。期刊 RSS 是官方提供的、免登录的"最新一期目录",语义上恰好就是"我的领域这周有什么新论文",因此作为中文主力。期刊代码可在知网期刊导航页的 URL 中看到(如 JJYJ=经济研究、JYYJ=教育研究、XLKX=心理科学)。
质量评分
总分 = (期刊档次 30 + 内容证据 25 + 时效 15 + 数据开放 10 + 社区关注 10 + 作者机构 10)
× (0.45 + 0.55 × 主题相关度)
- 硬门槛(打分前剔除):撤稿记录、标题缺失或过短、无链接且无 DOI、超期;期刊 RSS 条目豁免时效门槛,因为"最新一期"本身可能已出版数周。
- 内容证据从标题+摘要抽取:是否含方法、结果、局限表述,是否有数据/代码公开线索。
- 社区关注用引用数取对数;对新论文天然接近 0,这是有意的——它不该主导 T+0 排序。
运维
node scripts/live-run.mjs [输出文件] # 不经过 dsh,直接跑一次真实检索并打印统计
node --test "test/*.test.js" # 回归单测(关键词匹配、去重、选题、渲染)
node scripts/build-client.mjs # 重建设置面板 bundle(改 src/client 后必须执行)
配置与状态落盘在 ~/.dsh/storages/dsh-paper-digest/(config.json、status.json、core-journals.txt)。配置不使用 DSH 的 settings 服务:该服务对 out-of-tree 插件是 scope 隔离的,第三方插件注册不进去,所以插件自带 HTTP 路由持久化自己的配置。
已知限制
- 中文检索精度受关键词质量影响最大。2 字通用词已被排除,但仍有语义歧义(例如关键词里的"技术"会命中核物理论文)。日报的「命中关键词」就是为排查这类问题而设。
- 订阅式电子期刊(PubScholar/NCPSSD)无法在纯 HTTP 下检索,因为结果是浏览器内渲染的,且没有公开 JSON 接口。若要纳入,需要引入无头浏览器依赖。
- 核心期刊表需自行维护(书目受版权保护且有多个版本),未配置时中文论文不做等级加权,仅按其他信号排序。
- arXiv 偶发超时;插件已设超时与重试并做源级隔离。
许可
MIT