クエリ理解と生成——HyDE・Multi-Query・プロンプト設計・引用
レッスン5:クエリ理解と生成——HyDE・Multi-Query・プロンプト設計・引用
このレッスンで学ぶこと
- クエリ理解の役割(ユーザーが投げるクエリと検索に効くクエリの乖離)を把握する
- HyDE(Hypothetical Document Embedding)の狙いと使いどころがわかる
- Multi-Query/Query Expansion/会話履歴付き検索の使い分けができる
- RAG 特化の生成側プロンプト設計(参照情報の指示・出典明示・番号引用)を組み立てられる
- Lost in the Middle 対策としての断片順序と、構造化出力の設計ができる
- 該当情報がないときのフォールバック応答を設計できる
前レッスンでは、ベクトル DB とハイブリッド検索・リランクを扱いました。本レッスンでは、RAG の残る 2 段階「クエリ理解」と「生成」に踏み込みます。「検索の入り口」と「回答の出口」の 2 か所です。ここでの設計が、ユーザー体験に直結します。
クエリ理解の役割——ユーザーが投げるクエリは検索に最適ではない
RAG のスタックの中で、しばしば軽視されがちなのが「クエリ理解」です。ユーザーが自然な日本語で投げるクエリは、ベクトル検索や BM25 検索に最適な形式とは限りません。次のような乖離があります。
- 短すぎる:「有給休暇」のような単語だけでは、意図が絞れない
- 話し言葉:「これって、社員でも使えるやつ?」のような口語表現で、キーワードが埋もれる
- 曖昧語:「あの規程」「先週の会議」のような、文脈依存の指示語
- 省略された文脈:会話の流れで前提が省略されている
- 同じ意味・別表現:「有給」「有休」「年次有給休暇」といった表記の揺れ
クエリ理解の段は、これを「検索に効くクエリ」に変換する役割を担います。同じ検索エンジンを使っていても、クエリを整えるだけで検索精度は大きく変わります。
HyDE——「仮想の回答」を検索クエリにする
HyDE(Hypothetical Document Embedding)は、Luyu Gao らが 2022 年に arXiv:2212.10496 で提唱した技法です。狙いは「ユーザーのクエリを検索するのではなく、LLM が想像した回答文を検索する」ことです。
flowchart LR
Q[ユーザーの<br/>クエリ] --> LLM[LLM で<br/>仮の回答を生成]
LLM --> H[仮想回答文<br/>Hypothetical Doc]
H --> V[埋め込み]
V --> S[ベクトル検索]
S --> R[実際の<br/>関連文書]
例えば「就業規則で、テレワーク中の労働時間の管理はどうなっているか?」というクエリに対して、LLM に「テレワーク中の労働時間管理について、就業規則ではおおむね次のように規定される:…」といった仮想回答文を生成させ、それを埋め込みに変換して検索します。ベクトル空間では「回答」と「回答」の距離が近いため、質問と文書を直接埋め込むよりも、精度が上がる場合があります。
HyDE は特に「短いクエリ」「話し言葉のクエリ」で効きます。一方、コスト(LLM 呼び出し 1 回分の追加)とレイテンシが増えるため、すべてのクエリで無条件に使うのではなく、質問の種類で使い分けます。
Multi-Query——複数のクエリに展開する
Multi-Query は「1 つのユーザークエリから、LLM で複数の言い換えクエリを生成し、それぞれで検索して結果を統合する」手法です。「有給休暇の申請方法」というクエリから「年次有給休暇の申請手続き」「休暇の申請フロー」「有休申請のやり方」といった 3〜5 個の言い換えを作り、それぞれの検索結果を RRF で融合します。
- 強み:単一クエリで取りこぼす表現の揺れを吸収できる
- 弱み:LLM 呼び出しと検索呼び出しがクエリ数だけ増える。レイテンシ・コスト増
Query Expansion——同義語・表記揺れ・略語
Query Expansion は、Multi-Query に近い狙いですが、LLM ではなく事前に用意した同義語辞書・略語辞書・表記揺れテーブルで、クエリを機械的に拡張する手法です。社内 RAG では、社内用語辞書(レッスン 2 で扱ったトークナイズ用の辞書)を、Query Expansion にも活用できます。
- 強み:LLM 呼び出しがなく、レイテンシもコストも小さい
- 弱み:辞書のメンテナンスが必要。文脈依存の言い換えは扱えない
会話履歴付き検索——単一クエリでない場合
チャット UI で RAG を提供する場合、ユーザーは前のやり取りを前提に質問します。「じゃあ、その場合の残業代は?」のようなクエリは、前のターンで「フレックスタイム制」の話をしていて初めて意味を持ちます。
会話履歴を活かす典型的な方法は 2 つです。
- クエリ書き換え(Query Rewriting):直近数ターンの履歴と最新クエリを LLM に渡し、「単独で意味が通るクエリ」に書き換えてから検索する
- 履歴付き埋め込み:直近履歴の要約を含む形で埋め込みを作る
多くの実装では、Query Rewriting の方がシンプルで結果もコントロールしやすいため採用されます。ただし、この LLM 呼び出しも追加のレイテンシ・コストになるため、必要な会話局面でのみ発動する設計が実務的です。
生成側プロンプト設計——RAG 特化のパターン
検索で取り出した文書と、ユーザーのクエリを、生成 LLM に渡します。ここでのプロンプトは、汎用の生成プロンプトとは違い、いくつかの RAG 特化パターンがあります。
パターン 1:参照情報のみに基づいて回答する指示
RAG では「モデルの内部知識」ではなく「渡した参照情報」だけを使わせたいことが多くあります。プロンプトにこの指示を明示するのが原則です。
次の参照情報のみに基づいて、質問に答えてください。参照情報に含まれない事実は、
たとえ一般常識であっても回答に含めないでください。参照情報から答えを構成できない
場合は、「参照情報にはありません」と明記してください。
このタイプの制約を入れないと、モデルが「知っていること」を混ぜて答えてしまい、社内文書とは違う情報が回答に混入します。「参照情報のみに基づく」は、社内 RAG プロンプトの基本形として押さえてください。
パターン 2:出典明示の指示と番号引用
各チャンクに番号を振り、回答の中で「[3][5]」のように出典番号を明示させるパターンです。
参照情報の各項目には [1]、[2] のような番号が付いています。回答の中で、
根拠となった番号を [1] のように必ず示してください。1 つの記述に複数の
根拠がある場合は [1][3] のように併記してください。
社内 RAG では、回答の下部にクリック可能な出典リンクを出すことが多く、この番号引用が UI と直結します。「出典が示せない情報は、回答してはならない」という運用ルールを、プロンプト側から支えます。
パターン 3:該当情報がないときの応答
参照情報の中に答えがない場合の応答形式を、明示的に指定します。
参照情報に該当する記述がない場合は、次のように応答してください:
「参照情報の中に該当する記述はありませんでした。関連する可能性がある文書として、
[1]、[3] などが見つかりましたが、直接の回答は含まれていません」。
こうしないと、LLM は答えを「作って」しまう場合があります(ハルシネーション)。フォールバック応答の形式を先に定めることが、ハルシネーション対策の第一歩です。
パターン 4:断片の順序と Lost in the Middle 対策
Nelson F. Liu らが 2024 年 TACL で発表した「Lost in the Middle: How Language Models Use Long Contexts」(arXiv:2307.03172)は、多くの LLM が「与えたコンテキストの中央部の情報を無視しやすい」現象を報告した論文です。長い参照情報を渡す場合、この現象を意識した設計が必要です。
- 順序:最も関連度が高いチャンクを、コンテキストの先頭または末尾に配置する
- 数:無理に多くの断片を渡さず、10 件以下に絞る(多くの場合 3〜5 件で十分)
- 区切り:チャンク間に明確な区切り(XML タグや
---)を入れる
パターン 5:構造化出力
回答を JSON 形式などで返させると、UI での表示や、後段の処理(採点・集計)に扱いやすくなります。「回答本文」「出典番号のリスト」「信頼度」を JSON で返させるパターンが実務でよく使われます。
{
"answer": "テレワーク中の労働時間は、始業・終業の連絡が必要です。",
"citations": [1, 3],
"confidence": "high"
}
構造化出力は、生成 LLM の Structured Outputs 機能や、プロンプトでの JSON Schema 指定で実現します。回答本文と引用を分離できるため、社内 RAG の UI 設計との相性が良いです。
💡 ポイント RAG 特化の生成側プロンプトは、汎用プロンプトエンジニアリングとは重なる部分もありますが、「参照情報のみ」「出典必須」「該当なしを明示」の 3 点は RAG 固有の原則です。これを外すと、たとえ検索段階の精度が高くても、ユーザー体験は必ず崩れます。
フォールバック応答——「わからない」を上手に返す
RAG の最も難しい設計の 1 つが「わからないときの応答」です。ユーザー体験と信頼を左右する重要ポイントです。
- 完全な該当なし:「参照情報に該当する記述はありませんでした」と明示
- 部分的な該当:「直接の回答は含まれていませんが、関連する文書として [1]、[3] があります」
- 権限で見えない:「関連する文書は存在しますが、閲覧権限がないため、内容を表示できません。担当部署にお問い合わせください」
- 鮮度切れ:「参照した規程には『2024 年 3 月改訂』とあり、最新版でない可能性があります。原本を確認してください」
これらのバリエーションを、プロンプトと後処理の組み合わせで実現します。「間違った答えを流暢に返す」ことより「わからないと言える」ことが、社内 RAG の信頼を築くというのが、実務の現場感覚です。
中核メッセージの再確認
本レッスンで扱った内容を、中核メッセージに戻して整理します。
- RAG の 8 割は LLM の外側で決まる——クエリ理解と生成側プロンプト設計は、モデルの中身に触らずに RAG の品質を上げる代表領域
- 検索の品質が生成の品質の天井を決める——生成側でどんな工夫をしても、検索で取れなかった情報は答えられない。生成側は「取れた情報を最大限、忠実に使う」役に徹する
- 評価データセットのない RAG は「動いているように見える」だけ——生成プロンプトの微調整は、必ず評価で数値化して判断する(次レッスン)
まとめ
- クエリ理解は「ユーザーの言葉」を「検索に効くクエリ」に変換する段
- HyDE は仮想回答文を検索クエリにする手法。短いクエリ・話し言葉に効く
- Multi-Query は複数の言い換えクエリで検索して融合する手法。表現の揺れを吸収
- Query Expansion は辞書ベースの同義語・略語拡張。コストが小さい
- 会話履歴付き検索は、Query Rewriting が実務での定番
- 生成側プロンプトの 5 パターン(参照情報のみ・出典明示・該当なし応答・断片順序・構造化出力)が RAG 特化の骨格
- Lost in the Middle 対策として、順序・数・区切りを意識する
- フォールバック応答は 4 種類(完全なし・部分あり・権限で見えない・鮮度切れ)を設計する
次のレッスンでは、ここまで組み上げた RAG を「数値で評価する」方法を扱います。Recall/MRR/nDCG/Faithfulness/Answer Relevancy と、Ragas・TruLens・DeepEval の実務です。
確認クイズ
このレッスンの内容の理解度をチェックしましょう。