RAGの精度が伸び悩む最大の原因が、実は「検索アルゴリズム」でも「埋め込みモデル」でもなく、その手前にある「チャンクの切り方」にあることをご存じでしょうか。
多くの社内RAGシステムは、いまだに「512トークンで均等に分割する」という固定サイズチャンキングに依存しています。この方式は実装が簡単な反面、議事録の発言途中で切られたり、契約書の条項が分断されたりと、文脈を破壊する重大な欠陥を抱えています。結果として、Top-Kで取れる文書は表面上「ヒット」していても、LLMが回答生成に必要な情報の一部しか持っていない——という状況が頻発します。
2026年現在、この問題を根本から解決する「チャンク戦略 2.0」と呼べる新しい手法群が実用フェーズに入っています。本記事では、セマンティックチャンキング、プロポジショナルチャンキング、ドキュメント構造認識分割、ペアレント-チャイルド構造といった主要な技術を、日本語社内文書に適用する観点から実装レベルで整理します。
なぜ「固定サイズ分割」がRAG精度を頭打ちにするのか
固定サイズチャンキングの仕組みと問題点
固定サイズチャンキングは、文書を512トークン(あるいは1024トークン)といった一定の長さで機械的に区切る最も古典的な手法です。LangChainのRecursiveCharacterTextSplitterや、LlamaIndexのSentenceSplitterのデフォルト動作がこれにあたります。
この方式の問題点は、文書の意味的な単位を一切考慮しない点にあります。具体的に何が起きるかを、現場で頻出する3つのドキュメントタイプで見ていきましょう。
「文脈切断問題」の3つの実例
実例1:議事録
「田中部長:来期の予算については、営業部の意見を踏まえて——」というところでチャンクが切れ、次のチャンクが「——3割増で計上することにしました」から始まる、というケースです。検索クエリ「来期予算の方針」に対して前半チャンクがヒットしても、結論部分が抜け落ちているため、LLMは「結論は不明です」としか答えられません。
実例2:契約書
「第8条(解除)」の本文と「第9条(損害賠償)」の本文が同じチャンクに混在し、しかも第9条の途中で次のチャンクに継続する、という状態が起こります。これは法務QAにとって致命的で、「第9条の損害賠償の上限は?」という質問に対して、第8条の文言まで混ざった文脈が返ってしまい、ハルシネーションの温床となります。
実例3:技術仕様書
「3.2.1 認証方式」の説明文とコードサンプル、その下の「3.2.2 トークン管理」が機械的に分断され、コードブロックの途中で切れることもあります。エンジニア向けRAGでこれが起きると、「サンプルコードの後半が消えている」という状態で回答が生成され、実装ミスの原因になります。
固定サイズが「Retrieval精度」を下げるメカニズム
固定サイズチャンキングが精度を下げる理由は、大きく次の3点に整理できます。
- 埋め込みベクトルの「平均化」によるノイズ: 1チャンクに複数のトピックが混在すると、埋め込みベクトルが各トピックの「平均」になり、どのクエリにも中途半端にしかマッチしなくなります。
- Top-K選択でのトピック分散: 関連情報が複数チャンクに分散すると、Top-K(例:K=5)で全部を拾いきれず、必要な文脈の一部が欠落します。
- LLMへのコンテキスト過剰投入: 不足を補うためにチャンクサイズを大きくすると、今度はLLMのコンテキストにノイズが増え、回答精度が下がるというジレンマに陥ります。
これらの問題は、検索アルゴリズム(BM25・Dense・Sparse)をいくらチューニングしても解決しません。チャンクの切り方そのものを変える必要があります。
チャンク戦略 2.0——4つの主要アプローチ
2024年〜2026年にかけて、固定サイズの限界を超える4つの主要アプローチが実用化されました。
| 手法 | 切り方の基準 | 得意な文書タイプ | 実装難易度 |
|---|---|---|---|
| セマンティックチャンキング | 埋め込みベクトルのコサイン類似度で意味境界を検出 | 議事録、論文、ブログ記事 | 中 |
| プロポジショナルチャンキング | 1命題(事実1つ)=1チャンクに分解 | FAQ、マニュアル、規程集 | 高(LLM呼び出しが必要) |
| ドキュメント構造認識分割 | 見出し階層・表・箇条書きを意味単位として保持 | PDF、Word、技術仕様書、契約書 | 中(ライブラリ依存) |
| ペアレント-チャイルド構造 | 小チャンクで検索、大チャンクで生成 | 長文記事、白書、研究レポート | 中 |
以下、それぞれを実装レベルで掘り下げていきます。
セマンティックチャンキング——「意味の切れ目」で分割する
仕組み:埋め込みコサイン類似度による境界検出
セマンティックチャンキングは、文書を一旦センテンス単位(あるいは小さなウィンドウ)に分け、隣接するセンテンス同士の埋め込みベクトルのコサイン類似度を計算します。類似度が大きく落ち込む箇所——つまり話題が切り替わった箇所——をチャンク境界として採用する手法です。
例えば、「来期予算は3割増で計上します。次に、人事評価制度の改定について議論します。」という流れがあった場合、前半と後半で埋め込みベクトルが大きく変化するため、ここに境界が引かれます。固定サイズと違い、議事録の話題が変わるタイミングで自然にチャンクが分かれるわけです。
LangChainでの実装
LangChainではSemanticChunkerクラスとして提供されています。基本的な使い方は以下の通りです。
from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai import OpenAIEmbeddings
text_splitter = SemanticChunker(
OpenAIEmbeddings(),
breakpoint_threshold_type="percentile", # percentile / standard_deviation / interquartile
breakpoint_threshold_amount=95,
)
chunks = text_splitter.create_documents([long_text])
breakpoint_threshold_typeには複数の方式があり、文書の性質によって使い分けます。議事録のように話題転換が明確な文書ではpercentile(上位N%の差が大きい箇所で切る)、論文のように緩やかに話題が遷移する文書ではstandard_deviationが向いています。
LlamaIndexでの実装
LlamaIndexではSemanticSplitterNodeParserとして実装されています。
from llama_index.core.node_parser import SemanticSplitterNodeParser
from llama_index.embeddings.openai import OpenAIEmbedding
splitter = SemanticSplitterNodeParser(
buffer_size=1,
breakpoint_percentile_threshold=95,
embed_model=OpenAIEmbedding(),
)
nodes = splitter.get_nodes_from_documents(documents)
buffer_sizeは、類似度を計算する際に何センテンス分まとめて見るかのパラメータです。短いセンテンスが多い日本語文書では2〜3に設定するとノイズが減ります。
セマンティックチャンキングの限界
万能ではありません。次のような文書では効果が薄い、あるいは逆効果になる場合があります。
- 表形式データ: 各行のセンテンスが似たような構造のため、境界検出が機能しません。
- 箇条書きの羅列: 個々の項目の埋め込みが近すぎて1チャンクに圧縮されすぎることがあります。
- コードブロック: 自然言語の埋め込みモデルではコードの意味境界を捉えられません。
これらは後述の「ドキュメント構造認識分割」と組み合わせるのが定石です。
プロポジショナルチャンキング——「1命題=1チャンク」でノイズを排除する
仕組み:LLMで命題に分解する
プロポジショナルチャンキング(Propositional Chunking)は、2023年末にDense X Retrieval論文で提唱され、2024〜2025年にかけて急速に普及した手法です。文書をLLMに通して、1つの命題(事実)=1チャンクになるように分解します。
例えば、「弊社の有給休暇は入社6ヶ月後に10日付与され、勤続年数に応じて最大20日まで増加します。」という文は、次の3つの命題に分解されます。
- 命題1:弊社の有給休暇は入社6ヶ月後に付与される。
- 命題2:付与時の日数は10日である。
- 命題3:勤続年数に応じて最大20日まで増加する。
これらをそれぞれ独立したチャンクとして埋め込み、検索対象とします。
なぜRetrievalノイズが減るのか
従来のチャンクは「複数の命題+背景説明+関係ない隣接情報」を含む混合体でした。これを命題単位に分解すると、各チャンクの埋め込みベクトルが「その命題のみ」の意味を表すようになり、クエリとの一致精度が劇的に上がります。
「有給休暇の付与日数は?」というクエリに対して、固定サイズなら「就業規則第○章の前後文脈ごと」が返ってきますが、プロポジショナルなら「命題2:付与時の日数は10日である」だけがピンポイントで返ります。
実装上の注意点とコスト
プロポジショナルチャンキングの最大の弱点は、初期インデックス作成時にLLM呼び出しが大量に発生する点です。1万ページの社内文書を分解するには、数千〜数万回のAPI呼び出しが必要になります。
このコストを抑える実務的な工夫として、次の3点が有効です。
- 軽量モデルでの分解: Claude HaikuやGPT-4o-mini、あるいはローカルLLM(Llama 3.1 8B等)で十分な品質が出ます。Opus級は不要です。
- バッチ処理APIの活用: Anthropic Message Batches APIやOpenAI Batch APIを使うと、コストが約50%に圧縮できます。
- 差分インデックス: 全文書を毎回分解せず、更新された文書だけを再分解する仕組みを最初から組み込みます。
また、命題分解のプロンプト設計も重要です。「事実を箇条書きで列挙して」という曖昧な指示ではなく、「文脈なしで読んでも意味が通る独立した命題に分解せよ」と明示することで、後段のRetrievalで使い物になる出力が得られます。
日本語固有の課題と対処
英語で開発されたチャンキング手法を日本語にそのまま適用すると、いくつかの固有問題に直面します。
課題1:文末判定の失敗
英語の文末判定はピリオドベースですが、日本語は「。」「!」「?」に加え、「です/ます」「である」「だ」といった語尾パターンが混在します。NLTKやspaCyのデフォルト設定では、日本語の文を正しく分割できないことがあります。
対処として、GiNZAやsudachi.rs、ja_sentence_segmenterといった日本語特化のセンテンス分割ライブラリを前処理に組み込みます。LangChainのSemanticChunkerに渡す前に、これらでセンテンス分割を済ませておくのが定石です。
課題2:助詞・係り受けによる文脈依存
日本語は「これは」「それについては」のように、前文の指示語に依存した表現が多用されます。1命題に分解する際、指示語の参照先が失われると意味が通らなくなります。
プロポジショナルチャンキングのプロンプトに、「指示語は具体的な対象に置換すること」「それ/これ/彼/同社などの代名詞は元の名詞に展開すること」というルールを明示することで、独立した命題として機能するチャンクが得られます。
課題3:改行のない長文段落
特にWordや古いPDFから抽出した日本語文書には、1段落が数千文字続くケースがあります。これは固定サイズだと中途半端に切られ、セマンティックチャンキングでもセンテンス分割が失敗しがちです。
対処は2段階で、まず形態素解析ベースで強制的にセンテンス候補を生成し、その上でセマンティック境界検出を走らせます。長文段落が多い文書群では、前処理パイプラインに「強制改行ルール」(例:「ます。」「である。」の直後で改行)を組み込んでおくのが現実解です。
ドキュメント構造認識分割——PDFの見出し・表・箇条書きを保持する
UnstructuredとDoclingの位置付け
PDFや複雑なWord文書を扱う場合、テキストを単純に抽出してから分割するのではなく、文書構造そのものを認識して意味単位を保ったまま分割するアプローチが有効です。
このカテゴリの代表的なツールがUnstructuredと、IBM Researchが2024年にリリースしたDoclingです。
| ツール | 特徴 | 適した用途 |
|---|---|---|
| Unstructured | 多様なファイル形式に対応(PDF、HTML、Word、PowerPoint、メール等)。要素ごとにメタデータ付与 | 形式が混在する社内文書一括処理 |
| Docling | PDFのレイアウト解析が高精度。表構造・数式・図表キャプションを認識 | 技術文書、学術論文、レポート |
見出し階層の活用
これらのツールは、PDFやWordから「H1」「H2」「H3」といった見出し階層を抽出します。チャンキング時にこの階層情報を活用すると、次のような工夫が可能になります。
- 見出し境界での強制分割: H2が変わったら必ずチャンクを分ける。
- 見出しパス情報の付与: 各チャンクに「第3章 > 3.2 認証 > 3.2.1 OAuth」というパスをメタデータとして埋め込み、検索時にフィルタや再ランキングに使う。
- 見出し本体の文脈付与: チャンク本文の冒頭に親見出しのテキストを付加してから埋め込みを生成する。
表と箇条書きの扱い
表は分割せず1つの表=1チャンクとして保持するのが基本です。Doclingは表をMarkdown形式で出力できるため、そのままチャンク化することでLLMが表構造を理解した上で回答を生成できます。
箇条書きについても、項目を途中で分断しないのが鉄則です。Unstructuredのchunk_by_title戦略を使うと、見出し直下の箇条書きグループを1単位として扱えます。
Unstructuredの基本実装
from unstructured.partition.pdf import partition_pdf
from unstructured.chunking.title import chunk_by_title
elements = partition_pdf(
filename="contract.pdf",
strategy="hi_res", # OCRと構造解析を行う高精度モード
infer_table_structure=True,
)
chunks = chunk_by_title(
elements,
max_characters=2000,
combine_text_under_n_chars=200,
)
combine_text_under_n_charsを指定することで、見出し直下の短いテキストが孤立しないように親要素と結合されます。契約書のような階層的文書で特に有効です。
ペアレント-チャイルド構造——検索と生成で粒度を変える
「小さく検索、大きく生成」というアイデア
ペアレント-チャイルドチャンキング(Parent-Child Chunking、別名Small-to-Big Retrieval)は、近年のRAG設計でデファクトに近づきつつある手法です。考え方はシンプルで、検索には小さなチャンクを使い、LLMに渡すコンテキストには大きなチャンクを使うというものです。
具体的には次のような構造を作ります。
- チャイルドチャンク(小、200〜400トークン): 埋め込みベクトルを作って検索対象にする。
- ペアレントチャンク(大、1500〜3000トークン): チャイルドが属する上位の文脈。検索ではヒットさせず、ヒットしたチャイルドの「親」として参照される。
クエリに対してチャイルドが上位に来たら、対応するペアレントを取り出してLLMに渡します。検索の精度(小さい単位での意味マッチ)と、生成の質(十分な文脈)を両立できます。
LangChainとLlamaIndexでの実装
LangChainにはParentDocumentRetrieverとして実装されています。
from langchain.retrievers import ParentDocumentRetriever
from langchain.text_splitter import RecursiveCharacterTextSplitter
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=docstore,
child_splitter=child_splitter,
parent_splitter=parent_splitter,
)
retriever.add_documents(documents)
LlamaIndexではHierarchicalNodeParserとAutoMergingRetrieverの組み合わせで同様の機能が提供されています。複数階層(粗い→中間→細かい)を作れる点で、長文書には向いています。
運用上のポイント
ペアレント-チャイルド構造で見落とされがちなポイントが2つあります。
- ペアレントの上限サイズ管理: ペアレントが大きすぎるとLLMコンテキストを食いつぶし、複数ヒット時に入りきらなくなります。3000トークンを上限にし、超える場合は中間階層を挟むのが安全です。
- 重複ペアレントの除去: 複数のチャイルドが同じペアレントを指す場合、ペアレントを重複してLLMに渡さないよう、Retriever層でデデュープロジックを入れます。
チャンク戦略によるFaithfulnessスコアのA/B比較
評価フレームワーク:Ragas Faithfulness
チャンク戦略の効果を定量評価するには、RagasのFaithfulnessスコアが標準的な指標として使われます。Faithfulnessは、LLMが生成した回答が、Retrieverが渡したコンテキストに「忠実か(事実として裏付けられているか)」を0〜1で評価する指標で、ハルシネーション検出に強い相関があります。
典型的な比較結果のパターン
同一の社内文書セットと同一のクエリセットで、チャンク戦略のみを変えた場合、典型的には次のような傾向が観測されます(数値はあくまで一般的な相対比較のレンジで、実環境でのベンチマークが必須です)。
| チャンク戦略 | Faithfulness(相対) | 主な改善要因 |
|---|---|---|
| 固定サイズ(512トークン) | ベースライン(1.00) | — |
| セマンティックチャンキング | 1.10〜1.20 | 話題境界での切断回避 |
| ドキュメント構造認識分割 | 1.15〜1.25 | 表・箇条書きの保持、見出しパス付与 |
| プロポジショナル | 1.20〜1.35 | 命題単位での精密マッチ |
| ペアレント-チャイルド + セマンティック | 1.25〜1.40 | 検索精度と生成文脈の両立 |
重要なのは、これらの数値はあくまで「正しいデータセットで正しく測った場合」の相対比較であり、文書の性質、言語、クエリ分布によって順位が入れ替わることです。必ず自社データでA/Bを取るのが大原則です。
A/B評価の実装手順
Ragasを使った最小限の比較スクリプトは次のようになります。
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision
# 各チャンク戦略で同一のテストセット(質問・期待回答)を生成
result_fixed = evaluate(dataset_fixed, metrics=[faithfulness, answer_relevancy, context_precision])
result_semantic = evaluate(dataset_semantic, metrics=[faithfulness, answer_relevancy, context_precision])
result_parent_child = evaluate(dataset_parent_child, metrics=[faithfulness, answer_relevancy, context_precision])
print(result_fixed, result_semantic, result_parent_child)
評価データセット(質問・期待回答ペア)の品質が結果を大きく左右します。最低でも50問、理想的には200問以上を、業務の実クエリ分布に近い形で準備しましょう。
実務での導入ステップ
「明日からチャンク戦略を変えよう」と思っても、いきなり全文書を再インデックスするのは現実的ではありません。段階的な導入を推奨します。
ステップ1:文書タイプの棚卸し
社内文書を「議事録」「契約書」「技術仕様書」「FAQ」「Wiki」などのタイプに分類し、それぞれに最適な戦略をマッピングします。すべてを同じ戦略で処理する必要はありません。
ステップ2:評価データセットの整備
業務で実際に使われるであろうクエリと、その正解(期待される回答とソース文書)をセットで用意します。これがないと、戦略変更の良し悪しを定量判断できません。
ステップ3:1文書タイプから試験導入
影響範囲を限定し、例えば「議事録だけセマンティックチャンキングに切り替える」といった形で部分導入し、Ragasで効果を測定します。改善が確認できたら次の文書タイプへ展開します。
ステップ4:チャンク戦略の継続的見直し
RAGの精度は、チャンク戦略・埋め込みモデル・検索アルゴリズム・LLMが相互に影響します。1つを変えたら他もチューニングが必要です。CI/CDに評価パイプラインを組み込み、変更のたびに精度を測る運用が理想です。
よくある質問(Q&A)
Q1. 結局、どのチャンク戦略を選べばいい?
文書タイプごとの「合わせ技」が現実解です。PDF中心ならドキュメント構造認識分割(Docling/Unstructured)をベースに、長文セクションにはセマンティックチャンキングを適用、最終的にペアレント-チャイルド構造でラップする、という3段構えが多くの社内RAGで安定した結果を出しています。プロポジショナルはコストが見合うFAQや規程集に限定するのが無難です。
Q2. 既存の固定サイズRAGをすぐに置き換えるべき?
必ずしも「すぐ置き換え」が正解ではありません。まず評価データセットを整え、現状のFaithfulnessを測ってください。0.85以上出ている場合、改善余地は限定的です。0.70未満なら、チャンク戦略の見直しによる改善幅が大きい可能性が高いと言えます。
Q3. プロポジショナルチャンキングのコストが心配
軽量モデル(Claude Haiku、GPT-4o-mini、ローカルLLM)+バッチAPIの組み合わせで、初期コストは想定の20〜30%程度に圧縮可能です。また、全文書ではなく「特に重要な規程・FAQ」だけ命題分解し、他はセマンティックで処理する選択的適用も有効です。
Q4. 日本語の埋め込みモデルは何を使えばいい?
多言語対応モデル(OpenAI text-embedding-3-large、Cohere embed-multilingual-v3など)が業務利用では扱いやすい選択肢です。日本語特化なら、intfloat/multilingual-e5-largeやcl-nagoya/sup-simcseなどがOSSとして利用できます。チャンク戦略の評価とは別に、埋め込みモデル自体のA/Bも実施することを推奨します。
Q5. チャンクサイズはどう決めればいい?
埋め込みモデルの「最大入力長」と、ユーザークエリの平均的な抽象度に依存します。日本語社内文書では、チャイルドチャンク300〜500トークン、ペアレントチャンク1500〜2500トークンが多くのケースで機能します。ただし、これも自社データでのA/Bが必須です。
まとめ——「切り方」を変えるだけで、RAGの天井は上がる
多くの組織がRAGの精度問題を「もっと良いLLM」「もっと良い検索アルゴリズム」で解決しようとしますが、本当のボトルネックは手前のチャンク戦略にあるケースが少なくありません。
本記事の要点を整理します。
- 固定サイズ分割は文脈切断問題を起こし、精度の天井を作る。 議事録・契約書・技術仕様書で特に深刻。
- セマンティックチャンキングは話題境界で自然に分割でき、議事録や記事に有効。
- プロポジショナルチャンキングは命題単位で精密マッチを実現するが、コスト管理が鍵。
- ドキュメント構造認識分割(Unstructured/Docling)はPDF・契約書・技術文書の表や見出しを保持できる。
- ペアレント-チャイルド構造は「小さく検索、大きく生成」を実現し、長文書で特に効く。
- 日本語固有課題(文末判定、指示語、改行なし長文)には前処理パイプラインで対処する。
- Ragas FaithfulnessでA/B評価を行い、自社データでの効果を必ず定量検証する。
RAGの精度改善は、検索アルゴリズムや評価指標と並んで、「チャンクの切り方」という地味だが本質的な領域に注目することで、新しい改善余地が見えてきます。本記事が、社内RAGを次のレベルに引き上げる一助になれば幸いです。
関連記事
- RAG×ハイブリッド検索 設計ガイド【2026年版】——BM25・Dense・Sparse・Late Interactionで日本語社内文書の検索精度を上げる実装差別化ポイント
- RAG×「評価駆動開発(Eval-Driven Development)」完全ガイド【2026年版】——Ragas・DeepEval・TruLensで「とりあえず動くRAG」から「精度を継続的に改善できるRAG」に引き上げる指標設計・ゴールデンデータセット構築・CI/CD組み込み
- RAGってなに? ― AIをもっと賢く使うための仕組み
参考リンク
- LangChain – Semantic Chunker ドキュメント
- LlamaIndex – Node Parsers ドキュメント
- Unstructured 公式サイト
- Docling GitHub リポジトリ
- Ragas 公式ドキュメント
- Dense X Retrieval(プロポジショナルチャンキング論文)
免責事項: 本記事は2026年4月時点の公開情報・公開ライブラリに基づく技術解説であり、特定環境での動作保証や精度保証を行うものではありません。実装・導入にあたっては、各ライブラリの最新ドキュメントおよび自社環境での評価を必ず実施してください。

コメント