上級 11 分最適化

戦略について chunking

端的な回答

ローカルRAGでは、まず300〜500トークン、重複率0〜10%のチャンクから始めてください。文字単位ではなく段落や見出しの境界で分割し、自分で用意した質問で性能を測定してから調整します。意味に基づくチャンク分割は、そのコストに見合うと証明されていません。2024年の研究では、得られる改善は追加の計算コストを正当化しないと結論づけられています。最も重要な設定は、テキストの自然な境界で分割することです。

文書をどのようにテキストのまとまりに分割するかによって、検索で見つけられる内容が決まります。不適切な位置で分割すると、回答全体を含むまとまりがなくなり、大きすぎるまとまりでは回答がノイズに埋もれます。このガイドでは、一般的な分割方法を比較し、公表された研究に基づく初期設定のサイズを示します。また、単位(トークンか文字か)の落とし穴を説明し、お使いの文書で設定の選択が適切かを検証する手順を提案します。

著者 Mohamed Meguedmi·更新 2026-09-30·Windows・macOS・Linuxでテスト済み

#チャンク分割が埋め込みモデルと同じくらい重要な理由

チャンク分割とは、文書をインデックス化する前に、複数の部分に分割する処理です。各部分にベクトルが割り当てられ、検索で取得されて言語モデルに渡されるのは、その部分であって、文書全体ではありません。その後のすべての処理は、この分割に左右されます。質問の答えとなる文が2つの部分にまたがって分断されると、どちらにも文全体が含まれず、検索で見逃されます。また、1つの部分に3つの話題が混在すると、そのベクトルは曖昧な平均となり、どの質問とも強い類似性を示さなくなります。より高性能な埋め込みでも、不適切な分割は修正できません。与えられたものしかベクトル化できないからです。

分割戦略を評価した Chroma の研究が示すように、RecursiveCharacterTextSplitter のようなヒューリスティック手法は、パラメータを適切に設定すれば、実際の運用で良い結果を出すことが多く、選択したチャンクサイズと重複量によって結果は大きく変わります。したがって、このガイドでは、一般に当てはまる数値的な改善を約束しません。唯一確かなのは、お使いの文書で測定することです。

i
良いチャンク
適切なチャンクには、それだけで理解できる、ひとまとまりの考えが含まれています。短すぎると考えが途中で切れ、ベクトルが曖昧になります。長すぎると複数の考えが混ざり、検索結果にノイズが含まれるようになります。

#チャンクのサイズはどのくらいに設定すべきですか

ローカルRAGキット

あなたのドキュメント、あなたのAI:あなたのPDF、メモ、メールを扱う信頼性の高いローカルRAG。何もクラウドに送信しません。

  • 永久に利用できるオンラインスペース
  • PDF + ファイル
  • 生涯アップデート

どのコーパスにも適したサイズはありませんが、目安はあります。Chromaの研究では、重複なしで400トークン以下のサイズの場合、再帰的な分割がトークン単位の分割を上回ります。サイズが大きい場合や重複がある場合には、挙動が異なります。OpenAIのファイル検索ツールのデフォルト設定である800トークン、重複400トークンは、このベンチマークでは再現率が平均をわずかに下回り、ほかの指標では最も低いスコアとなっています。以下の目安はこの結果に基づくものであり、あなたのコーパスでも正確に当てはまると主張するものではありません。

ドキュメントおよび質問のタイプに応じた初期サイズ
サイズ適した対象リスク
200から300トークン情報量の多い文書に含まれる具体的な事実(日付、条項、値)についての質問回答の前後の文脈が失われます。セクションのタイトルを添えることを検討してください。
300~500トークンドキュメント、手順書、記事を扱う際の基本的な目安リスクは低く、まず試すべき範囲です
500から800トークン論旨が複数の段落にわたって展開される論説文複数の考えが一つのベクトルに混在して、それぞれの特徴が薄まり、プロンプトも早く埋まります
1,000 トークン超検索にはほとんど適さないため、階層的に分割する際の親レベルに限って使うベクトルが汎用的すぎて、文章の各部分を選別しにくい
→
最初の目安
まずは400トークン、重複部分は0~50トークンで始め、250トークンと700トークンも試してください。設定を変えるのは、ご自身の質問で再現率を測定してからにしてください。

