為什麼給模型 Markdown 而不是 PDF
把 PDF 附到聊天裡,應用程式會替你擷取文字,但你看不到模型實際拿到了什麼。先自己轉換有三個好處:
- 看得到文字。 壞掉的表格、錯亂的分欄、沒有文字的頁面,會在把模型搞糊塗之前就暴露出來。
- 結構保留下來。 標題、清單和表格保留為模型讀得懂的 Markdown,而不是一串平鋪的文字行。
- 更省 token。 頁碼、重複的頁首、行尾連字號和排版留白都會拿掉,上下文視窗能更多地留給內容。
這個頁面打開時已經依這個目的調好了設定:不保留圖片,每頁開頭加一個 <!-- Page N --> 註解方便模型引用頁碼,並拿掉圖片行。
可信的 token 計數
Markdown 上方的數字,是你將要複製或下載的內容的準確 token 數,包括 front matter 和頁碼標記。計數使用 o200k_base,也就是 GPT-4o 及之後 OpenAI 模型的編碼。Claude 等其他模型用各自的分詞器,對它們來說這個數字是接近的估計值,不是精確值。
為 LLM 精簡下的每個開關,在你打開之前就會顯示它能為你的檔案省多少 token:
| 開關 | 作用 |
|---|---|
| 去掉連結網址 | 保留連結文字,拿掉 URL |
| 去掉粗體和斜體 | 拿掉 ** 和 * 標記 |
| 去掉圖片行 | 不留圖片預留位置,也不留圖片連結 |
| HTML 標籤轉成純文字 | <sup>、<sub> 和 <br> 變成純文字 |
| 正規化字元 | fi 這類連字變成 fi,奇怪的空白變成一般空白 |
| 緊湊表格 | 拿掉空欄和儲存格周圍的空白 |
因為不必重新讀取 PDF,開關切換只要幾毫秒。
給 RAG 用的分塊
檢索需要把文件切成小到能做向量嵌入、又能獨立讀懂的片段。分塊分頁會替你切分 Markdown:
- 先依標題切。 只要能避免,分塊就不會從某一節的中間開始,所以每塊只講一個主題。
- 不超過你選的 token 上限,可選 256 到 8,192。比上限大的章節在句子之間切開,大表格在列之間切開,並重複表頭列。
- 帶著標題路徑。 每個分塊都知道自己上面的各級標題,例如
方法 › 資料蒐集,也可以用它們開頭,這樣檢索到的分塊依然說得清自己來自哪裡。 - 帶著頁碼,回答可以指回原文第 12 頁。
下載 JSONL 得到的檔案每行一個 JSON 物件:
{
"id": "report.pdf#3",
"source": "report.pdf",
"chunk": 3,
"headings": ["Methods", "Data collection"],
"page_start": 4,
"page_end": 5,
"tokens": 812,
"text": "..."
}
幾行程式碼就能把它匯入你用的向量資料庫。
一個好用的流程
- 拖入 PDF,先看待檢查頁面。轉得不對的頁面,修正或用 OCR 重新辨識。
- 打開那些省下的 token 值得的精簡開關;想讓模型引用來源,就保留連結。
- 用於聊天,就複製 Markdown 貼進去。用於流程,就拿 JSONL 分塊。
一切都在你的瀏覽器裡完成,這一點在這裡很重要:人們餵給模型的文件,常常是內部報告、合約或研究資料,不該再上傳到又一個服務。
常見問題
對 LLM 來說,Markdown 真的比純文字好嗎?
對有結構的文件,通常有幫助:標題告訴模型各節如何巢狀,表格讓每個數字緊挨著它的標籤。如果只是一頁散文,差別不大。你可以用開關保留或拿掉這些結構。
分塊大小該設多少?
針對文件做問答,先從 512 或 1,024 token 開始。小分塊和具體問題對得更準,大分塊能把更多上下文放在一起。分塊分頁下方的摘要會顯示分塊數量和最大的一塊,效果一眼就看得到。
token 是在我的裝置上數的嗎?
是的。分詞器和轉換器的其他部分一樣在分頁裡執行,不會為了計數把任何東西傳給 OpenAI 或別人。
能為資料集處理很多 PDF 嗎?
一次最多可以拖入 20 個,並打包成一個 .zip 全部下載。幾千個檔案的話,腳本更合適,見 用 Python 把 PDF 轉成 Markdown。