Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Chunking

RAGでは文書を検索単位(chunk)に分割してからインデックスする。chunkの切り方は検索精度に大きく影響し、RAGの精度を最も左右する工程の一つ。

chunkが

  • 大きすぎる:1つのembeddingに複数の話題が混ざり、ベクトルがぼやけて検索でヒットしにくくなる。LLMに渡すコンテキストも無駄に増える

  • 小さすぎる:文脈が失われ、chunk単体では意味が分からなくなる(「同社の売上は前年比10%増」の「同社」が誰なのか分からない、など)

というトレードオフがある。

基本的な分割方法

固定長分割

文字数やトークン数で機械的に区切る。前後のchunkと一部を重ねる overlap を設けて、境界で文が切れる問題を緩和するのが一般的。

実装が簡単だが、文や段落の途中で切れやすい。

再帰的分割(recursive splitting)

段落 → 改行 → 文 → 単語 のように区切り文字の優先順位を決めておき、chunkが上限サイズに収まるまで大きい単位から順に分割する。LangChainの RecursiveCharacterTextSplitter が代表例。

シンプルだが実用上かなり強いベースライン。

構造に沿った分割

Markdownの見出し、HTMLのタグ、PDFの章・節、コードの関数・クラスなど、文書の構造を使って区切る。構造がはっきりした文書では意味のまとまりと一致しやすい。

Semantic chunking

隣接する文のembeddingの類似度を計算し、類似度が大きく下がる箇所(話題が変わる箇所)で区切る。

計算コストが高い割に、再帰的分割と比べて常に良いとは限らない。

どれが良いのか

Chromaの評価(Evaluating Chunking Strategies for Retrieval)では、

  • RecursiveCharacterTextSplitter で 200〜400トークン・overlapなし がシンプルで性能も良い

  • embeddingモデルを考慮してクラスタリングで区切る ClusterSemanticChunker は効率(precision)が最も良いが、実装は複雑

という結果だった。まずは再帰的分割をベースラインにして、評価しながら調整するのが無難。

文脈を補う手法

chunk単体では文脈が失われる問題に対して、いくつかの対策がある。

Contextual Retrieval

Anthropicが提案した手法(Introducing Contextual Retrieval)。

各chunkについて、文書全体とchunkをLLMに渡して「このchunkが文書全体の中でどういう位置づけか」を説明する短い文脈(50〜100トークン程度)を生成させ、chunkの先頭に付けてからembeddingとBM25のインデックスを作る。

例:「同社の売上は前年比10%増」→「この部分はACME社の2023年第2四半期の決算報告書からの抜粋。前四半期の売上は…。同社の売上は前年比10%増」

top-20の検索失敗率が

手法失敗率
ベースライン(embeddingのみ)5.7%
Contextual Embeddings3.7%(-35%)
+ Contextual BM252.9%(-49%)
+ reranking1.9%(-67%)

と改善したと報告されている。prompt cachingを使えば文脈生成のコストは100万トークンあたり約$1.02。

Late chunking

Günther et al. (2024). Late Chunking: Contextual Chunk Embeddings Using Long-Context Embedding Models

通常は「分割 → 各chunkをembedding」の順だが、late chunkingでは

  1. 文書全体をlong-contextのembeddingモデルに通してトークンごとの埋め込みを得る

  2. その後でchunkの範囲ごとにトークン埋め込みをmean poolingする

という順にする。各chunkの埋め込みが文書全体の文脈を反映したものになる。LLMを呼ばないのでContextual Retrievalより安い。

Small-to-big(parent document retrieval)

検索は小さいchunk(文や段落)で行い、ヒットしたらその親(節や周辺の段落)をLLMに渡す。検索の精度と生成に渡す文脈の豊かさを両立させる。

Proposition単位の分割

Chen et al. (2023). Dense X Retrieval: What Retrieval Granularity Should We Use?

LLMで文書を「それ単体で意味が通る最小の事実(proposition)」に書き換えて、それを検索単位にする。代名詞も解決された形になるので文脈の欠落が起きにくい。

PageIndexとの関係

PageIndex はchunking自体をやめて、文書の目次構造をLLMにたどらせる方向の解決策。上記の手法はchunkingを前提に文脈を補う方向の解決策と整理できる。