スキップしてメイン コンテンツに移動

【RAG精度向上のカギ】TextSplitterの選び方と適切なチャンク分割戦略

【RAG精度向上のカギ】TextSplitterの選び方と適切なチャンク分割戦略

はじめに

RAGシステムを構築する際、Vector DBやEmbeddingsモデルにはこだわっても、「ドキュメントの分割方法(Text Splitting)」はデフォルトのままにしていませんか?

実は、この地味な前処理プロセスこそが、検索精度を大きく左右します。長すぎるチャンクはノイズを含み、短すぎるチャンクは文脈(Context)を失います。今回は、最適な分割戦略について解説します。

なぜ分割が必要なのか

Constraints

EmbeddingsモデルやLLMにはトークン制限(入力長の上限)があります。PDFなどの長いドキュメントをそのまま処理することはできません。

そのため、適切なサイズ(例えば500文字など)に分割する必要があります。しかし、単に「500文字ごとにカット」すると、重要な文章の途中で切れてしまい、意味が通じなくなるリスクがあります。

RecursiveCharacterTextSplitter

LangChainが推奨する最も汎用的な分割クラスが RecursiveCharacterTextSplitter です。

from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=400,
    chunk_overlap=50,
    separators=["\n\n", "\n", "。", "、", " ", ""]
)

このクラスはスマートです。まず段落(\n\n)で区切ろうとし、それが無理なら改行(\n)、それでも無理なら句点(。)...という順序で、なるべく意味の塊を壊さないように分割を試みます。

文脈の分断を防ぐオーバーラップ

分割の際、前のチャンクの最後と次のチャンクの最初を少し重複させるのが「Overlap(オーバーラップ)」です。

例えば「犯人は/ヤスだ」のような重要な情報が分割点で切れてしまっても、オーバーラップがあれば「~犯人は」「犯人はヤスだ」のように、どちらかのチャンクで情報が保持される確率が高まります。

日本語に特化した分割戦略

日本語の場合、英語のスペース区切りと違って単語の境界が曖昧です。そのため、separators 引数に日本語の句読点("。", "、")を明示的に含めることが非常に重要です。

Tip

Pythonのトークナイザー(JanomeやMeCab)を使って文単位で正確に分割するカスタムSplitterを作るのも有効ですが、まずは `RecursiveCharacterTextSplitter` のセパレータ設定をチューニングするだけで十分な効果が得られます。

まとめ

「Garbage In, Garbage Out(ゴミを入れたらゴミが出る)」はAIの世界でも真理です。丁寧な分割処理を行うことで、RAGの回答品質は確実に向上します。

次回は、PDFやWord、Webページなど、あらゆるソースからテキストを抽出するための「Document Loaders」について解説します。

このブログ記事はAIを利用して自動生成されました。

コメント