8月21日、Towards Data Scienceが「Three Kinds of RAG Corpus, and What It Costs to Build for the Wrong One」と題した記事を公開した。この記事では、RAGシステムを単一ドキュメントから複数ドキュメントへとスケールさせる際に、コーパスの「形状」を見誤ることで生じる設計ミスとそのコストについて詳しく紹介されている。記事の核心は「コードを書く前に、ビジネスユーザーとの1回の会話でアーキテクチャを決定できる」という3つの質問にある。
「フラットな積み上げ」がスケールで破綻する理由
RAG(Retrieval-Augmented Generation)の実装において、最もよく見られるパターンは「すべてのドキュメントをベクトルストアに突っ込み、質問をembeddingして類似度検索する」というものだ。デモ用の小さなフォルダ上ではそれなりに動く。しかし、エンタープライズ規模の文書棚に対しては機能しない。パラメータの問題ではなく、アーキテクチャの前提が間違っているからだ。
記事が挙げる具体例は、25万件の文書を抱える中規模保険ブローカーだ。ユーザーが「販売業者Xとの流通契約における売り手の義務は何か」と質問したとする。
熟練の担当者なら1分以内に答えられる。「流通契約」に絞り、Xのマスター契約と2つの修正契約を引き出し、該当セクションだけ読む。関係のない請求書や証明書は最初から除外する。
一方、フラットなベクトル検索は「義務(obligation)」という単語を含む30チャンクを返す。別の小売業者の契約、無関係な証明書、2017年の請求書——これらが混在して1つのプロンプトに入り、モデルは「それっぽい回答」を生成するが、実在しないドキュメントの内容を記述している。
この差は精度の問題ではない。担当者はドキュメントを選択してから読む。フラットパイプラインはドキュメントの選択を一切しない。
5つの破綻パターン、どれもチューニングでは解決しない
記事はフラットな積み上げが規模拡大で壊れる5つのパターンを挙げ、「top-kを増やしてもノイズが増えるだけ」「embeddingモデルを変えても失敗の位置が移動するだけ」「チャンクサイズはドキュメント境界の未記録という問題に無関係」と指摘する。
さらに、re-ranker(クロスエンコーダーを用いてembeddingの類似度検索結果を再スコアリングし順位を付け直す手法)も救済策にならないと述べる。re-rankerはembeddingステップが返したリストを並び替えるだけだ。正しいドキュメントがそのリストに入っていなければ、並び替えるものが存在しない。
コーパスの「形状」を見極める3つの質問
記事の核心はここにある。コードを書く前に、ビジネスユーザーとの1回の会話でアーキテクチャを決定できるという主張だ。
Q1:コレクション内の2つのドキュメントが互いを参照しているか?
修正契約がマスター契約を指す、更新契約が前年のポリシーを指す——「はい」なら形状は一意に決まらないが、追加要件が生じる。
Q2:ビジネスユーザーが、全ドキュメントに共通して同じ意味で存在するフィールドを即座に挙げられるか?
「クライアント」「有効日」「保険料番号」——答えが2秒以内に4例出てくれば、それはまだ誰もタイピングしていないデータベースだ。間を置いてから「まあ…フィールドXがあるかもしれないが…」という答えなら「いいえ」として扱う。
Q3:ドキュメントが「1つの案件についての束」として届くか?
整理のために誰かが作ったフォルダではなく、固定のピースセットが期待される束——請求フォルダ、与信審査、医療記録——かどうか。
Q2とQ3の答えによって、3つの形状に分類される。
3つの形状と、間違えた場合のコスト
| 形状 | 特徴 | 必要な準備 | 誤った場合のコスト |
|---|---|---|---|
| 無関係ファイルの山 | フィルタ可能なフィールドなし | ファイル毎のサマリ行+目次による階層検索 | — |
| 同一型の大量コピー | 同一プロセス由来、フィールドが明確 | ベクトルストアではなくインデックステーブル | (下記参照) |
| 案件ごとの束 | 内部は異質、束単位で反復的 | 束を組み立ててから横断的に読む | (下記参照) |
「タイプ済みコーパスを山として扱う」コスト
これがデフォルトの選択だ。何も決断せずにすべてをベクトルストアに入れると、5つの破綻パターンが定刻通りにやってくる。最大の問題はコンピュート費用ではなく、ビジネスユーザーが10秒で手書きできた正しいフィルタ(doc_type = 'distribution agreement' AND client = 'retailer X')を、誰も追跡できない形で間違える点だ。このフィルタ1行で25万件が3件に絞れる。その後にembeddingを計算すればよい。
「山をタイプ済みコーパスとして扱う」コスト
こちらは勤勉さに見える分、発見が遅れる。全ファイルに対して分類パスと抽出パスを実行してカラムを埋める。数ヶ月後、ほとんどのセルが空か、行によって意味が異なるカラムのテーブルができあがる——「日付」がある行では公開日、別の行では有効日、また別の行では審査期限。3つの意味を持つカラムは、カラムがないより悪い。フィルタがそれを信頼するからだ。
「案件ファイルを独立ドキュメントとして扱う」コスト
最も静かな破綻だ。各ピースが個別に回答するので、一見壊れているように見えない。しかし比較が起きない。「契約書は3月1日開始、証明書は4月1日」という矛盾が誰にも検知されない。また、医療報告書が提出されていない場合、ドキュメント単位のシステムは空の結果を返し、それが「情報なし」として読まれる。本当は「必要なピースが存在しない」というシグナルであるにもかかわらず。
5つのPDFで動くベースライン
記事にはNIST公開文書5点(Cybersecurity Framework v1.1、FIPS 199、SP 800-207、AI 100-1、CSWP 29)を使ったコンパニオンノートブックが付属している。1つの質問に対して複数回のモデルコールを実行し、ドキュメントをまたいだ検索結果の違いを表形式で可視化する構成になっている。フラットパイプラインがどのドキュメントで失敗し、どこで正答を返すかを最小構成で確認できる。コードはdoc-intel/notebooks-vol1で公開されている。
詳細はThree Kinds of RAG Corpus, and What It Costs to Build for the Wrong Oneを参照していただきたい。