引用文獻速覽(citation-digest)
輸入一篇論文,輸出「誰引用了它 + 每篇在解決什麼問題 + 按類別分組」,落成 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...
腳本內建三條你一定會踩的規則:
- 去重:S2 常把同一篇 arXiv 論文返回兩條(
A Survey on ...和A Summary on ...,一條帶 ArXiv、一條只有 DOI10.48550/arXiv.xxxx)。按 arXiv id → DOI → 標題去重,保留被引高的那條。 - 超過 20 篇只留兩個 top10:
--max-total 20 --top 10,保留「被引數 top10」∪「日期 top10」。預設已開,別自己再篩。 - 標題匹配:搜尋介面取 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 |
| 想「移動」已有 block | Notion 沒有 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 invalid | Notion 最終一致性抖動:剛建好的塊馬上往裡追加就可能報這個,寫入其實常常已經成功,緊接著 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 原文(小標題/列表/粗體都在)