引用文献速览(citation-digest)

给定一篇论文,抓取它的引用列表(Semantic Scholar,含被引数),抓取每篇的 papers.cool Kimi 总结(只取「试图解决什么问题」原文),按给定类别归类,输出 markdown 或发布到 Notion。

O que é 引用文献速览(citation-digest)?

此技能旨在帮助研究人员快速消化一篇论文的引用文献。它通过一个四步骤流水线自动化处理:首先使用 Semantic Scholar API 抓取引用论文的元数据(包括被引次数、DOI、arXiv ID);接着从 papers.cool 平台获取每篇论文的 Kimi AI 总结(专注于论文试图解决的问题);然后由用户或 AI 按预设类别(如场景创新、技术改进、仅综述)进行分类;最后将整理好的内容输出为 Markdown 文件或发布到 Notion 数据库。该技能特别适合用于处理「引用/被引/citing papers/literature digest」请求,并能按主题分类或将结果写入 Notion 页面。它支持通过 Semantic Scholar 和 papers.cool 的 API 获取数据,并内置了去重、限流、重试等稳健性机制,以及针对 Notion 发布的各种坑(如块嵌套限制、字符数限制等)的防护措施。

Funciona com✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/RuijieH/agent-skills/tree/main/skills/citation-digest

Installed? Explore more Produtividade e Colaboração skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que 引用文献速览(citation-digest) faz?

输入一篇论文,输出「谁引用了它 + 每篇在解决什么问题 + 按类别分组」,落成 markdown 或 Notion 页面。

流水线四步,脚本已经封装好,不要重新发明:

s2_citations.py  →  citations.json   谁引用了它(含被引数/日期/DOI/arXiv)
kimi_q1.py       →  kimi.json        每篇的 Kimi Q1 原文(结构化块)
(你来判断)      →  classify.json    分类结果
build_content.py →  content.json + digest.md
notion_publish.py→  Notion 页面

0. 前置

  • S2 key:优先 $SEMANTIC_SCHOLAR_API_KEY,其次 --key,最后 ~/.env/semantic-scholar。没 key 也能跑,但 429 会很多,脚本会自动重试(8 次 × 12s)。
  • Notion token:~/.notion-token 或 $NOTION_TOKEN;目标页必须先 share 给这个 integration,否则 search 找不到。

1. 抓引用

python3 scripts/s2_citations.py --title "MP-GUI: Modality Perception with MLLMs for GUI Understanding" --out citations.json
# 也可以 --arxiv 2503.14021 / --paper-id 0e931ba8...

脚本内建三条你一定会踩的规则:

  1. 去重:S2 常把同一篇 arXiv 论文返回两条(A Survey on ... 和 A Summary on ...,一条带 ArXiv、一条只有 DOI 10.48550/arXiv.xxxx)。按 arXiv id → DOI → 标题去重,保留被引高的那条。
  2. 超过 20 篇只留两个 top10:--max-total 20 --top 10,保留「被引数 top10」∪「日期 top10」。默认已开,别自己再筛。
  3. 标题匹配:搜索接口取 token 重合度最高的结果;分数 <0.55 会在 stderr 列出候选,让用户确认是不是同一篇。

先看 citations.json 里的 source.citationCount,这是要汇报的「被引数」。

2. 抓 Kimi 总结

python3 scripts/kimi_q1.py --in citations.json --out kimi.json --sleep 10 --resume
  • 走 POST https://papers.cool/arxiv/kimi?paper=<arxiv_id>(就是本机 papers-cool MCP 的底层实现),必须带 User-Agent / Origin / Referer 头,否则被挡。
  • 返回 HTML FAQ,只取 Q1「这篇论文试图解决什么问题?」,按结构转成块:### → heading_3、- → bulleted_list_item、**bold** → 加粗。原文照搬,不压缩、不改写。
  • papers.cool 不止收 arXiv,还有 venue 板块:/venue/<CODE>.<YEAR>,CODE ∈ AAAI/ACL/COLM/COLT/CoRL/CVPR/ECCV/EMNLP/ICCV/ICLR/ICML/IJCAI/INTERSPEECH/IWSLT/MICCAI/MLSYS/NAACL/NDSS/NeurIPS/OSDI/UAI。脚本对没有 arXiv id 的论文会自动走这条兜底:/venue/<CODE>.<YEAR>?show=5000 列表页按 id="title-<pid>" 匹配标题拿到 paper id(形如 49@2026@IJCAI,IJCAI 的序号就是 DOI 尾号),再 POST /venue/kimi?paper=<pid>,返回同样的 FAQ HTML。venue 列表页默认只给 25 条,必须带 ?show=。
  • 两条路都走不通的(IEEE MIPR/AIoTC 这类 papers.cool 没收的会)才进 missing,退回摘要或标题,必须在页面上标注「非 Kimi 总结」——build_content.py/notion_publish.py 已对 source != "kimi" 自动加 ⚠️ 标记,再在 classify.json 的 notes 里写清原因。
  • --sleep 10 比 2 稳;没缓存的论文 Kimi 要现算,单篇可能 60-90s。每篇抓完就写 --out,被中断后加 --resume 续抓。
  • ⚠️ 别用 pkill -f kimi_q1.py:多个 Claude 会话同时跑这个技能时会互相误杀(实测丢过 26 篇已抓好但未落盘的结果)。要在后台跑就先 cp scripts/kimi_q1.py <scratchpad>/pcfetch_<会话号>.py,用独立进程名。

