Flat RAGの限界を突破するデータ階層化の設計思想
連載「階層型RAG完全ガイド」について:
本シリーズは全5回を通じて、特定のフレームワーク(LangChain, LlamaIndex等)に依存せず、本番環境で真に機能する**検索システム設計(Retrieval System Design)**の基礎から応用までを網羅的に解説します。
1. はじめに:RAG本番運用の壁
RAG(Retrieval-Augmented Generation:検索拡張生成)の PoC(概念実証)を行う際、多くのチュートリアルでは次のようなシンプルなパイプラインが紹介されます。
元ドキュメント(PDF / Markdown)
│
▼ 一定サイズで分割(Chunking)
500文字程度のチャンク群
│
▼ ベクトル化(Embedding)
Vector DBに格納
│
▼ ユーザーの質問
類似度検索(Cosine Top-K)
│
▼ プロンプトに注入
LLMが回答を生成
このアプローチは Flat RAG(フラットRAG) と呼ばれ、すべての情報が単一の階層(フラットな平面)に配置されます。
少量の短いドキュメントを用いた検証段階では、これでも十分に動作します。しかし、実際のエンタープライズ環境――数千ページに及ぶ業務マニュアル、契約書、技術仕様書、財務報告書、あるいはトピックが密接に関連する10ページ程度のFAQ集であっても――に適用した途端、回答精度の低下やハルシネーション(幻覚)が頻発します。
その根本原因こそが、「チャンクサイズ・パラドックス(The Chunk Size Paradox)」 です。
例:メモ用紙と百科事典のジレンマ
巨大な図書館で目的の情報を探す場面を想像してみてください。
- 本を1行ずつのメモ用紙に切り刻んだ場合(小さいチャンク): 「納期限は毎月30日」というメモは瞬時に見つかります。しかし、前後の文脈が切り離されているため、それが「法人税」なのか「住民税」なのか、何年度の規定なのかが分からず、結果として誤った回答をしてしまいます。
- 百科事典を1冊まるごと抱えて探す場合(大きいチャンク): 1冊の中に多種多様な税金の話が詰まっているため、ピンポイントな質問に対して索引(ベクトル検索)がどのページを指せばよいか迷い、該当箇所を見落としてしまいます。
Hierarchical RAG(階層型RAG)はこのトレードオフを解消するために生まれました。
検索時は「小さなメモ(Child Chunk)」で素早く正確にヒットさせ、LLMが読むときにはそのメモが含まれる「ページ全体(Parent Chunk)」を展開して渡す、という設計思想です。
2. Flat RAGの仕組みと文脈欠落の根本原因
従来のFlat RAGでは、データは単一のサイズでのみ存在します。
Document ──> [Chunk 1, Chunk 2, Chunk 3,...] ──> Vector Index
│
User Query ──> Query Embedding ─────────────────────────┤
▼
Top-K Chunks
│
▼
LLM
Flat RAGにおける3つの致命的なボトルネック
- 構造境界の破壊(Structure Loss): 文字数やトークン数で機械的にスプリットすると、テーブル(表)の途中で分断されたり、「〜の場合、ただし…」といった条件節が泣き別れになったり、見出し(Heading)と本文が切り離されてしまいます。
- 大域的コンテキストの喪失(Lost Global Context): 本文に「当四半期の売上高は1,200億円(前年同期比 +15%)」と書かれていても、上位の見出しである「西日本支社・リテール事業部」から切り離されると、その数値がどの組織の業績なのかLLMには判定不能になります。
-
コンテキスト汚染と埋もれ現象(Context Noise & Lost in the Middle): 情報不足を恐れて検索件数(
Top-K)を 3 から 10 や 20 に増やすと、プロンプト内に関連度の低い断片的なノイズが大量に混入します。結果としてLLMの注意機構が散漫になり(Lost in the Middle 現象)、APIコストとレイテンシも肥大化します。
3. Hierarchical RAGの基本思想:データの階層化
すべてのデータを均一なサイズに押し込めるのではなく、Hierarchical RAGでは次の一線を明確に引きます。
中核となる設計思想:
「検索のための表現(Search Representation)」 と 「生成・理解のための文脈(Generation Context)」 を完全に分離する。
現実世界のドキュメントは、本来以下のような自然なツリー構造を持っています。
Document(ドキュメント全体 / 規程集)
└── Section(章 / 節)
└── Paragraph(段落)
└── Sentence / Fact(文 / 具体的事実)
検索のフェーズでは最小単位(Sentence / Child Chunk)を用いてクエリとのベクトル類似度をピンポイントで最大化し、LLMへのコンテキスト供給フェーズでは上位階層(Section / Parent Chunk)へと自動的に遡ることで、完全な文脈を復元します。
4. 主要用語の定義(Glossary)
今後のアーキテクチャ理解を円滑にするため、主要な用語を整理します。
| 用語 | 概念と本質 | システム内での役割 | 具体例 |
|---|---|---|---|
| Chunk | ドキュメントから分割されたテキストの基本単位。 | 格納および検索の最小構成要素。 | 契約書内の150トークン程度の段落。 |
| Parent Chunk | 広い文脈を保持する上位のテキストブロック。 | 回答生成時にLLMへ渡すコンテキスト。 | 「第5条:保証および返品特約」全体。 |
| Child Chunk | Parent Chunkをさらに細分化したテキスト。 | ベクトル化し、類似度検索の対象にする。 | 第5条1項「初期不良の返品期限は7日以内とする」。 |
| Retrieval Node | インデックス内に登録される任意のデータポイント。 | 検索アルゴリズムが直接探索する対象。 | 単一の文のベクトル、または要約文のベクトル。 |
| Summary Node | 複数のチャンクやドキュメント群の要約を保持するノード。 | 全体的な傾向や概要を問う質問に対応。 | 2024年度の通期決算概要を200文字でまとめたノード。 |
| Leaf Node | 階層ツリーの最下層(葉)に位置するノード。 | 最も詳細で生のテキストデータを保持。 | 表の各行データや個別の条文。 |
| Root Node | ドキュメント全体の頂点に位置するルートノード。 | ファイル全体の包括的メタデータを保持。 |
Toyota_Prius_Manual.pdf の全体概要と属性。 |
| Metadata | チャンクに付与される構造・属性情報。 | 事前フィルタリング、グループ化、権限制御。 | {"page": 12, "section": "第3章", "year": 2024} |
| Vector Store | ベクトルの近傍探索(ANN)に特化したデータベース。 | セマンティック検索(意味検索)の実行。 | Qdrant, Milvus, pgvector, Chroma, Pinecone |
| Document Store | 元のテキストやParent Chunkを保持するKey-Valueストア。 | ID指定による高速な本文取得。 | Redis, MongoDB, PostgreSQL, Local Disk |
| Retriever | クエリを受け取り関連ノードを抽出するモジュール。 | 検索ロジックの実行主体。 | Dense Retriever, BM25, Hybrid Retriever |
| Reranker | 抽出された候補群の関連度を再スコアリングするモデル。 | ノイズを除去し、最良の候補を上位に再配置。 | Cohere Rerank, BGE-Reranker-Large |
| Query Router | クエリの意図を分析し、適切なインデックスにルーティング。 | 検索パイプラインの分岐制御。 | スペック表の質問 $\rightarrow$ 表インデックスへ振り分け。 |
| Context Builder | LLMに渡す前にテキストを整形・重複排除するビルダー。 | トークン効率の最適化と文脈の結合。 | 同一の第5条に属する3つの子チャンクを1つの親に統合。 |
5. スプリッターとパーサーの分類
データの分割(Chunking)段階で文脈が破壊されると、後段のRerankerや高性能なLLMを用いても復元することはできません。
適切なSplitterの選択 ──> 意味の保たれたChunk ──> 正確なSearch ──> 適切なGeneration
代表的な11種類のスプリッター/パーサーの特徴は以下の通りです。
1. Character Splitter
- メカニズム: 指定した文字数で機械的に切断。
- 評価: 単語や文の途中で切断されるため、本番運用には推奨されません。
2. Recursive Character Splitter
-
メカニズム: 優先順位リスト
["\n\n", "\n", " ", ""]に従って再帰的に分割を試みる。段落 $\rightarrow$ 文 $\rightarrow$ 単語の順に境界を維持。 - 評価: 一般的なテキストドキュメントにおける標準的な選択肢。
3. Sentence Splitter(NLPベース)
- メカニズム: 形態素解析や構文解析(spaCy, NLTK, GiNZA等)を用い、「博士」「東京都」「e.g.」等の表記に惑わされず、正確な文末(句点)を認識して分割。
- 適用先: 法規約約款や医療記録など、一文単位での厳密な検索が必要なケース。
4. Semantic Splitter
- メカニズム: 連続する文同士の埋め込みベクトルを計算し、コサイン類似度の低下(閾値超え)を検出したポイントでトピック境界として分割。
- 適用先: 見出しのない長文記事やインタビュー記事。
5. Markdown Header Splitter
-
メカニズム:
#,##,###などの見出しタグを基準に分割し、見出し階層パスをメタデータ({"header_path": "第1章 > 第2節"})として自動保持。 - 適用先: 社内Wiki(Notion, Confluence)、技術ドキュメント。
6. HTML Header & DOM Parser
-
メカニズム:
<article>,<section>,<div>などのDOMツリー構造に基づいて本文を抽出し、ヘッダー・フッター・ナビゲーション等のノイズを除去。 - 適用先: Webサイトのスクレイピングデータ。
7. Layout-aware PDF Parser
- メカニズム: コンピュータビジョンや構造認識モデル(Docling, Marker, PyMuPDF4LLM, Unstructured等)を用い、2段組レイアウト、ヘッダー/フッター、図表を人間が読む順序通りに抽出。
- 適用先: 財務諸表、有価証券報告書、スキャンPDF。
8. Table Parser
- メカニズム: 表構造をMarkdown Table形式に変換するか、各行に対して列ヘッダーを明示的に付与したテキスト表現にシリアライズ。
- 適用先: 製品価格表、スペックシート。
9. Code Splitter(AST Parser)
- メカニズム: Tree-sitter等の抽象構文木(AST)を利用し、関数(Function)、クラス(Class)のスコープ単位で分割。
- 適用先: コードベースに対するRAG。
10. JSON / XML Parser
-
メカニズム: キーの階層深度やスキーマパス(
user.profile.orders[0])を維持したまま分割。 - 適用先: APIレスポンス、ログデータ、設定ファイル。
11. Speaker-turn Splitter
- メカニズム: 発話者の交代(「オペレーター:」「お客様:」)を検知してターンごとに分割。
- 適用先: コールセンターの通話録、面談記録。
6. ドキュメント種別に応じた分割戦略マトリクス
| ドキュメント種別 | 推奨スプリッター / パーサー | 推奨Parent構成 | 推奨Child構成 |
|---|---|---|---|
| Markdown / Notion | Markdown Header Splitter |
## / ### 単位のセクション |
段落単位(150-200 tokens) |
| 契約書 / 報告書(PDF) | Layout Parser(Docling等) | 条文単位またはページ群 | 1〜3文のセンテンス群 |
| ソースコード | AST Code Splitter | ファイル / クラス単位 | 関数 / メソッド単位 |
| Excel / CSV | Table / Row Serializer | 表全体 + 概要テキスト | ヘッダー付きの各行データ |
| 議事録 / 対話ログ | Speaker-turn + Semantic | アジェンダ・話題セグメント | 2〜4ターンの発話ブロック |
| 法規・社内規程 | Clause Parser(章/条/項) | 条(Article)全体 | 各項・号の個別要件 |
| 学術論文 | Section Splitter | 章(Abstract, Methods等) | 実験結果や議論の各段落 |
| Webページ(HTML) | HTML DOM Parser + Readability |
<article> ブロック |
<p> タグ単位のテキスト |
7. 初期チャンクサイズ設定のガイドライン
万能の数値は存在しませんが、多くの本番プロジェクトで実証された推奨初期設定値は以下の通りです。
┌──────────────────────────────────────────────────────────┐
│ 推奨初期パラメータ(BASELINE CONFIG) │
├──────────────────────────────────────────────────────────┤
│ • Parent Chunk Size : 800 – 1,500 tokens(LLM理解用) │
│ • Child Chunk Size : 150 – 250 tokens(ベクトル検索用) │
│ • Child Overlap : 20 – 40 tokens(文の接続維持) │
│ • Parent Overlap : 100 – 150 tokens │
│ • Top-K Child検索数 : 20 – 40 件 │
│ • 最終Parent採用数 : 3 – 5 件(重複排除後) │
└──────────────────────────────────────────────────────────┘
トークンバジェットの考慮:
LLMのコンテキストウィンドウの40%〜50%は、システムプロンプト、対話履歴、およびLLMの推論領域(CoT/Thinking)のために常に確保しておくことが推奨されます。
8. Hierarchical RAGを支える周辺技術
階層型RAGの性能を最大限に引き出すためには、以下の6つの要素技術との組み合わせが不可欠です。
- Hybrid Search(ハイブリッド検索): ベクトル検索(意味的類似性)とBM25/SPLADE(型番、固有名詞、エラーコードの完全一致)を融合。
- Metadata Filter(事前フィルタリング): 組織ID、作成年、アクセス権限に基づき、探索空間をあらかじめ絞り込み。
- Cross-Encoder Reranker(再ランキング): クエリと候補ドキュメントを直接突き合わせて精密な関連度を算出。
- Context Compression(コンテキスト圧縮): チャンク内の不要な言い回しや重複文を削ぎ落としてプロンプト長を圧縮。
- Query Routing(クエリルーティング): 定量データの質問か全体概要の質問かを判定し、最適な検索先へ誘導。
- Document Routing(ドキュメントルーティング): 全体を網羅的に探す前に、対象となる文書群を特定。
9. 検索アーキテクチャの進化系統樹
今後のシリーズで解説する各パターンの位置付けは以下の通りです。
[Flat RAG] ──────────> 単一サイズで分割。構造が失われやすく文脈が不足。
│
▼
[Parent–Child] ──────> 2階層構造。検索は子(小)、LLMへの供給は親(大)。
│
▼
[Auto-Merging] ──────> N階層ツリー。子チャンクのヒット率が閾値を超えたら親へ自動統合。
│
▼
[Multi-Rep] ─────────> 要約・想定質問・テーブル解説など1つのデータに複数の検索表現を付与。
│
▼
[RAPTOR / Tree] ─────> ボトムアップのクラスタリングと再帰的要約により全域的な把握を実現。
│
▼
[GraphRAG] ──────────> エンティティと関係性をグラフ化し、ドキュメント横断の推論を可能に。
10. Part 1のまとめと次回予告
本章のキーポイント
- エンタープライズRAGにおいて、単一サイズのFlat RAGは構造破壊と文脈不足を引き起こす。
- Hierarchical RAGの本質は**「検索用ノード」と「生成用コンテキスト」の分離**にある。
- 適切なスプリッターとメタデータ設計が、検索システムの成否の5割を決定づける。
👉 次回 階層型RAG完全ガイド:Part 2 - Parent–Child & Auto-Merging では、本番環境で最も費用対効果の高い「Parent–Child」および「Auto-Merging」の詳細なデータ構造、Python実装コード、そして陥りがちな落とし穴について徹底解説します!
参考文献
- Lewis, P., et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (NeurIPS 2020)
- Liu, N. F., et al. (2023). Lost in the Middle: How Language Models Use Long Contexts (TACL 2024)
- Karpukhin, V., et al. (2020). Dense Passage Retrieval for Open-Domain Question Answering (EMNLP 2020)
- LangChain Official Documentation. Text Splitters & Chunking Strategies Guide
- LlamaIndex Official Documentation. Loading & Node Parser Architecture
- Pinecone Research. Chunking Strategies for LLM Applications