メインコンテンツへスキップ

8.1.7 高度な RAG アーキテクチャ

学習目標

この節が終わると、あなたは次のことができるようになります。

  • 基本の RAG が複雑な場面でなぜ足りなくなるのかを理解する
  • ルーティング型、多段型、Agentic RAG などのよくあるアーキテクチャを知る
  • 「複数ナレッジベースのルーティング」のおもちゃ例を動かす
  • いつ RAG アーキテクチャをアップグレードすべきか、いつすべきでないかを判断する

一、なぜ基本の RAG にはいずれ限界が来るのか?

基本の RAG は「1回の質問 -> 1回の検索 -> 1回の回答」に向いている

これは多くの FAQ や簡単な QA には十分です。
しかし、問題が複雑になるとボトルネックが出てきます。

たとえば:

  • 複数のナレッジベースをまたぐ必要がある
  • まず規約を確認してから、具体的な製品ドキュメントを調べる必要がある
  • 複数のサブ問題に分解する必要がある

よくある複雑な場面

たとえば、ユーザーがこう聞いたとします。

「この受講者は返金できますか? できないなら、延長の方法はありますか?」

これは実際には、複数の行動を含んでいます。

  1. 返金ポリシーを確認する
  2. 現在の条件が満たされているか判断する
  3. さらに延長方法を確認する

このとき、「1回だけ検索する」では足りないことが多いです。

高度な RAG アーキテクチャの選択図

この図のポイントはとてもシンプルです。いきなり一番複雑な構成にするのではなく、本当に失敗している部分を最小の構成で直すことです。


二、ルーティング型 RAG:まず、どこを調べるかを決める

1つのナレッジベースで足りないなら、まずルーティングする

多くのシステムには、1つの文書庫だけでなく、次のようなものがあります。

  • ポリシー庫
  • 製品庫
  • 技術ドキュメント庫
  • FAQ 庫

すべての問い合わせを同じ庫に入れると、ノイズが大きくなります。
このとき、よりよい方法は次のとおりです。

まず問題がどの庫に属するかを判断してから、検索する。

複数の庫を使う、実行可能なルーティング例

policy_docs = [
"返金ポリシー:コース購入後 7 日以内なら返金申請できます。",
"証明書ポリシー:テスト合格後に証明書を取得できます。"
]

tech_docs = [
"ログイン失敗時は、まずアカウントとパスワード、ネットワーク接続を確認してください。",
"API 呼び出しで 401 エラーが出る場合は、通常、認証失敗を意味します。"
]

def route_query(query):
query_lower = query.lower()
if "返金" in query_lower or "証明書" in query_lower:
return "policy"
if "ログイン" in query_lower or "api" in query_lower or "401" in query_lower:
return "tech"
return "default"

def retrieve_simple(query, docs):
query_lower = query.lower()
keywords = []

if "返金" in query_lower:
keywords.extend(["返金", "返金ポリシー"])
if "証明書" in query_lower:
keywords.extend(["証明書", "証明書ポリシー"])
if "ログイン" in query_lower or "401" in query_lower or "api" in query_lower:
keywords.extend(["ログイン", "401", "api"])
if not keywords:
keywords = query_lower.split()

return [doc for doc in docs if any(keyword in doc.lower() for keyword in keywords)]

queries = ["どうやって返金しますか", "401 エラーはどう対処しますか"]

for q in queries:
route = route_query(q)
if route == "policy":
hits = retrieve_simple(q, policy_docs)
elif route == "tech":
hits = retrieve_simple(q, tech_docs)
else:
hits = []
print(q, "-> ルーティング先", route, "->", hits)

期待される出力:

どうやって返金しますか -> ルーティング先 policy -> ['返金ポリシー:コース購入後 7 日以内なら返金申請できます。']
401 エラーはどう対処しますか -> ルーティング先 tech -> ['API 呼び出しで 401 エラーが出る場合は、通常、認証失敗を意味します。']

これは、最もシンプルな「Router RAG」です。 Router RAG は、それだけで検索が賢くなる魔法ではありません。先に検索範囲を狭め、retriever が余計な資料と戦わなくてよい状態を作るのが価値です。


三、多段 RAG:問題を複数のステップに分ける

1回で答えきれない問題もある

たとえば、次のような質問です。

「この人はどんな条件を満たしていて、証明書取得まであと何が必要ですか?」

この種の問題では、たいてい次のことが必要です。

  1. 証明書のルールを確認する
  2. ユーザーの達成状況を確認する
  3. その後で比較する

