起因

看到两个论文库网站,把2026年的ICLR和ICML的所有论文扒下来用LLM做了中文导读,还有研究方向的分类,非常具有参考价值:
https://jenniferzhao0531.github.io/ICLR2026-Guide-CN/
https://tsrigo.github.io/ICML2026-Guide-CN/
image-20260915155756020

image-20260915155908692

于是想到:平时泛读的论文能不能也做一个类似的论文库,用于快速浏览、进行参考呢?
本地的笔记收录了论文的元信息和英文摘要,并且按照自己的思路进行了分类,和参考站相比,再用LLM按照摘要做解读就可以了。既然参考站能跑在 GitHub Pages 上,那我的论文库能跑在我的 Hexo 站点里吗?

让deepseek帮我看一下是否可行🧐

Hexo+Butterfly 能不能做到

我的站是 Hexo 7.3 + Butterfly,部署在自建服务器上。动手前先确认了原生能力边界,避免走弯路。

参考站的能力 Butterfly 现状
三级树状侧栏 + 每级计数 ❌ 侧栏是固定 widget(作者卡 / 最近文章 / 分类 / 标签),塞不进自定义树
一页内按分类聚合 ❌ Hexo 分类支持多级,但渲染成「归档列表」,不是同页聚合
全站秒搜 ⚠️ hexo-generator-searchdb 已经装了,但 search.use: 是空的,搜索其实是关的
折叠卡片 ✅ collapse / note / tabs 标签插件可以
文章内目录 ✅ 但 75 篇论文挤在一篇里,TOC 会长到没法用

结论:Butterfly 原生做不到,但不是技术做不到,是「承载方式」不对。

参考站本身就是个单文件静态 HTML——没有框架、没有后端,一个 <script id="paper-data" type="application/json"> 里塞了全部论文数据,剩下全靠前端 JS。

所以方案定为:不动主题,把论文库做成一个预生成的独立静态页。

关键一环:skip_render

D老师让脚本把页面生成到 source/papers/index.html。然后第一次 hexo generate,打开一看——炸了。

页面确实生成了,但它的 <head> 里出现了 Butterfly 的东西:

1
2
3
<html lang="zh-CN" data-theme="light">
<title>薜荔阁 - Xjelly's Blog | 薜荔阁 - Xjelly's Blog</title>
<meta name="description" content="MAS 拓扑论文库 · 薜荔阁 :root{ --bg:#f6f8fa; ...">

Hexo 把 source/papers/index.html 当成了一个普通 page,套上了主题的 page 布局。 整个 HTML(包括 <style>)被塞进了主题的 <head> 里,页面结构彻底报废。

原因是:source/ 下的文件只要 Hexo 能处理,就会被当文章/page 渲染。要让它原样拷贝,得显式声明:

1
2
3
4
5
# _config.yml
i18n_dir: :lang
skip_render:
# 论文库是预生成的独立静态页,不能套 Butterfly 主题布局
- 'papers/**'

改完立刻 hexo generate——还是坏的。差点以为方法不对。

其实是 Hexo 的缓存:它认为这个文件没变,复用了上次渲染的结果。必须 hexo clean 一次:

1
npx hexo clean && npx hexo generate

之后用哈希对比确认它是原样拷贝的:

1
if ((Get-FileHash 'public\papers\index.html').Hash -eq (Get-FileHash 'source\papers\index.html').Hash) { "原样输出 ✓" }

踩坑提示:skip_render 生效后一定要 hexo clean。

菜单接入就一行:

1
2
3
4
5
# _config.butterfly.yml
menu:
首页: / || fas fa-home
论文库: /papers/ || fas fa-book-reader
存档: /categories/技术/ || fas fa-archive

数据管道:一条不能全自动的流水线

75 篇论文的「结构化解读」没法脚本化——那需要真读懂摘要。但除了这一步,剩下的全可以自动化。

D老师把它拆成了这样:

