HEROZ Tech Blog

日本将棋連盟公認「将棋ウォーズ」や、AIを活用したシステム企画・開発を行う、AI企業HEROZの公式テックブログです。

Agentic RAGの前に整えるべきもの:実務RAGの入口を設計する Router RAG

はじめに

前回の記事では、Agentic RAGの有効性について、社内実験と最新研究の両面から検証しました。

その結果、Agentic RAGは確かに強力なアプローチである一方、エンタープライズ検索のようなユースケースでは、必ずしも複雑化に見合う効果が得られるとは限らない、ということが分かりました。

では、なぜ期待したほどの改善が得られないのでしょうか。

この問いをシステム全体で分解していくと、次のような気づきに至ります。

💡 結論

問題は後段(検索・生成)ではなく、
前段(問い合わせ処理)にある

実際の業務システムでは、ユーザは必ずしも検索に適した形で質問してくれるわけではありません。

  • 「こんにちは」
  • 「売上を集計して」
  • 「この機種のエラー原因は?」
  • 「操作方法を教えて」

これらはすべて“質問”ですが、必要な処理はまったく異なります。

しかし従来のRAGでは、これらを十分に区別せず、そのまま検索に流してしまう構造になりがちです。

本記事で扱うのは、機器ごとに分かれたマニュアルや社内ドキュメントを対象とする検索システムです。

このような文書群では、似た説明が複数の機種やカテゴリにまたがって存在するため、単純な検索では別機種の情報が混ざりやすくなります。そのため、機種名やカテゴリーといった分類情報を前提とした設計が重要になります。

前回のAgentic RAG検証から見えてきたこと

前回の記事では、高難度な質問への対応として、Agentic RAGのようなより高度な構成を検証しました。

techblog.heroz.jp

Agentic RAGは柔軟で強力な一方で、

  • 挙動が不安定になりやすい
  • コストやレイテンシが増えやすい

という特徴もあります。

そのため、すべての問い合わせに対していきなりAgenticな構成を適用するよりも、

まずは問い合わせを整理し、適切な処理に振り分ける

という前段の設計の方が重要になります。

実際、複雑な質問に対しては、検索戦略の動的制御やツール利用が有効に働くケースもあります。

一方で、エンタープライズ検索では、すべての質問に対してそのような複雑な処理が必要なわけではありませんでした。 コストやレイテンシが増える一方で、効果が限定的なケースも少なくありませんでした。

そこで後段については、よりシンプルな構成、具体的には ReRanking を中心とした Enhanced RAG に整理しました。

しかし、ここでより重要な問題に気づきます。

そもそも、すべての質問を同じ検索フローに流してよいのか?

実際の入力を見てみると、

  • 雑談
  • 計算依頼
  • 条件不足の質問
  • 単純に答えられる質問
  • 丁寧な検索が必要な質問

が混在しています。

この状態で後段だけを高度化しても、入力が整理されていなければ、期待した効果は出ません。

つまり、Agentic RAGの前に、問い合わせを正しく振り分ける仕組みが必要だった

この気づきから設計したのが、今回の Router RAG です。

実務で起きていた問題

雑談が検索に流れ、事故的な回答が出る

⚠️ 問題: 関係ないチャンクを拾い、“それっぽい誤回答”を生成することがある

単純な挨拶であっても、検索に流してしまうと、偶然ヒットしたチャンクをもとに文脈と無関係な“それっぽい回答”が生成されることがあります。

場合によっては、まったく関係ない業務情報を返してしまうなど、事故に近い挙動になることもあります。

metadata不足による誤検索

マニュアル検索では、似た説明が複数の機種にまたがって存在します。

このとき、機種などの条件が曖昧なまま検索すると、

  • A機種の質問に対してB機種の情報が混ざる

といったことが起きます。

これは単なるノイズではなく、誤情報そのものになります。

検索ではなく計算を求められる

ユーザは普通にこう言います。

  • 「売上を集計して」
  • 「平均を出して」

これは検索ではなく計算です。

RAGに流すと、断片的な情報を組み合わせてもっともらしい答えを返す危険があります。

ユーザは「無駄には待ちたくない」が「間違いは避けたい」

ユーザはできるだけ早く答えがほしい一方で、間違うくらいなら少し待ってもいいという期待も持っています。

つまり、

  • 簡単な質問はすぐ答える
  • 難しい質問は丁寧に扱う

という切り分けが必要になります。

