RAGの回答が悪いとき、最初にモデルやプロンプトを替えると原因を隠すことがあります。文書が索引へ入っていない、利用者の権限フィルタで落ちた、正解が下位に沈んだ、取得できたのにモデルへ渡らなかった、根拠を渡した後に生成が誤った、という経路を同じ問い合わせIDで追います。本稿の成果物は、症状から調査順を決める「RAG障害切り分け票」です。
RAGの症状を再現できるログをそろえる
切り分けの開始点は、利用者が見た回答ではなく、一連の処理記録です。Lewisらの原著論文が示したRAGは、外部記憶を検索する部分と、その取得結果を条件に文章を生成する部分を組み合わせます[1]。この二段階を分離して記録しなければ、「検索できなかった」のか「検索できたが使わなかった」のか分かりません。
一件の障害について、発生時の質問、会話履歴、利用者の部門・権限、検索対象、コーパス版、インデックス更新時刻、検索式、フィルタ、上位件数、取得チャンクIDと順位、再順位付け後の値、モデルへ渡した文脈、生成モデル識別子、指示文の版、回答と引用、各工程の所要時間を集めます。個人名や入力本文を調査環境へ持ち出す場合は、社内ルールに沿って匿名化し、元の権限条件だけは再現できる識別子へ置き換えます。
Microsoft Foundryの現行RAG説明は、取得、拡張、生成の三工程を示し、品質がコンテンツ準備、検索設定、指示文に依存すると説明しています。また、取得内容が不十分なら、根拠付きの構成でも不完全・不正確な回答になり得ると明記しています[2]。したがって、最終回答だけを保存する運用では調査情報が足りません。
再現に必要な最小ログ
trace_id: rag-incident-7f31occurred_at: 2026-07-30T09:15:42+09:00user_role: sales_contract_viewercorpus_snapshot: policy-2026-07-15index_build: idx-2026-07-15T23:10query_text_hash: sha256:...retrieval: lexical+vector / top_k=8 / filter=department:salesretrieved_chunks: [doc-18#c07 rank=1, doc-42#c03 rank=2]context_sent: [doc-18#c07]generator: model_alias + snapshot_or_effective_versionprompt_version: answer-policy-v12output_citations: [doc-18#c07]latency_ms: retrieval=180, generation=1420, total=1710
再現時は本番データへ書き込まない隔離環境を使い、コーパスと設定を固定します。固定した入力を3回実行し、失敗する層が毎回一致するかを確認します。3回とも正解文書が検索外なら検索系の再現性が高く、検索順位は安定しているのに回答だけ変わるなら生成系の非決定性を疑います。再現しない場合は「解消」とせず、発生時刻のインデックス、キャッシュ、依存API、権限変更履歴を先に比較します。
検索結果が0件または不足する原因を調べる
0件のときは、質問文を工夫する前に、正解文書が検索可能な状態かを確認します。原本の存在、取込ジョブの成功、文字抽出、言語判定、チャンク生成、埋め込み作成、索引投入、公開状態、権限フィルタの順で追います。文書一覧APIには存在しても、抽出文字数が0、埋め込み作成が失敗、索引の別名が旧版を向いている、といった途中欠落があります。
検索基盤へ直接、正解文書IDを指定して取得できるか試します。ID指定でも見つからなければデータ取込または権限層です。ID指定では取得でき、文書固有の製品番号でも見つからないなら、解析器、フィールド設定、検索対象列を確認します。製品番号では見つかるが自然文では出ない場合に、初めて埋め込み、同義語、クエリ変換を疑います。この順番なら、存在しないチャンクに対してモデル調整を続けずに済みます。
境界をさらに絞るには、正解の`chunk_id`を一件指定し、検索順位付けを通さず生成要求へ直接渡す診断を行います。ID指定取得に失敗すれば、取り込み、索引、認可のいずれかです。直接渡せば正しく答えるのに通常検索では失敗する場合は、クエリ解析、候補生成、融合、再順位付けを調べます。直接渡しても回答が崩れる場合は、生成入力の切り捨て、指示文、出力検証が確認先です。この診断は本番回答を置き換える運用ではなく、検索系と生成系を分ける隔離試験です。三経路の要求ID、コーパス版、入力ハッシュ、回答を一組で保存すると、修正後に同じ境界を再確認できます。
MicrosoftのAzure AI Search向けRAG概要は、大きな文書を独立して照合できる単位へ分け、ベクトル化し、検索側ではキーワードとベクトルを組み合わせる方法や閾値調整を挙げています[4]。ただし、ハイブリッド検索は取込漏れを直しません。検索方式の変更前に、正解文書の全チャンク数、本文文字数、親文書との対応、更新時刻を照合します。
| 確認点 | テスト入力 | 合格条件 | 不合格時の担当 |
|---|---|---|---|
| 原本と正本 | 文書管理ID | 有効版と所有者を特定できる | 文書管理担当 |
| 文字抽出 | 既知の見出しと段落 | 文字化けせず本文へ存在する | 取込・OCR担当 |
| チャンク | 正解箇所の親文書ID | 根拠文と見出しを追跡できる | 前処理担当 |
| 索引 | チャンクIDの完全一致 | 使用中の索引から取得できる | 検索基盤担当 |
| 権限 | 許可ロールと拒否ロール | 前者だけが同じ文書を取得する | 認証・認可担当 |
| 自然文検索 | 実質問と同義表現 | 正解が定義した上位k件へ入る | 検索品質担当 |
複数ソース検索では「結果が返った」と「全ソースが成功した」を分けます。Azure AI Searchのretrieve actionは、2026-04-01が一般提供版で、2026-05-01-previewでは200、206、400、502などを工程別に説明しています。206は一部ソース成功、502は全選択ソース失敗または必須ソース失敗を表すため、200以外ではAPI版、時刻、無害化した要求、応答ヘッダー、相関IDを保存するよう公式文書が案内しています[3]。一部成功を完全成功として生成へ渡す設計では、欠けた根拠をモデルが補う危険があります。
正解文書が検索されても順位が低い原因を調べる
正解チャンクが検索候補には存在するものの、モデルへ渡す上位件数より下にある場合は順位問題です。まずキーワード検索、ベクトル検索、統合後、再順位付け後の4地点で順位を別々に保存します。統合後の結果だけを見ると、どちらの検索方式が正解を拾い、どの段階で下がったのか見えません。
固有の型番、条文番号、略称を含む質問はキーワード検索が強く、言い換えや説明的な質問はベクトル検索が拾いやすい傾向があります。ここでいう傾向は一般的な設計上の仮説であり、自社データで確かめる必要があります。20件の失敗集合を「固有語あり・なし」「一文・複合質問」「日本語・英語混在」に分け、方式別のRecall@kを比較します。
Elasticの公式RRF資料は、異なる検索結果を順位で統合する式を示しています。文書dのRRFスコアは、各検索結果における順位rへ定数kを加え、その逆数を合計します[5]。生のキーワードスコアとベクトル類似度を直接足さずに済む一方、各検索器へ同じ重みを与えるため、重要な方式を強くしたい場合や結果集合がほぼ重ならない場合は別の統合方法も検証します。
RRFの確認用計算
RRF(d) = Σ 1 / (k + rank_i(d))想定例: k=60、文書Aがキーワード2位・ベクトル5位RRF(A) = 1/(60+2) + 1/(60+5) = 0.01613 + 0.01538 = 0.03151
順位が低い原因は、チャンクが長すぎて複数話題を含む、短すぎて見出しを失う、質問と文書で用語が違う、古い版が重複して競合する、メタデータの重みが強すぎる、ベクトル化した版と問い合わせ側のモデルが違う、再順位付け対象件数が少ない、などです。一度に全設定を変えず、正解順位が落ちた地点ごとに仮説を立てます。
top_kを増やして一時的に正解を含めても、不要文書が増えれば生成品質と遅延が悪化します。想定例として、top_k=5でRecall@5が0.78、平均入力6,000トークン、p95応答2.4秒だったものが、top_k=12でRecall@12は0.91、入力13,000トークン、p95応答4.8秒になったとします。検索再現率の増分0.13と、トークン・待ち時間の増加を同じ試験票へ記録し、業務の上限内か判断します。
正しい根拠を取得した後に回答が崩れる箇所を調べる
正解チャンクが上位にあっても回答が誤る場合、次に「モデルへ実際に送ったか」を確認します。検索ログの上位結果と、生成要求に含めたコンテキストは一致しないことがあります。トークン上限で末尾が切れた、重複排除で正解を落とした、引用IDの結合に失敗した、会話履歴が長く根拠を圧迫した、といった中間処理を調べます。
生成要求へ正解箇所が入っているなら、回答を事実主張へ分け、各主張がどのチャンクに支えられるか採点します。主張が根拠と矛盾する場合は忠実性、根拠にはあるが質問された項目を省いた場合は完全性、根拠がない質問へ断定した場合は保留制御の問題です。単なる文体の違いを精度障害へ混ぜないよう、必須要素と禁止要素を先に定義します。
失敗を最小化する再現試験では、同じ正解チャンクだけを固定入力としてモデルへ渡します。これで正答するなら、問題は検索結果の組み合わせ、順序、文脈量にあります。固定根拠でも誤るなら、指示文、出力形式、モデル設定を調べます。指示文だけを修正するときは、検索結果を保存済みのfixtureから読み、検索の揺れを除きます。
| 観測 | 疑う箇所 | 最小試験 | 期待値 |
|---|---|---|---|
| 検索ログには正解、生成入力にはない | 文脈選択・切詰め | 選択前後のチャンクIDを比較 | 除外理由を一件ずつ説明できる |
| 生成入力に正解があり、回答は矛盾 | 忠実性制約 | 正解チャンク単独で3回生成 | 事実主張が根拠と一致する |
| 引用先は正しいが必要事項を省略 | 回答要件 | 必須項目を構造化して出力 | 正解票の全項目を満たす |
| 根拠不足でも回答を断定 | 回答可能性判定 | 答えのない質問だけを投入 | 不足理由と確認先を返す |
| 会話が長い時だけ崩れる | 履歴・文脈予算 | 新規会話と長期会話を比較 | 許容履歴内で合格を維持する |
自動採点を使う場合も、障害分析では人の確認を残します。OpenAIの評価ガイドは、実運用に近い分布、通常・境界・敵対ケースを含むデータ、自動評価と人のラベルの校正を重視しています[6]。採点モデルが流暢な長文を好み、短い正答を低く付ける可能性があるため、支持・矛盾・根拠不足の分類と、必須項目の機械照合を組み合わせます。
古い回答と権限違反を同じ「精度低下」にしない
最新版ではない文書を引用する問題は、検索類似度だけでは直りません。原本の改訂、取込ジョブ、索引切替、キャッシュ、検索結果、回答表示の各時刻を並べます。文書の更新時刻から新チャンクが検索可能になるまでを「更新反映時間」とし、想定式は「検索可能時刻−正本公開時刻」です。10時公開、10時18分検索可能なら18分です。
旧版が検索される場合は、有効開始日・失効日をメタデータに持たせ、検索時刻の条件で絞れるか確認します。旧版を監査目的で残す組織では削除が正解とは限りません。利用者の質問が「2025年時点」を求める場合は旧版が必要です。質問の基準日を取得できないなら、現行版を断定せず確認を求める応答へ送ります。
権限問題はさらに優先度が高く、正解率の一項目として平均化しません。許可ユーザー、同じ部門の拒否ユーザー、別部門ユーザー、退職・異動直後のユーザーを使い、同じ質問へ取得文書IDがどう変わるか試します。生成画面に本文が出なくても、検索ログ、引用候補、要約、オートコンプリートへ権限外の名称が出たら漏えいとして扱います。
Azure AI Searchの2026年版RAG概要は、検索時の文書レベル制御、権限メタデータ、フィルタによるセキュリティトリミングをRAGの安全条件として挙げています。検索の上流で許可範囲を絞る考え方であり、取得後にプロンプトで「表示しない」と指示する代替策ではありません[4]。
古い版の取得は鮮度障害、許可されていない版の取得は認可障害です。どちらも回答が不適切に見えますが、修正担当、事故対応、再開承認が異なります。
キャッシュがある場合は、キーに利用者権限、コーパス版、検索設定版が含まれるかを確認します。権限の異なる利用者で同じキャッシュを共有すると、検索基盤が正しくても古い結果や他部門の結果が再利用されます。キャッシュ無効化後だけ直るなら、検索モデル変更ではなくキー設計と失効処理を修正します。
RAG障害切り分け票で原因頻度を集計する
切り分け票は、一件の症状に複数原因を付けず、「最初に期待状態から外れた工程」を主原因とします。取込漏れのため検索0件となり、結果としてモデルが推測した場合、主原因は取込、二次影響は根拠なし回答です。主原因を統一すると、どの工程へ改善工数を配るか決めやすくなります。
| 症状 | 最初に見る証拠 | 主原因候補 | 再試験の合格条件 |
|---|---|---|---|
| 結果0件 | 正解チャンクIDの直接取得 | 取込、索引、フィルタ、権限 | 許可ロールで正解が上位k件へ入る |
| 関連文書はあるが正解が下位 | 方式別・統合前後の順位 | 用語差、分割、重み、再順位付け | 対照集合を悪化させず順位が改善する |
| 検索正解、生成入力で欠落 | 文脈選択前後のID | 重複排除、トークン予算、結合 | 必須チャンクが生成要求へ残る |
| 根拠あり、回答が矛盾 | 主張と根拠の対応表 | 指示文、文脈順序、生成設定 | 重大主張の支持率100% |
| 旧版を引用 | 正本公開から索引反映までの時刻 | 更新ジョブ、失効条件、キャッシュ | 鮮度SLA内に現行版へ切り替わる |
| 権限外情報を取得 | 利用者ロールと取得文書ID | 認可、フィルタ、キャッシュ分離 | 拒否ロールで本文・名称とも0件 |
原因頻度は「主原因の件数÷切り分け完了件数×100」で求めます。想定例として40件を分析し、取込8件、順位12件、文脈選択6件、生成9件、鮮度4件、認可1件なら、順位問題は12÷40×100=30%です。この数字は実績ではなく集計方法の例です。未確定案件は分母へ入れず、別欄で未確定率を示します。
発生頻度だけで順番を決めると、1件の認可事故が後回しになります。優先度は「影響度1〜5×発生件数×再現率」で補助的に比較します。認可1件が影響度5、3回中3回再現なら5×1×1.0=5、順位12件が影響度2、3回中2回なら2×12×0.667=16.0です。ただし認可と機密漏えいは上位の即時停止規則を適用し、式より先に対応します。
票の末尾には、暫定回避、恒久修正、担当、期限、再試験集合、切り戻し条件を記載します。「プロンプト改善」のような大きい言葉ではなく、「prompt-v12の根拠外断定禁止を構造化し、失敗9件と対照20件で再試験」と書けば、完了条件を第三者が確認できます。
修正後の改善率と回帰率を測る
修正の確認には、障害を起こした失敗集合、以前から合格していた対照集合、境界条件を集めた安全集合の三つを使います。失敗集合だけを回すと過適合を見逃し、全件平均だけを見ると直したい症状が埋もれます。主要な変更は一度に一つとし、コーパス版、質問、権限、モデル、指示文のうち変更対象外を固定します。
再試験で使う式
修正成功率 = 合格へ変わった失敗ケース数 ÷ 修正前の失敗ケース数 × 100回帰率 = 今回不合格になった対照ケース数 ÷ 修正前の対照合格数 × 100再現率 = 同じ症状を再現した実行回数 ÷ 同一条件の実行回数 × 100鮮度違反率 = 反映上限を超えた更新件数 ÷ 更新試験総数 × 100p95増分 = 修正後p95応答時間 − 修正前p95応答時間
想定例では、失敗30件中24件が合格へ変われば修正成功率80%、対照60件中3件が新たに失敗すれば回帰率5%です。修正前後のp95が2.6秒から3.9秒なら増分は1.3秒です。精度だけ改善して利用者の待ち時間上限を超えた場合、限定運用に進めるか、検索候補数や再順位付け範囲を再調整します。
再試験は通常入力だけで終えません。空質問、長文、表記揺れ、複数の質問を一度に含む入力、根拠のない質問、改訂日境界、許可・拒否ロール、依存検索のタイムアウトを含めます。同じcase_idで検索、文脈、生成のログを残し、期待した層で安全に止まったかを見ます。
合格後は少量の本番トラフィックで段階確認します。例えば社内利用者の5%に限定し、重大障害0件、修正対象症状の再発率が事前値以下、p95が業務上限内という条件を満たしたら25%へ広げます。条件を外れたら旧設定へ戻し、途中の会話・キャッシュが新旧どちらを参照しているかを確認します。
同じ障害が二回連続で再発した場合は、その場のパラメータ調整を止め、原因仮説を見直します。再現ログが不足している、複数変更が同時に入った、評価データの正解が古い可能性を調査し、証拠を取り直してから再開します。
自動修正を止めて専門担当へ引き継ぐ条件
次の条件では、検索件数や指示文をそのまま調整せず、システム利用を停止または範囲制限します。権限外文書の本文・題名・要約が取得された、機密区分が欠落した、法務・安全・金額・期限の重大主張が根拠と矛盾した、正本を特定できない、ログ欠落で漏えい範囲を追えない場合です。総合精度が高くても例外にしません。
引継ぎ先を迷わない停止表
- 認可・漏えい: 情報セキュリティ、認証認可、文書所有者へ即時連絡し、対象索引とキャッシュを隔離します。
- 正本・保存期間: 文書管理と法務へ渡し、有効版・失効版・削除可否を確定します。
- 継続的な5xx・部分失敗: 基盤運用へ相関ID、依存先、API版、発生時刻を渡し、無制限再試行を止めます。
- モデル入力の機密混入: 利用中のデータ保持条件を確認し、送信先と期間を事故対応票へ記録します。
- 原因不明の重大誤答: 影響範囲を限定し、検索・生成の両担当による共同再現へ切り替えます。
依存APIの429、タイムアウト、一時的な5xxは、読み取り処理に限って回数上限付きで再試行できます。ただし設定不備、認証失敗、権限不足、存在しない文書、入力形式エラーは待っても直らないため再送しません。三回の上限を超えたら障害として記録し、不完全な検索結果で回答を作らないフェイルクローズを選びます。
この手順が向かないのは、創作やブレインストーミングのように唯一の正解文書を定義しない用途です。また、ログ取得が禁止され、質問と取得文書の対応を追えない環境では原因層を特定できません。その場合は本番運用を広げず、匿名化した検証環境または監査可能な構成を先に準備します。
再開には、停止原因の修正、停止ケースの再現不能、同じ権限・版に属する横展開ケースの合格、対照集合の回帰なし、責任者の承認が必要です。引継ぎ票にはtrace_id、コーパス版、利用者ロール、取得ID、生成入力、表示範囲、暫定措置、再試験結果をそろえます。口頭で「直った」と連絡するだけでは再開条件を満たしません。
RAGの精度トラブルへ着手する次の行動
直近の失敗を10件選び、回答画面、検索結果、モデルへ渡した文脈をtrace_idで結べるか確認してください。結べない場合は設定変更より先にログを補います。結べる場合は、正解チャンクの直接取得、方式別順位、生成入力への残存、主張と根拠の対応という順で、最初に期待状態から外れた工程へ印を付けます。
10件の主原因を取込、順位、文脈選択、生成、鮮度、認可へ分類し、再現回数と影響度を記録します。変更仮説を一つだけ選び、失敗10件、対照20件、権限・根拠不足を含む安全10件で再試験します。修正成功率、回帰率、p95増分、重大事故件数を同時に確認し、停止条件を満たさない範囲だけで段階展開します。
変更前には切り戻し点も残します。インデックス、埋め込み、検索設定、プロンプトを同じrelease_idへ結び、旧版へ戻した場合に同じ10件を再現できる状態にします。新旧を混ぜた比較は原因の説明力を失うため、試験中に別の取込更新が走った場合はその回を無効として記録します。修正が効かなかったときは追加調整を重ねず、保存した版へ戻して新しい仮説として試験を組み直します。
調査を終える基準は、症状が一度消えたことではありません。原因層と証拠を説明でき、同じ条件で再発せず、以前の正常ケースを壊しておらず、運用担当が監視指標と切り戻し手順を持った状態を完了とします。
参考文献・出典
- Patrick Lewis et al. 原著論文「Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks」NeurIPS 2020(公開年: 2020年、参照日: 2026年7月30日)
- Microsoft公式ドキュメント「Retrieval augmented generation (RAG) and indexes」(最終更新: 2026年5月20日、参照日: 2026年7月30日)
- Microsoft公式ドキュメント「Query a knowledge base using the retrieve action or MCP endpoint」(REST API 2026-04-01一般提供版、2026-05-01-previewの記述を参照。参照日: 2026年7月30日)
- Microsoft公式ドキュメント「Retrieval-augmented generation (RAG) in Azure AI Search」(継続更新ページ、版表記なし。参照日: 2026年7月30日)
- Elastic公式仕様「Reciprocal rank fusion」(継続更新版、RRF retriever仕様。参照日: 2026年7月30日)
- OpenAI公式ドキュメント「Evaluation best practices」(継続更新ページ、版表記なし。2026年7月30日時点の内容を参照)
コメント