Extract PDF text in your browser with LiteParse for the web
59 分鐘 vibe coding、0 行程式碼親自看過,Simon Willison 把 LiteParse PDF 解析工具移植進瀏覽器
- LiteParse 用啟發式算法解決 PDF 多欄排版問題,完全不依賴 AI 模型,速度快且可離線
- Claude Code 59 分鐘完成移植,Simon 本人連一行 HTML 或 TypeScript 都沒看過
- 工具完全在瀏覽器端執行不對外傳資料,GitHub Pages 免費部署,安全與成本雙無憂
59 分鐘、0 行程式碼親自審閱——Simon Willison 用 Claude Code(Anthropic 的 AI 程式設計助手)把 LlamaIndex 的 PDF 解析工具 LiteParse 從 Node.js CLI 搬進純瀏覽器環境,連一行 HTML 或 TypeScript 都沒有看過,最終部署在 GitHub Pages 免費上線。整個過程他形容是「最純粹的 vibe coding」,卻又認為這個案例在技術判斷上是合理且可推薦的。
LiteParse 的空間文字解析技術原理
LiteParse 是 LlamaIndex(開源 AI 應用框架公司)推出的開源 PDF 文字擷取工具,以 Node.js CLI(命令列介面)形式提供。它最大的特點是完全不依賴 AI 模型:採用傳統 PDF 解析技術,遇到影像型 PDF(掃描件)才退回使用 Tesseract OCR(開源光學字元辨識引擎)處理。
它要解決的核心難題叫「spatial text parsing(空間文字解析)」。PDF 格式本身不保證文字的儲存順序和視覺閱讀順序一致,雙欄排版、表格、浮動圖注等情況下,直接讀取 PDF 的文字流可能毫無意義。LiteParse 用啟發式算法(heuristics,依規則判斷而非機器學習)偵測多欄排版,把文字重新排列成線性、符合閱讀習慣的流序。
文件中另一個值得注意的功能是「Visual Citations with Bounding Boxes(帶邊界框的視覺引用)」:在 RAG(retrieval-augmented generation,檢索增強生成,讓 AI 根據文件回答問題)情境下,回答問題時可附上原 PDF 頁面截圖和標示框,提升答案可信度。LiteParse 底層依賴 PDF.js 和 Tesseract.js 兩個 JavaScript 函式庫,而這兩個庫本就可以在瀏覽器環境運行——這正是後來移植工作的技術基礎。
從 iPhone 到 Claude Code:59 分鐘完成瀏覽器移植
Simon 最初是在 iPhone 上使用 Claude 網頁介面嘗試 LiteParse,上傳一份 PDF 後請 Claude 直接 clone GitHub 倉庫並試跑。他隨後問了一個關鍵問題:「這個函式庫能在瀏覽器裡跑嗎?」Claude 的回答讓他確信技術上可行,而 LiteParse 之所以還沒有瀏覽器版,僅僅是因為「還沒有人做」。
Simon 隨即打開筆電,切換到 Claude Code,fork 原倉庫、建立新 branch,把 Claude 的研究結果存成 notes.md,然後告訴它:「把這件事做成一個網頁 app,先把詳細實作計畫寫成 plan.md。」他習慣在這類專案中要求 Claude 先輸出 plan 文件,方便後續討論與修改——例如 Claude 原本計畫把 PDF 截圖功能延到 v2,他直接下指令要求 v1 就做完。
計畫確認後,他說了句「build it」,然後去做別的事、刷 Duolingo,偶爾回來補充需求。Claude Code 從這個指令到完成,總共花了 59 分鐘。為了驗證 Claude 沒有偷懶——例如把關鍵功能標成 TODO 或假裝完成——Simon 用 GPT-5.5(OpenAI,他有搶先使用權)要它描述 Node.js CLI 版與瀏覽器版的技術差異,得到詳細且正確的對比後才放心。
TDD、Playwright 與 Safari Bug:開發過程的幾個細節
在對 Claude Code 的一系列指令中,Simon 要求採用 Playwright(微軟推出的端對端瀏覽器測試框架)進行紅綠 TDD(test-driven development,先寫測試再寫實作,測試先失敗才算有效)。他也要求「small commits along the way(每個步驟各自一個 commit)」,認為這有助於讓 AI 一次聚焦一個問題,也讓事後審閱更容易。
開發過程出現了一個典型的跨瀏覽器問題:Chrome 和 Firefox 正常,Safari 出現「Parse failed: undefined is not a function」。Simon 把錯誤訊息直接貼給 Claude Code 並點出是 Safari,Claude 快速定位並修復。UI 細節方面,他直接截了一張 Firefox 上長檔名破版的截圖貼給 Claude,讓它看圖修 bug——他形容這個做法「效果出乎意料地好」。
開發伺服器部分,他開了另一個 Claude Code session 詢問怎麼即時預覽,被告知用 npx vite 啟動本地開發伺服器。部署流程由第三個獨立的 Claude Code session 處理,設定 GitHub Actions:每次 push 先跑 Playwright 測試,通過後用 Vite(前端建置工具)打包並自動部署到 GitHub Pages,整個流程零費用。
Vibe Coding 的邊界:Simon 自己怎麼看這個案例
Simon Willison 對「vibe coding」有嚴格的個人定義:不是指「用 AI 輔助寫程式」,而是指「完全不看、不在乎 AI 寫出什麼程式碼」。按他的標準,LiteParse 瀏覽器版是他做過最純粹的 vibe coding——寫這篇文章時才去確認 Claude 到底用了 JavaScript 還是 TypeScript。
他認為這個案例是「安全的 vibe coding」,理由有三:第一,靜態瀏覽器端工具的「blast radius(爆炸半徑)」幾乎是零——出 bug 的後果頂多是解析某份 PDF 失敗,不影響任何伺服器或用戶資料。第二,所有 PDF 處理都在本地瀏覽器執行,他查看 network panel 確認解析過程中沒有任何額外外部請求,安全審查因此不必要。第三,這個案例仍然需要工程判斷:識別出 LiteParse 可以被移植、選對函式庫組合、決定用 TDD 控制品質,這些都是有意識的技術決策。
他目前尚未對原 LiteParse 倉庫發 PR,已開了一個 issue,歡迎原團隊取用這個瀏覽器版作為官方功能的起點。
把靜態頁面、瀏覽器端執行、GitHub Pages 疊在一起,vibe coding 的爆炸半徑可以小到近乎無害——這才是讓人放心推薦的結構性前提。