RAG・検索基盤

セマンティックチャンクとは|同じ平均51文字でも、文字数で切ると1/3、近さで切ると3/3

セマンティックチャンクとは何をする方法なのか文字数で切るのと何が違うのかしきい値はどう決めるのか

文書を分けるとき、文字数で切ると話題の途中で切れることがあります。前半が宿泊費、後半が社用車という塊ができます。

実際に測ったところ、同じ平均51文字でも、文字数で切ると3話題中1つ、近さで切ると3つすべてが1つの塊に収まりました。

この記事の要点

  • 文字数で切ると、話題が1つに収まったのは3つ中1つ
  • 近さで切ると3つすべて
  • どちらも平均51文字で、塊の大きさは同じ
  • しきい値を上げすぎると0/3まで落ちる

同じ平均51文字でも、文字数で切ると1/3、近さで切ると3/3

話題が3つ入った本文を5通りに分けました。塊の大きさが同じでも、切る位置の決め方で結果が3倍違います。

セマンティックチャンクがどう効くのかを、実際に分けて測りました。用意したのは宿泊費・社用車・健康診断という3つの話題が並んだ本文9文です。

分割も判定も本当に実行しています。ただし文の近さは共通する2文字の割合で測っており、埋め込みによる判定ではありません。

javascript
// 隣り合う文の近さ。共通する2文字の割合で測る
const sim = (a, b) => {
  const A = new Set(bigrams(a)), B = new Set(bigrams(b));
  let n = 0; for (const w of A) if (B.has(w)) n++;
  return n / Math.max(A.size, B.size);
};

// 近さがしきい値を下回ったところで切る
const bySim = (th) => {
  const out = []; let cur = SENTS[0];
  for (let i = 1; i < SENTS.length; i++) {
    if (sim(SENTS[i - 1], SENTS[i]) < th) { out.push(cur); cur = SENTS[i]; }
    else cur += SENTS[i];
  }
  out.push(cur);
  return out;
};
text
隣り合う文の近さ
  1文目 → 2文目: 0.31
  2文目 → 3文目: 0.29
  3文目 → 4文目: 0.00  ← 話題の切れ目
  4文目 → 5文目: 0.16
  5文目 → 6文目: 0.18
  6文目 → 7文目: 0.00  ← 話題の切れ目
  7文目 → 8文目: 0.29
  8文目 → 9文目: 0.33

分け方              かたまり数  平均文字数  話題が1つに収まった数
40文字ごと                   4個        38文字             0 / 3
60文字ごと                   3個        51文字             1 / 3
80文字ごと                   2個        77文字             0 / 3
近さ0.15で切る                3個        51文字             3 / 3
近さ0.30で切る                7個        22文字             0 / 3

4行目と5行目を見比べてください。どちらも3個・平均51文字なのに、1/3と3/3で違います

話題の切れ目は数字に出る

上の一覧が仕組みを示しています。同じ話題の中では0.16から0.33ですが、話題が切り替わるところは2箇所とも0.00です。

宿泊費の文と社用車の文には、共通する2文字がありません。切れ目が数字としてはっきり見えるので、しきい値を置けます。

大きさが同じでも中身が違う

60文字ごとに切った場合も3個できます。ところが境目が話題の途中に来るので、1つの塊に2つの話題が混ざります

収まったのは3つ中1つだけでした。塊の数も平均文字数も同じなので、これらの数字を見ているだけでは差に気づけません

しきい値を上げすぎると割れる

最後の行が失敗例です。しきい値を0.30にすると、7個に割れて0/3になりました。

同じ話題の中の0.16や0.18も切れ目と判定されるためです。切れ目の値と、同じ話題の値の間に置くのが条件になります。

塊の数も大きさも同じ。違うのは境目の位置だけ。

単位: 話題40文字ごと(38文字)0話題60文字ごと(51文字)1話題近さ0.15で切る(51文字)3話題近さ0.30で切る(22文字)0話題本文9文・話題3つでの実測。近さは共通する2文字の割合で測っており、埋め込みによる判定ではない。
図1 ── 分け方ごとの、話題が1つに収まった数
出典LlamaIndex Developer Documentation「Node Parser Usage Pattern」2026-08-18 確認
Node parsers are a simple abstraction that take a list of documents, and chunk them into Node objects, such that each node is a specific chunk of the parent document.
原文LlamaIndex Developer Documentation「Node Parser Usage Pattern」 この内容の有効期限2027-02-18

セマンティックチャンクとは何をする方法なのか

隣り合う文の近さを見て、離れたところで切ります。切る位置を文字数ではなく内容で決める方法です。

セマンティックチャンクは、隣り合う文がどれだけ近いかを測り、離れたところで切る方法です。切る位置を内容で決めます。

