検索 top-k / 投入文脈量¶
このダイヤルは何か¶
検索 top-k は、RAG(Retrieval-Augmented Generation)において外部知識ストアから取得する文書チャンクの件数を制御するパラメータです。広義には「LLM のコンテキストウィンドウに投入する外部情報の量」を意味し、top-k の値だけでなくリランク後の絞り込み、チャンクサイズ、投入枠の窓占有率を含む概念です。
AI エージェントシステムでは、コンテキストウィンドウという有限の資源を複数の用途(システム指示、検索結果、会話履歴、長期メモリ、ツール出力)で奪い合います。検索結果を多く入れれば根拠は増えますが、他の情報が押し出されます。少なければ根拠不足でハルシネーションが増えます。この「情報量のちょうどよい中点」を探すのが本ダイヤルの目的です。
さらに、件数だけでなく「何を上位に置くか」も重要です。初期検索(ベクトル検索やキーワード検索)で広めに候補を取り、リランカーで信号密度の高い順に並べ替えて上位 k 件を投入するパイプラインが標準的です。k の値はこのリランク後の投入件数を指します。
効かなすぎる害 ⇔ 効きすぎる害¶
top-k が小さすぎる場合(効かなすぎ)¶
top-k を 1〜2 件に絞りすぎると、以下の問題が起きます。
- 根拠の欠落:質問に答えるために必要な情報が検索結果に含まれず、LLM が根拠なしに回答を生成します。これはハルシネーションの直接的な原因になります。とくに、回答に複数の文書からの情報統合が必要な場合(「A 社と B 社の比較」など)、1 件では対応できません。
- 検索ノイズへの脆弱性:取得件数が少ないと、1 件のノイズ(無関係な文書)が結果の大半を占め、回答品質が大幅に低下します。k=5 なら 1 件のノイズは 20% ですが、k=2 なら 50% です。
- 再現率の低下:正解文書がベクトル空間で微妙に離れている場合、top-1 や top-2 では拾えません。リコール(再現率)を確保するには、ある程度の幅をもって取得する必要があります。
top-k が大きすぎる場合(効きすぎ)¶
top-k を 20 件以上に増やすと、以下の害があります。
- "Lost in the Middle" 問題:LLM はコンテキストの先頭と末尾に注意を集中させる傾向があり、中盤に配置された情報は実質的に無視される可能性があります。大量の文書を投入すると、最も重要な情報が中盤に埋もれてしまいます。
- コストの直線的増加:トークン課金モデルでは、投入トークン数がそのままコストに直結します。k を 5 から 20 に増やせば検索結果部分のトークンは概ね 4 倍になります。精度の向上がコスト増に見合わないケースが多いです。
- ノイズの混入:k を増やすほど、関連性の低い文書が混入する確率が上がります。無関係な情報がコンテキストに含まれると、LLM がその情報に引きずられて不正確な回答を生成するリスクがあります。
- 他の情報枠の圧迫:D2 Context Budget Allocator の観点では、検索結果がコンテキストウィンドウの大部分を占めると、システム指示・会話履歴・長期メモリの枠が縮小し、エージェントの振る舞いが劣化します。
決め方¶
top-k の設定は主に [cost_sensitivity] と回答品質のバランスで決まります。
[cost_sensitivity]:コスト感度が高いほど top-k を絞ります。ただし最低限の根拠は確保する必要があるため、k=3 を下回ることは稀です。[failure_cost]:失敗コストが高い領域では、根拠の網羅性が重要になります。k を多めにとり、リランクで品質を担保する戦略が有効です。ただし、多く取れば良いわけではなく、リランク後のスコアが閾値を下回る文書は切り捨てるべきです。[accountability]:説明責任が求められる場合、回答の根拠として引用できる文書を十分に取得する必要があります。k を増やすよりも、リランクスコアの高い少数の文書を確実に含め、出典を明示する方が効果的です。
以下の判定フローが実践的です。
- 初期検索では広めに取得する(概ね k=20〜50)
- リランカーで関連性スコア順に並べ替える
- スコアが閾値を超える文書のうち、上位 k 件を投入する
- 投入後のトークン数がコンテキストウィンドウの 50% を超えないようにする
- 超える場合は圧縮(要約)またはさらなる絞り込みを行う
目安値(出発点)¶
| 設定項目 | 目安 | 補足 |
|---|---|---|
| 初期検索の取得件数 | 20〜50 件 | リランク用の候補プール。ベクトル検索の上位を広めに取る |
| リランク後の投入件数(top-k) | 3〜8 件 | これが実際に LLM に投入される件数。大半のユースケースで 5 件前後が出発点 |
| 検索枠のウィンドウ占有率 | 20〜40% | コンテキストウィンドウ全体に対する割合。50% を超えたら圧縮を検討 |
| リランクスコアの足切り | モデル依存 | スコアが一定以下の文書は k 件に満たなくても投入しない |
| チャンクサイズ | 200〜500 トークン | 小さすぎると文脈が切れ、大きすぎると不要な情報が混入 |
k の値は「件数の定数」ではなく「リランクスコアが閾値を超えた文書の件数(上限 k 件)」として動的に決めるのが理想です。高関連の文書が 2 件しかなければ 2 件だけ投入し、無理に k 件まで埋めません。
実践的なアドバイス¶
- リランカーを使わずに top-k を増やすのは逆効果です。ベクトル検索の上位 20 件をそのまま投入すると、ノイズが大量に混入します。リランカー(cross-encoder ベースなど)で関連性を再評価し、信号密度の高い文書だけを投入してください。
- チャンクの配置順序に注意してください。最も関連性の高いチャンクをコンテキストの先頭(システム指示の直後)または末尾(ユーザー入力の直前)に配置すると、"Lost in the Middle" の影響を軽減できます。
- k の値を固定せず、クエリの複雑さに応じて動的に変えることを検討してください。単純な事実質問(「A 社の設立年は?」)は k=2〜3 で十分ですが、比較・分析質問(「A 社と B 社の戦略の違いは?」)は k=5〜8 が必要です。クエリ分類器で場合分けすると効率的です。
- コンテキストウィンドウの使用率を常にモニタリングしてください。検索結果の投入によって窓の 50〜70% を超えたら、D2 Context Budget Allocator の圧縮トリガーを発動させます。
- 検索結果の品質メトリクスを定期的に計測してください。回答に実際に使われた文書(引用された文書)と投入した文書の比率を追跡し、使われない文書が多ければ k を下げるか、検索パイプラインの改善が必要です。
関連パターン¶
- D2 Context Budget Allocator — コンテキスト予算の配分と検索枠の管理
- D1 Tiered Memory — 長期メモリからの想起と検索結果の協調
- D6 Semantic Cache with No-Cache Zones — 検索結果のキャッシュによるコスト削減
- B7 Model Router & Adaptive Effort — モデル選択と投入文脈量の連動