3秒でわかる
長いデータを扱いやすい大きさに切り分けた一片のこと。RAG で文書を検索単位に分けるときや、通信データを届いた順に処理するときに登場します。
もう少し詳しく
どういうものか
大きなデータを、そのままでは扱いにくいときに切り分けた一片を指します。使われる場面は主に 2 つあります。ひとつは、長い文書を検索や埋め込みの単位に分けるとき。もうひとつは、通信で受け取ったデータを全部そろうのを待たずに、届いた分から順に処理するときです。
どちらも「全体を一度に扱えない、または扱うと効率が悪い」という制約から来ています。切り方をどう決めるかが、そのまま結果の質に響きます。
なぜ必要か
RAG の文脈では、モデルに渡せる文字数に上限があることが出発点です。100 ページの社内規程をまるごと渡すことはできないため、質問に関係する部分だけを取り出して渡す必要があります。取り出す単位が細かすぎると文の意味が切れ、粗すぎると関係ない話が大量に混ざって、本当に必要な記述が埋もれます。
通信の側では、応答が完成するまで何も表示されない待ち時間を無くすためです。生成 AI の回答が少しずつ流れて表示されるのは、届いた一片ごとに画面へ足しているからです。
具体例
文書を分ける際は、隣り合う一片を少し重ねておくと、境界で意味が切れる問題を減らせます。
def split_text(text, size=500, overlap=100):
chunks = []
start = 0
while start < len(text):
end = start + size
chunks.append(text[start:end])
start = end - overlap # 100 文字ぶん重ねて次へ
return chunks
doc = open("handbook.md", encoding="utf-8").read()
for i, c in enumerate(split_text(doc)):
print(i, len(c), c[:30].replace("\n", " "))実務では文字数で機械的に切るより、見出しや段落の区切りを優先して分けたほうが検索精度が上がります。
つまずきやすいところ
固定の文字数だけで切ると、表や箇条書きが途中で分断されます。「対象者」の行と「金額」の行が別々の一片に入ってしまえば、どちらを引いても答えにならない断片が返ります。
重なりを大きく取りすぎる失敗もあります。半分近く重ねると保存量が増え、検索結果に似た内容が並んで、渡せる枠を同じ話で埋めてしまいます。1 割から 2 割程度から始めて、実際の検索結果を見ながら調整します。
切り出した文章だけでは意味が通らないことも見落としがちです。「この場合は申請が必要です」という一片だけを取り出しても、何の場合か分かりません。どの文書のどの見出しの下から来たかを一緒に持たせておくと、この問題は大きく減ります。
似た用語との違い
トークンはモデルが文章を扱う最小単位で、日本語では 1 文字が 1 つ以上のトークンに対応します。上限として数えられるのはトークン数で、切り分けの単位として人が指定するのは文字数や段落であることが多く、両者は別の尺度です。バッチは処理をまとめて一括で流す考え方で、大きなものを分ける方向とは逆になります。