Firecrawl PDF Inspector 實測:幾毫秒判斷 PDF 要不要 OCR

Firecrawl 開源的 pdf-inspector 用 Rust 在本地判斷 PDF 是原生文字還是掃描檔,再決定哪些頁面送 OCR。這篇實際安裝 1.15.0,用自建的純文字、純影像與混合檔案測分流欄位的實際行為,整理基準測試的解讀方式,以及接進文件管線前要留意的欄位落差。

用 AI 摘要這篇文章:

把一批 PDF 餵給 AI 之前,幾乎每條文件管線都會撞上同一個分岔:有的檔案本身就有文字層,直接抽取就好;有的只是掃描成圖片的紙本,非要光學辨識不可。最省事的做法是全部送 OCR 或視覺模型,代價是把已經是文字的頁面再辨識一次,帳單和等待時間都跟著膨脹。Firecrawl 在 2026 年 2 月把自家處理 PDF 時的判斷環節開源成 pdf-inspector,用 Rust 寫成本地程式庫,照官方文件的說法,它讀取 PDF 的結構就能在 10 到 50 毫秒內判出這份檔案是原生文字、掃描檔、純影像還是混合型,同時列出需要 OCR 的頁碼。

我在 Mac 上用 pip 裝了當下的最新版 1.15.0,自己做了三種測試檔實際跑一遍:兩頁純文字、一頁純影像、五頁裡夾一頁影像的混合檔。純文字檔的表現符合預期,分類、抽取、轉成 Markdown 一次完成,反覆計時都在 1 毫秒以下,比官方給的區間還快上一截。真正值得花一整篇講的是混合檔的行為:文件層級 API 回傳的「需要 OCR 的頁碼」清單,把四個純文字頁也一起標了進去,而逐頁可靠的分流結果,其實要從另一個抽取 API 的回傳裡拿。兩個介面對同一份檔案給出不同答案,這件事 README 沒有提醒。

GitHub 上 firecrawl/pdf-inspector 儲存庫首頁,顯示 MIT 授權與一萬六千多顆星Pin
pdf-inspector 在 GitHub 上的儲存庫首頁,截至 2026 年 8 月 18 日約 16,000 顆星、1,100 多個 fork,授權條款為 MIT。

送 OCR 之前,先花幾毫秒問一個問題

企業報告、合約、發票、論文這類文件,很多本來就是 Word 或排版軟體直接匯出的原生文字 PDF,文字和座標資訊都在檔案裡,根本不需要先把頁面變成圖片再辨識。Firecrawl 給出的數字是自家經手的 PDF 中約 54% 屬於這一類,這是作者的宣稱,抽樣基礎沒有公開,你的文件來源組成不同,比例自然會不一樣。但方向大機率成立:知識庫與檢索管線裡,原生文字檔佔比通常不低,全部送 OCR 等於把最貴的一步平白加在多半的檔案上。

近年把 PDF 丟給 AI 的應用愈來愈多,從 對著論文問答的聊天工具 到各種文件摘要服務,第一步都是把頁面變成文字。這一步的品質與成本,直接決定後面模型看到什麼。分流器要做的事情很單純:在貴的 OCR 之前放一個便宜的檢查站,原生文字頁走本地抽取,只有缺文字層的頁面才往後送。

三種測試檔,實際跑一遍

測試檔是我自己做的,盡量貼近兩種極端與一種中間狀態。純文字檔有兩頁,用標準字型排出固定文字;純影像檔把文字畫成圖片再塞進 PDF,檔案裡沒有任何文字物件;混合檔有五頁,其中一頁是影像頁,另外四頁是原生文字。三種檔案都只有幾 KB 到幾十 KB,計時結果不能直接代表幾百頁的正式文件。

測試檔判定結果信心分數被標成要 OCR 的頁抽出內容
兩頁純文字text_based0.50完整抽出並轉 Markdown
一頁純影像scanned0.95第 1 頁無,回傳空值
五頁混合(4 文字+1 影像)image_based0.80第 1 到 5 頁全部逐頁 API 只標影像頁
2026 年 8 月 18 日以 pip 安裝的 1.15.0 在 Apple M4 Max 上實測,測試檔為自建的小型 PDF。

純文字檔抽出的 Markdown 內容與原稿逐字相符,純影像檔回傳掃描檔判定,頁碼清單正確指向那一頁,內容自然抽不出來。計時方面,完整處理(分類加抽取)反覆跑大多落在 0.3 到 0.4 毫秒,單純分類約 0.2 毫秒。這數字比官方帳面上的 10 到 50 毫秒快很多,原因是我的檔案極小,演算法掃的內容流也單純,真實世界的文件頁數多、字型雜,落在官方區間比較合理。