3. 分类(你来做,脚本不做)

写 classify.json:

{
  "categories": [
    {"name": "🧩 场景创新 / 问题创新", "desc": "新任务、新基准、新评测维度,或重新定义了要解决的问题",
     "papers": ["2503.14021", "10.1109/CVPR52734.2025.02766", "Exact Title"]},
    {"name": "🔧 技术改进", "desc": "问题已知,贡献在方法/训练流程/系统/架构",
     "papers": ["..."]},
    {"name": "📚 仅综述", "desc": "不提出新方法或新任务,价值在脉络与开放问题",
     "papers": ["..."]}
  ],
  "notes": {"2504.20464": "该篇 S2 有两条重复记录,已合并"}
}

papers 里写 arXiv id / DOI / 标题都行(精确或包含匹配)。没覆盖到的会自动进「❓ 未分类」,不会静默丢。

判据(用户没另说时用这三条):

  • 场景创新 / 问题创新:提出新任务、新 benchmark、新的评测维度(如「只看终态不够,要看过程」)、或把某现象重新定义成一个问题(如「工具挂了却不用」)。
  • 技术改进:问题已被公认,贡献是方法、训练流程、系统实现、架构。
  • 仅综述:Survey / Review / 立场文章,不提出可实验的新方法。
  • 边界情况(benchmark 到底算问题创新还是单独一类、分析型论文归哪)——先按上面判,然后在回复里把判断理由说一句,别默默归类。

正文标签:普通论文用「试图解决的问题」,综述用「核心洞见」——但既然 Q1 原文照搬,通常不加标签,让原文自己说话。

4. 拼装 + 落盘

python3 scripts/build_content.py --citations citations.json --kimi kimi.json \
    --classify classify.json --out content.json --md digest.md

5. 发 Notion

python3 scripts/notion_publish.py --content content.json --page-title "topic论文阅读"
# 或 --page-id xxx;要覆盖已有内容加 --replace

结构固定为:一个以论文命名的根 toggle → 说明段落 + 三个分类 toggle → 每篇论文一个 toggle(第一行灰色元信息:发表处 · 日期 · 被引 N · arXiv:xxx,可点;下面是 Q1 原文块)。

坑(都是实测踩过的)

症状原因 / 解法
POST /v1/blocks/{id}/children → 400 invalid_request_url这个 integration 只吃 PATCH 追加;notion_publish.py 已经用 PATCH
想「移动」已有 blockNotion 没有 move API,只能重建:读旧 block → 在新父级重建 → 删旧 block
删 block 报 Can't edit block that is archived用 DELETE /v1/blocks/{id}(PATCH {archived:true} 之后就不能再改它)
单个 rich_text 超长每段 ≤2000 字符;seg() 已自动按 1900 切成多段(退回摘要的长英文 abstract 必踩,实测 2063 字符)
PATCH /blocks/{id}/children → 400 ... start_cursor provided is invalidNotion 最终一致性抖动:刚建好的块马上往里追加就可能报这个,写入其实常常已经成功,紧接着 GET children 还可能读到 0 子块。req() 已对这个 400 退避重试;排查时别急着重发整页,先按根 toggle 遍历看实际结构
重发整页前脚本不幂等,直接重跑会多出一个根 toggle。先 DELETE /v1/blocks/<上次的 root toggle id>(日志里的 root toggle: 行),再重跑
一次 append 太多每个请求 ≤100 blocks(脚本按 80 切)
嵌套建不出来单次请求最多两层:toggle 的 children 里再套 toggle 可以,三层以上要分次 append
S2 一直 429正常,退避重试;并行请求会更容易挂,串行 + sleep

收工前自检

  • citations.json.source.citationCount 和实际列出的篇数对得上(<=20 全列;>20 是两榜并集)
  • 每篇都有元信息行(被引数必填),有 arXiv 的有可点链接
  • 没有 Kimi 原文的篇目都标了原因(⚠️ 标记 + notes)
  • Notion 顶层只有一个根 toggle(没有重发留下的重复)
  • 分类条数 + 未分类 = 总篇数
  • Notion 上抽查一个 toggle:标题 → 元信息 → Q1 原文(小标题/列表/粗体都在)

Habilidades Relacionadas