引用文献速覽 (citation-digest)
入力:一篇論文 出力:「誰が引用したか + 各論文が何を解決しようとしているか + カテゴリ別グループ」を Markdown または Notion ページとして出力します。
パイプラインは4ステップで、スクリプトは既に用意されています。新たにスクリプトを書かないでください。
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 キー:優先順位
$SEMANTIC_SCHOLAR_API_KEY、次に--key、最後に~/.env/semantic-scholar。キーがなくても動作しますが、429 エラーが多発します。スクリプトは自動リトライ(8回 × 12秒)します。 - Notion トークン:
~/.notion-tokenまたは$NOTION_TOKEN。対象ページは事前にこのインテグレーションと共有しておく必要があります。そうしないと 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...
スクリプトには、必ず踏むであろう3つのルールが組み込まれています。
- 重複除去:S2 は同一の arXiv 論文を2 回返すことがよくあります(例:「A Survey on ...」と「A Summary on ...」、片方は ArXiv ID 付き、もう片方は DOI
10.48550/arXiv.xxxxのみ)。arXiv ID → DOI → タイトルの順に重複を除去し、被引用数の高い方を残します。 - 20 件を超える場合は上位 10 件のみを2グループ保持:
--max-total 20 --top 10で「被引用数 Top10」と「日付 Top10」の和集合を保持します。デフォルトで有効なので、自分でフィルタリングしないでください。 - タイトルマッチング:検索 API はトークン一致度が最も高い結果を返します。スコアが 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 がその場で計算するため、1 件あたり 60 ~ 90 秒かかる場合があります。各論文の取得が終わるたびに--outに書き出すため、中断後は--resumeで再開できます。- ⚠️
pkill -f kimi_q1.pyは使わないでください:複数の Claude セッションが同時にこのスキルを実行すると、互いに誤ってプロセスを強制終了する可能性があります(実際に、取得済みだが未書き出しの 26 件を失った事例があります)。バックグラウンドで実行する場合は、最初にcp scripts/kimi_q1.py <scratchpad>/pcfetch_<セッションID>.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 に重複レコードが2件あったため、統合済み"}
}
papers には arXiv ID / DOI / タイトル(完全一致または部分一致)を記述します。どのカテゴリにも該当しないものは自動で「❓ 未分類」に振り分けられます。黙って消失することはありません。
判断基準(ユーザーから特に指示がない場合は、次の3つを使用):
- シナリオ革新 / 問題革新:新しいタスク、新しいベンチマーク、新しい評価軸を提案している(例:「最終状態だけでなくプロセスも見るべき」)、またはある現象を問題として再定義している(例:「ツールが壊れているのに使わない」)。
- 技術的改善:問題は既に認識されており、貢献は手法、トレーニングパイプライン、システム実装、アーキテクチャにある。
- サーベイのみ:サーベイ/レビュー/ポジションペーパーであり、実験可能な新しい手法を提案していない。
- 境界例(ベンチマークを問題革新とするか独立したカテゴリとするか、分析論文の分類など)は、まず上記の基準で分類し、その判断理由を回答に一句添えてください。黙って分類しないでください。
本文のラベル:通常の論文には「解決しようとする問題」、サーベイには「核心的洞察」を使用します。ただし 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 を追加
構造は固定です:論文名を付けたルートトグル → 説明段落 + 3 つの分類トグル → 各論文に 1 つのトグル(最初の行は灰色のメタ情報:発表場所 · 日付 · 被引用 N · arXiv:xxx、クリック可能。以下に Q1 原文ブロックが続く)。
よくある落とし穴(実地で踏んだものです)
| 症状 | 原因 / 解決策 |
|---|---|
POST /v1/blocks/{id}/children → 400 invalid_request_url | このインテグレーションは PATCH による追記しか受け付けません。notion_publish.py は既に PATCH を使用しています |
| 既存ブロックを「移動」したい | Notion に move API はありません。再構築するしかありません:古いブロックを読む → 新しい親に再作成 → 古いブロックを削除 |
ブロック削除で Can't edit block that is archived エラー | DELETE /v1/blocks/{id} を使用してください(PATCH {archived:true} した後はそのブロックを変更できなくなります) |
| 1 つの rich_text が長すぎる | 各段落は ≤2000 文字。seg() が自動的に 1900 文字で分割します(長い英語アブストラクトにフォールバックした場合に必ず発生。実測 2063 文字) |
PATCH /blocks/{id}/children → 400 ... start_cursor provided is invalid | Notion の結果整合性の揺らぎ:作成直後のブロックにすぐ追記しようとすると発生することがありますが、実際には書き込みは成功していることが多いです。直後に GET children しても子ブロックが 0 と返ることがあります。req() はこの 400 に対してバックオフ・リトライを行います。調査する際は、いきなりページ全体を再送信せずに、まずルートトグルをたどって実際の構造を確認してください |
| ページ全体を再送信する前に | スクリプトは冪等ではありません。そのまま再実行するとルートトグルが重複します。最初に DELETE /v1/blocks/<前回のルートトグル ID>(ログの root toggle: 行にあります)を実行してから、再実行してください |
| 一度に追加しすぎる | 各リクエストは最大 100 ブロック(スクリプトは 80 で分割) |
| ネストが作成できない | 1 回のリクエストで作成できるのは最大 2 階層まで。トグルの children にさらにトグルを入れることはできますが、3 階層以上は複数回に分けて追加する必要があります |
| S2 が 429 を返し続ける | 正常です。バックオフ・リトライで対処してください。並列リクエストはより簡単に失敗します。直列 + sleep が安全です |
完了前のセルフチェック
-
citations.json.source.citationCountと実際にリストアップされた論文数が一致している(<=20 は全件表示、>20 は2つのランキングの和集合) - 各論文にメタ情報行(被引用数は必須)があり、arXiv がある場合はクリック可能なリンクがある
- Kimi 原文がない論文はすべて理由が明記されている(⚠️ マーク +
notes) - Notion の最上位にはルートトグルが 1 つだけある(再送信による重複がない)
- 各カテゴリの論文数 + 未分類の論文数 = 総論文数
- Notion 上で 1 つトグルを開いて確認:タイトル → メタ情報 → Q1 原文(小見出し/リスト/太字がすべて保持されている)