中文文件要多看一眼。我另外用 macOS 內建的轉檔產生一份中文原生文字 PDF 餵進去,判定完全正確:原生文字、信心滿分、不需要 OCR,編碼問題的旗標也沒有亮。但抽出來的文字語序被打散了,一句「這是中文原生文字頁」變成左右交錯的三段,每個字都解對,組回來的句子卻讀不通。這種檔案分類器幫不上忙,它是抽取階段把行的分組判斷錯了。官方功能表列有 CID 與 Type0 字型的解碼支援,中文字多半正是走這條路,所以中文環境接這個工具,分類可以信,抽取的結果請逐份抽驗語序,這一步省不得。

幾毫秒的判斷是怎麼做出來的

它不是把頁面渲染成圖片再分析,而是直接解析 PDF 的交叉參照表與頁面樹,接著掃內容流裡的運算子:出現 TjTJ 代表頁面有文字顯示指令,出現 Do 代表引用了圖片物件。根據取樣頁面上這些指令的分佈,歸類成四種型別並給出 0 到 1 的信心分數。因為不必完整載入文件物件,幾百頁的檔案也能在毫秒級得到判定。

掃描策略有四種可以選。預設的 EarlyExit 會掃到第一個非純文字頁就停,適合只想知道「能不能直接抽」的管線;Full 掃完全部頁面,用來精確區分混合型與掃描型;Sample(n) 均勻抽幾頁,給頁數極多又只需要快速定性的場景;Pages 則只查指定頁碼。這套設計背後的假設很清楚:判定這一步要愈便宜愈好,貴的處理留給確定需要的頁面。

最容易被串錯的一個欄位

回到那份五頁混合檔。呼叫文件層級的 detect_pdf,回傳型別是 image_based、信心 0.80,而「需要 OCR 的頁碼」清單給了 1 到 5 頁全部。這份檔案明明有四頁是純文字,其中任何一頁送 OCR 都是重複工。我把影像頁換到第一頁、中間、最後一頁各測一次,結論一致:只要整份被判成非純文字型,這個清單就把所有頁都放進去。

同一份檔案改呼叫逐頁抽取的 extract_pages_markdown,結果就對了:只有影像頁被標成需要 OCR,理由欄寫著 scanned,其餘四頁都抽出了正確的文字。換句話說,逐頁分流的承諾是真的,但它住在抽取 API 的回傳裡;文件層級那個欄位在混合檔上等於全部標記。README 對這個欄位的說明是「列出缺少文字的具體頁碼,讓 OCR 可以逐頁路由而非全有或全無」,對照我實測的行為,兩者有明顯落差。版本是 1.15.0,之後會不會修正我不知道,接上管線的當下值得自己驗一次。

另外兩個邊角也記錄下來。拿一份真實世界的原生文字測試檔跑,process_pdf 把唯一一頁標成需要 OCR,detect_pdf 卻說不用,兩個介面對同一檔案給出不同答案,而且被標記的那頁附帶的理由清單是空的;同時它照樣把這頁的 Markdown 抽得乾淨完整。再來是結構損壞的檔案,我把資源字典故意寫壞,它不報錯,回傳掃描檔判定加 0.9 的信心,但頁數是 0。管線上要自救不難:串逐頁 API、用已知文件抽驗、看到頁數為 0 就擋下來轉人工,這三道防線成本都很低。

基準測試要連著時間基準一起看

pdf-inspector README 中的基準測試表格,列出五個本地解析引擎的成績Pin
README 的基準測試表,資料更新於 2026 年 7 月 31 日,測試機為 Apple M4 Pro,成績取五次完整跑的中位數。

官方在 README 公布的成績使用 opendataloader-bench 這份 200 份 PDF 的公開語料,只比較不依賴 OCR 與模型的本地引擎。pdf-inspector 綜合分 0.875,LiteParse 0.873,差距 0.002,實質是並列;表格辨識 0.814 是這組最高,閱讀順序 0.915 也居首,但標題辨識 0.788 輸給 LiteParse 的 0.811。速度差距比較實在:200 份跑完 0.470 秒對 0.750 秒,而 PyMuPDF4LLM 和 MarkItDown 都要 16 秒以上。這是官方自己跑的結果,測試環境、語料組成都寫得清楚,拿來當參考可以,當成絕對排名就過頭了。

對文件管線來說,比排名更有用的解讀是:在原生文字檔上,它的優勢在閱讀順序、表格結構與速度,這三項恰恰是餵給大型語言模型時最影響品質的;標題層級如果對你的下游很重要,0.811 對 0.788 的差距值得拿自己的文件再驗一次。

開源核心裡,留著通往付費管線的欄位