手順は3つ

  1. 文に分ける。句点などで区切る
  2. 隣り合う文の近さを測る。埋め込みの近さを使うのが一般的
  3. しきい値を下回ったところで切る。ここが境目になる
  4. 文字数で均等に切る。この方法とは別物

2番目が方法の中心です。前の節では共通する2文字の割合で代用しましたが、実際には文を数値に変えて近さを測ります

分ける部品として提供されている

この処理は、文書を扱う枠組みに部品として用意されています。LlamaIndexでは文書の一覧を受け取り、それぞれが元の文書の一部となる単位に分ける仕組みだと説明されています。

同じ文書では、この部品は単体でも使えるとされています。文書を取り込む流れの中に組み込むこともできます。

分けるのに計算が要る

文字数で切る方法との違いは、計算の量にも出ます。文の数だけ数値に変える処理が必要です。

文書が1万件なら、その文の数だけ処理が走ります。文書を入れ直すたびに掛かるので、取り込みの時間に効いてきます

余談 近さの一覧を先に見る

測ってみて実際的だったのは、しきい値を決める前に、隣り合う文の近さを全部並べて見ることでした。前の節の一覧のように、切れ目が0.00で同じ話題が0.16以上なら、その間に置けばよいと一目で分かります。

出典LlamaIndex Developer Documentation「Node Parser Usage Pattern」2026-08-18 確認
Node parsers can be used on their own:
原文LlamaIndex Developer Documentation「Node Parser Usage Pattern」 この内容の有効期限2027-02-18

セマンティックチャンクの落とし穴

しきい値を文書ごとに合わせないと崩れます。1つの値をすべての文書に当てる形では、割れすぎるものが出ます。

セマンティックチャンクの難しさは、しきい値が文書によって変わることにあります。前の節の0.15は、あの本文での値です。

文書によって近さの水準が違う

同じ話題を続ける文書では、隣り合う文の近さが全体的に高くなります。逆に1文ごとに話題が変わる箇条書きでは、全体的に低くなります

0.15という値を後者に当てると、すべての文が別々の塊になります。前の節の0.30の行と同じ状態です。

塊の大きさが揃わない

もうひとつの性質が、塊の大きさが均等にならないことです。話題の長さがそのまま塊の長さになります。

長い話題は1つの大きな塊になり、渡す量が増えます。上限を別に設けて、超えたら分けるという組み合わせが要ります。渡す量の話はチャンク戦略の記事で扱っています。

確かめ方

確かめるのは話題が1つの塊に収まっているかです。前の節では、話題ごとの文が1つの塊に入り、他の話題が混ざっていないかを数えました。

この判定はコードで書けます。塊の数や平均文字数だけを見ていると、1/3と3/3の差に気づけません

しきい値は文書ごとに違う。1つの値を全部に当てない。

充足 2 / 4隣り合う文の近さを一覧で見た切れ目が0.00、同じ話題が0.16以上と分かればしきい値を置ける話題が1つに収まったかを数えている塊の数も平均文字数も同じなのに、1/3と3/3で差がついた1つのしきい値を全文書に当てている近さの水準は文書で変わる。低い文書ではすべての文が別々に割れる塊の大きさに上限を設けていない長い話題がそのまま1つの塊になり、渡す量が増える本文9文・話題3つでの実測にもとづく。しきい値0.30では7個に割れて0/3になった。
図2 ── 近さで分けるときの点検項目
出典LlamaIndex Developer Documentation「Node Parser Usage Pattern」2026-08-18 確認
Node parsers can be included in any set of transformations with an ingestion pipeline.
原文LlamaIndex Developer Documentation「Node Parser Usage Pattern」 この内容の有効期限2027-02-18

よくある質問

文の近さはどう測るのですか
この計測では、隣り合う文に共通する2文字の割合を使いました。実際の製品では埋め込みの近さを使います。
話題の切れ目は数字で見えますか
見えます。この計測では、同じ話題の間は0.16から0.33、話題が切り替わるところは0.00でした。
しきい値はどう決めますか
切れ目の数字と、同じ話題の数字の間に置きます。この計測では0.15にしました。0.30まで上げると同じ話題まで割れます。
文字数で切る方法は使えないのですか
話題が1つしかない文書なら問題ありません。複数の話題が混ざる文書で差が出ます。

まとめ

  • セマンティックチャンクは文の近さで境目を決める方法
  • 文字数で切ると3話題中1つしか収まらない
  • 近さで切ると3つすべて
  • しきい値を上げすぎると0/3まで落ちる

今日から始められること

  1. 分けたい文書に、話題がいくつ入っているかを数える
  2. 隣り合う文の近さを計算して並べる
  3. 話題の切れ目で数字が下がっているかを見る
  4. 下がっている値と、同じ話題の値の間にしきい値を置く

実務で組んだセマンティックチャンクのワークフローには、値段が付きます

同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。

出品の仕組みを見る