RAGを超えて – あなたの文書を理解するシステム

RAG
この記事は約15分で読めます。

本動画は、従来のRAG(Retrieval-Augmented Generation)システムの限界と、それを超えるエージェント型ファイル検索システムの優位性を解説する技術解説である。標準的なRAGは文書をチャンクに分割して埋め込みベクトル化するが、この過程で文脈や文書間の関係性が失われ、クロスリファレンスを追跡できない問題がある。これに対し、エージェント型アプローチは人間が文書を読むように目次を確認し、関連セクションに移動し、参照を追跡する。3段階戦略(全文書の並列スキャン、関連文書の精読、クロスリファレンスのバックトラッキング)により、複数文書にまたがる複雑な質問に対して正確な回答を提供できる。実装はLlamaIndexワークフローとGemini 3 Flashをベースとし、6つのツール(スキャン、プレビュー、パース、テキスト読み取り、grep、glob)を駆使する。従来のRAGより遅く、トークン消費量も多いが、法的文書や技術仕様書のような構造化された文書群において、速度よりも精度が重要な場合に真価を発揮するシステムである。

Beyond RAG - A system that understands your documents
In this video we will look at file search exploration as a potential replacement to RAG. This is built on top of the the...

標準的なRAGパイプラインの問題点

これが皆が教えている標準的なRAGパイプラインです。文書を取得して埋め込みを作成し、ベクトルデータベースに保存します。そして誰かが質問すると、関連するチャンクを取得してLLMに入力します。売り文句はいつも同じです。文書を埋め込んで質問するだけ。魔法のように聞こえますよね。

シンプルなユースケースなら、これは機能します。しかし、ここから面白くなってきます。では、実際の文書をRAGシステムに投げたときに何が起こるか見せましょう。チャンクは文脈を失います。文書を500トークンの断片に分割すると、セクション間の関係性が破壊されます。購入価格について書かれたチャンクは、3ページ後の別紙Bと繋がっていることを知りません。

クロスリファレンスが見えなくなります。埋め込みはこれらのリンクを追跡できません。類似性は関連性と同じではありません。2つのテキストが意味的に類似しているからといって、両方があなたの質問に答えるのに役立つとは限りません。そして推論は行われていません。RAGは表面レベルでのパターンマッチングです。

文書を理解していないのです。似ているものを見つけているだけです。主な原因について話しましょう。購入価格について質問したとき、RAGシステムが実際に見ているものがこれです。チャンク47は購入価格について話していて、そこで途切れます。チャンク48はセクション2.3bに言及していて、そこに方法論が概説されています。

これらのチャンクは文書内で隣り合っていますが、RAGシステムはそれを知りません。実際に必要なのは完全な文脈です。つまり、これは実際には連鎖なのです。文書は構造化されています。階層があります。チャンキングはその構造をすべて破壊します。では、典型的な文書を見てみましょう。フォルダ内に10個の文書があります。

質問すると、そのうち3つか4つから情報が必要になるかもしれませんが、それらは互いに参照し合っています。この行を見てください。別紙Bの条件はスケジュール4.2に従うとあります。これは2つの文書にまたがる1つの文章です。RAGシステムは1つのチャンクを取得します。文章を見つけるかもしれませんが、連鎖を追跡しません。

問題は、これがニッチな問題ではないということです。法的文書、技術仕様書、財務書類、これらはすべて同じように機能します。クロスリファレンスは例外ではなく、標準なのです。チャンクを計算して最善を期待する代わりに、人間が文書をナビゲートするようにAIに実際にナビゲートさせたらどうでしょうか。人がどのように文書を読むか考えてみてください。

人間のような文書ナビゲーション

具体例を挙げましょう。返品ポリシーを探しているとします。何をしますか。最初のページは読みませんよね。目次を見ます。第3章が返品ポリシーとなっています。関連がありそうです。28ページに行って、電化製品をスキャンします。これがインテリジェントな文書検索の仕方です。似たテキストを見つけるのではなく、理解してナビゲートするのです。

同じ質問に対してRAGシステムが返すものはこうです。返品ポリシーに言及しているチャンクが存在して、セクション3.2を参照するよう指示されます。関連テキストは見つけましたが、答えは見つかりませんでした。しかしエージェント型アプローチは実際の答えを見つけ、参照を追跡して延長保証情報を取得し、完全な文脈を提供します。それが違いです。

エージェント型ファイル検索の仕組み