#トークンか文字か:単位の誤解

ライブラリによって、数える単位は異なります。LlamaIndexのSentenceSplitterでは、chunk_sizeとchunk_overlapをトークン単位で指定します。ドキュメントによると、デフォルト値はそれぞれ1024と200です。LangChainのRecursiveCharacterTextSplitterなど、他のツールではデフォルトで文字数を数えます。お使いのバージョンのlength_functionパラメータを確認してください。同じ「500」を設定しても、どちらのツールを使うかによってチャンクの大きさには約4倍の差が生じます。2つ目の制約は、埋め込みモデル自体に最大入力長があることです。BGE-M3モデルは、モデルの説明によると最大8,192トークンの入力に対応しています。より古いモデルや軽量なモデルでは、受け入れられる入力長がはるかに短く、上限を超えると文章の末尾が無視されます。チャンクの大きさを決める前にモデルの上限を確認し、目測ではなく、そのモデルのトークナイザーで数えてください。

#重複:有用ですが、必ずしもそうではありません

オーバーラップは、あるチャンクの末尾を次のチャンクの先頭で繰り返すことで、境界で分断された文が少なくともどちらか一方では読めるようにする仕組みです。ただし、チャンク数の増加、インデックスの肥大化、検索結果の重複というコストがあります。Chromaの研究では、オーバーラップを減らすとIoUスコアが改善すると指摘されています。IoUは、冗長な情報を減点する指標です。固定サイズで分割する場合にはオーバーラップを設ける理由がありますが、すでに段落や見出しに沿って分割している場合は、その重要性は低くなります。分割位置が自然な区切りに一致するためです。

0トークン
段落や構造ごとに分割すれば十分です。最も経済的です。
サイズの10〜15%
文単位または文字数で分割する場合に、バランスのよい選択です。
25%超
妥当なケースはまれです。重複が多く、結果にはほぼ同じ文章が並びます。

#分割戦略:最も簡単なものから最もコストの高いものまで

#1. 固定文字数で

テキストの内容を考慮せず、N文字またはNトークンごとに分割する方法です。最も単純で、内容を最も損ないやすい方法でもあります。単語、文、表の途中で分割してしまいます。プロトタイプに限って使うべき方法です。

#2. パラグラフごとまたは文ごと

ダブル改行や記号の削除後、ターゲットサイズまで単位をまとめていく。コストゼロで明確な境界でチャンクが開始・終了するため、大幅な改善となる。

#3. 再帰的

まず大きな区切り(段落、行、文、スペース)での分割を試し、文字単位での分割は最後の手段にします。これは主要なフレームワークのデフォルト動作であり、堅実な出発点です。Chromaの研究では、この種の分割方法は適切に設定すれば良好な結果を得られることが多いとしています。

#4. ドキュメントの構造に従って

見出し、リスト、表、コードブロックの構造を保ちます。たとえば、LlamaIndex の MarkdownNodeParser は見出しに沿って分割し、各ノードに、そのノードに至る見出しの階層を付加します。これにより、パッセージの本文だけでは得られない文脈を与えられます。技術ドキュメント、Wiki、エクスポートした HTML ページには最適な方法です。

#5. 意味に基づく分割

文ごとに埋め込みを計算し、隣接する二つの文の間で類似度が低下する箇所で分割します。LlamaIndex の SemanticSplitterNodeParser は、buffer_size(一緒に比較する文の数、デフォルトは 1)と breakpoint_percentile_threshold(デフォルトは 95。値を下げるとノードが増えます)を受け取ります。インデックス作成時に追加の埋め込み計算が必要になりますが、その効果は確立されていません。2024 年 10 月に三つの検索タスクを対象に行われた研究では、セマンティック分割による性能向上は一貫しておらず、その計算コストを正当化できないと結論づけています。採用する前に、ご自身のコーパスでテストしてください。

