【RAG】セマンティックチャンキング手法
チャンク化の種類
- 固定サイズのチャンク: 文字数で分ける
- 可変サイズのチャンク:
特定の文字で区切る, マークダウン言語構造を使用した分割, - 自然言語処理 (NLP) ライブラリを使用した分割
正規表現に基づいたチャンキングなど - 意味で分ける
今回は意味で分けるセマンティックチャンキングについて
意味(セマンティック)に分けると何がいいの?
LLMの精度向上につながる
意味の塊ごとに分けることで、検索の際にピンポイントでヒットし、LLMに必要な情報を渡せるようになる。
無駄な情報を与えすぎると、精度が悪くなるし、APIの使用量が高くなる。
意味(セマンティック)に分ける方法
- LLM chunking
LLMにチャンクさせる
これが一番精度が高そうなので今回はこちらでチャンキング
- オープンソースライブラリのチャンキング
(ソース見ればわかるんだろうけど)
結局どうチャンク化されているのかがわかりずらく制御しずらい
例:
・LLamaIndexのSemantic Chunker
おそらく文の分割は正規表現で行われているようで、英語では機能する
・LamngChainのSemantic Chunking
最初の文の分割。次に意味的に十分に類似している場合は、隣り合ったものを結合します
恐らくAdjacent Sequence Clusteringと同様の手法
- パブリッククラウドのSemanticChunking
Azure AI Searvice
(Amazon Kendra)
文書のスマートチャンキング
意味によってチャンキングしているかは不明
- Adjacent Sequence Clustering
隣接したセンテンスの類似度からチャンキング
spaCyを使用してコンテキストを含んでchunking
spaCyとは自然言語処理 (NLP) ライブラリ
参考:
- 人力
最終手段
結局何がいい?
意味で分割したいなら
LLMを活用したチャンキングがよさそう
手順
-
LLMにドキュメントを投げて意味のまとまりに分けてもらう
タイトル、見出し、本文なところを抽出して返してもらう
本文の場合は長文で生成するのに時間がかかってしまうので、抽出する文章の最初と最後のセンテンスのみ抽出してもらう。 -
本文の抽出
抽出する文章の最初と最後のセンテンスをドキュメントの中で検索して取ってくる
ただし、1. の過程でLLMが変な文字を混ぜてしまうことがあるので完全一致で検索するのではなく、部分一致でも引っ掛かるようにする。
ここで引っ掛からなかった時のことも考慮
その場合は、検索して本文を取ってくるのではなく、見出しに合う文章をLLMに生成してもらうように分岐しておく。 -
格納する
見出しと本文だけでは、何に関することかわからないので見出しごとにタイトルも含めて、ベクトル化してIndexに格納しておく
参考:
Discussion