チャンキング
長い文書を小さな単位(チャンク)に分割する処理。RAGの検索精度を大きく左右する重要な前処理。
なぜチャンキングが必要か
- 検索精度の向上: 小さい単位の方が特定のトピックにフォーカスできる
- コンテキストウィンドウの節約: 関連部分だけをLLMに渡せる
- 埋め込みの品質: 混在したトピックよりも単一トピックの方が精度が高い
チャンクサイズの例
- 文章: 200〜500トークン(約150〜400語)
- コード: 関数単位、またはクラス単位
- 会話履歴: 1メッセージ単位
- FAQ: 1質問・回答ペア
チャンキングの難しさ
問題例:文脈の断絶
チャンク1: 「当社のシステムは、JWTベースの認証を採用しています。」
---(分割)---
チャンク2: 「ユーザーがログインすると、サーバーはトークンを発行し...」
この場合:
- 「JWT認証について教えて」→ チャンク1だけ取得 → 説明が不完全
- 「トークンの発行方法は?」→ チャンク2だけ取得 → JWTという文脈が失われる
解決策:重複(Overlap)
チャンク間で一部を重複させることで文脈を維持:
チャンク1: 「当社のシステムは、JWTベースの認証を採用しています。ユーザーがログインすると...」
チャンク2: 「JWTベースの認証を採用しています。ユーザーがログインすると、サーバーはトークンを発行し...」
重複率の目安: 10〜20%
チャンキング戦略
1. 固定長分割
- 指定トークン数で機械的に分割
- シンプルだが文脈を無視
2. 意味単位分割
- 段落、見出し、文単位で分割
- 文脈は保たれるが、サイズが不均一
3. 階層的分割
- 大チャンク(全体の要約)
- 中チャンク(セクション)
- 小チャンク(詳細)
- 検索時に適切な粒度を選べる
4. コード専用戦略
- 関数単位(小さいが文脈が失われやすい)
- ファイル単位(大きすぎて検索精度が下がる)
- クラス+依存関数(バランスが良い)
トレードオフ
| チャンクサイズ | 利点 | 欠点 |
|---|---|---|
| 小さい(100〜200トークン) | 検索精度が高い | 文脈が失われやすい |
| 大きい(500〜1000トークン) | 文脈が豊富 | 検索精度が下がる、コスト増 |
ベストプラクティス
- ドメインに応じて調整: 文章、コード、FAQで最適なサイズは異なる
- 重複を持たせる: 10〜20%の重複で文脈の断絶を防ぐ
- メタデータを保存: チャンクの元ファイル、位置情報を記録
- 実験と調整: 検索精度を測定しながらサイズを調整
コードのチャンキング例
# 悪い例:関数だけ
def authenticate(user):
# 文脈(JWTを使うこと)が失われる
return generate_token(user)
# 良い例:関数+コメント+依存関係
"""
JWT-based authentication system.
Uses HS256 algorithm for token signing.
"""
def authenticate(user):
return generate_token(user)
def generate_token(user):
return jwt.encode({"user_id": user.id}, secret_key)
運用上の注意点
- 更新時の再チャンキング: 元データが更新されたら、チャンクも再生成
- 削除時の同期: 元データ削除時にチャンクも削除
- バージョン管理: チャンキング戦略の変更履歴を記録
関連
- RAG
- 埋め込み
- ベクトルデータベース
- セマンティック検索
- コンテキストウィンドウ
- 推論ベース検索 - チャンキングを回避する手法
参照
- PageIndex - ベクトルレスRAGの新しいアプローチ - チャンキング問題の解決策としての階層的インデックス