RAGのチャンク設計に全社共通の正解はありません。規程の例外条件を一緒に取得したいのか、型番を含む一行だけを探したいのかで、必要な単位が変わるからです。本稿では、原本の構造を壊さずに四つの分割案を作り、正解範囲付き180問で検索漏れ・境界切れ・重複費用を測り、採用した規則を再現可能な設定として残すところまで扱います。
RAGのチャンクは質問の答えが収まる単位から設計する
分割幅はモデルの上限ではなく、業務上の回答範囲から逆算します。就業規則の「対象者・原則・例外」が連続3段落にあるなら、三つを同じ検索単位へ収めるか、子チャンクを検索した後に親節を取得します。障害コードと対処手順が一行ずつ対応する表では、表全体を一つの長文へ平坦化せず、行と列見出しの関係を保持します。契約書では条・項・号を切り離すと、「ただし」の参照先を失うため、条単位を上限にしながら項の親子関係を残します。
Microsoftの「Chunk large documents for RAG and vector search in Azure AI Search」は2026年7月2日更新です。同資料は固定幅、文や段落、レイアウトに沿う方法を紹介し、開始値として2,000文字と500文字の重複を示しています。
Microsoftの「Chunk large documents for RAG and vector search in Azure AI Search」は、最適値が利用方法に依存すると説明しているため、開始値として示される2,000文字と500文字の重複は普遍的な合格値ではありません[1]。特に日本語では「1トークンがおよそ何文字」という英語中心の換算をそのまま採用せず、実際に使うトークナイザーで分布を測ります。
| 原本 | 守る境界 | 初期候補 | 避ける切り方 |
|---|---|---|---|
| 社内規程 | 編・章・条・項・例外 | 条を親、項を子にする | 「ただし」を前文から分離 |
| 製品マニュアル | 機種、手順、警告、図表 | 見出し配下を手順群で分ける | 警告だけを別チャンク化 |
| FAQ | 質問と回答の組 | 一組を一単位にする | 全質問と全回答を別々に連結 |
| 議事録 | 議題、発言者、決定、期限 | 議題ごとに決定事項を含める | 発言文字数だけで機械分割 |
| 表計算 | シート、表題、列名、行 | 列名を各行へ付与する | セル値だけを順に並べる |
短いほど精密、長いほど文脈豊富という単純な二択ではありません。答えと条件を一緒に取れ、余計な主題を混ぜない最小のまとまりを探します。
分割前に原本を正規化して境界を取る
PDF、Word、HTML、表計算を同じ文字列処理へ渡す前に、抽出品質を確認します。PDFでは読み順、二段組、ヘッダー・フッター、脚注、ページをまたぐ表が崩れやすく、OCR文書では全角半角、濁点、改行、誤認識が検索語を変えます。原本100件を形式別に抽出し、空本文率、見出し検出率、表の列保持率、文字化け率を記録します。抽出本文が壊れていれば、チャンク幅を調整しても根拠は戻りません。
構造を識別できる文書では、`h1 > h2 > h3`、章 > 条 > 項、シート > 表 > 行の階層を先にJSONへ変換します。Azure AI SearchのDocument Layout Skillに関する公式資料は2026年6月8日更新で、文書レイアウトに基づくチャンク化、親子索引、見出し項目の保持を扱っています[5]。
これはAzure固有機能の説明ですが、「抽出後の平文だけでなく、見出しや親を索引へ投影する」という設計原則は、他の実装でも検証できます。
{ "document_id": "manual-MX410", "revision": "2026-05-14", "nodes": [ { "path": ["第4章 保守", "4.3 再起動", "警告"], "type": "warning", "text": "主電源を切る前に...", "source": {"page": 38, "char_start": 18204, "char_end": 18376} } ]}
正規化の完了条件は、文書形式ごとに20件以上を目視し、見出し階層の欠落0件、表の列入れ替わり0件、原本へ戻れない節0件とする例が考えられます。OCR誤りが5%を超える形式、ページ画像しかなく根拠位置を確定できない文書、同じファイル名で版を上書きする運用は、検索PoCへ入れる前に修正します。原本識別と版管理ができないまま索引を作ると、削除も引用も検証できません。
| 統計 | 算出単位 | 設計へ反映する判断 | 異常の例 |
|---|---|---|---|
| 節長p50/p95/最大 | tokens | 上限超過する節の再分割方法 | p95の10倍ある一節 |
| 一文の最大長 | tokens | 文境界だけで分割可能か | OCRで句点が消失 |
| 表の行列数 | 各table | 行単位か表全体か | 列見出し0、結合セル過多 |
| 見出しなし率 | 文書件数 | 固定幅へのfallback比率 | 同形式だけ100%欠落 |
たとえば節長p50が180tokens、p95が720tokens、最大が9,400tokensなら、上限800の構造分割だけでは一件の巨大節が残ります。巨大節を段落境界で再分割し、それでも超える段落だけ文境界へ落とす階層規則を用意します。p95を採用上限へ機械的に置くのではなく、超過5%に表・コード・付録が集中していないかを確認します。分布表は文書形式と部門でも分け、短いFAQの中央値で長い契約書を設計しません。
正解範囲付き180問を作る
評価質問は、答えが含まれる文書だけでなく、必要な文字範囲を指定します。180問の構成例は、単一段落60問、前後2段落を要する35問、表・箇条書き30問、章をまたぐ参照20問、版指定15問、回答不能20問です。各質問に、根拠となる`document_id`、`revision`、開始・終了位置、関連度0〜3、閲覧可能な主体を付けます。回答文を先に作るのではなく、どの範囲が取得されれば担当者が答えられるかを確定します。
境界の品質を見るため、正解範囲の前後へ似た語を含む妨害文書を置きます。「有給休暇の繰越上限」を問うとき、旧規程、派遣社員向け規程、海外法人規程を同じ集合へ入れます。最新版だけを正解3、旧版を関連0または1とラベル付けします。単純な文書ヒット率では旧版を取っても成功扱いになるため、チャンクと版を組にして採点します。
| 質問区分 | 件数 | 設計上の狙い | 失敗の判定 |
|---|---|---|---|
| 局所事実 | 60 | 短い単位の検索力 | 正解行がtop5にない |
| 条件と例外 | 35 | 境界をまたぐ意味保持 | 原則だけ取得し例外が欠落 |
| 表・リスト | 30 | 見出しと値の対応 | 数値はあるが列名がない |
| 相互参照 | 20 | 親子・隣接取得の必要性 | 参照先の節をたどれない |
| 版指定 | 15 | 有効期間と改訂の扱い | 無効版が現行版より上位 |
| 回答不能 | 20 | 類似語だけの誤取得抑制 | 根拠のない断片を強く返す |
180問は提案値であり、実測値ではありません。質問の80%に当たる144問を最終判定へ固定し、36問だけを分割調整へ使います。業務担当者二人の関連度判定が一致しない質問は、曖昧なまま平均せず、問いの条件不足か原本の矛盾かを記録します。原本自体が曖昧なら、RAGの検索性能では解決せず、コンテンツ所有者へ改訂を戻します。
固定幅・構造単位・親子方式を比較する
候補は一度に一要素だけ変えます。抽出器、埋め込みモデル、検索方式を固定し、まず分割規則を四案にします。Aは256トークン・重複32、Bは512・重複64、Cは見出し単位で上限800・下限120、Dは子256で検索し親見出し最大1,200を生成時に渡す方式です。重複率は、全チャンクの重複トークン数÷重複前の本文トークン数で計算し、索引件数と埋め込み費用への影響を出します。
OpenAIのVector Store File作成API v2は、参照時点の`auto`方式を最大800トークン、重複400トークンとし、`static`では最大100〜4,096トークン、重複は最大幅の半分以下と定めています[2]。この数値は同APIの現行仕様です。他社の検索基盤や自作パイプラインの推奨値ではなく、自社で800/400を使えば必ず高精度になるという根拠でもありません。管理サービスを使う場合は、変更可能な範囲と再取り込み方法を版ごとに確認します。
| 候補 | 検索単位 | 利点 | 注意点 |
|---|---|---|---|
| A | 256 tokens、overlap 32 | 局所事実の混入語が少ない | 条件と例外が分断されやすい |
| B | 512 tokens、overlap 64 | 短い手順を収めやすい | 複数主題が同居する場合がある |
| C | 見出し単位、120〜800 tokens | 意味境界と引用位置を保ちやすい | 極端に長い節の再分割が必要 |
| D | 子256を検索、親1,200を取得 | 検索の細かさと回答文脈を分離 | 親展開後のトークン増加を管理 |
箇条書きは項目だけをばらさず、直前の見出しと導入文を各子へ引き継ぎます。表は列名と行見出しを各行へ付け、表タイトルを親情報にします。コードや手順は、入力・処理・期待結果を同じまとまりに置きます。重複部分を検索結果で二重に数える場合は、`document_id + source span`で統合し、同じ根拠が上位を埋め尽くさないようにします。
固定幅の概算件数は、本文長を`L`、最大幅を`S`、重複を`O`としたとき、`L≤S`なら1、超える場合は`1+ceil((L-S)/(S-O))`で求められます。10,000tokensを512/64で分ける試算では、`1+ceil((10,000-512)/448)=23`チャンクです。
256/32なら`1+ceil(9,744/224)=45`となり、索引件数はほぼ二倍です。実際には文・見出し境界へ寄せるため件数がずれますが、予算と再索引時間の下見に使えます。
split(node): if token_length(node.text) <= max_tokens: return [attach_context(node)] if node.has_child_blocks: return flatten(split(child) for child in node.children) if node.type == "table": return split_rows_with_headers(node) return split_by_priority(node.text, ["paragraph", "sentence", "token"])
一つの原本を固定設定で処理したとき、一定の`chunk_id`が出るよう、分割の順序、Unicode正規化、空白処理、tokenizer版を固定します。IDを配列番号だけで作ると、冒頭へ一段落追加しただけで後続IDが全て変わります。`document_id + revision + source locator + splitter version`から決定的に生成すれば、差分の確認と引用の追跡が容易になります。
検索と引用をつなぐチャンク項目を持たせる
本文断片だけをベクトル化すると、回答が正しくても根拠表示を再現できません。各チャンクには不変の`document_id`、改訂ごとの`revision_id`、分割規則の`splitter_version`、階層を示す`heading_path`、原本位置、本文ハッシュ、親ID、前後ID、アクセス制御値を付けます。PDFのページ番号に加え、文字オフセットまたは抽出ブロックIDを保存すると、ページ内の該当位置まで戻せます。
OpenAI File Searchの公式ガイドは、応答に`file_citation`注釈が含まれ、検索結果本体を確認するには`include=[“file_search_call.results”]`を指定すること、メタデータで結果を絞れることを説明しています[4]。この仕様を使う場合でも、ファイル名だけで社内改訂を識別できるか、チャンク内の原本範囲をどこまで保持できるかは別途確かめます。検索APIが返す内部IDと、自社の原本台帳を結ぶ対応表が必要です。
chunk = { "chunk_id": "policy-27:r6:sec-5:p2", "document_id": "policy-27", "revision_id": "r6", "parent_id": "policy-27:r6:sec-5", "heading_path": ["旅費規程", "第5条", "例外"], "source_locator": {"page": 7, "block": "b-143"}, "acl_version": "acl-20260718-02", "splitter_version": "rules-ja-3.2", "content_sha256": "..."}
引用の受入条件は、180問のうち回答可能160問で、表示した引用が正解範囲と重なる割合を測ります。`引用一致率=正解範囲と重なる引用数÷表示引用数`とし、たとえば表示引用310件中294件が正解範囲なら94.8%です。検索ヒットが正しくても、引用が隣のチャンクへずれるなら、原本位置の投影か親展開に不具合があります。生成モデルの文章評価へ進む前に修正します。
検索指標と費用を同じ表で判定する
分割案は、Hit@5、MRR@10、境界保持率、引用一致率、重複率、平均取得トークンで比較します。Hit@5は正解チャンクが上位5件に一つでも含まれる質問の割合です。MRR@10は最初の正解順位の逆数を質問ごとに平均し、上位に正解が来る案を評価します。境界保持率は「正解に必要な連続範囲が一つの取得単位または親展開で欠けずに揃った質問÷境界評価55問」と定義できます。
以下は手順を示す架空試算で、製品やモデルの実測結果ではありません。固定した144問でA〜Dを比較し、回答不能20問は別に誤取得率を測った想定です。実案件では最低3回実行し、索引キャッシュ状態と設定を揃えます。
| 候補 | Hit@5 | MRR@10 | 境界保持率 | 重複率 | 平均取得tokens |
|---|---|---|---|---|---|
| A 256/32 | 88.2% | 0.68 | 72.7% | 12.5% | 1,280 |
| B 512/64 | 90.3% | 0.71 | 83.6% | 12.5% | 2,560 |
| C 構造単位 | 92.4% | 0.75 | 89.1% | 6.8% | 2,140 |
| D 親子取得 | 93.1% | 0.77 | 96.4% | 4.1% | 4,620 |
Dは品質が高くても、平均取得トークンがCの約2.16倍です。生成入力の予算が3,000トークンならDはそのまま採用できず、親展開を上位2件だけに限定する、重複親をまとめる、長い親を要約せず必要節だけ連結する、といった再試験が要ります。
採用基準をHit@5 92%以上、境界保持90%以上、回答不能誤取得10%以下、平均3,000トークン以下とした場合、この架空表ではCは境界、Dは入力量が未達です。どちらかを感覚で選ばず、改善案を一回だけ試し、それでも満たさなければ要件側を再検討します。
埋め込み費用は、`重複後総tokens÷1,000,000×単価`で算出します。月間更新が2,000万tokens、重複率25%なら処理対象は2,500万tokensです。単価は利用サービスの公開直前価格を入れ、索引保存と再取り込み時間も加えます。重複は検索品質への投資ですが、隣接チャンクの同文が上位を占有するなら費用だけでなく多様性も損ないます。
全体スコアが近い案は、質問区分と文書形式で分解します。Cが規程ではDに勝ち、表計算では大きく負けるなら、全コーパスへ一つの分割器を押し付けず、形式別profileを持たせます。ただしprofileを増やすたびに回帰試験と再索引経路も増えるため、改善がHit@5で3ポイント以上ある形式だけを分岐候補にします。質問数が10件未満の小区分は偶然差が大きく見えるので、追加ラベルを作るまで採否を保留します。
計測結果には点推定だけでなく、失敗件数を併記します。144問でHit@5 92.4%なら成功約133問、失敗約11問です。別案93.1%は成功約134問で、差は一問程度にすぎません。その一問が安全手順か周辺FAQかで判断は変わります。割合の小差だけで複雑な方式へ移らず、質問ID、関連度、業務影響、取得token増加を一緒に読んでください。
検索漏れを六つの工程へ切り分ける
「チャンクが悪い」と結論づける前に、原本、抽出、分割、埋め込み、索引、検索の順で証拠を見ます。原本に答えがないならコンテンツ問題です。原本にはあるが抽出JSONにない場合はパーサー、抽出JSONにはあるがどのチャンクにも完全な範囲がない場合は分割を疑います。
正解チャンクが存在するのにExactベクトル検索でも出ない場合は埋め込み、Exactでは出るが近似検索で落ちる場合は索引を調べます。権限条件を付けたときだけ消えるなら、メタデータまたはフィルターが確認先です。
| 症状 | 最初に見る証拠 | 主な原因 | 修正後の再試験 |
|---|---|---|---|
| 表の値だけ欠ける | 抽出ブロックと列名 | 表構造の平坦化 | 表30問のHit@5 |
| 例外条件が出ない | 正解spanと境界 | 段落間の分断 | 条件・例外35問 |
| 短い型番が弱い | 検索方式別順位 | 語彙検索不足 | BM25併用との比較 |
| 旧版が上位になる | revisionと有効期間 | 削除・フィルター不良 | 版指定15問 |
| 権限付きだけ空になる | ACL投影値 | 子チャンクの属性欠損 | 許可・拒否の対テスト |
| 回答は正しいが引用が違う | source_locator | 親展開後の位置ずれ | 引用一致率 |
生成回答のプロンプトを変えるのは、検索ログで正解範囲が渡っていると確認した後です。正解がtop20に存在せず、回答だけが合っている場合は、モデルの内部知識や推測に依存しています。逆に正解チャンクがtop3にあり、引用も一致するのに回答が誤るなら、分割を変更せず生成段階を調べます。工程を混ぜて同時変更すると、改善理由も回帰原因も分からなくなります。
差分更新と全量再索引の条件を定める
文書一件の改訂は、その文書の旧チャンクを無効化し、新しいrevisionだけを差分登録します。ただし、分割器の版、埋め込みモデル、トークナイザー、抽出器、正規化規則、距離関数が変わる場合は、同じ検索空間とみなせないため全量または対象コーパス全体を作り直します。親子構造やACL項目を追加するときも、既存チャンクへ値を投影できるか確認し、欠損を許可扱いにしません。
| 変更 | 索引対応 | 固定して比較するもの | 公開条件 |
|---|---|---|---|
| 原本1件の改訂 | 文書単位の差分 | 同じsplitter・embedding | 旧版0件、更新SLA内 |
| 見出し規則の修正 | 該当形式を全再分割 | embedding・検索設定 | 形式別質問で回帰なし |
| 埋め込み変更 | 別索引へ全再生成 | 分割案と評価質問 | 144問と負例が合格 |
| ACL列の追加 | 全子へ属性をバックフィル | 本文ベクトル | 欠損0、拒否試験0漏えい |
| パーサー主要版更新 | 影響形式を再抽出 | 原本セット | 構造差分を承認 |
新索引は旧索引と並行構築し、固定144問、直近20問、権限負例を通してからaliasを切り替えます。旧索引は復旧目標の期間だけ読取可能に残します。切替直後の1時間は、空結果率、旧版取得率、p95、引用解決失敗を5分窓で監視します。空結果率が通常の2倍、権限属性欠損が1件、引用解決失敗が1%超のいずれかなら旧aliasへ戻します。
この方法が向かないのは、再索引を実行できないサービス、旧索引を並行保持できない容量、revisionを付けず上書きする原本管理です。先に版管理と容量を整えます。更新停止時間を取れず、青緑切替もできない場合は、業務範囲を低頻度更新の文書へ限定し、高鮮度を要求する規程や価格表を対象外にします。
再索引runごとに、原本manifest、抽出器、正規化規則、splitter設定、tokenizer、embedding、索引名、開始・終了、成功・隔離件数を一つの記録へまとめます。投入件数と索引件数を照合し、原本100件から期待2,430チャンクなのに2,401件しかない場合は29件の所在を確定するまで切り替えません。隔離文書を黙って除外すると、検索品質の問題に見えるため、利用者へ対象外範囲を示します。
高度な分割へ進む条件と停止線を置く
構造単位と親子取得で合格しない場合だけ、文脈付き埋め込み、意味境界検出、Late Chunkingを比較します。Late Chunkingの原著論文は、文書全体を先に長文対応モデルへ通し、トークン表現を得た後に各範囲をpoolingすることで、代名詞などが失う文書内文脈を補う方法を示しています[3]。同論文は広い検索課題で改善を報告する一方、無関係な長文へ短い答えを埋めた課題では追加文脈が役立たず、大きいチャンクで通常方式が同等または優れる場合も記載しています。
高度な方式へ進む条件は、境界評価55問のうち少なくとも10問で、正しい分割が存在しても指示語・省略主語のため埋め込み検索が失敗し、単純な親見出し付与でも改善しないことです。比較時は同じ埋め込みモデルがLate Chunkingに対応するか、最大文書長、計算時間、GPUメモリ、再索引時間を測ります。論文の英語ベンチマーク結果を日本語社内文書の保証値として転用しません。
実装を止める条件
原本の版を識別できない、ACLを子へ継承できない、正解範囲付き質問を最低60問作れない、分割前の抽出品質を確認できない場合は、チャンク最適化を中止します。また、四案の差がHit@5で1ポイント未満なのに再索引費用が2倍を超えるなら、複雑な案を採らず、単純な構造単位を残します。根拠位置が必要な法務・品質保証業務で引用解決ができない場合は、本番対象から外して専門部署へ戻します。
分割規則は一度決めて終わりではありません。質問分布が変わる、長い表が増える、規程形式が変わる、埋め込みモデルが更新されると、同じ幅の意味が変わります。月次では失敗質問を区分別に追加し、四半期ごとに固定144問を再実行します。ただし毎回パラメーターを動かさず、合格値を二回連続で下回るか、主要形式の失敗が5件以上集まったときに変更候補を作ります。
RAGチャンクの予備検証を完了させる
次の行動は、規程、マニュアル、FAQ、表計算を各5件選び、正解範囲付き質問を各15問、計60問作ることです。抽出JSONへ見出し階層と原本位置を残し、256/32、512/64、構造単位の三案だけを同じ埋め込みと検索条件で測ります。Hit@5、境界保持率、平均取得トークン、引用解決失敗を算出すると、追加の親子方式が本当に必要か判断できます。結果と`splitter_version`を保存した時点で予備検証は完了です。
参考文献・出典
- Microsoft「Chunk large documents for RAG and vector search in Azure AI Search」[公式ドキュメント] 2026年7月2日更新(参照日: 2026年7月30日)
- OpenAI「Create vector store file」[公式APIリファレンス] v2 API、更新日表記なし(参照日: 2026年7月30日)
- Michael Günther et al.「Late Chunking: Contextual Chunk Embeddings Using Long-Context Embedding Models」[原著論文] arXiv:2409.04701、初稿2024年9月7日(参照日: 2026年7月30日)
- OpenAI「File search」[公式ドキュメント] 更新日表記なし(参照日: 2026年7月30日)
- Microsoft「Chunk and Vectorize by Document Layout」[公式ドキュメント] 2026年6月8日更新(参照日: 2026年7月30日)