EN

3.3 固定大小分塊策略

最簡單的切法:每隔固定的字數切一刀,相鄰的塊再重疊一點。

RAG下一篇 →

最直接的分塊方法是固定大小分塊(fixed-size chunking):不管內容是什麼,每隔固定的長度就切一刀。

怎麼運作

設定兩個參數:

  • size:每一塊多長。
  • overlap:相鄰兩塊重疊多少。

程式從頭開始,每次取 size 這麼長的一段,下一段的起點往前移 size - overlap,這樣相鄰的塊就會共用一小段內容。

固定大小分塊:每塊 size 個字,相鄰兩塊重疊 overlap 個字

為什麼要重疊

沒有重疊的話,一個完整的句子或概念,剛好被切在兩塊中間,兩邊都只有一半。有了重疊,被切開的地方會同時出現在前後兩塊裡,至少有一塊能保有完整的上下文。

重疊的代價是:資料量變多、儲存和搜尋成本增加,也可能檢索到內容重複的兩塊。一般會設 size 的 10% 到 20% 左右。

實作

用純 Python 寫就只要幾行:

def fixed_chunks(text, size, overlap):
    """固定大小:每 size 個字切一刀,相鄰兩塊重疊 overlap 個字"""
    step = size - overlap
    chunks = []
    for start in range(0, len(text), step):
        piece = text[start:start + size]
        if piece.strip():
            chunks.append(piece)
        if start + size >= len(text):
            break
    return chunks

拿一份簡單的員工手冊(共 214 個字),用 size=80, overlap=20 去切,得到這樣的結果:

[1] (80 字) '# 員工手冊\n\n## 特別休假\n\n員工在同一公司服務滿六個月未滿一年者,每年有三天特別休假。滿一年未滿兩年者,有七天。滿兩年未滿三年者,有十天。\n\n特別休假的日'
[2] (80 字) '兩年未滿三年者,有十天。\n\n特別休假的日期,由員工和公司協商安排。年度結束時沒有休完的天數,公司應該折算成工資發給員工。\n\n## 加班規定\n\n加班必須事先經主管'
[3] (80 字) '\n\n## 加班規定\n\n加班必須事先經主管同意。平日加班前兩小時,以平日每小時工資的 1.34 倍計算。第三小時起,以 1.67 倍計算。\n\n休息日加班另有規定,'
[4] (34 字) '.67 倍計算。\n\n休息日加班另有規定,不得低於勞動基準法的標準。\n'

看看問題在哪

仔細看這個結果:

  • 第 1 塊的結尾是「特別休假的日」,句子被切到一半。
  • 第 3 塊的結尾是「休息日加班另有規定,」,下一塊開頭卻是「.67 倍計算」,一個數字被切成兩半(1.67 變成「1」和「.67」)。
  • 標題「## 加班規定」被拆開,第 2 塊最後有一半,第 3 塊開頭有一半。
  • 重疊確實發揮作用:第 1、2 塊都有「兩年未滿三年者,有十天」這段。

這就是固定大小分塊的特性。

優缺點

優點

  • 簡單,幾行程式就能做。
  • 結果可預測,每塊大小一致,容易估算成本。
  • 不依賴文件格式,什麼文字都可以切。

缺點

  • 完全不管內容,可能在句子、段落、表格中間切開。
  • 同一個主題可能被分散到好幾塊,不同主題也可能被混在同一塊。

中文要注意的事

  • 切的單位是「字數」還是 token 數要分清楚。嵌入模型的長度上限通常是用 token 算的,而中文一個字常常對應一個或多個 token,所以要預留空間。
  • 要用的 size 可以先用字數估,再用實際的 tokenizer 驗證有沒有超過模型的限制。

什麼時候用它

  • 快速做第一版原型。
  • 資料本身沒有結構,例如逐字稿、長篇純文字。
  • 作為基準:之後試了更複雜的方法,拿它來比較有沒有真的進步。

如果文件本身有標題、段落或句子等明顯結構,內容感知分塊通常更合適。

← 全部文章