検索に流してはいけない入力が混ざっている

つまり、RAGの問題は検索精度ではなく、 「入力の整理不足」にあると言えます。

Router RAGという考え方

こうした問題に対して導入したのが、Router RAGです。

ここでのポイントは、RAGを改善するのではなく、

「そもそも検索に流すべきか」を先に判断する

という設計に変えたことです。

図1:まず何をすべきかを決めてから、必要な処理に進む

Before / After

Before(従来のRAG)

すべての質問を検索に流してしまう

After(Router RAG)

質問に応じて処理を分離する

この違いは、構造として見るとより分かりやすくなります。

図2:すべて検索に流す構造から、適切に処理を分離する構造へ

PreRetrieveは「判断材料を集める」ためにある

Router RAGでは、質問を受けると最初に少量の検索を行います(top_k=4)。

これは最終回答のための検索ではなく、次に何をすべきかを判断するための材料集めです。

ここで得られたチャンクは、主に次の用途に使われます。

  • 🔍 ナレッジに関係するかの判定
  • ❓ 情報が足りているかの判定
  • ✏️ クエリ書き換えのヒント

つまり、PreRetrieveは「検索の前段」ではなく、Routerのための観測ステップです。

Classifierは「次の動き」を決める

PreRetrieveの結果をもとに、Classifierが次の処理を決めます。

ここで重要なのは、Classifierは回答を作らないことです。 やるのは一つだけで、次にどの経路に進めるかを決めることです。

Classifierの役割:次にどの処理に進むかを決める

  • 挨拶 → 雑談として処理
  • 意味が不足 → 確認質問
  • 集計・計算 → Code Interpreter
  • 条件不足(metadata) → 追加質問
  • すぐ答えられる → 即答
  • それ以外 → 詳細検索

(具体的なプロンプト設計については、本記事では詳細には触れませんが、 事前取得したチャンクやスコアを含めて一度に判断させる形にしています)

metadataとRouter Query Engine

ここで少しだけ、検索の前提となる仕組みを説明します。

今回のシステムでは、文書ごとに

  • 機種名
  • カテゴリー
  • 種類

といった分類情報をLLMで自動付与し、metadataとして保存しています。

検索時には、質問文からこれらの値を推定し、フィルタとして使います。

ここで重要なのが、必須の項目(required metadata)です。

例えば機種が必須の場合:

  • 「エラー原因は?」 → 機種が不明
  • → そのまま検索すると危険
  • → 先に聞き返す

この処理を担当しているのが Router Query Engine です。

fast と slow の分離

今回の設計では、処理を2つに分けています。

fast

  • PreRetrieveの結果を使って即答
  • 低レイテンシ

slow

  • クエリ変換
  • 再検索
  • ReRanking

重要なのは、これは単なる最適化ではなく、

ユーザの期待に合わせた分離

であることです。

  • 簡単な質問 → 待たせない
  • 難しい質問 → 無理に急がない

ノード構成

全体の処理の流れをまとめると、次のようになります。

図3:Router RAGの全体構成

なお、確認質問に対するユーザの応答は、次のターンで会話履歴(history)として再度 Router 側に渡します。Router Query Engine はその履歴を見て、前のターンで不足していた項目が埋まったかを再評価します。

たとえば「どの機種ですか?」という確認質問に対して、次のターンで「A-120です」と返ってきた場合、その応答単体を新しい質問として扱うのではなく、直前の確認質問と合わせて metadata を補完する入力として解釈します。

設計上の知見

実装を進める中で感じたのは、

細かく調整するより、大まかに分けた方が安定する

という点です。

  • fast / slow の境界
  • rewriteの有無
  • rerankの強さ

こういった要素は、個別にチューニングすると全体のバランスが崩れやすくなります。

そのため今回は、

  • 雑談
  • 確認質問
  • 計算
  • 即答
  • 詳細検索

といった大きな分類を先に決める方針にしました。

おわりに

前回のAgentic RAGの検証を通じて見えてきたのは、

後段を強くする前に、前段を整える必要がある

ということでした。つまり、RAGを高度化する前に、

「入力を整える」

ことが重要だった、というのが今回の結論です。

Router RAGは、そのための仕組みです。

雑談は雑談として扱い、計算は計算に回し、条件が足りなければ確認し、必要なときだけ検索する。

こうした分離を行うことで、RAGは単なる検索付き生成から、実務で使えるシステムへと近づきます。