1
2
3
4
5
草稿.md
└─ parse-draft.mjs ─────▶ raw.json (解析出标题/摘要/分区)
└─ split-batches.mjs ─▶ batches/*.json (按分区拆成 6 批)
└─ [LLM 逐篇解读] ─▶ out/*.json ← 唯一的人工/LLM 环节
└─ build.mjs ─▶ source/papers/index.html

从草稿解析元数据这一步可以放心交给D老师,尽管D老师吐槽“比想象中麻烦”。
草稿长这样:(确实是平时做记录的时候没有结构化。)

1
2
3
4
5
#### (arxiv 2026.08 通过蒙特卡洛树搜索从多个候选拓扑中选取节点)HELENA:Hierarchical Sparse Coordination...

LLM-based multi-agent systems (MAS) typically optimize a single topology...
基于 LLM 的多智能体系统通常只优化单一拓扑结构...

至于那 6 批解读,D老师拆给了 6 个并行的 LLM 任务,每个负责一个分区,产出统一的 JSON schema:

1
2
3
4
5
6
7
8
9
{
"analysis": {
"motivation": "研究动机:原有做法缺什么",
"problem": "解决问题:一句话",
"method": "主要方法:关键机制,不能写空话",
"results": "关键实验:数据集 / 基线 / 提升幅度",
"takeaway": "可借鉴点:对做这个方向的人有什么用"
}
}

草稿里的中文摘要是机器翻译的,不能直接用。D老师提前列了一张术语对照表塞给子代理,并点名了已知的机翻错误。事后扫描确认全库零残留。D老师会给子代理写好任务规范,挑第一个子代理的prompt看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
你在 Windows 上的一个 Hexo 博客仓库里工作,工作目录是 `D:\Blog\my-blog`。

任务:为一批 MAS(多智能体系统)拓扑方向的论文生成结构化中文解读。这是要公开发布到博客的论文库内容,质量要求高。

步骤:
1. 先读 `D:\Blog\my-blog\tools\papers\ANALYSIS-SPEC.md`,严格遵守其中的输出格式、字段约束、术语规范和三级子方向(sub3)设计规则。
2. 读输入文件 `D:\Blog\my-blog\tools\papers\data\batches\batch-1.json`(共 17 篇论文,section2 为「MAS拓扑设计」)。
3. 按规范产出结果,写入 `D:\Blog\my-blog\tools\papers\data\out\batch-1.json`。若 `out` 目录不存在,先用 pwsh 执行:
`New-Item -ItemType Directory -Force -Path "D:\Blog\my-blog\tools\papers\data\out"`
4. 写完后必须自校验:该文件是合法 JSON;`papers` 数组长度 == 17;每篇的 `id/title/titleZh/venue/year/venueNote/type/sub3/tags/abstractZh` 以及 `analysis.motivation/problem/method/results/takeaway` 全部非空;所有 `sub3` 都出现在 `sections` 声明的标签里;`id` 集合与输入完全一致。
校验方式示例:`node -e "const j=require('./tools/papers/data/out/batch-1.json'); ..."`(在 D:\Blog\my-blog 下执行)。

硬性要求:
- 输出文件必须是**严格合法的 JSON**(UTF-8,无注释、无尾逗号),不要用 ```json 代码块包裹。
- 只依据 batch 文件里给出的标题、关键词注释、英文摘要、中文机翻摘要来判断。**不要联网、不要读论文原文、不要编造任何数字或数据集。**
- 中文机翻摘要有明显错误(如 LLM 被译成「逻辑逻辑模型」、token 被译成「令牌/词元」、`\helena{}` 之类 LaTeX 残留),必须按规范修正。
- 逐篇认真写,`analysis.method` 必须具体(写出关键机制/算法/指标),不能写空话。

完成后回复一段简短总结:处理篇数、该 section 采用的三级标签及各自覆盖的论文编号、以及 `results` 里写了「摘要未给出量化结果」的篇数。

Deepseek-V4-Flash看不见页面,怎么验证

D老师用无头 Chrome 注入一段探针脚本,把布局和交互的实测结果 dump 出来:

1
2
3
4
5
6
7
var out = [];
out.push('sidebar=' + rect(document.querySelector('.sidebar')) + ' pos=' + getComputedStyle(sb).position);
inp.value = '拓扑'; inp.dispatchEvent(new Event('input'));
out.push('SEARCH[拓扑] cards=' + document.querySelectorAll('.paper:not(.hidden)').length);
var pre = document.createElement('pre'); pre.id = 'probe';
pre.textContent = '<<<PROBE ' + out.join(' ;; ') + ' PROBE>>>';
document.body.appendChild(pre);

配 --dump-dom 读结果:

1
2
3
4
5
6
7
8
9
sidebar=340x805@0,0 pos=sticky      main=1069x39387      无横向滚动
papers=75 priSec=4 subSec=16 subsubSec=40 navLinks=40
一级默认展开 / 二级默认收起(navPri expanded=4, navSub expanded=0)
firstPaper=1001x474 analysisDisplay=flex absEnDisplay=none
SEARCH[拓扑] cards=74 SEARCH[shapley] cards=1
SEARCH[Ollivier-Ricci] cards=1 SEARCH[zzzzzz] cards=0 emptyShown=true
展开全部:analysisDisplay 先 none 再 flex;单卡折叠按钮文案随之切换
收藏写入 localStorage:stored=["ofa-mas"];只看收藏筛选命中 1 篇
anKeys={"研究动机":75,"解决问题":75,"主要方法":75,"关键实验":75,"可借鉴点":75}

最后那行证明 75 篇的解读字段一篇都没漏。

顺带一提:papers=75 和 anKeys 里的 75 是完全独立的两个统计口径,能对上才说明数据和渲染是一致的。


论文库的后续维护

和参考站不一样的是,参考站已经扒下了会议中所有的论文,不需要增加、删除和修改了。而我的论文库还会一直更新。D老师第一版做的方案里有两个大坑,是从草稿解析时埋下的:

坑 A:用「第几篇」当 ID

第一版里论文的 ID 是 p001、p002……按它在草稿里的顺序编号。解读文件也按这个 ID 索引。

听起来没问题,直到在中间插入一篇新论文:

1
2
3
4
5
插在第 3 篇之前 →
p003 变 p004,p004 变 p005 …… 全部后移一位
而 out/ 里的解读还是按旧 ID 存的
→ 75 篇的解读全部错位到别人的标题上
→ 构建成功,页面正常,没有任何报错

这是最危险的一类 bug:不报错,只是默默给你错误的内容。

修法是让 ID 只依赖论文标题,不依赖位置——取英文标题派生一个 slug:

1
2
3
"HELENA: Hierarchical Sparse Coordination over a Union of ..."  → helena
"EMAS: Stabilizing Multi-Agent System Evolution through ..." → emas
"Topology Linearization for Multi-Agent Systems Security: ..." → topology-linearization-for-multi-agent

规则是优先取冒号前的方法名(大多数论文标题都是「方法名: 描述」的结构),没有冒号就取标题前 5 个单词。

实测验证过:在草稿中间插一篇新论文,其余 75 篇的解读零漂移,只有新论文被正确地报「缺少解读」。

代价是改了标题就等于改了 ID,不过这个有办法兜(见下一节)。

坑 B:改了二级标题,17 篇论文凭空消失

页面的分类树是从一个 taxonomy.json 里定义的,一级大区显式列着它包含哪些二级分区。而二级分区的名字,就是草稿里的 ### 标题。

所以:在草稿里把 ### MAS拓扑设计 改成别的名字,却没同步 taxonomy.json,那 17 篇论文就从页面上消失了——它们还在数据里,但不属于任何一级大区,所以不会被渲染。构建显示成功。

第一版的校验只检查了「论文总数对不对」,这种消失完全检测不到。

修法:把构建分成「能过」和「过不去」两档

D老师把校验重写了一遍,结构性问题一律致命,直接非零退出、不写任何文件:

  • 某篇论文没有解读
  • out/ 里有草稿中不存在的 ID(标题改了导致 ID 漂移)
  • 某个二级分区没有被任何一级大区认领 ← 就是坑 B
  • 分类树覆盖的论文数 ≠ 论文总数 ← 兜底防线
  • 必填字段为空
  • 某篇的三级子方向不在该分区声明的标签里

现在改了标题不配套,得到的是这个:

1
2
3
4
5
✗ 致命错误 19 条,已中止(未写出 papers.json):
- 以下二级分区没有被 taxonomy.json 的任何一级大区认领,其论文会从页面上消失:
- 「通信拓扑设计」 (17 篇)
处理办法:在 taxonomy.json 里把它加进某个 primary 的 sections 数组。
- 分类树只覆盖了 58 篇,但共有 75 篇论文——有论文不会出现在页面上

报错直接告诉你去哪改、怎么改。这比「构建成功但少了 17 篇」好一万倍。


给未来留的第三个机制:源指纹

前面提到,页面上的会议 / 年份 / 期刊等级只从解读文件读,草稿里那行 (arxiv 2026.08 …) 页面根本不看。

这就埋了个雷:论文从 arXiv 变成正式发表了,去草稿里改成 (NeurIPS 2026 …),页面一个字符都不会变。

于是D老师加了个指纹机制:每篇在产出解读时,把草稿的「会议注释 + 标题 + 中英摘要」算一个哈希存下来。构建时重算比对,不一致就提示:

1
2
3
4
5
6
提示 4 条:
· 以下 1 篇的草稿内容在解读产出后被改动过,out/ 里的信息可能已过时:
- emas
草稿现在是: NeurIPS 2026 利用观测经验修改拓扑结构和提示
页面还显示: arXiv 2026(预印本)
处理办法:核对后改 out/ 里的对应记录,确认无误后跑 papers:stamp 消除本提示。

这顺带解决了另一个问题:改写了某篇的摘要,还记得去更新它的解读吗? 指纹会替你记着。

再配一个按 ID 改元数据的命令行工具,改会议信息就是一行:

1
node tools/papers/edit.mjs emas --venue "NeurIPS 2026" --venueNote "CCF-A 会议" --year 2026

它会自动定位这篇落在哪个文件里(我拆了 6 个批次文件),不用手动 grep。


最后的结果

页面本体 901 KB,纯静态,无框架无后端:

  • 75 篇论文,一级 4 个大区 → 二级 16 个方向 → 三级 40 个子方向
  • 左侧三级折叠树,每级带数量角标;搜索时实时过滤,并同步更新各级计数、隐藏空分区
  • 每张卡片:中文译名 + 英文原题 + 会议年份 + 类型徽章 + 关键词 + 重写的中文摘要,加上研究动机 / 解决问题 / 主要方法 / 关键实验 / 可借鉴点 五段解读
  • 客户端搜索(支持搜解读正文)、收藏(localStorage)、一键展开/收起全部解读、快捷键 / 聚焦搜索
  • 英文原始摘要折叠,深色模式跟随系统

有意思的一个副产品:75 篇里有 38 篇的摘要根本没给出量化结果。这些是靠摘要判断不了成色的,真要引用得回去读原文。

image-20260915170455431


几条可复用的经验

  1. 抄一个站之前,先看清它是什么。 把参考站扒下来才发现是单文件静态 HTML + 一段 JSON。看清了这个,方案自然就出来了。
  2. Hexo 部署独立静态页要 skip_render,改完记得 hexo clean。 缓存会让你在一个已经修好的问题上反复怀疑自己。
  3. 不要用位置当标识符。 不管在什么系统里,只要数据源可能被插入元素,「第几项」就是定时炸弹。用内容派生的稳定标识。
  4. 静默失败比崩溃危险得多。 「构建成功但少了 17 篇」远比「构建失败」糟糕。凡是能自动校验的,就让它失败得响一点。
  5. 让 LLM 产出结构化结果时,先写规范再开工。 我把术语对照表、字段约束、三级标签的设计规则都写进了一份规范文档,再分给 6 个并行任务。事后扫描确认全库零术语残留——如果靠事后返工,成本会高得多。

整个工具链放在 tools/papers/ 里,包含解析、拆分、合并、渲染、校验、编辑脚本和两个说明文档。这套东西一次写好,以后加论文、改会议信息、调分类,都有明确的流程可以走。

请教D老师的时间与开销

这次用的是DSH搭配DeepSeek-V4-Flash,完成整个论文页面库设计和实现,加上修bug和写后续维护文档的时间,一共是35分钟左右,花费¥5.43。虽然V4只是文本模型,没法在页面上截图验证,但是参考站和本站都是静态页面,可以从html中验证。D老师使用无头 Chrome 注入一段探针脚本,把布局和交互的实测结果 dump 出来。这说明有的功能不一定非要视觉模型,文本模型+tools也能完成,主要是看任务场景是否适配。