検索のために文書をうまくチャンク分割する
検索はチャンクの良さ以上にはなりません。適切な一節がそのまま、文脈とともに返ってくるよう文書を分割する方法を紹介します。
検索システムが失敗するとき、その原因はモデルや検索アルゴリズムではなく、チャンクであることがしばしばです。チャンクとは、インデックス化し取得する単位、すなわちクエリと照合され、コンテキストとしてモデルに渡される文書の一片です。チャンクの切り方が悪ければ、完璧な検索でさえ、有用であるには小さすぎる、関連的であるには大きすぎる、あるいは答えの真ん中で割れた断片を返してしまいます。チャンク分割を正しく行うことは地味であり、下流のすべてがどれだけうまく機能するかを決めるのです。
なぜチャンクサイズが下流のすべてを決めるのか
クエリごとに文書全体をモデルに与えることは、たいていできません。無駄ですし、関連する一節を何ページもの無関係なテキストに埋めると、答えは良くなるどころか悪くなります。そこで文書をチャンクに分割し、それぞれを埋め込み、クエリに合致するチャンクだけを取得します。したがってチャンクは、検索の単位であると同時にコンテキストの単位でもあります。そのサイズと境界が、モデルが何を見られるかを決めるのです。
この二重の役割が緊張を生みます。正確な検索マッチであるほど小さいチャンクは、モデルが答えるのに十分なコンテキストを運ぶには小さすぎるかもしれません。自己完結するほど大きいチャンクは、複数のトピックを混ぜて信号を薄めるため、特定のクエリにきれいに合致するには広すぎるかもしれません。良いチャンク分割とは、この緊張を解消する技です。正確に取得できるほど特定的で、かつそこから答えられるほど完全なチャンクを作るのです。
文書の構造を尊重する
最悪のチャンク分割の仕方は、内容に関わらずN文字ごとに切ることです。それは文の途中、表の途中、思考の途中に落ちる境界を保証し、答えを二つのチャンクにまたがらせて、どちらにも全体が含まれないようにします。より良いデフォルトは、文書自身の構造、すなわち段落、節、見出し、リスト項目に沿って切ることです。これらの境界は、著者がすでに関連するアイデアをまとめたから存在するのであり、それを尊重するチャンクは、まとまった意味の単位になりがちです。
文書が違えば、自然な継ぎ目も違います。文章は段落と節できれいに区切れます。コードは関数や論理的なブロックで区切れます。FAQは質問と回答のペアごとに区切れます。表とリストはそのまま保ちたいものです。半分の表はたいてい役に立たないからです。原則はどれも同じです。継ぎ目がどこにあるかを文書に語らせ、任意のオフセットではなく継ぎ目で切るのです。構造を意識したチャンクは、まとまったチャンクです。
チャンクは固定の数ではなく、問いに合わせてサイズを決める
普遍的に正しいチャンクサイズは存在しません。正しいサイズは、期待する問いの種類に依存するからです。ユーザーが狭い、事実レベルの問いを尋ねるなら、小さなチャンクのほうがより正確に取得できます。合致する一節が周囲の素材で薄められないからです。ユーザーが節全体を統合する必要のある広い問いを尋ねるなら、チャンクはその広がりを運べるだけ大きくなければなりません。さもないとモデルは断片を受け取り、要点を取り逃します。
実践的な一手は、完全な答えに何が必要かを考え、それを収めるようチャンクのサイズを決めることです。チャンクは理想的には、単独で読んで意味が通るだけの周囲のコンテキストを含むべきです。直前の文に完全に依存し、その文が別のチャンクにある一節は、うまく取得されず、答えはさらに悪くなります。実際に来る問いに対して自己完結する意味の単位となるチャンクを目指し、丸い数字を選んで祈るのではなく、それにサイズを導かせましょう。
オーバーラップで答えが半分に切れるのを防ぐ
構造を意識した境界をもってしても、答えが境界をまたぐことはあります。問いのコンテキストが一つのチャンクの末尾にあり、その結論が次のチャンクの冒頭にある、という具合です。オーバーラップが標準的な対処法です。連続するチャンクが端で少しテキストを共有するようにし、境界付近の一節が少なくとも一つのチャンクにそのまま現れるようにします。小さなオーバーラップは、答えを真ん中で割らないための安価な保険です。
やりすぎないことです。重いオーバーラップはインデックスを膨らませ、同じクエリにほぼ重複したチャンクを返し、繰り返しでコンテキストの予算を浪費します。目標は、境界をまたぐ答えをそのまま保つのにちょうど足りるだけの共有テキストです。次のチャンクに持ち越す控えめな末尾であって、大きく冗長なウィンドウではありません。チャンクサイズと同様、適切な量はコンテンツに依存します。原則は、答えが半分に切れるのを止める最小のオーバーラップを使うことです。
チャンクが意味を成すのに必要なコンテキストを保つ
文書から引きはがされたチャンクは、文書が暗黙に与えていた情報を失います。それがどの節から来たのか、文書が何についてのものか、三段落上の「それ」が何を指すのか、といったことです。そのチャンクが単独で取得されると、モデルはテキストは見るが枠組みは見えず、答えが損なわれます。その枠組みを少しだけ各チャンクとともに持ち運ぶこと、すなわち文書のタイトル、節の見出し、チャンクが何に関するものかの短い注記が、切断によって投げ捨てられたコンテキストを取り戻します。
これは検索の正確さと、曖昧な一節にとって最も重要です。「上限は従来の値の2倍に引き上げられる」と書かれたチャンクは、どの上限でどの従来の値かを知らなければほぼ無価値です。節の見出しを携えたチャンクは、モデルと検索インデックスに拠り所を与えます。修正は小さなものです。各チャンクに付けたヘッダー行か一文のコンテキストです。そしてそれは、取得されるものと、モデルがそれをどう扱うかの両方を一貫して改善します。
チャンク分割を実際のクエリに対して評価する
チャンクを眺めても、チャンク分割が良いかどうかは分かりません。実際のクエリを走らせ、適切な一節がそのまま使える形で返ってくるかを確認することでしか分かりません。正しいソース一節が分かっている代表的な問いの一式を集め、検索を走らせ、返ってきたものを精査しましょう。関連するチャンクは現れたか。完全だったか、それとも割れていたか。無関係なチャンクがそれを押しのけたか。
チャンク分割は、一度下す決定ではなく、その一式に対して調整するパラメータとして扱いましょう。境界戦略、目標サイズ、オーバーラップを変え、同じクエリを走らせ、どの設定が正しく完全な一節をより頻繁に取得するかを比較します。あなたのコーパスにとって最良のチャンク分割戦略は実証的な問いであり、その答えは文書の種類とクエリのスタイルによって異なります。検索が機能するチームは、測定したチームです。チャンクサイズを当てずっぽうで決めて先へ進んだチームではありません。
まとめ
検索はチャンク次第で生きも死にもします。任意のオフセットではなく文書自身の構造に沿って切り、実際に来る問いに対して完全な答えを収めるようチャンクのサイズを決め、境界付近の答えがそのまま保たれるよう控えめなオーバーラップを使いましょう。タイトルや見出しといったコンテキストを少しだけ各チャンクとともに持ち運び、単独でも意味が通るようにします。そして全体を、答えの分かっている実際のクエリに対して証明し、境界、サイズ、オーバーラップを実証的に調整しましょう。良いチャンク分割は、機能しているときは見えず、機能しないときは根本原因です。ここに労力を費やせば、パイプラインの残りはずっと楽になります。