このエージェント型ファイル検索がどのように機能するか見てみましょう。これは皆さんがおそらく見たことのある通常のエージェント型RAGアプローチとは異なります。ユーザークエリから始まるのはRAGと同じですが、事前計算されたチャンクを取得する代わりに、エージェントがすべての文書を並列でスキャンします。すべてを一度に素早くプレビューします。次に、実際に関連性のある文書を決定し、それらすべてのファイルの完全な文脈を読み込む深掘りを行います。

そして重要なのは、別の文書への参照を見つけた場合、戻ってそれも読むということです。これを3段階戦略と呼んでいます。フェーズ1は、すべての文書を並列でプレビューすることです。これは高速です。すべてを読むわけではなく、分類するのに十分なだけ読みます。フェーズ2では、関連性がありそうな文書の完全な内容を読みます。

そしてフェーズ3はバックトラッキングです。文書Aが文書Bを参照していて、以前文書Bをスキップしていたら、戻って読みます。エージェントは質問に基づいて何を読むかを決定します。それがRAGとの主要な違いです。では、根本的な違いをまとめましょう。RAGは事前計算された埋め込みを使用します。これらはインデックス時に固定されます。

質問の言い回しに関わらず、同じチャンクが得られます。エージェント型ファイル検索は動的です。各クエリに適応します。異なる質問は異なる探索パスにつながります。そして意味的類似性ではなく、論理的な接続を追跡します。実用性も重要です。はるかに多くのトークンを使用することになります。RAGが無用だと言っているわけではありません。適切な場所があります。

RAGを使うべきなのは、シンプルな質問応答や大規模コーパスがある場合です。文書が独立していて互いに参照し合っていない場合、そして速度が重要な場合。RAGの方が高速です。エージェント型ファイル検索を使うべきなのは、複雑な複数文書にまたがる推論が必要な場合です。文書が互いに参照し合っている場合、法的文書や技術文書のように構造が重要な場合、そして速度よりも精度が重要な場合です。これらは異なる仕事のための異なるツールです。

エージェント型とRAGの本質的違い

まとめると、RAGは検索器です。似たテキストを見つけます。エージェント型ファイル検索は推論です。文書を理解します。埋め込みは似たテキストを見つけます。エージェントは文書を理解します。そして未来は単なる検索ではなく、探索だと考えています。では、この仕組みの技術的な説明の前に、実践例をお見せしましょう。

実践デモ

エージェント型ファイル検索エクスプローラーが実際にどのように機能するか、簡単なデモをお見せします。フォルダを選択できます。その中には26の異なるファイルがあります。これは私が作成した大規模買収のデモデータです。ファイルは数ページから数十ページまで様々です。これは買収に関するものなので、「買収後の従業員はどうなるのか、定着給付と競業避止義務をカバーして」というような質問をします。

従来のRAGシステムでは、このような複雑な質問には答えられないかもしれません。これは従来の検索ステップと比べて比較的遅くなります。リアルタイムチャットには使えません。より正確な答えが欲しいが、レイテンシに制約されていない場合に非常に役立ちます。第二に、Claude Codeのようなコーディングエージェントが行うアプローチと似た方法を使います。

コード変更を依頼すると、Claude Codeはgrepコマンドと正規表現ベースの検索メカニズムを使用して、ユーザーの質問に最も関連するコードスニペットを探します。これも非常に似たことをします。どの文書を処理するかをインテリジェントに特定します。

すべての文書を一度に読むわけではありません。これが得られた答えです。情報がどこから来ているかをファイル内で引用しているのが分かります。従業員の定着について話しています。従業員は合計何人いたのか。そして給付と株式についてそれぞれ話しています。

競業避止義務についても話していて、最後に参照したすべてのソースをリストアップしています。では、エージェントがどのように考えていたのか、ステップバイステップのプロセスを見てみましょう。まずスキャンフォルダツールを使用しました。技術的な詳細は動画の後半で説明します。これは並列スキャンを使用して、従業員問題との関連性に基づいてフォルダ内のすべての文書を分類します。

その初期評価に基づいて、最も関連性が高いと思われる1つの文書をパースすることにしました。また、他のいくつかの文書を明示的にクロスリファレンスしています。主要従業員定着契約です。これらはフォルダ内の異なる文書です。エージェントが文書を読み、このフォルダ内の他の文書をクロスリファレンスしているかどうかを特定しようとしているのが分かります。

これが重要なイノベーションです。法的文書でも財務文書でも、技術文書の多くで異なる文書へのクロスリファレンスが見られるからです。エージェントはそれらのクロスリファレンスを特定し、その特定の文書を探しに行くだけの賢さを持っています。最初のファイルを読んだ後、クロスリファレンスされている別のファイルを読みに行きます。

