Unstract 評測:用 Prompt 把 PDF 變成 JSON,以及 AGPL-3.0 部署前該確認的事
LLM-Driven Extraction of Unstructured Data — Built for API Deployments & ETL Pipeline Workflows
秒懂
- 它是什麼?
- Unstract 把文件抽取從寫 regex 改成寫 prompt,並以 REST API、ETL pipeline、MCP server 三種形式輸出 JSON。本文拆解它的實際架構、部署指令,以及自架時最容易踩到的加密金鑰與版本節奏問題。
- 適合誰用?
- Unstract 適合已經有明確文件類型、想把抽取邏輯從程式碼搬到 prompt 的團隊,尤其是金融、保險、醫療與 KYC 這類欄位固定但版型多變的場景;如果你的文件量極小、或你完全不想維運 Docker 與資料庫,直接呼叫單一 LLM API 會更省事。採用前先確認三件事:第一,跑一次 ./run-platform.sh -h 看懂版本參數,決定你要固定版本還是跟隨最新;第二,把 backend/.env 或 platform-service/.env 裡的 ENCRYPTION_KEY 備份到獨立位置,這是不可回復的;第三,確認你的產品形態是否能接受 AGPL-3.0 的網路服務條款,若你的抽取服務要對外提供,這一步不能跳過。
- 可以商用嗎?
- 可以,但條件嚴格。AGPL-3.0 是網路 copyleft 授權:如果別人透過網路使用你修改過的版本(例如作為託管服務),你必須以同一授權向他們提供原始碼。
- 還在維護嗎?
- 有在維護。儲存庫在最近一天內有新的提交。
- 用什麼語言寫的?
- 主要是 Python(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。
開源專案深度解析
Unstract 要解的是版型漂移,不是 OCR 準確度
多數文件抽取的痛點不在辨識,而在同一種文件換一家供應商就換一套版型。README 的對照表把這件事講得很直白:沒有 Unstract 時,schema 定義要寫 regex、每家供應商建一套模板;用了之後,寫一次 prompt,讓它處理變體。新增一種文件類型,對照表寫的是「幾天開發」對上「Prompt Studio 幾分鐘」。
這個定位決定了它的適用邊界。它服務的是欄位相對穩定、但來源格式持續變動的抽取任務,README 點名的產業是 finance、insurance、healthcare 與 KYC/compliance。反過來說,如果你的文件格式從頭到尾只有一種,而且幾十年不變,regex 或固定模板仍然更快、更便宜、更好除錯,因為它不需要呼叫模型,也不需要維護一整套平台。
真正被解決的問題其實是維護成本的位置轉移:把規則從程式碼搬到 prompt,讓非工程角色也能改抽取邏輯。這個轉移有代價,代價在後面幾節會談。
四個服務組成的平台:frontend、backend、worker、platform-service
README 的架構圖把 Unstract 拆成四個區塊:Frontend、Backend、Worker、Platform Service。這個切法透露了它的資料流。Frontend 是操作介面,你在這裡用 Prompt Studio 定義抽取 schema。Backend 承接 API 請求。Worker 是非同步的執行單元,實際跑抽取工作。Platform Service 則負責平台層級的事務,README 提到的 platform-service/.env 與 backend/.env 並列,代表它有自己的環境設定與憑證。
這種拆法的直接後果是:Unstract 不是一個可以塞進單一 process 的函式庫,而是一組需要協調啟動的服務。README 的系統需求寫得很清楚,Linux 或 macOS(Intel 或 M 系列)、Docker 與 Docker Compose、最少 8 GB RAM、Git。8 GB 是下限,不是舒適值,因為四個服務加上資料庫同時在跑。
Worker 獨立出來這件事值得注意。抽取呼叫外部 LLM,延遲以秒計,把它放在非同步 worker 而不是 API 請求執行緒裡,是合理的設計。但這也意味著你要面對佇列堆積、worker 掛掉後任務卡住這類維運問題,而 README 沒有描述這些失敗路徑的處理方式。這是文件偏薄的地方。
模型供應商方面,README 列出 OpenAI、Anthropic、Bedrock 與 Ollama。Ollama 在名單裡代表它支援本地推論,對不能把文件送出去的場景是必要選項,但本地模型能否達到與雲端模型相當的抽取品質,README 沒有給任何數據,這需要你自己用實際文件驗證。
用 run-platform.sh 起一整套平台
README 的 quickstart 只有四行:git clone、cd、./run-platform.sh,然後開瀏覽器連到 http://frontend.unstract.localhost,用 unstract 這個帳號與同樣是 unstract 的密碼登入。預設帳密是公開的,任何照著 README 跑起來的實例在暴露到網路之前都必須改掉,README 本身沒有在這段加警告。
run-platform.sh 的參數決定了你怎麼管理版本,這比 quickstart 本身重要。不加參數是拉取並執行預設環境設定;-v v0.1.0 指定版本標籤;-u 是升級既有安裝到最新版;-u -v v0.2.0 是升級到指定版本;-b 是本地建置映像;-b -v current 是從工作分支建置並標記為 current;-e 只做環境檔案的設定;-p 只拉映像不啟動;-d 是 detached 模式。
把這些參數放在一起看,可以看出官方預期的維運方式:升級是明確動作,不是自動的。搭配 release 節奏來看,v0.188.0 在 2026-09-09 發布,前一版 v0.187.2 在 2026-09-03,再前一版 v0.187.1 在 2026-09-01。兩週內三個版本,這個頻率意味著如果你用 -u 跟著最新版走,你實質上是在跑一個持續變動的系統。要用在正式環境,-v 指定具體版本並在升級前看 release notes 是比較務實的做法。
部署形態上,README 列出三種輸出方式:REST API 接收文件回傳 JSON、ETL Pipeline 從資料夾拉文件處理後載入倉儲、以及 MCP Server 讓 Claude 這類 AI agent 連接。另外有 n8n node 可以接進既有自動化流程。這三種形態共用同一套 Prompt Studio 定義,所以切換形態不需要重寫抽取邏輯。
ENCRYPTION_KEY 是單點故障,而且沒有復原路徑
README 用一個 WARNING 區塊講這件事:這個金鑰加密 adapter 的憑證,遺失會讓既有 adapter 無法存取。金鑰的位置在 backend/.env 或 platform-service/.env,README 要求你把它複製到安全的位置。
這段警告值得單獨拿出來討論,因為它是整個自架流程裡唯一不可回復的環節。其他設定錯了可以改,容器掛了可以重啟,但金鑰丟了,你存在資料庫裡的 adapter 憑證就解不開。而 adapter 正是 Unstract 連接外部系統的介面,也就是 ETL pipeline 拉文件、載入倉儲所依賴的東西。
README 沒有說明金鑰輪替的流程,也沒有說是否支援多把金鑰並存。這代表如果你的資安政策要求定期輪替加密金鑰,這個需求在目前文件裡找不到對應做法。這不是小問題,是需要向官方確認的事項。同樣地,備份策略也不能只備資料庫,金鑰必須分開保存,否則備份與被備份的資料放在一起,等於沒有備份。
Prompt 取代 regex 之後,換來的是不確定性
把抽取規則從 regex 換成自然語言 prompt,換到的是表達力,付出的是可預測性。regex 對同一份輸入永遠給同一個答案,prompt 加上 LLM 不是。同一個 prompt 在不同模型、不同版本、甚至同一模型的兩次呼叫之間,輸出都可能不同。
這對下游是有影響的。如果你的抽取結果要直接寫進資料庫的強型別欄位,格式漂移會變成寫入失敗。README 強調輸出是 clean JSON,但沒有描述 schema 驗證機制、重試策略或信心分數。這些在正式環境是必要的,目前只能靠外部流程補上。
另一個實際限制是成本結構的改變。regex 的邊際成本是零,LLM 抽取的邊際成本是每次呼叫的 token 費用。文件量大的時候,這個差異會直接反映在帳單上,而且會隨著你調整 prompt、增加重試而放大。README 沒有提供任何成本估算或 token 用量參考,這部分必須用你自己的文件與選定的模型實測。
Prompt Studio 讓非工程角色能改抽取邏輯,這是優點也是風險。改動 prompt 等於改動生產行為,但改動的門檻降低了,如果沒有搭配版本控制與回歸測試,很容易在無意間改壞既有流程。專案本身沒有在 README 描述 prompt 的版本管理方式。
AGPL-3.0 對自架服務的實際意義
Unstract 採用 AGPL-3.0。這個授權與 MIT、Apache-2.0 的關鍵差異在於網路服務條款:如果你修改了程式碼,並讓使用者透過網路與這個修改後的版本互動,你需要向這些使用者提供對應的原始碼。單純在內部使用、不對外提供服務,通常不觸發這個義務。
README 同時指向一個 Enterprise 頁面,這代表專案採用開源核心加商業版本的雙軌模式。對企業使用者來說,這衍生出幾個要釐清的問題:哪些功能在 AGPL 版本、哪些在企業版,以及如果你需要服務水準保證或支援合約,該走哪條路。README 沒有列出功能對照表。
這裡不提供法律意見。可以確定的是,如果你的抽取服務是產品的一部分、要對外提供,AGPL-3.0 的條款需要你的法務看過,而不是由工程團隊自行判斷。如果你的使用情境純粹是內部 ETL,風險輪廓完全不同。
授權之外還有維護成本的問題。專案在兩週內發布三個版本,這個節奏對自架者意味著你要嘛固定版本、定期手動升級,要嘛接受系統持續變動。README 提供的 -u 與 -v 參數讓這兩條路都可行,但沒有描述升級時的資料庫遷移方式或回溯程序。升級前先讀 release notes,是這個專案目前唯一能給的具體建議。
跟直接寫 LLM 呼叫相比,多出來的是平台稅
最直接的替代方案是自己寫:用 OpenAI 或 Anthropic 的 SDK,把文件內容塞進 prompt,要求回傳 JSON,然後自己處理驗證與重試。這條路幾十行程式就能跑起來,沒有 Docker、沒有四個服務、沒有資料庫,也沒有 AGPL 的考量。
差別在於當文件類型從三種變成三十種的時候。自己寫的話,你會開始需要一個地方管理 prompt、需要版本控制、需要知道哪一份文件用了哪個版本的抽取邏輯、需要非工程角色能參與調整。Unstract 的價值就在這裡:它把這些東西變成產品功能,Prompt Studio 管 prompt,API Deployment 與 ETL Pipeline 管執行形態,MCP Server 與 n8n node 管整合。
所以選擇的判準不是技術能力,而是規模與角色分工。文件類型少、只有工程師會碰抽取邏輯,自己寫會更輕。文件類型多、有領域專家需要參與、而且抽取結果要進倉儲或餵給 agent,Unstract 提供的封裝就開始划算。
要注意的是,Unstract 並沒有取代 LLM 供應商,它是在上面加一層。你仍然要自己選模型、自己付 token 費用、自己承擔模型行為改變的風險。它解決的是管理問題,不是模型品質問題。
編輯結論
Unstract 適合已經有明確文件類型、想把抽取邏輯從程式碼搬到 prompt 的團隊,尤其是金融、保險、醫療與 KYC 這類欄位固定但版型多變的場景;如果你的文件量極小、或你完全不想維運 Docker 與資料庫,直接呼叫單一 LLM API 會更省事。採用前先確認三件事:第一,跑一次 ./run-platform.sh -h 看懂版本參數,決定你要固定版本還是跟隨最新;第二,把 backend/.env 或 platform-service/.env 裡的 ENCRYPTION_KEY 備份到獨立位置,這是不可回復的;第三,確認你的產品形態是否能接受 AGPL-3.0 的網路服務條款,若你的抽取服務要對外提供,這一步不能跳過。
社群筆記