jia-hong-peng/rag-to-skill/pdf-ocr-skill
Claude Code and agent skill by jia-hong-peng/rag-to-skill
- community
- ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Checking that the SKILL.md file is still in the repository.
PDF → JSONL,會先判斷是文字型還是掃描型: - 文字型:直接用 PyMuPDF 抽文字(不浪費 token) - 掃描型:用 LLM 視覺能力(Read / view_image)逐頁辨識 嚴禁任何傳統 OCR 引擎(Tesseract / PaddleOCR / EasyOCR)、雲端 OCR API、MCP 圖像工具。 一次只做一本書(單機鎖),完成後清除所有暫存(PNG 與 progress 檔)。 每次最多處理一個 batch(預設 8 頁),支援 --resume;長時間任務必須採用低上下文 append-only 流程。 觸發時機: - 使用者說「OCR 這個 PDF」 - 使用者說「把掃描 PDF 做成 JSONL」 - 使用者說「/pdf-ocr <path>」 - 使用者說「用 LLM 視覺辨識這個 PDF」 典型呼叫: - /pdf-ocr /path/to/book.pdf - /pdf-ocr /path/to/book.pdf /path/to/output.jsonl - /pdf-ocr /path/to/book.pdf --resume - /pdf-ocr /path/to/book.pdf --batch 8 --dpi 120
Install
npx vskill@latest install jia-hong-peng/rag-to-skill/pdf-ocr-skillSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
PDF → JSONL(智慧路由:文字型直取 / 掃描型 LLM Vision)
核心原則:本技能先判斷 PDF 類型再決定做法。- 有文字層的 PDF → 直接抽文字(PyMuPDF),零 token 成本- 掃描型 PDF → LLM 視覺辨識(Read / view_image),唯一允許的辨識方式- 嚴禁任何傳統 OCR 引擎、雲端 OCR API、第三方 OCR 服務、MCP 圖像工具這些規則不可協商,違反即視為任務失敗。
強制規則(Hard Rules — 違反即任務失敗)
0. Guard Hook 機制(強制使用)
本 skill 內建 pdf_ocr_guard.py 作為可執行的 guard hook。Codex/Claude 目前不會自動在每個 shell tool call 前注入 skill hook,因此使用本 skill 時必須在下列檢查點手動執行 guard;少跑任一檢查即視為流程不完整:
| 檢查點 | 必跑指令 | 目的 | |
|---|---|---|---|
| 啟動前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-single-book --current-output "<OUTPUT_PATH>" | 阻止同時處理多本書 | |
| 啟動前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-duplicate-output "<PDF_PATH>" "<OUTPUT_PATH>" | 阻止同一本 PDF 已有同名 JSONL 卻在 ocr-jsonl/ 另做一份 | |
| 啟動/續跑前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-existing-jsonl "<OUTPUT_PATH>" | 阻止沿用污染 JSONL | |
| 續跑前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py validate-progress "<PROGRESS_FILE>" | 阻止沿用高上下文舊 progress | |
| 每次準備執行 shell 命令前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-command -- <COMMAND...> | 阻止 Tesseract/Paddle/EasyOCR/雲端 OCR/MCP 圖像工具 | |
| 建立 worker subagent 時 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-subagent-hook | 阻止非 fresh worker、fork 主上下文或缺少任務包的 OCR subagent | |
| 渲染後 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py write-manifest "<PDF_PATH>" "<OUTPUT_PATH>" --png-dir "<PNG_DIR>" | 保存 PDF/頁圖 SHA256 證據 | |
| 寫出 JSONL 後 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py validate-jsonl "<OUTPUT_PATH>" | 驗證 source、頁序、record 序 | |
| 完成前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py finalize-audit "<OUTPUT_PATH>" --total-pages <TOTAL> | 產生 final hash chain | |
| 刪 PDF 前 | python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py deletion-gate "<OUTPUT_PATH>" --total-pages <TOTAL> --keep-pages | 確認可刪 PDF 的條件 |
Claude Code 安裝位置若是 ~/.claude/skills/pdf-ocr/,同一套指令改用該路徑。
Claude Code 會透過本 skill frontmatter 的 TaskCreated / SubagentStart hook 自動執行 check-subagent-hook。Codex CLI 0.128 的 lifecycle hooks 目前不攔截 spawn_agent 建立事件;Codex 執行本 skill 時仍必須使用 spawn_agent(..., fork_context:false, agent_type:"worker"),並可用 check-subagent-payload 驗證任務包。
A. 永不允許的辨識方式
| 類別 | 禁止項目(範例) | |
|---|---|---|
| 命令列 OCR 引擎 | tesseract, paddleocr, easyocr, cnocr, ocrmypdf | |
| Python OCR 套件 | pytesseract, paddlepaddle-ocr, easyocr, mmocr, cnocr | |
| 雲端 OCR API | Google Cloud Vision OCR、Azure Computer Vision、AWS Textract、阿里雲 / 騰訊雲 / 百度 / 有道 OCR | |
| 第三方 OCR 服務 | ABBYY FineReader、Adobe Acrobat OCR、商務 OCR SaaS | |
| MCP 圖像理解工具 | mcp__MiniMax__understand_image、任何 mcp__* 圖像相關工具 | |
| 自寫包裝 | 自行寫的 Tesseract / Paddle / EasyOCR wrapper、subprocess 包裝、shell 腳本呼叫 OCR 引擎 |
若你正準備執行tesseract、paddleocr、easyocr、pytesseract等指令,立刻停止並告知使用者你正準備違反 skill 規則,請使用者裁示是否取消任務。
B. 兩條合法路徑
| 路徑 | 適用 | 工具 | source 欄位 | |
|---|---|---|---|---|
| 文字直取 | 有文字層的 PDF(電子書、有 OCR 過的 PDF) | PyMuPDF page.get_text() | pdf_text_layer | |
| LLM Vision | 掃描型 PDF(純圖像、古籍、影印本) | Claude Read / Codex view_image | llm_vision |
「LLM Vision 辨識」 = 讓 LLM 本身直接看 PNG 圖片。禁止先用 OCR 引擎轉文字再交給 LLM 整理。
C. JSONL 必填驗證欄位
每一筆 record 必須包含:
source 欄位必填,且僅能為以下兩值之一:
"llm_vision"(掃描型 PDF 走 LLM Vision 辨識)"pdf_text_layer"(文字型 PDF 走 PyMuPDF 抽文字)
任何其他值(tesseract, paddleocr, chi_tra_vert, mcp_minimax, manual 等)即視為違規輸出,整批作廢重做,不可只修補單筆。
C2. 頁序與忠實性欄位(Hard Audit)
為避免 append 亂序、漏頁、重複頁、上下文壓縮失憶或 worker 偷吃步,每筆 JSONL 必須滿足:
| 欄位 | 規則 | |
|---|---|---|
record_index | 全檔從 0 開始,逐筆 +1,不可跳號、重複或倒退 | |
page_index | 0-based PDF 頁碼,必須單調不倒退 | |
page_number | 必須等於 page_index + 1 | |
page_record_index | 同一頁內從 0 開始逐筆 +1 | |
page_sha256 | LLM Vision 路徑必填,等於該頁 PNG 在 manifest 中的 SHA256 | |
text | 必須是逐字轉錄或圖示忠實描述;不可摘要、補寫、推測 |
每頁即使 SKIP,也要寫一筆 skip:true record,包含 skip_reason、page_index、page_number、page_sha256。這樣 validate-coverage 才能證明整本每一頁都被看過。
D. 既有 JSONL 完整性檢查(Step 0 強制執行)
D0. 目錄批次處理的既有成果優先規則
處理整個資料夾時,必須先掃描每個 PDF 同目錄是否已有同名 JSONL:
- 對
/path/book.pdf,若/path/book.jsonl已存在,預設視為已完成成果,必須跳過該 PDF。 - 不可因為要把輸出集中到
ocr-jsonl/,就另建/path/ocr-jsonl/.../book.pdf.jsonl重做同一本書。 - 若既有 JSONL 的 schema 不同於 pdf-ocr 新 schema,仍不可直接重做;必須回報使用者「已有舊成果,需要轉換/標準化或明確重做」。
- 只有使用者明確指定「重做、覆蓋、忽略原 JSONL」時,才能用新輸出路徑;並且要先說明會消耗 token。
啟動 OCR 前必跑:
若要明確重做,必須使用:
執行 --resume 或對既有 JSONL 重做時,必須先:
- 讀取 JSONL 第一筆 record,檢查
source欄位 - 若
source不在合法清單(llm_vision/pdf_text_layer):
- 標示此 JSONL 為「已污染」
- 立即通知使用者來自非法 OCR 流程
- 不可使用 `--resume` 沿用,只能整本重做
- 建議刪除該檔再啟動全新 OCR
- 若
source欄位不存在:
- 視為可疑,告知使用者,請求確認
E. Bash 指令防火牆
執行流程中,禁止透過 Bash 工具呼叫下列關鍵字:
tesseract,pytesseractpaddleocr,paddle_ocr,paddleocr-cli,paddle ocreasyocr,cnocr,ocrmypdf- 雲端 OCR CLI:
gcloud vision,aws textract,az cognitiveservices vision,aliyun ocr,tencent ocr
每次準備執行 shell 命令前,先用 guard 檢查完整命令字串:
若 guard 輸出 BLOCKED: 或非 0 exit code,必須停止,不可改寫命令繞過。
如使用者明確要求改用上述工具,禮貌拒絕並說明本 skill 唯一支援文字直取 / LLM Vision;使用者堅持,請使用者離開本 skill 自行處理。
F. 一次只做一本書(單機鎖機制)
啟動前必須確認目前沒有其他 OCR 任務進行中:
- 掃描
/tmp/pdf-ocr-*/與*.ocr-progress.json是否存在 - 若有 ≥ 1 個未完成的進度檔(
completed_pages 數 < total_pages):
- 拒絕啟動新書 OCR
- 告知使用者:「目前還有
<那本.pdf>在進行中(X/Y 頁),請先完成或清除」 - 請使用者選擇:
- (a) 先
--resume完成那本 - (b) 手動刪除
*.ocr-progress.json與對應/tmp/pdf-ocr-xxx/後再開新書
平行多本會塞爆暫存空間、混淆進度、每批接近 context 上限只會降低品質。強制串行。
G. 完成後清除暫存(強制執行)
全部頁面 OCR 完成(Step 6 寫出最終 JSONL)後,必須先完成 finalize-audit。PNG 是否刪除取決於 PDF 保存策略:
- 刪除 PROGRESS_FILE:
{OUTPUT_PATH}.ocr-progress.json - 若保留原始 PDF,才可刪除 PNG 暫存目錄:
/tmp/pdf-ocr-xxxxxxxx/ - 若準備刪 PDF,必須先把 PNG 移到正式 archive/workdir,不可刪 PNG
- 確認本次任務沒有未審計暫存
- 回報「✅ 暫存/證據保存策略已完成」
使用者只應拿到輸出的 JSONL 檔案,不該看到 progress 或 PNG 殘留。文字直取路徑沒有 PNG 暫存,仍須確認沒生出多餘檔案。
H. 長時間上下文控制(10 小時任務強制)
掃描型 LLM Vision OCR 可能跑數小時到十多小時。為避免主上下文滿出、壓縮後遺失狀態,必須遵守:
- 不可把整本 records 放進對話或 progress:
PROGRESS_FILE只保存狀態,不保存全文 records。 - JSONL 採 append-only:每完成一頁,立即把該頁 records 追加到
OUTPUT_PATH,再更新completed_pages。 - 主上下文只保留控制資訊:PDF 路徑、輸出路徑、總頁數、已完成頁數、目前章節、下一批頁碼、最近 1-3 筆短摘要。不要貼整頁 OCR 文字回主對話。
- 預設 batch 降為 8 頁:一般書籍用
--batch 8;密集古籍、直書、表格多時用--batch 3到--batch 5。 - 每 60-90 分鐘做一次 checkpoint:執行
validate-jsonl,回報完成頁數與剩餘頁數即可,不貼內容。 - 上下文壓縮前後可恢復:恢復工作只依賴
OUTPUT_PATH、PROGRESS_FILE、PNG_DIR,不可依賴對話裡的未落盤內容。 - 每個 batch 前讀取最後狀態:worker 必須從
PROGRESS_FILE與OUTPUT_PATH最後一筆取得record_index、current_chapter、item_chunk_counts,不可憑對話記憶續接。 - 每個 batch 後做硬驗證:必跑
validate-jsonl;失敗即停止,不可繼續 append。 - 正式 artifact 不可覆寫:page artifact、batch manifest、run manifest、final report、deletion report 都用 run id/generation id;重試時產生新 generation,不覆寫舊正式檔。
- 原子寫入:所有正式 JSON artifact 必須先寫
*.tmp,flush/fsync 後 atomic rename,再 fsync parent directory。
Subagent / Fresh Worker 模式(建議用於長時間 OCR)
若平台支援 subagent,掃描型 OCR 應使用「每 batch 一個 fresh worker」:
- 主 agent 只負責:前置檢查、渲染 PNG、分配頁碼、驗證 JSONL、清理暫存。
- worker agent 負責:讀取本批 PNG、用 LLM Vision 轉錄、append JSONL、更新 progress。
- worker 必須是全新上下文:不要 fork 主對話全文;只傳必要任務包。
- 每個 worker 完成後關閉;下一批重新開新 worker,避免同一個 worker 累積十小時上下文。
- 不要平行開多個 worker 處理同一本書。單書仍然串行,避免章節狀態與 chunk index 競爭。
worker 任務包只包含:
Codex 可用 spawn_agent,設定 fork_context:false,agent type 用 worker;Claude Code 若沒有等效能力,則用短 batch + --resume 重啟新會話達到同樣目的。
建立 worker 前若平台沒有自動 Task/Subagent hook,先把即將送出的任務包寫成 JSON 後執行:
I. 原始資料保存與刪除限制
在 JSONL 完成後立刻刪 PDF 是高風險操作,預設禁止。 因為 JSONL 是衍生資料,不等同原始掃描證據。若真的需要刪除 PDF,必須先完成以下全部條件:
- 產生
{OUTPUT_PATH}.manifest.json,包含原始 PDF SHA256、每頁 PNG SHA256、輸出 JSONL 路徑、total_pages。 - 完成
finalize-audit,產生{OUTPUT_PATH}.final-report.json。 - 至少保留以下二選一:
- 原始 PDF;或
- 每頁 PNG + manifest + JSONL。
- 執行
deletion-gate;若 PDF 與 PNG 都要刪除,guard 必須拒絕,且不可宣稱可審計。
最佳實務:把原始 PDF 移到 archive/ 或冷儲存,不要刪除;若要節省空間,優先刪 /tmp/pdf-ocr-* PNG,保留 PDF + JSONL + manifest。
J. 95 分模式:Artifact / Hash Chain / Lease
若目標是 24 小時長跑後允許刪 PDF,必須啟用 95 分模式:
- 正式 workdir:使用
<OUTPUT>.ocr-work/,不要把唯一頁圖證據放/tmp。 - page artifact:worker 不直接 append 最終 JSONL;每頁先產生
pages_ocr/page_000001.g0001.ocr.json。 - batch manifest:每 batch 產生
batch_manifest.json,列出 page artifact SHA256、worker id、lease token、generation。 - central state:主 agent 維護 run state,worker 只提交 completion manifest,不直接宣告全域完成。
- lease token:每個 batch 有 lease token、created_at、expires_at;逾期後只能用新 generation 重試。
- canonical assembler:最終 JSONL 只能由 deterministic assembler 依
page_index ASC, page_record_index ASC組裝,record_index由 assembler 產生。 - hash chain:page artifact hash -> batch manifest hash -> run manifest hash -> final report hash -> deletion report hash。
- QA layer:文字正確性不能由 hash 證明;必須標記低信心頁、抽樣人工審查或第二 pass 差異審查。
參數解析
| 參數 | 說明 | 預設值 | |
|---|---|---|---|
PDF_PATH | PDF 檔案路徑(必要) | — | |
OUTPUT_PATH | 輸出 JSONL 路徑(選用) | PDF 同目錄 + .jsonl | |
--resume | 從上次中斷點繼續 | false | |
--batch N | 每次最多處理頁數(僅 LLM Vision 路徑) | 8 | |
--dpi N | 圖片渲染解析度(僅 LLM Vision 路徑) | 120 | |
--force-ocr | 強制走 LLM Vision,跳過文字型偵測 | false | |
--long-run | 啟用長時間低上下文模式:batch 預設 8、append-only、可用 fresh worker | true |
PROGRESS_FILE = OUTPUT_PATH + ".ocr-progress.json"
Step 0:前置檢查
- 確認
PDF_PATH存在 - 若
OUTPUT_PATH未指定,設為PDF_PATH同目錄、副檔名換成 jsonl - Guard:單機鎖檢查:
``bash python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-single-book --current-output "<OUTPUT_PATH>" `` 若有未完成任務 → 依 §F 處理
- Guard:同名既有成果檢查:
``bash python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-duplicate-output "<PDF_PATH>" "<OUTPUT_PATH>" ` 若 PDF 同目錄已有 <PDF_STEM>.jsonl,必須跳過或請使用者明確確認重做,不可另輸出到 ocr-jsonl/` 製造重複成果。
- Guard:既有 JSONL 完整性驗證:
``bash python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py check-existing-jsonl "<OUTPUT_PATH>" ` 若 OUTPUT_PATH 已存在且 source 不合法,視為污染,不可 --resume`
- Guard:progress 狀態檔驗證:
``bash python3 ~/.codex/skills/pdf-ocr/pdf_ocr_guard.py validate-progress "<OUTPUT_PATH>.ocr-progress.json" ` 若 progress 內含完整 records`,代表是舊版高上下文格式;必須先遷移或重建 progress,不可直接續跑
Step 0.5:判斷 PDF 類型(強制執行 — 避免浪費 token)
在啟動任何 PNG 渲染或 LLM Vision 前,必須先判斷 PDF 是文字型還是掃描型:
讀取輸出的 TYPE: 與 AVG_CHARS_PER_PAGE::
| TYPE | 平均字元/頁 | 處理方式 | |
|---|---|---|---|
text | ≥ 50 | 走 Step 1A 文字直取路徑(不啟動 LLM Vision) | |
scanned | < 50 | 走 Step 1B–6 LLM Vision 路徑 | |
| 邊界 | 30–50 | 抽樣讀 1–2 頁 PNG 確認後再決定 |
如使用者用 --force-ocr 旗標強制走 OCR,跳過此判斷直接進 Step 1B。
過往教訓:曾把文字型電子書(裡面就有可抽的文字)硬走 OCR,浪費大量 token。判斷錯了等於 skill 失敗。
Step 1A:文字直取路徑(適用 TYPE:text)
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingpdf-ocr-skill/skill.md
Popularity
- Repository stars
- 64
- Repository forks
- 8
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 18 May 2026, 5 months ago.
Extension points
hookPre/post lifecycle hooks
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/jia-hong-peng/rag-to-skill/pdf-ocr-skill)