他のいくつかのファイルについても同じことをします。ここでは、主要従業員とその定着ボーナスを特定したが、株式報酬の扱いに関する具体的な条件を見つける必要があると言っています。つまりここでバックトラッキングしていて、見るべき別のファイルがあると特定します。

他のいくつかのファイルを見て、それらのファイルの内容を読み、今集めた情報に基づいて、最終的な包括的な解決策を考え出します。従来の埋め込みベースのセマンティック類似性検索システムや、キーワードベースの検索システムでこれと同じプロンプトを使用しても、たとえセマンティック類似性に基づくエージェント型RAGシステムを構築していたとしても、このような多段階プロセスを実行することはできません。

しかしここでは、はるかに包括的な回答が得られます。技術的な詳細を説明する前に、非常に重要なポイントがいくつかあります。エージェント型ファイル検索は従来のRAGシステムと比べてかなり遅くなります。はるかに多くのトークンも使用します。大規模言語モデルに供給されるコンテキストを削減する従来のRAGシステムと比べて、比較的高価になります。

良いニュースは、完全にローカルモデルを実行している場合、この目的のために長いコンテキストのオープンウェイトモデルも使用できることです。しかし要点は、レイテンシが問題でなく、より時間がかかるより正確な回答を待てる場合に、このシステムを使用したいということです。

システムの構築方法

では、このシステムがどのように構築されたか説明しましょう。インストールプロセスは説明しません。GitHubリポジトリへのリンクは動画の説明欄にあります。このシステムをインストールしてローカルで実行するのは非常に簡単です。これはファイル検索エクスプローラーで、LlamaIndexの例をベースに構築されたオープンソースのエージェント型文書検索システムです。

これが正確にどのように構築されているか見せましょう。高レベルアーキテクチャがこれです。ユーザークエリが入ってきてワークフローエンジンに行きます。ワークフローは、意思決定のためにGemini 3 Flashと対話するエージェントを調整します。この場合、エージェントはテキストを返すだけではありません。構造化されたアクションを返します。エージェントが使用できるツールは6つあります。

これらをエージェントの手と考えてください。フォルダをスキャンし、ファイルをプレビューし、文書をパースし、テキストを読み、grepで検索し、globでファイルを見つけることができます。エージェントはこれまでに学んだことに基づいて、どのツールを使用するかを決定します。固定パイプラインではありません。また、ここにインデックス作成ステップは見られません。

コアコンポーネント

コアコンポーネントについて話しましょう。まずワークフローエンジンです。これにLlamaIndexワークフローを使用しています。イベント駆動型です。エージェントがイベントを発行し、ワークフローが反応します。これにより非同期実行、タイムアウト処理、関心事のクリーンな分離が得られます。第二はエージェントです。これはGemini 3 Flashの薄いラッパーです。必要であれば別のモデルに置き換えることができます。

重要な部分は構造化されたJSON出力です。モデルは自由形式のテキストではなくスキーマを返します。第三は文書パーサーです。この場合、docklingを使用しています。オープンソースでローカルで実行されます。パース用のAPIコールはありません。PDF、Word文書、PowerPointなど想像できるものすべてを処理します。すべてがクリーンなマークダウンテキストに変換されます。

個人的には、エージェントが作業できる標準フォーマットが好きです。6つのツールがありますので、それぞれを説明しましょう。これがパイプライン全体の核心です。最初はスキャン文書です。これが最も重要なツールです。フォルダ内のすべての文書を並列でスキャンし、それぞれの簡単なプレビューを返します。

第二はプレビューファイルです。単一文書の素早いプレビューです。約3,000文字、おおよそ最初のページを取得します。スポットチェックに便利です。第三はパースファイルです。完全な文書抽出です。これが深掘りです。すべてが得られます。次にプレーンテキストファイル用の読み取りツールがあり、文書処理が不要な場合はパースファイルより高速です。

それからgrepがあり、ファイル内での正規表現検索で、特定のパターンを探しているときに便利です。最後はglobです。フォルダ内のすべてのPDFを見つけるというようなパターンでファイルを見つけます。エージェントは現在のコンテキストに基づいてどのツールを使用するかを選択します。意思決定こそがインテリジェンスが存在する場所です。スキャンフォルダにズームインしましょう。これが鍵となるコンポーネントだからです。

実装がこれです。フォルダ内のすべての文書を見つけ、それからスレッドプールエグゼキューターを使用してすべてを並列で処理します。デフォルトで4ワーカーです。各文書は約最初の1,500文字の素早いプレビューを取得します。なぜこれが重要なのか。3つの主な理由があります。まず単一のAPIコールです。エージェントがプレビューファイルを10回呼び出す代わりに、スキャンフォルダを1回呼び出してすべてを見ます。