Firecrawl 本業是收費的網頁與文件抓取服務,把 PDF 前處理環節用 MIT 條款開源,看起來像把城牆拆了一段,細看比較像把城門口的分流亭搬出去。OCR 相關的回傳結構裡有一個 pages_recommending_hosted 欄位,逐頁標記哪些頁面建議改走官方的代管文件管線。本地能處理的它在本地處理,本地處理起來吃力的頁面,回傳結構會替城內的付費服務指路。這不是什麼陰謀,商業模式寫在 API 的形狀裡,明白這一層再決定要不要接,比單看開源兩個字務實。

同一家的開源腳步不止這個專案,先前的 Open Scouts 網頁監控平台 也是 Firecrawl 拿 MIT 釋出的作品;而站上先前介紹過的 E-Ink 網頁轉 EPUB 工具,底層呼叫的正是 Firecrawl 的付費 API,同一套技術以開源程式庫與計費服務兩種姿態存在,是這家公司一貫的打法。

想全程留在自己機器上也有路。選擇性 OCR 用的是 PP-OCRv6 Small 模型,在本地跑,但 PDFium 與 ONNX Runtime 這兩個執行依賴要另外裝,模型檔也是外部下載,不是裝完套件就有。官方文件明講,完整的 OCR 路徑只在 Linux x64 的 CI 上端對端驗過,macOS 與 Windows 的外部執行依賴路徑屬於預覽狀態;Intel 版 macOS 的 Python 套件存在,對應的 ONNX Runtime 官方包沒有。這條路徑我沒有實際架起來驗,以上是官方文件的說法;要依賴本地 OCR 的場景,部署前自己跑一次是必要的。

版本節奏也值得知道。專案 2026 年 2 月建立,六個多月衝到一萬六千顆星,釋出頻率很高。三個套件庫在 8 月 11 日之前各走各的版本號,npm 在 1.13、PyPI 在 0.2.7、crates.io 在 0.1.8,當天起三邊一起跳到 1.14 並保持同步,之後一週內又推了三個版本。修得快是好事,用它的人要跟上:鎖版本、升級前重跑自己的測試檔,特別是上面那個分流欄位的行為。

四種安裝方式,瀏覽器就能先試

核心是 Rust,官方提供四種接法:Python 用 pip 裝 pdf-inspector、Node 用 npm 裝 @firecrawl/pdf-inspector、Rust 專案直接從 crates.io 拉,命令列工具則用 cargo 安裝後得到 pdf2mddetect-pdf 兩個指令。Python 與 Node 的預編譯包涵蓋主流的 Linux、macOS 與 Windows 平台,npm 安裝時只抓符合當前平台的那份。Node 端還貼心做了同步與非同步兩組介面,同步版會佔住事件迴圈,伺服器場景用非同步版丟給執行緒池。

不想裝任何東西,官方還有一個 WebAssembly 展示頁,同一顆 Rust 核心編譯成瀏覽器版本,拖檔案進去就地分類並轉 Markdown,檔案不會上傳,單檔上限 25 MB。展示頁以原生文字檔為主,掃描檔丟進去只會得到型別判定,不要期待它當場辨識。需要正經批次處理,還是回到本地程式庫或命令列,搭配站上先前介紹過的 Speedpdf 這類線上轉檔工具時,也提醒一句:雲端工具的隱私邊界和本地程式庫是兩回事。

pdf-inspector 官方瀏覽器展示頁,提供拖放 PDF 檔案就地分類與轉換的介面Pin
官方 WebAssembly 展示頁,解析在瀏覽器本地完成,檔案不上傳,單檔上限 25 MB。

誰該接,誰先繞路

適合接的場景很明確:每天要吃進來源混雜的 PDF,原生文字與掃描件混在一起,又對成本或隱私有感的管線。知識庫、法務文件流、發票處理都算,分流省下來的 OCR 呼叫是持續的錢,本地抽取也讓大多數檔案不必離開自己的環境。反過來,來源單一且確定都是原生文字的管線,本來就不需要這層判斷;庫存幾乎全是老紙本掃描檔的,分流無利可圖,直接挑一個強的 OCR 才是正事。

接的時候記住三件事:分流用逐頁抽取 API 的回傳,不要直接信文件層級的頁碼清單;上線前拿自己的一批已知文件對答案,特別是混合型檔案;鎖定版本,升級時重驗行為。這三件事都做完,這個工具的價值就會站在你這邊:判斷快、抽取乾淨、MIT 條款沒有後顧之憂,難處理的頁面要送哪裡,決定權也還在你手上。

Sliven 褚崇名
Sliven 褚崇名

每日分享科技新知、免費資源以及 WordPress、虛擬主機相關主題,任何問題歡迎在科技月球下方留言,或是發送 Email 至 [email protected] 與我聯繫。

文章: 911

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


Share to...