RuijieH/citation-digest

指定論文を入力として、その引用文献リストを取得し、各論文の Papers.cool Kimi 要約(「解決しようとする問題」原文)を抽出、与えられたカテゴリに分類して Markdown または Notion ページとして出力します。ユーザーが「引用」「被引用」「引用文献」「文献ダイジェスト」を求め、テーマ別分類や Notion への書き出しを希望する場合に使用します。

citation-digest とは?

このスキルは、ある論文を引用しているすべての論文を取得し、各引用論文が何を解決しようとしているか(Papers.cool Kimi 要約から「解決しようとする問題」部分だけを原文のまま抽出)を調べ、指定されたカテゴリで分類して Markdown または Notion に出力するためのものです。 Semantic Scholar API を用いて引用文献リストを取得し、被引用数や日付による重複除去・フィルタリングを行います。次に Papers.cool サービスの Kimi 要約から必要な段落だけを抽出し、分類はユーザーがスクリプト外で定義した classify.json に従います。最後に build_content スクリプトで Markdown を生成し、任意で Notion のトグル構造(論文ルート → 分類トグル → 各論文トグル)に発行します。 Claude Code, Cursor, Codex などの AI エージェント環境で動作し、引用文献の系統的な整理と文書化に役立ちます。

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

Installed? Explore more 生産性&コラボレーション skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

引用文献速覽 (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つのルールが組み込まれています。

  1. 重複除去:S2 は同一の arXiv 論文を2 回返すことがよくあります(例:「A Survey on ...」と「A Summary on ...」、片方は ArXiv ID 付き、もう片方は DOI 10.48550/arXiv.xxxx のみ)。arXiv ID → DOI → タイトルの順に重複を除去し、被引用数の高い方を残します。
  2. 20 件を超える場合は上位 10 件のみを2グループ保持:--max-total 20 --top 10 で「被引用数 Top10」と「日付 Top10」の和集合を保持します。デフォルトで有効なので、自分でフィルタリングしないでください。
  3. タイトルマッチング:検索 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 invalidNotion の結果整合性の揺らぎ:作成直後のブロックにすぐ追記しようとすると発生することがありますが、実際には書き込みは成功していることが多いです。直後に 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 原文(小見出し/リスト/太字がすべて保持されている)

関連スキル