#6. 階層型(親と子)

検索精度を高めるために小さなチャンクをインデックス化し、文脈を提供するために、それを含むより大きな親ブロックをモデルに渡します。LlamaIndexのHierarchicalNodeParserはこのような階層を生成します。ドキュメントには、例えば2048、512、128トークンの3段階の構成が示されています。これは長い文章への対処法です。小さなチャンクだけにも、大きなチャンクだけにも頼りません。

どのドキュメントにどの戦略を適用するか
ドキュメントの種類推奨される戦略
ドキュメント、Wiki、Markdown、HTML構造(見出し)に沿って分割し、長いセクション内では再帰的に分割
契約書、法的文書条または条項ごとに分割;サイズは300〜500トークン;各チャンクに条の見出しを再掲
構造化されていない自由形式の文章(メール、メモ、文字起こし)再帰的で、10%の重複あり、場合によっては階層的
テーブル付きPDF事前に構造を抽出し、質問に応じて表を丸ごと1つのチャンクにするか、行ごとに分割する
ソースコード関数またはクラスごとに分割し、ブロックの途中では決して分割しない

#LlamaIndexでの実装

重複を持たせた文単位の分割
from llama_index.core.node_parser import SentenceSplitter

splitter = SentenceSplitter(chunk_size=400, chunk_overlap=40)  # en tokens
nodes = splitter.get_nodes_from_documents(docs)
Markdownの構造に従って
from llama_index.core.node_parser import MarkdownNodeParser

parser = MarkdownNodeParser()
nodes = parser.get_nodes_from_documents(docs)
# le chemin des titres est stocké dans les métadonnées de chaque nœud
階層的
from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes

parser = HierarchicalNodeParser.from_defaults(chunk_sizes=[2048, 512, 128])
nodes = parser.get_nodes_from_documents(docs)
leaves = get_leaf_nodes(nodes)  # ce sont les feuilles qu'on vectorise
意味に基づく分割(採用前にテストする)
from llama_index.core.node_parser import SemanticSplitterNodeParser
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

embed = HuggingFaceEmbedding(model_name="BAAI/bge-m3")
splitter = SemanticSplitterNodeParser(embed_model=embed, buffer_size=1, breakpoint_percentile_threshold=95)
nodes = splitter.get_nodes_from_documents(docs)

#各チャンクにコンテキストを再び与える

文書から切り取られた断片は、その文脈を失います。「期限は30日です」という記述だけでは、それが何を指しているのか分かりません。この問題を解決するには、3つのシンプルな手法があります。各チャンクに文書のタイトルとセクションパスをプレフィックスとして付与すること、これらの情報をメタデータとして保存してフィルタリング(日付、ソース、文書タイプ別)に利用すること、そして代名詞や参照(「この条項」など)で始まる断片については、階層型分割の上位レベルを検討することです。多くの場合、テキストの前に1行のコンテキストを付与するだけで十分であり、モデルを変更するよりもはるかにコストが低いです。

#チャンク分割の方法を確定する前に評価する

  1. 01
    実際に想定される質問を30〜50件書く
    ユーザーが尋ねそうな質問を用意し、それぞれに、回答の根拠として想定する原文の箇所を添えてください。結果を見る前に作成してください。
  2. 02
    2つまたは3つの設定でインデックス作成
    たとえば250、400、700トークンで、重複率は0%と10%に設定します。他のパラメータは同じにしてください。
  3. 03
    検索結果の上位5件での再現率を測定する
    各質問に対して、期待される文が最初の5つの結果に含まれているかを確認します。このパーセンテージは5件の再現率を示します。
  4. 04
    適合率と重複の度合いも確認する
    再現率が同じなら、結果の多様性が高い設定のほうが優れています。上位5件の重複を数えてください。
  5. 05
    失敗を一つずつ検証する
    正しく答えられなかった質問ごとに、回答に必要な情報が含まれているはずのチャンクを開いてください。途中で切れていないか、範囲が広すぎないか、テキストの抽出が壊れていないかを確認します。原因に応じて修正方法を決めてください。

