似ているように見えることと、実際に関連していることは別である。
RAGは現在の標準である
2024年現在、RAGは企業がLLMを活用する最も一般的な方法である。
Retrieval-Augmented Generation。 外部文書を検索し、コンテキストに詰め込み、それに基づいてモデルに回答させる。
RAGは機能する。 LLMが訓練されたことのない社内文書を参照できるようにする。 最新情報を反映できるようにする。 ハルシネーションを大幅に減少させる。
RAGがなければ、企業によるLLM導入は遥かに遅れていただろう。 RAGは敬意に値する技術である。
しかしRAGには根本的な限界がある。 これらの限界は、より良いRAGを構築しても解決されない。 RAGそのものの前提に起因するからである。
RAGの仕組み
RAGの核心は三つのステップである。
ステップ1: 文書をチャンクに分割する。 PDF、Wiki、社内文書を固定サイズ(通常200〜500トークン)に分割する。
ステップ2: 各チャンクを埋め込みベクトルに変換する。 数百〜数千次元の実数値ベクトル。 テキストの「意味」をベクトル空間上の一点に写像する。
ステップ3: クエリが来たら、類似ベクトルを検索する。 クエリもベクトルに変換される。 cosine類似度が最も高い上位5〜20チャンクを選択し、コンテキストに挿入する。
シンプルでエレガントである。 そしてここに三つの根本的な問題がある。
問題1: 類似は関連ではない
埋め込み類似度は「二つのテキストが似た文脈で似た単語を使っているか」を測定する。
これは関連性ではない。
例。
クエリ: 「Appleの2024年第3四半期の売上高は?」
チャンク埋め込み検索が返す可能性があるもの:
- 「Appleの2024年第3四半期の売上高は949億ドルであった。」 – 関連あり
- 「Appleの2023年第3四半期の売上高は818億ドルであった。」 – 類似しているが時期が異なる
- 「サムスン電子の2024年第3四半期の売上高は79兆ウォンであった。」 – 類似しているが企業が異なる
- 「アップルパイのカロリーは約296kcalである。」 – キーワードの重複
埋め込み類似度はこの四つを区別できない。 ベクトル空間上では「Apple 売上高」は一つの領域に集まる。 2023年か2024年か、AppleかSamsungか―― ベクトル距離では確実に分離できない。
リランカーを追加すれば改善される。 しかしリランカーも自然言語テキストを読んで判断するため、 根本的な曖昧性の問題は残る。
意味構造ベースの検索は異なる。 「Apple」という個体に固有の識別子があれば、 果物の「apple」と混同されることはない。 「2024年第3四半期」が時間フィールドであれば、 「2023年第3四半期」と機械的に区別される。
類似度を計算する必要がない。 一致するか否か。イエスかノーか。
問題2: チャンクは意味の単位ではない
RAGの最初のステップをもう一度見てほしい。 「文書をチャンクに分割する。」
その「分割」が問題である。
文書を500トークン単位で分割すると、 意味が途中で切断される。 一つの段落が二つのチャンクにまたがる。 論証の前提と結論が分離される。
「李舜臣は鳴梁海戦でわずか12隻で133隻に立ち向かった」がチャンクAに、 「学者たちはこの数字に異論を唱えている」がチャンクBにある。 クエリに対してチャンクAだけが取得されると、 信頼度情報はすでに失われた状態でコンテキストに入る。
チャンクを大きくする? ウィンドウの消費が増える。 チャンクを小さくする? より多くの文脈が切断される。 オーバーラップを追加する? ウィンドウを重複に浪費する。
どう調整しても根本的な問題は同じである。 自然言語テキストをトークン数で分割することは、 意味をトークン数で分割することに等しい。 意味には固有のサイズがあり、 無関係な単位で分割すれば問題が生じる。
構造化表現では、意味の単位が明示的である。 一つの述語構造が一つのエッジである。 エッジは分割されない。 検索はエッジ単位で行われる。 意味の途中で切断されることはない。
問題3: 検索結果の品質が不明である
RAGが5つのチャンクを返した。 この5つをコンテキストに入れる前に、問うべきことがある。
この情報の出典は何か。 基準日はいつか。 確実性はどの程度か。 この5つは互いに矛盾していないか。
自然言語チャンクでは、これらを知ることができない。
出典はチャンク内のどこかに自然言語として記載されているかもしれないし、されていないかもしれない。 時間的参照は文書のどこかにあるかもしれないし、チャンク分割時に失われたかもしれない。 確信度は自然言語に構造的なスロットがないため、ほぼ常に欠如している。 矛盾の確認には5つのチャンクをすべて読み、推論する必要がある。
結局、品質判断をLLMに委ねることになる。 LLM呼び出しコストを削減するためにRAGを使いながら、 RAGの結果を検証するためにLLMを呼び出す。
構造化表現では、出典・時間・確信度はフィールドである。 「出典のない記述を除外する」はクエリ一行で済む。 「2023年以前の情報を除外する」はフィールド比較一つで済む。 「確信度0.5未満を除外する」は数値比較一つで済む。 LLM呼び出しは不要である。
RAGの根本的前提
三つの問題の根源は一つである。
RAGは自然言語を自然言語のまま検索する。
文書は自然言語である。 チャンクは自然言語である。 埋め込みは自然言語の統計的近似である。 検索結果は自然言語である。 コンテキストに入るものは自然言語である。
自然言語の曖昧性がパイプライン全体に浸透する。
曖昧な内容を曖昧なまま検索するから、検索が不正確になる。 曖昧な内容を意味と無関係なサイズで分割するから、文脈が失われる。 曖昧な内容から品質情報を抽出できないから、検証が不可能になる。
RAGを改善する試みのほとんどは、この前提の内側で行われている。
より良い埋め込みモデルを使う。 – 統計的近似がより精緻になるだけである。 より良いチャンキング戦略を使う。 – 分割位置が改善されるだけである。 リランカーを追加する。 – 自然言語をもう一度読むだけである。 ハイブリッド検索を使う。 – キーワードと類似度を混合するだけである。
いずれも効果はある。 いずれも自然言語の枠内にとどまる。 いずれも根本的ではない。
根本的代替策の条件
RAGの限界を超えるには、前提を変えなければならない。 自然言語を自然言語のまま検索するのではなく、 構造化表現を構造的に検索する。
この代替策は三つの条件を満たす必要がある。
類似ではなく一致で検索する。 「似ているもの」を見つけるのではなく、 「一致するもの」を見つける。 識別子が一致するか。時間範囲内か。 イエスかノーか。確率ではない。
意味の単位が検索の単位である。 トークン数で分割するのではなく、 述語構造で保存し、述語構造で検索する。 意味の途中で切断されることはない。
メタデータが構造に組み込まれている。 検索結果の品質を判断するためにLLMを呼び出す必要がない。 出典・時間・確信度がフィールドであるため、 機械的なフィルタリングが可能である。
この三つの条件が満たされると、 検索は「もっともらしい候補を推測する」から 「一致するものを確認する」に変わる。
RAGは過渡期の技術である
これはRAGを貶めるものではない。
RAGは、自然言語しかない世界における最善の解答であった。 文書が自然言語で、知識が自然言語で保存され、 LLMが自然言語を処理するツールであったとき、 自然言語で自然言語を検索するのは当然の選択であった。
そしてRAGは実際に機能する。 RAGありのLLMは、なしのLLMよりも遥かに正確である。 これは事実である。
しかし「自然言語しかない世界」という前提が変われば、 RAGの位置も変わる。
構造化表現が存在すれば、 RAGは「自然言語の入力を受け取り、構造化ストアを検索する」フロントエンドとなる。 自然言語 -> 構造化クエリ -> 構造的検索 -> 構造化結果 -> コンテキスト。
RAGは消えない。 バックエンドが変わるのである。 埋め込み類似度検索から、意味構造ベースの検索へ。
まとめ
RAGはコンテキストエンジニアリングの現在の標準である。 そして三つの根本的な限界がある。
- 類似 ≠ 関連。 埋め込み類似度は関連性を保証しない。「似ている」と「関連している」は異なる。
- チャンク ≠ 意味。 トークン数で分割すれば意味の途中で切断される。前提と結論が分離される。信頼度情報が失われる。
- 品質判断が不可能。 検索されたチャンクの出典・時間・確信度を機械的に判定できない。判断にはLLM呼び出しが必要になる。
三つの問題の根源は一つである。 自然言語を自然言語のまま検索していること。
根本的代替策は前提を変えることである。 類似ではなく一致。 トークンチャンクではなく述語構造。 外部的判断ではなく組み込みメタデータ。
RAGは過渡期の技術である。 自然言語しかない世界における最善の解答であった。 その前提が変われば、RAGのバックエンドが変わる。