一打開編程書 PDF,文字順序亂掉、程式碼缺行、頁碼和版本資訊消失,最後生成的 Skill 只會「講概念」卻不能可靠執行。
最快的解法是採用三段式架構:本週先完成 PDF 解析,再建立保留來源的 Knowledge Base,最後才把觸發條件、工具呼叫和驗證流程封裝成 Agent Skill。只有內容短小、穩定且不需要頻繁引用原頁時,才適合直接寫入 Skill。
這篇文章適合三類讀者:需要處理包含程式碼、表格和掃描頁的編程 PDF 使用者;正在比較「全文放入 Skill」與知識庫檢索方案的 Agent 開發者;以及準備批量維護多本技術書籍的團隊。
先確定三層架構:Knowledge 保存事實,Skill 負責行動
不要把整本書直接貼進 Agent Skill。這會同時帶來三個問題。
第一,Skill 變得過長,觸發條件、操作步驟和背景知識混在一起,Agent 難以判斷何時應該使用哪一段內容。第二,書籍更新後,你需要重新修改整個 Skill,而不是只替換受影響的章節。第三,回答無法穩定回溯到書名、章節、頁碼和版本,出錯時很難定位。
較穩定的拆法如下:
| 層級 | 保存內容 | 主要責任 | 不應承擔的工作 |
|---|---|---|---|
| PDF 解析層 | 原始文字、版面、圖片、頁碼 | 將合法 PDF 轉成可檢查資料 | 直接決定 Agent 行為 |
| Knowledge Base | 章節、段落、程式碼、版本、引用來源 | 供檢索、比對與回答回溯 | 自動執行高風險程式 |
| Agent Skill | 觸發條件、檢索順序、工具呼叫、驗證流程 | 把知識轉成可重複任務 | 複製整本書的全部內容 |
LlamaIndex 將資料載入流程拆成載入、轉換、索引與儲存等階段;其 Document 和 Node 也能保存 metadata 與來源關係。這正好適合用來建立可追蹤的 Knowledge 層。你可以參考官方 Documents 與 Nodes 說明及官方 Ingestion Pipeline 文件。
第一步:先判斷 PDF 類型,再決定解析路線
PDF 不等於文字文件。你至少要先分成三類:
- 文字型 PDF:可以用滑鼠選取文字,複製後仍大致可讀。
- 掃描型 PDF:每頁本質上是圖片,直接呼叫文字提取通常得到空白。
- 複雜版式 PDF:包含雙欄、表格、浮動圖片、圖片程式碼或特殊字型。
文字型 PDF 建議先使用保留頁面與區塊位置的解析方式。PyMuPDF 提供 text、blocks、words、dict 等不同輸出形式;其中 blocks 可保留文字區塊的邊界位置,words 則能提供單字座標。這些資訊可用於修正雙欄閱讀順序、剔除頁眉頁腳,並找回程式碼區塊。詳情可查看PyMuPDF 文字提取文件與TextPage 結構說明。
解析後要檢查三項內容:
- 章節標題是否依照原書順序排列。
- 頁眉、頁腳、重複頁碼是否被誤當成正文。
- 引號、底線、特殊符號和程式碼縮排是否出現編碼污染。
不要只輸出純文字檔。至少同時保留原始頁碼、區塊座標和解析器版本,否則後續的引用回溯會失去依據。
第二步:掃描版編程書如何提取程式碼
掃描版編程書最容易出現「文字看起來完整,但程式碼不能執行」的情況。OCR 可能把 0 和 O、1 和 l、反引號和單引號混淆,也可能吞掉縮排、括號或換行。
因此,不要對整本 PDF 無差別 OCR。先用低成本方式找出沒有文字層或文字品質異常的頁面,再只對這些頁面進行 OCR。對於表格、雙欄和圖片程式碼,還要個別抽查原頁。
Unstructured 的 PDF 分割流程提供 auto、fast、hi_res 和 ocr_only 等策略。官方文件也說明,fast 適合一般文字內容,hi_res 會利用版面資訊處理複雜文件,而 ocr_only 主要面向圖片型內容。你可以參考官方 PDF partitioning strategies 文件。
| PDF 狀態 | 優先方案 | 必做檢查 | 常見失敗 |
|---|---|---|---|
| 可選取文字、單欄 | 直接提取文字與區塊 | 閱讀順序、頁眉頁腳 | 段落順序錯亂 |
| 可選取文字、雙欄或表格 | 版面感知解析 | 欄位對應、表格行列 | 兩欄文字交錯 |
| 掃描頁、一般正文 | 局部 OCR | 字元、標點、頁碼 | 漏字或錯字 |
| 掃描頁、圖片程式碼 | OCR 加人工抽查 | 縮排、括號、版本 | 程式碼無法執行 |
| 圖文混排 | hi_res 或分區處理 |
圖片來源、區塊邊界 | 圖說插入正文 |
如果使用 hi_res,不要只驗證輸出的文字。你還要確認每個元素是否保留頁面來源和版面位置。對 Agent 而言,「這段內容來自第幾頁」往往比「這段文字是否語法通順」更重要。
第三步:把程式碼、依賴與版本綁在一起
編程書的知識單位不應只有一段程式碼。至少要把以下內容放在同一個 Knowledge record:
- 使用的語言與框架。
- 執行環境,例如作業系統、執行時期或套件管理器。
- 套件版本或書籍出版版本。
- 程式碼前置依賴。
- 預期輸入與輸出。
- 原始書名、章節和頁碼。
- 是否經過實際執行驗證。
例如,一段 API 範例若只保存函式本身,Agent 可能會忽略前面建立的設定檔、環境變數或資料表。結果是它能生成「像樣的程式碼」,卻無法在你的環境啟動。
建議將程式碼知識單位整理成這種結構:
title: 建立非同步 HTTP Client
source_book: Python 非同步程式設計
chapter: 第 6 章
pages: 142-146
language: Python
runtime: 以原書版本為準
dependencies:
- httpx
preconditions:
- 已設定 API_TOKEN
expected_result:
- 回傳 JSON 並處理逾時例外
verification:
- 在隔離環境執行最小測試
這裡的重點不是格式本身,而是讓檢索結果能回答三個問題:這段程式碼解決什麼?在什麼版本下成立?你能否安全地執行它?
PDF 應該直接放進 Agent Skill 嗎?
通常不應該。完整 PDF 適合放在 Knowledge Base,由 Agent 在有明確任務時檢索。Skill 只保留「如何找、如何用、如何驗證」。
直接放入 Skill 只適合以下條件:
- 內容短小。
- 規則長期不變。
- 不需要頻繁引用頁碼。
- 不包含大量程式碼、表格或版本差異。
- 失誤時不會造成部署、資料刪除或權限問題。
若書籍內容會持續更新,或你需要同時維護多本書,全文放入 Skill 的維護成本會迅速上升。更合理的做法是讓 Skill 指向 Knowledge 的檢索流程,而不是複製 Knowledge 的全文。
第四步:按語義任務切分 Knowledge Base
固定每段切成相同長度,是最常見也最難察覺的錯誤。固定切分可能把「安裝依賴」和「執行範例」拆開,也可能把一個完整函式切成兩半。
切分時應優先考慮:
- 章節邊界。
- 一個完整概念或問題。
- 一個可獨立理解的程式碼範例。
- 前置條件與預期結果。
- 同一版本或同一 API 的內容。
LlamaIndex 的 Node 可以代表來源文件中的文字區塊、保存 metadata,並與原始 Document 建立關係。這讓你可以在檢索時保留書名、章節和來源資訊,而不是只回傳一段無上下文的文字。
| 切分方式 | 檢索準確度 | 引用回溯 | 適合場景 | 評分 |
|---|---|---|---|---|
| 固定字數切分 | 中 | 低 | 快速概念驗證 | 2/5 |
| 依段落切分 | 中高 | 中 | 一般技術文章 | 3/5 |
| 依章節與任務切分 | 高 | 高 | 編程書與 Agent | 5/5 |
| 程式碼與說明分離 | 低至中 | 中 | 只查語法片段 | 2/5 |
| 程式碼、依賴、版本綁定 | 高 | 高 | 需要執行驗證的任務 | 5/5 |
每個 Knowledge 單位至少應保留以下 metadata:
book_id
book_title
edition
chapter
page_start
page_end
content_type
language
framework
runtime
source_hash
parser_version
verification_status
其中 source_hash 可協助你判斷檔案是否改變;verification_status 則能區分「僅從書中提取」與「已在隔離環境驗證」。
第五步:讓知識庫查資料,讓 Skill 推進任務
可以把兩者想成「資料庫」和「操作手冊」。
Knowledge Base 回答:
- 某個 API 的用途是什麼?
- 這段範例出自哪一章?
- 哪個版本的框架支援這個寫法?
- 原書對限制條件有什麼說明?
Agent Skill 回答:
- 什麼任務會觸發這項能力?
- 先檢索哪些欄位?
- 何時需要詢問使用者補充版本?
- 何時呼叫程式碼執行工具?
- 如何判定輸出通過驗證?
Anthropic 的 Agent 設計資料也強調,生產環境中的 Agent 應採用可組合、可控制的工作流程,並妥善管理上下文與工具使用。你可以參考官方 Building Effective AI Agents 指南。
Skill 的流程可以寫成:
1. 識別使用者任務與技術版本
2. 從 Knowledge Base 檢索相關章節
3. 檢查來源頁碼與版本差異
4. 生成或修改程式碼
5. 在隔離環境安裝允許的依賴
6. 執行最小測試
7. 回報結果、錯誤與原始引用
需要執行程式碼時,還要限制檔案權限、網路連線、套件來源和執行時間。不能因為書中範例看似簡單,就讓 Agent 直接在生產伺服器上執行未驗證指令。
第六步:為多本編程書建立可維護流程
多本書不能只合併成一個「技術知識大索引」。同一個主題可能存在版本衝突、術語差異和互相矛盾的建議。
建議採用「共同主題索引,加上來源隔離」的方式:
- 以
topic、framework和version建立檢索欄位。 - 保留每一本書的原始來源。
- 發現衝突時,不要直接覆蓋舊內容。
- 將衝突標記為「版本差異」或「作者觀點差異」。
- 新版書籍只重建受影響章節。
- 重新測試引用該章節的 Agent Skill。
LlamaIndex 的 Ingestion Pipeline 支援轉換流程、快取和文件管理;官方文件也描述了利用文件識別與雜湊值判斷重複或變更資料的方式。這種增量處理思路適合多書維護,但你仍需要自行設計版本衝突規則。
| 維護模式 | 更新範圍 | 衝突處理 | 適合度 |
|---|---|---|---|
| 全部重新解析 | 整個資料集 | 容易覆蓋來源差異 | 2/5 |
| 以檔案為單位更新 | 受影響書籍 | 可保留書籍版本 | 4/5 |
| 以章節與雜湊值增量更新 | 受影響知識單位 | 最容易追蹤變更 | 5/5 |
| 只修改 Skill 文字 | 幾乎沒有資料更新 | 容易留下過期知識 | 1/5 |
第七步:用驗收流程確認 Skill 真的可用
完成封裝後,不要只問 Agent「你是否理解這本書」。你應該準備可重複的測試案例。
至少測試以下五類任務:
- 定位測試:能否找到正確章節、頁碼和版本。
- 上下文測試:能否同時取得程式碼、依賴和前置條件。
- 衝突測試:多本書提供不同寫法時,是否清楚標示差異。
- 執行測試:程式碼能否在隔離環境完成最小執行。
- 拒答測試:找不到可靠來源時,是否承認資料不足,而不是自行補寫。
你可以把每次測試的輸入、檢索結果、引用頁碼、執行輸出和錯誤訊息保存下來。當 PDF 解析器、Embedding 模型或 Skill 規格更新時,重新執行同一批測試,才能知道品質是提升還是倒退。
若你需要在遠端環境處理合法 PDF、執行 OCR 或驗證書中程式碼,可先查看VPSSpark 幫助中心的環境與連線說明;需要面向特定地區部署測試環境時,也可參考美國東岸遠端環境方案的地域連線資訊。實際部署前,仍應先確認檔案授權、資料保留政策和執行權限。
最後的選擇:不要用全文 Skill 取代可追溯知識
如果你目前把整本 PDF 塞進 Skill,常見缺點是上下文過長、更新時需要整體重寫、引用頁碼容易遺失,而且書中程式碼沒有經過版本和執行環境檢查。若改用單純全文檢索,又可能遇到切分不合理、雙欄順序錯誤和 OCR 程式碼失真的問題。
較穩妥的長期方案是:PDF 解析層負責清理與保留版面,Knowledge Base 負責事實、來源和版本,Agent Skill 負責檢索順序、工具呼叫與結果驗證。對需要批量處理編程書或執行書中範例的團隊,使用 VPSSpark 租用隔離的 Mac 環境,比在個人電腦上臨時堆疊 OCR、依賴和測試工具更容易控制;但若你需要長期固定負載、實體介面或完全掌握硬體,購買自有裝置仍可能更合適。
讓 AI Agent 技能在雲端 Mac 真正落地
使用 VPSSpark 遠端 Mac,為 PDF 解析、Knowledge 整理與 Skill 測試建立穩定的開發環境。
集中處理文件轉換、程式執行與自動化流程,減少本機配置及維護環境的時間。