給 LLM 用的 PDF 轉 Markdown

為 ChatGPT、Claude 或你自己的流程準備乾淨的 Markdown:token 數一直看得到,每個精簡開關都顯示能省多少,分塊可以下載為 JSONL。

把 PDF 拖到這裡

也可以貼上或選擇檔案。一次最多 20 個,就在這個分頁裡轉換。

手邊沒有檔案?試試

檔案只在這個瀏覽器分頁裡讀取,從不上傳。

為什麼給模型 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": "..."
}

幾行程式碼就能把它匯入你用的向量資料庫。

一個好用的流程

  1. 拖入 PDF,先看待檢查頁面。轉得不對的頁面,修正或用 OCR 重新辨識。
  2. 打開那些省下的 token 值得的精簡開關;想讓模型引用來源,就保留連結。
  3. 用於聊天,就複製 Markdown 貼進去。用於流程,就拿 JSONL 分塊。

一切都在你的瀏覽器裡完成,這一點在這裡很重要:人們餵給模型的文件,常常是內部報告、合約或研究資料,不該再上傳到又一個服務。

常見問題

對 LLM 來說,Markdown 真的比純文字好嗎?

對有結構的文件,通常有幫助:標題告訴模型各節如何巢狀,表格讓每個數字緊挨著它的標籤。如果只是一頁散文,差別不大。你可以用開關保留或拿掉這些結構。

分塊大小該設多少?

針對文件做問答,先從 512 或 1,024 token 開始。小分塊和具體問題對得更準,大分塊能把更多上下文放在一起。分塊分頁下方的摘要會顯示分塊數量和最大的一塊,效果一眼就看得到。

token 是在我的裝置上數的嗎?

是的。分詞器和轉換器的其他部分一樣在分頁裡執行,不會為了計數把任何東西傳給 OpenAI 或別人。

能為資料集處理很多 PDF 嗎?

一次最多可以拖入 20 個,並打包成一個 .zip 全部下載。幾千個檔案的話,腳本更合適,見 用 Python 把 PDF 轉成 Markdown。