多段 RAG は「問題を解く」感覚に近い

資料を一気に全部探すのではなく、

  • まず最初のサブ問題を解く
  • その中間結果を使って、さらに検索する

という流れです。

これは Agent の考え方にかなり近いです。


四、Agentic RAG:検索を固定の流れにしない

普通の RAG と何が違うのか?

普通の RAG は、固定された流れに近いです。

  1. 検索する
  2. コンテキストを組み立てる
  3. 回答する

それに対して、Agentic RAG は次のように動くことがあります。

  1. 検索が必要か判断する
  2. 何回検索するか決める
  3. クエリを書き換えるか、データソースを切り替えるか決める
  4. さらに行動を続けるか判断する

メリットとコスト

メリット:

  • より柔軟
  • 複雑なタスクを扱いやすい

コスト:

  • デバッグが難しい
  • 遅くなりやすい
  • コストが高い

なので、すべての RAG を Agent 化すべきではありません。


五、構造化検索:すべての知識をプレーンテキストに入れるべきではない

データ自体に構造があるとき

たとえば:

  • 注文テーブル
  • ユーザー状態
  • チケットシステム
  • 成績表

このようなデータは、多くの場合、次の方法のほうが向いています。

  • SQL クエリ
  • API クエリ
  • グラフデータベース

むりにプレーンテキストへ変換してから検索するより適しています。

よくあるアップグレードの考え方

実際のシステムでは、次のものを組み合わせることがよくあります。

  • 非構造化文書の RAG
  • 構造化データベース検索
  • ツール呼び出し

これが、「高度な RAG」が Agent と結びつきやすい理由です。


六、Graph RAG とナレッジグラフ的な考え方

何を解決するのか?

知識同士に明確な関係があるとき、純テキストのチャンク分割だけでは不十分なことがあります。

たとえば:

  • 人物関係
  • 会社の組織構造
  • 製品の依存関係

このとき、グラフ構造のほうが「ノード同士のつながり」を表しやすいです。

どんなときに検討する価値があるか?

次のような質問が多いなら、グラフ型の検索を検討できます。

  • 複数のエンティティをまたいで移動する
  • 関係の連鎖をたどる
  • 構造化された推論をする

高度な RAG アーキテクチャ選択図

読み方のヒント

まず問題の形からアーキテクチャを選びましょう。複数ナレッジベースの干渉があるならまず Router RAG、複数ステップの問題なら Multi-hop RAG、自律的な判断が必要なら Agentic RAG、関係の連鎖がはっきりしているなら Graph RAG を考えます。


七、いつ高度な RAG にアップグレードすべきか?

アップグレードする価値があるサイン

すでに次のような問題にぶつかっているなら、アーキテクチャのアップグレードを考えてよいです。

  • 複数のナレッジベースが互いに干渉している
  • 1回の検索では足りないことが多い
  • 構造化データとの連携が必要
  • 問題が明らかに複数ステップに分かれている

まだアップグレードしないほうがよいサイン

もし今、基本の RAG すらまだ安定していないなら、

  • chunk が適切でない
  • 評価セットがない
  • top-k の調整もしていない

この状態で、急いで高度なアーキテクチャに進む必要はありません。


八、初心者がよくやる誤解

複雑なタスクを見るとすぐ Agentic RAG にしたくなる

多くの場合、まずルーティングと検索戦略を整えるだけで、大半の問題は解決できます。

「高度」を「コンポーネントが多いほど高度」と考える

コンポーネントが増えても、必ずしもシステムがよくなるわけではありません。
ただ保守が難しくなるだけかもしれません。

評価せずにアーキテクチャをむやみにアップグレードする

評価がなければ、アップグレードが本当に改善なのか、それとも「見た目が複雑になっただけ」なのか分かりません。


まとめ

この節で最も大事なのは、次の考え方です。

高度な RAG は見栄えのためではなく、基本の RAG では複雑な問題をカバーできないときに、システムへより賢い検索の組み立て方を追加するためのものです。

まずはシンプルなアーキテクチャをしっかり磨いてから、アップグレードするかどうかを決める。
これが、より成熟したエンジニアリングの進め方です。


練習

  1. ルーティング例に「コース内容庫」を追加して、route_query() のルールを拡張してみましょう。
  2. 自分のプロジェクトでは、実はどのデータがプレーンテキスト検索より SQL / API クエリに向いているか考えてみましょう。
  3. 多段検索が必須になる質問の例を 1 つ考えてみましょう。