National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 72 24°C PM2.5 13
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 12

文件切塊

切多大、要不要重疊,切壞了檢索就找不到
Interaction實作 25 minute(s)

Learning Objectives

  • 說明為什麼要把文件切塊,以及切太大、切太小各有什麼問題
  • 用固定長度與重疊切文字,並處理邊界情況
  • 依文件結構切塊,比較不同切法的真實檢索結果
  • 用自己的問題集決定切法,不依賴通用的數字

長文件不能整份拿去算一個向量

上一課的手冊已經切成一節一節。實際拿到的常常是一份長長的 PDF 或網頁,要自己切。為什麼不把整份算成一個向量就好?

  • 向量會糊掉: 一個向量要代表整份文件在談的所有事,和任何一個具體問題的相似度都不會突出。
  • 送不進去或太貴: 就算找到了,整份文件送進模型,費用高,也可能超過上下文長度(第 2 課)。
  • 引用不精確: 使用者想知道「哪一條」寫的,你只能回答「在這份文件裡」。

所以要切塊(chunking),每一塊各算一個向量。但切法會直接影響找不找得到答案。

這一課的教材是為課程編的虛構文件《優學大學學生校外實習辦法》,共十條、930 字,配上 12 個問題。它不是任何學校的規定。 每個問題都標出答案的原文,只有原文完整出現在取回的切塊裡才算命中。

逐步看:固定長度與重疊

請注意 start 怎麼移動,以及這條規定被切在哪裡。第一組沒有重疊,第二組每塊和前一塊重疊 8 個字。

逐步看:切壞了,回答就出問題

同一個問題「實習成績怎麼算?」,三種切法各取回最相似的一塊,交給模型回答。模型的回答是真實錄下來的。

從這個例子看到的事

切法 取回的那一塊 模型的回答
每塊 100 字、不重疊 結尾停在「實習機構評量佔」 說明資料不足,比例未提供
每塊 100 字、重疊 30 字 包含三項比例 答出 40%、30%、30%
依條文切 完整的第七條 答出 40%、30%、30%,還補上逾期的扣分規定

我們在提示詞裡要求資料不足時要明說,這次它照做了;這只是一次錄製的結果,不保證每次都如此。檢索看起來成功了(相似度最高的確實是講成績的那一塊),問題要到看回答才會發現。這就是為什麼切塊要用問題集評估,不能只看切出來的樣子。

逐步看:用問題集比較切法

每種切法的每一塊都事先呼叫 API 算好向量。這裡看三種切法:每塊 100 字不重疊、每塊 400 字不重疊、依條文切。除了 recall,也要看取回的內容有多長。

這份文件的完整結果

我們多算了幾組。「答案完整」是答案原文完整落在某一塊裡的題數,「前 3 塊字數」是取回前 3 塊的平均字數:

切法 塊數 答案完整 recall@1 recall@3 前 3 塊字數
60 字、不重疊 16 7 / 12 5 7 175
60 字、重疊 20 23 11 / 12 3 8 179
100 字、不重疊 10 11 / 12 6 9 294
100 字、重疊 30 13 12 / 12 7 12 298
200 字、不重疊 5 11 / 12 6 9 565
200 字、重疊 50 6 12 / 12 5 10 587
400 字、不重疊 3 12 / 12 8 12 930
400 字、重疊 100 3 12 / 12 6 12 1130
依條文切 10 12 / 12 10 12 275

幾件值得注意的事,有些和直覺不同:

  • 依條文切最好:一塊就是完整的一條,字數最少、recall@1 最高。這份文件結構整齊,換成沒有標題的逐字稿就無法這樣切。
  • 重疊有幫助,但不是一定:100 字加重疊後 recall@3 從 9 升到 12;200 字加重疊只從 9 升到 10,recall@1 還從 6 掉到 5。
  • 切太小不一定比較準:60 字的切塊,答案常常直接被切斷,加了重疊 recall@1 反而是最低的 3。
  • 400 字的 12 / 12 要打折看:這份文件太短,3 塊全部取回就是整份。指標好看,但檢索什麼也沒做。文件比較長時結果會不同。

沒有萬用的切塊大小。 網路上看到的建議數字只是一個起點,適不適合要看你的文件和問題。依文件結構切、加上用自己的問題集量一次,比背一個數字可靠。

另外兩個常見做法,有需要時可以試:長條文再切小塊時,在每一塊前面附上標題(例如「第七條 成績評定:」),讓向量保留脈絡;或用小塊來檢索、回傳時附上前後文。

互動練習:調整切法,看答案還在不在

左邊的切塊結果會隨著滑桿當場重算。表格列出的幾組設定,每一塊都用真實模型算過向量,所以看得到檢索結果;其他設定只有切塊,沒有向量。點表格裡的切法可以直接跳過去。

實作:chunk_text

完成 chunk_text(text, size, overlap):回傳切好的字串串列。要處理的邊界情況:

  • 文字是空字串時回傳空串列。
  • 最後一塊已經到結尾就停止,不要多切出一塊只有重疊內容的。
  • overlap 大於或等於 size 時,用 raise ValueError("overlap 要小於 size") 拒絕,否則迴圈永遠走不完。

這題不呼叫模型。

你的輸出
預期輸出

小測驗:文件切塊

1.

下面的程式會印出什麼?

text = "abcdefg"
size, overlap = 3, 1
start = 0
out = []
while start < len(text):
    out.append(text[start:start + size])
    if start + size >= len(text):
        break
    start += size - overlap
print(out)
2.

把切塊長度調得很小(例如 60 字),在本課的實驗裡發生什麼事?

3.

重疊(overlap)的主要目的與代價是什麼?

4.

同學說:「我查到切塊的最佳大小是 500 字,照用就好。」你會怎麼回應?

第 1 次作答

重點整理

  • 切塊讓向量聚焦、讓送進模型的內容變少、讓引用可以指到具體段落。
  • 固定長度最簡單,但會切在句子中間;重疊降低這個風險,也帶來重複的內容。
  • 文件有結構時優先依結構切。本課的依條文切字數最少、recall@1 最高。
  • 評估要同時看 recall 和取回的份量;切太大時 recall 好看,只是因為把整份文件都取回了。
  • 沒有萬用的切塊大小,要用自己的問題集試。

下一課: 把檢索到的內容組進提示詞,從頭寫一個 RAG,讓模型依據資料回答並附上引用。

這一課完成了!
Next lesson:從頭寫 RAG
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。