#よくある落とし穴

表の構造の崩れ
PDF抽出ツールが表を平坦化すると、意味の通らないセルの並びが出力されます。文書を分割する前に、表の構造を抽出してください。
途中で分割されたコードブロック
構文を認識しない分割ツールは、ブロックを途中で分割してしまいます。構造に沿って分割してください。
複数の言語が混在するドキュメント
半分がフランス語、半分が英語のチャンクは、あまり役に立たない平均的なベクトルを生成します。コーパスに複数の言語が混在している場合は、言語ごとに分けてください。
ほぼ空のチャンク
後に続く本文を伴わない見出しだけのチャンク(「3.2.1 義務」)はノイズです。短すぎるチャンクは除外するか、次のチャンクと結合してください。
再インデックス化せずにチャンク分割方法を変更する
分割方法はインデックス作成時に固定されるため、変更するたびにベクトルを再計算する必要があります。最初から再インデックス用のスクリプトを用意してください。
!
盲目的に最適化しないでください
質問セットがなければ、設定の変更で結果が改善するのか悪化するのか分かりません。「妥当に見える」サイズでも、再現率には、良い方向にも悪い方向にも測定可能な影響があります。

#チャンキングに関するよくある質問

FAQ
ローカルRAGで使用するチャンクのサイズはどのくらいですか?+
まずは300~500トークン、重複率0~10%で、段落や見出しの区切りに合わせて分割してください。その後、普段実際に使う質問30~50件で250トークンと700トークンを試し、上位5件の結果における再現率を比較してください。万能な値はありません。適切な値はドキュメントと質問によって異なります。
セマンティックチャンキングはコストに見合いますか?+
必ずしもそうではありません。インデックス作成時に追加の埋め込み計算が必要です。また、3つの検索タスクを対象とした2024年10月の研究では、固定サイズの分割と比べて一貫した性能向上が得られず、このコストに見合わないと結論づけています。ご自身のコーパスで試し、改善が見られなければ再帰的分割を使い続けてください。
チャンク間のオーバーラップは必要ですか?+
必ずしも必要ではありません。段落や見出しで区切っているなら、重なりを設けなくても問題ない場合が多いです。固定サイズや文単位で区切る場合は、10〜15%の重なりを設けると、境界で文が失われるのを防げます。重なりが大きいと、検索結果の重複が増え、インデックスも肥大化します。
トークンか文字か:chunk_sizeをどう設定すべきですか?+
使用するライブラリの単位を確認してください。LlamaIndexのSentenceSplitterはトークン数で数えますが、ほかのツールはデフォルトで文字数を使うため、実際のサイズに約4倍の違いが生じます。埋め込みモデルの最大入力長も確認してください。これを超えると、インデックス作成時に該当する文章が切り詰められます。
表を含むPDFはどのように分割すればよいですか?+
まず、表を認識できるツールで構造を抽出し、その後分割します。小さい表は 1 つのチャンクに 1 つの表、大きい表はヘッダー付きの 1 行を 1 つのチャンクとして分割します。表をプレーンテキストにフラット化する抽出ツールは、その後の分割方法に関わらず、使用できないテキスト断片を生成します。
チャンクのサイズを変更した場合に再インデックスが必要ですか?+
はい、必ず必要です。ベクトルは、インデックス作成時の各テキスト部分に基づいて計算されます。チャンクのサイズ、重複範囲、分割ツールを変更すると、すべてのベクトルを再計算する必要があります。元の文書からインデックスを再構築するスクリプトを保存し、使用した分割パラメータをバージョン管理してください。
このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。