paper-corpus-rag について
paper-corpus-ragは、研究者自身の論文ファイルを索引化し、該当箇所を引用して質問に答えるスキルです。BM25検索から始め、概念的な検索や大規模なコレクション向けの意味検索・ハイブリッド検索も案内します。
主な機能
- 01Markdownに変換した論文の索引化
- 02BM25全文検索とチャンク引用
- 03意味検索とハイブリッド検索の案内
- 04論文メタデータとセクション別分割
- 05出典を引用した根拠付き回答
活用シーン
- 01ローカルの論文群から該当箇所を検索
- 02索引化した論文に基づく研究質問への回答
- 03引用を添えて相反する知見を比較
- 04想定箇所を使った検索性能の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill paper-corpus-ragインストール後、Claude Code で/paper-corpus-ragを入力して読み込まれたか確認します。
同梱ファイルscripts/paper_index.py
詳細
研究論文コーパスの RAG
目標は、研究者が検証できる回答です。すべての主張を、特定の論文の特定の箇所までたどれるようにします。ベクトルデータベースの選択よりも、検索品質と引用の徹底が重要です。
ローカルコレクションを構築する前に新しい候補論文を見つけるには、ホスト型の論文検索と箇所の読み取りに firecrawl-research-index を使用します。合法的に入手したコピーがある論文だけを、DOI またはソース ID とともに保存してください。このスキルがインデックス化するのはユーザー自身のファイルです。Firecrawl のホスト型インデックスは、ローカルコーパスのダウンロードではありません。
Tier 0:1分で始める引用可能な全文検索(依存関係なし)
- まず PDF を Markdown に変換します(レイアウトを考慮するコンバーターは、生の PDF テキストより優れています)。
markitdownまたはliteparseスキルを使うか、組み込みのフォールバックとしてpip install pypdfを実行します。 - インデックスを作成して検索します。
python scripts/paper_index.py index papers_md/ --db corpus.sqlite # incremental: re-run after adding papers
python scripts/paper_index.py query "effect of batch size on calibration" --db corpus.sqlite -k 8
python scripts/paper_index.py query '"label smoothing" calibration' --db corpus.sqlite --json --full
各検索結果は file#chunk、セクション見出し、BM25 スコアで構成されます。完全一致には語句を引用符で囲んでください。
遺伝子名、手法名、データセット名などの正確な用語が多い科学分野のテキストでは BM25 が強力なので、埋め込みを追加する前に、まずはこれを使いましょう。
Tier 1:セマンティック検索とハイブリッド検索
「ラベル付きデータを使わない手法」のような概念的なクエリには、密な埋め込みを追加します。ハイブリッドスコアリングを使います。BM25 とベクトルの順位を Reciprocal Rank Fusion(RRF)で統合し、score = Σ 1/(60 + rank) とします。堅牢で、調整も必要ありません。
埋め込みモデルの選択:sentence-transformers の科学分野向けモデル、または性能の高い汎用モデルを使います(このスキルを参照)。論文全体ではなく、チャンクを埋め込みます。モデルを変更すると再埋め込みが必要になるため、インデックスにはモデル名と次元数を保存してください。
pgvector(Postgres)。 すでに Postgres を実行している場合や、SQL フィルター(年、会場、著者)が必要な場合に最適です。
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE chunks (id bigserial PRIMARY KEY, paper_id text, chunk int, section text,
body text, tsv tsvector GENERATED ALWAYS AS (to_tsvector('english', body)) STORED,
embedding vector(768));
CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops);
CREATE INDEX ON chunks USING gin (tsv);
-- hybrid: fetch top-k from each, fuse with RRF in the application
SELECT id FROM chunks ORDER BY embedding <=> $1 LIMIT 50;
SELECT id FROM chunks WHERE tsv @@ websearch_to_tsquery('english', $2)
ORDER BY ts_rank(tsv, websearch_to_tsquery('english', $2)) DESC LIMIT 50;
Chroma / Qdrant / FAISS。 ローカル優先のプロトタイピングには Chroma、本番環境でのフィルタリングとペイロードには Qdrant、大規模なインメモリ処理には FAISS を使います。API については chroma、qdrant-vector-search、faiss スキルを参照してください。各ベクトルのメタデータとして paper_id、chunk、section、year を保持してください。
論文のチャンク分割ルール
- 800~1500 文字、オーバーラップは 10~20%にします。段落の境界で分割し、文の途中では分割しないでください。
- 各チャンクにセクション見出し(「Methods > Training details」など)を含めます。これにより、意味を区別できます。
- 図表のキャプションは、それぞれ独立したチャンクとしてインデックス化します。参考文献リストはメインインデックスから除外します(BM25 の精度を損なうため)。ただし、引用を検索できるよう、別のテーブルには保持してください。
- 論文ごとに書誌メタデータ(DOI、タイトル、著者、年)を保存します。推測せず、DOI から調べてください。
回答プロトコル(根拠の提示)
- 8~20 個のチャンクを取得します。クロスエンコーダーを利用できる場合は、再順位付けします。
- 取得したテキストのみに基づいて回答します。事実を述べる各文に
[file#chunk]の形式で引用を付けます(または、書誌情報と対応付けた後に著者名と年を示します)。 - コーパスに回答が含まれていない場合は、その旨を伝えます。記憶で不足を補わないでください。
- 論文間で見解が異なる場合は、一方を黙って選ぶのではなく、両方を引用して提示します。
- 定量的な主張では、数値を文脈(データセット、指標、分割方法)とともに原文どおりに引用します。
整合性ルール
- 引用ハンドルや引用文を捏造しないでください。引用するすべての
file#chunkは、インデックスの出力に存在していなければなりません。 - 数値を報告する前に、出典箇所と照合してください。
評価
パイプラインを信頼する前に、コーパスから質問→期待される箇所のペアを 20~50 組作成し、検索の recall@k を測定します。論文 QA における「ハルシネーション」の多くは、実際には検索漏れです。チャンク分割、埋め込みモデル、またはコーパスを変更した後は、再評価してください。
関連スキル
research-knowledge-graph(同じコーパスの引用・概念グラフ)、markitdown、liteparse、sentence-transformers、chroma、qdrant-vector-search、faiss、open-notebook、literature-review、firecrawl-research-index。