第二に並列IOです。文書パースはIOバウンドです。並列化により実際の速度向上が得られます。順次処理の約4倍速いです。そして第三の理由は情報に基づく意思決定です。エージェントはすべての文書を一度に分類できます。これら3つが関連性があります。これら7つはスキップできます。つまりこれがインテリジェントなフィルタリングステップです。

3段階戦略の実践

これらのツールが実際にどのように使用されるか見せましょう。システムは3段階戦略に従います。フェーズ1は並列スキャンです。エージェントがフォルダに遭遇すると、スキャンフォルダを使用してすべてを一度にプレビューします。素早く広範囲をカバーします。フェーズ2は深掘りです。

これらのプレビューに基づいて、エージェントはどの文書が関連性があるかを特定し、それぞれにパースファイルを呼び出します。このフェーズで完全な内容を読んでいます。最後のフェーズはバックトラックと呼びます。文書が別紙Bを参照していて、エージェントがフェーズ1で別紙Bをスキップしていた場合、戻って読みます。システムプロンプトは参照を監視し、必要に応じてバックトラックするようエージェントに明示的に指示しています。

エージェントの意思決定ループについて話しましょう。各反復で何が起こるのか。エージェントは完全な会話履歴を受け取ります。元の質問、これまでのすべてのツール呼び出し、すべての結果です。それらをGemini 3 Flashに送り、自由形式のテキストではなく構造化されたJSONを返します。そしてJSONにはアクションタイプが含まれています。3つの可能性があります。

1つはツール呼び出しで、このツールをこれらのパラメータで使用することを意味します。次はより深く進むで、このディレクトリにナビゲートすることを意味します。そして停止で、答えがあることを意味します。アクションを実行した後、結果が履歴に追加され、ループします。これはエージェントが停止と言うか、タイムアウトに達するまで続きます。

最適化とクロスリファレンス

重要な最適化の1つは文書キャッシングです。パースファイルが呼び出されたとき、まずキャッシュをチェックします。文書がすでにパースされていた場合、おそらくプレビューまたは以前の質問から、キャッシュされたバージョンを即座に返します。ここでの実装はシンプルです。ファイルパスをパース内容にマッピングする辞書で、一度パースすればどこでも再利用できます。これはバックトラッキングにとって重要です。

エージェントが文書をプレビューして、後で完全な内容が必要になった場合、プレビュー作業が無駄になりません。次に、エージェントはいつバックトラックすべきかをどのように知るのか、そしてクロスリファレンス検出について見ていきます。別紙Aを参照、文書に記載されている通り、セクション4.2を参照などのパターンを監視するようエージェントに指示します。これらはシステムプロンプトに含まれています。

エージェントが参照に遭遇すると、その文書がスキップリストにあったかどうかをチェックします。もしあれば、バックトラックして読みます。参照文書がフォルダスキャンにさえなかった場合、globを使用してそれを見つけるかもしれません。ここがエージェント部分が輝く場所です。エージェントは単純なRAGシステムのようなパターンマッチングではなく、何が必要かについて推論しています。

システムは拡張可能に設計されています。新しいツールを追加したい場合、4つの簡単なステップがあります。fs.pyで関数を定義します。agent.pyのツールディレクトリに追加します。models.pyでツールを更新します。システムプロンプトで文書化します。完了です。LMを交換したい場合、Google Generative AIインポートをAnthropicまたはOpenAIに置き換えます。

generate call関数を更新するだけです。システムの残りは全く変更されません。アーキテクチャはモデル、ツール、LLM、ワークフローが別々の関心事です。これを構築することから得られたいくつかの重要な洞察です。並列スキャンは極めて重要です。スキャンフォルダコールはエージェントに賢い意思決定を行うための完全なコンテキストを提供します。

これがなければ、何十回もラウンドトリップすることになります。第二に、構造化された出力がエラーを防ぎます。LLMが自由形式のテキストではなくスキーマを返すとき、バグのクラス全体を排除できます。正規表現の心配は不要で、パース失敗もありません。そして第三に、バックトラッキングが徹底性を可能にします。クロスリファレンスに基づいてスキップした文書を再訪問できる能力こそが、これを実際の文書で機能させるものです。

コードはオープンソースです。リンクは説明欄にあります。エージェント型システムへのより深い掘り下げをもっと見たい場合は、コメントで教えてください。

コメント

タイトルとURLをコピーしました