examhub .cc 用最有效率的方法,考取最有價值的認證
Vol. I
本篇導覽 約 27 分鐘

透過 Tool Use 與 JSON Schema 的結構化輸出

5,400 字 · 約 27 分鐘閱讀

使用 Tool Use 與 JSON Schema 實現結構化輸出這個主題直接對應 CCA-F 考試任務說明 4.3:使用 tool use 和 JSON schema 強制結構化輸出。此任務說明位於 Domain 4(Prompt Engineering 與結構化輸出,佔比 20%)核心,並錨定整個「結構化資料擷取」情境叢集——考試從六個情境叢集中抽取四個出題。若擷取 pipeline 回傳格式錯誤的 JSON,所有下游系統都會崩潰;若 schema 嚴格但語意空洞,系統則會悄悄產生錯誤答案。使用 Tool Use 與 JSON Schema 實現結構化輸出,正是考試期望你在情境需要機器可讀輸出時優先選用的架構模式。

這份學習筆記涵蓋架構師必須深刻理解的完整面向:為何帶有 JSON schema 的 tool_use 是 Claude 上最可靠的強制機制、三種 tool_choice 模式("auto""any"、forced tool selection)如何改變模型行為、防止幻覺的 schema 設計模式(nullable 欄位、enum + other、required vs optional)、語法錯誤與語意錯誤的關鍵區別(strict schema 只能防止前者,永遠無法防止後者),以及在 schema 旁搭配提示的格式正規化模式。每個章節都為結構化資料擷取情境叢集而調校——考試會要求你在嚴格可靠性限制下,設計發票解析器、醫療記錄擷取器或合約條款分類器。

結構化輸出為何在 CCA-F 結構化資料擷取情境中如此重要

結構化資料擷取是官方考試指南列出的六個 CCA-F 情境叢集之一,叢集內的每道題目都默默預設你會以使用 Tool Use 與 JSON Schema 實現結構化輸出作為預設模式。情境描述的是一個生產系統,它接收發票、醫療記錄、法律合約或研究論文,並必須輸出下游服務可以在無人工驗證的情況下直接消費的 JSON。自由格式文字輸出不可接受;夾在 markdown 程式碼區塊中的 JSON 不可接受;帶有尾隨逗號的 JSON、含幻覺欄位的 JSON、或欄位值放到錯誤 key 下的 JSON,一律不可接受。

考試的壓力測試在於:你是否理解使用 Tool Use 與 JSON Schema 實現結構化輸出在可靠性上根本優於透過 system prompt 要求 Claude「請以 JSON 回應」。基於提示的 JSON 強制方式把 schema 合規性交給模型盡力生成。基於工具的強制方式則給 Claude 一份契約:你離開這個 turn 的唯一方式,就是輸出符合此 schema 的參數。架構上的差異是巨大的:基於提示的強制是建議性的,基於工具的強制是程式化的。

結構化輸出在 CCA-F 考試藍圖中的位置

  • Domain 4,Task 4.3 — 使用 tool use 和 JSON schema 強制結構化輸出(本主題)。
  • Domain 4,Task 4.4 — 實作驗證、重試與回饋迴圈以提升擷取品質(與本主題搭配使用)。
  • Domain 2,Task 2.1 — 設計具備清晰描述與邊界的有效工具介面(相同的工具定義紀律也適用於擷取 schema)。
  • Domain 2,Task 2.3 — 跨 agent 適當分配工具並設定 tool_choice(與本主題直接重疊的子技能)。

由於 tool use 概念在 Domain 2 和 Domain 4 重複出現,考試經常將結構化資料擷取問題與工具設計問題安排在同一叢集中,誤學其中一個就會連帶影響另一個。

Tool Use 作為最可靠的結構化輸出強制機制

使用 Tool Use 與 JSON Schema 實現結構化輸出的核心洞察,在於 Anthropic 將工具定義視為一等型別合約。當你以 input_schema 定義一個工具,並強制 Claude 呼叫它,API 就在語法層面保證結果 tool_use 區塊中的 input payload 符合 schema——key 存在、值的型別正確、required 欄位都已填寫。

用於結構化輸出的 tool use 是一種架構模式:定義一個工具,其 input_schema 就是你希望模型輸出的 JSON schema,然後強制 Claude 呼叫該工具。工具從不真正執行——你的應用程式從結果 tool_use content block 中提取 input 物件,並將其視為結構化結果。這個模式是從 Claude 取得符合 schema 之 JSON 的最可靠方法,因為 Messages API 在回應生成時就強制執行 schema,而非在後處理階段。 Source ↗

擷取工具模式的端到端流程

  1. 定義工具,其名稱與描述說明擷取任務(例如 record_invoice,描述「記錄從文件中擷取的結構化發票欄位」)。
  2. 填寫 input_schema,寫入下游服務期望的 JSON schema——required 欄位、型別、enum、nullable 標記、巢狀物件。
  3. 將文件作為 user 訊息送出,並在 tools 陣列中包含此工具。
  4. 設定 tool_choice,強制模型呼叫這個特定工具(見下一節)。
  5. 接收回應:Claude 的輸出包含一個 tool_use content block,其 input 物件就是擷取的資料,stop_reasontool_use
  6. 直接消費 input 物件——你從不實際執行工具。若不需要下游行動,可完全跳過 tool_result 的來回。

為何優於基於提示的 JSON 請求

基於提示的 JSON 強制方式(「請回傳一個帶有 invoice_number、total、line_items 欄位的 JSON 物件……」)依賴模型的訓練來產生格式正確的 JSON。常見失敗模式包括:JSON 被 markdown 程式碼區塊包裹、尾隨逗號、引號不匹配、JSON 前後夾有說明文字,以及幻覺 key。基於工具的強制方式消除了所有這些失敗模式,因為 API 返回的是一個有型別的 input 物件,而非客戶端需要解析的文字 blob。

在 CCA-F 考試中,每當結構化資料擷取情境呈現兩個答案選項——一個使用帶有 input_schematool_use,一個使用要求 JSON 的 system prompt——除非情境明確禁止 tool use,否則 tool_use 答案就是正確的。考試一貫偏好程式化強制勝過基於提示的強制;這是整個認證中最穩定的模式匹配規則之一。 Source ↗

tool_choice 參數:auto vs any vs Forced Tool Selection

tool_choice使用 Tool Use 與 JSON Schema 實現結構化輸出中被考得最多的單一參數。它控制模型是否可以用自由格式文字回覆、是否必須呼叫某個工具,或必須呼叫一個特定的命名工具。三種模式對應三種截然不同的擷取架構,混淆它們是最常見的考試陷阱之一。

tool_choice: "auto" 讓模型決定要呼叫工具還是用文字回覆。模型可能回傳純文字而不呼叫任何工具。適用於文字回覆(例如澄清問題)是合法輸出的 agentic loop。

tool_choice: "any" 強制模型呼叫提供清單中的某個工具,但由模型選擇呼叫哪一個。適用於有多個擷取工具且希望模型依文件類型路由的情況。

tool_choice: {"type": "tool", "name": "..."} 強制模型呼叫一個特定的命名工具,即 forced tool selection。適用於每個輸入都對應確定性擷取 pipeline 且只有一個 schema 的情況。 Source ↗

模式一:"auto" — 模型可自由選擇文字或工具

使用 tool_choice: "auto"(預設值)時,模型可以檢視 user 輸入,決定不需要呼叫工具,並以純文字回覆。在 CCA-F 考試中,若情境要求對每個輸入都保證有結構化輸出,"auto"錯誤選擇——無法保證模型一定會呼叫工具,而文字回覆會讓下游 JSON 消費者崩潰。"auto" 只適用於文字回覆是合法結果的場景(例如,客服 agent 可能執行動作,也可能提出澄清問題)。

模式二:"any" — 模型必須呼叫某個工具

tool_choice: "any" 保證一定會有工具呼叫,但讓模型自行選擇呼叫哪個工具。當你有多個擷取 schema 時,這是正確選擇——例如,一個工具對應 record_invoice、一個對應 record_receipt、一個對應 record_purchase_order——你希望 Claude 將每份文件路由到正確的 schema。回應永遠是 tool_use 區塊;你的應用程式處理被呼叫的任一工具。當只有一個擷取 schema 時,"any"錯誤選擇,因為多餘的路由自由度不帶來任何價值,反而可能引入模糊性。

模式三:Forced Tool Selection — 模型必須呼叫特定工具

tool_choice: {"type": "tool", "name": "record_invoice"} 強制模型只呼叫 record_invoice。這是最具決定性的模式,也是單一 schema 擷取 pipeline 的預設建議。結合設計良好的 input_schema,forced tool selection 是你能對 Claude 輸出施加的最嚴格約束。

值得了解的第四種模式:"none"

tool_choice: "none" 完全停用工具呼叫,即使提供了工具也一樣。這在你想跨 turn 重用相同訊息歷史,但暫時強制文字回覆時很有用。考試鮮少直接測試 "none",但認識它可以防止在干擾選項中產生混淆。

tool_choice: "auto" 不保證工具呼叫。 當結構化資料擷取情境說下游 pipeline 必須永遠收到符合擷取 schema 的 JSON,而某個答案選項使用 "auto",那個選項就是錯的,無論 schema 設計多完善。模型在 "auto" 下可以自由回傳文字,文字回覆會讓消費者崩潰。

這個陷阱的第二種常見變體:情境只有一個擷取 schema,但答案使用 "any""any" 在技術上不是錯的,但 forced tool selection({"type": "tool", "name": "..."})更為嚴格,因此是 CCA-F 偏好的答案。 Source ↗

語法錯誤 vs 語意錯誤:Strict Schema 無法修復的問題

這是整個使用 Tool Use 與 JSON Schema 實現結構化輸出主題中最具份量的區別,考試對此窮追不捨。嚴格的 JSON schema 保證語法合規——key 存在、型別匹配、enum 值來自允許清單、required 欄位已填寫。它保證以下任何一項:

  • line_items 陣列的加總等於 total 欄位。
  • invoice_date 在時間上早於 due_date
  • 擷取出的 customer_name 是實際客戶,而非帳單聯絡人。
  • 來源文件中的貨幣符號已正確正規化為 currency enum。
  • 屬於 shipping_address 的值沒有跑到 billing_address

上述每一項都是語意錯誤——JSON 格式正確、通過 schema 驗證,卻仍然是錯的。任何 schema 功能都無法防止語意錯誤,因為 schema 對來源文件沒有任何了解。

語法錯誤是違反 schema 的 JSON 輸出:缺少 required 欄位、型別錯誤、無效的 enum 值、格式錯誤的 JSON。嚴格的 input_schema 加上 forced tool_choice 可消除語法錯誤。

語意錯誤是符合 schema 但值在現實世界中是錯的 JSON 輸出:數字填到錯誤欄位、計算總計與 line items 不符、幻覺日期、客戶名稱歸屬錯誤。Schema 無法消除語意錯誤——你需要驗證邏輯、重試迴圈、多輪審查或人工介入的工作流程。 Source ↗

為何考試如此鍾愛這個區別

結構化資料擷取情境常常呈現一份故障報告:「擷取 pipeline 產出的 JSON 通過了 schema 驗證,但 total 欄位不等於 line_items[].amount 的加總。架構師應對 pipeline 做什麼修改?」相信 strict schema 能修復所有錯誤的考生,會選「對工具定義加入 strict: true」。這個答案是錯的——JSON 本來就已符合 schema。正確的修復方式在 task 4.4:加入一個驗證步驟來檢查語意不變式,並將違規作為後續 turn 回饋給 Claude,讓它自行修正。

語意錯誤的緩解策略

  • 驗證 + 重試迴圈(task 4.4):在應用程式端計算不變式,回傳帶有 is_error: true 和描述性訊息的 tool_result,讓 Claude 重新嘗試。
  • 在提示中加入格式正規化規則(下文介紹):明確告訴 Claude 如何計算衍生欄位,可以減少——但不能消除——語意錯誤。
  • 多輪審查(task 4.6):第二個 Claude 呼叫驗證第一個 Claude 呼叫的輸出,獨立於 schema 驗證。
  • 信心校準與人工審查(task 5.5):將低信心的擷取結果路由給人工處理。

Required vs Optional 欄位:防止幻覺的 Schema 設計選擇

JSON schema 中每個欄位對 Claude 的行為都有微妙影響。required vs optional 的區別不只是下游消費者的考量——它直接影響 Claude 是否會產生幻覺。

Required 欄位

列在 schema 的 required 陣列中的欄位必須出現在輸出中。當 Claude 在來源文件中找不到這些資訊時,它要嘛幻覺一個值,要嘛讓 schema 驗證完全失敗。將欄位設為 required 因此是一種承諾:你在告訴 Claude「這個資訊在每份來源文件中必然存在;請務必擷取它」。

Optional 欄位

不在 required 陣列中的欄位可以省略。Claude 只在來源文件提供相關資訊時才會包含它們。對於領域中確實是選填的欄位,這是更安全的預設值——例如發票上的 discount_percentage

反模式:Required 但不允許 Nullable

將一個不一定出現在來源文件中的欄位設為 required 且不允許 null,是使用 Tool Use 與 JSON Schema 實現結構化輸出中頻率最高的幻覺配方。Claude 面對一個要求它找不到的值的 schema,會產生一個看似合理但實為捏造的值。解法是將欄位改為 optional,或者——更好的方式——將它設為 required 且 nullable

Nullable 欄位:防止幻覺的模式

Nullable 欄位模式結合了兩個 schema 特性:欄位在 required 中,且欄位的型別是包含 null 的聯合型別(通常是 ["string", "null"]["number", "null"])。

Nullable 欄位模式讓一個欄位必須永遠出現在輸出中,但其型別聯合包含 null,因此當來源文件缺少相關資訊時,Claude 可以明確輸出 null。這個模式透過給 Claude 一個符合 schema 的方式來表達「我不知道」而不用捏造值,進而防止幻覺。它是結構化資料擷取 pipeline 中最有效的 schema 層級防幻覺機制。 Source ↗

為何 Nullable 優於 Optional(針對已知 Schema)

Optional 欄位(不在 required 中)讓你的下游消費者面臨兩種模糊情況:欄位缺席是因為來源沒有相關資訊,還是因為 Claude 忘記填寫?Nullable 且 required 的欄位消除了這兩種情況:null 永遠意味著「來源沒有這個資訊」,而缺少 key 則是你可以拒絕的 schema 違規。這種清晰性正是為何成熟的擷取 pipeline 對所有已知欄位都偏好 nullable-required 而非 optional。

各模式的適用時機

  • Required,不 nullable — 欄位保證出現在你領域的每份來源文件中(例如每張發票上的 invoice_number)。
  • Required,nullable — 欄位在你的 schema 領域中,但在任何特定來源文件中可能存在也可能不存在(例如 discount_codeshipping_tracking_number)。
  • Optional — 欄位只對特定文件子類型有意義,在其他情況下應缺席(例如只在 B2B 發票上出現的 tax_exempt_certificate_id)。

Enum + Other 模式:可延伸的受控詞彙表

許多擷取 schema 包含分類欄位——文件類型、客戶區隔、事件類別——允許值集合大部分已知,但偶爾會遇到新值。簡單的 enum 會拒絕未知值;自由格式字串則失去受控詞彙表的好處。Enum + other 模式同時解決這兩個問題。

模式的運作方式

定義一個包含字面值 "other" 的 enum 欄位,並加入一個伴隨字串欄位,只在選擇 "other" 時才為 required。以 JSON schema 表示:

  • category — enum,值為 ["refund", "shipping", "billing", "technical", "other"]
  • category_other_detail — 字串,當 category == "other" 時為 required。

當 Claude 遇到明顯屬於 refund 的事件時,它選擇 refund 並將 category_other_detail 留為 null。當 Claude 遇到真正超出 enum 範圍的事件時,它選擇 "other" 並在 category_other_detail 中填入簡短描述。

為何這個模式受考試青睞

結構化資料擷取情境常常包含這樣一句話:「團隊回報 3% 的文件含有不在原始清單中的類別,pipeline 正在拒絕它們。」正確的架構修復方式是 enum + other 模式,而不是無限擴充 enum(會悄悄無界成長),也不是完全移除 enum(會失去受控詞彙表的保證)。

當 CCA-F 情境提到固定清單分類欄位偶爾遇到未知值時,請選用帶有伴隨自由格式詳情字串的 enum + other 模式。這個模式對常見情況保持 schema 嚴謹性,保留下游對已知類別的分析能力,並為新類別提供乾淨的逃生出口而不破壞 pipeline。在可延伸分類問題上,它幾乎永遠是正確答案。 Source ↗

格式正規化規則:在 Strict Schema 旁搭配提示

Strict schema 保證型別與結構,但它無法告訴 Claude 如何解析原始日期字串、如何處理貨幣符號,或如何轉換百分比。這些格式正規化決策存在於提示中,而非 schema。最可靠的使用 Tool Use 與 JSON Schema 實現結構化輸出 pipeline,都結合了嚴格 schema 與 system prompt 中一份簡短的明確正規化規則。

值得明確指定的常見正規化規則

  • 日期 — 指定 ISO 8601(YYYY-MM-DD);告訴 Claude 如何處理模糊的來源格式(03/04/2026 可能是 3 月 4 日或 4 月 3 日)。
  • 貨幣 — 指定是否包含符號、ISO 4217 代碼,或只保留數值,以及如何處理多貨幣來源。
  • 數字 — 指定小數分隔符、千位分隔符,以及是否去除百分比符號。
  • Enum — 若來源使用同義詞("運費" vs "物流費" vs "配送費"),告訴 Claude 每個同義詞對應哪個規範的 enum 值。
  • 空白與大小寫 — 指定字串欄位的修剪與大小寫正規化方式。

這些規則放在哪裡

放在 system prompt 或工具描述中,而非 schema 裡。Schema 強制型別;提示強制語意。配合 few-shot examples 區塊(task 4.2),正規化規則能大幅減少語意錯誤,而不需要修改 schema。

白話文解釋:Tool Use 與 JSON Schema 的結構化輸出

抽象的 schema 與模式參數,一旦錨定在日常生活情境上,就會變得直觀。以下三個類比涵蓋使用 Tool Use 與 JSON Schema 實現結構化輸出的完整面向。

類比一:政府報稅表格 — Required 欄位、Nullable 欄位與 Strict Schema

想像政府的所得稅申報表。表格有固定的欄位——有些是必填的(姓名、身分證字號、總收入),有些是條件式的(扶養親屬、捐款抵稅、海外所得)。一個強迫填寫而不管是否適用的必填欄位,就是 schema 反模式:面對「海外所得」必填欄但實際上沒有海外所得的納稅人,只能空白(schema 違規)或捏造數字(幻覺)。解法就是 nullable-required 模式:這個欄位一定要出現在表格上,但表格明確允許填寫「無」。

使用 JSON schema 的 tool use 是一樣的紀律:你交給 Claude 一張結構化表格,標記哪些欄位必須填寫,而對可能不適用的欄位,你允許明確的「null」,而不是強迫捏造值。Forced tool selection 就像只交給 Claude 這張表格、不提供任何白紙——完全沒有辦法繞過表格用散文作答。

類比二:餐廳點餐本 — tool_choice 模式如同點餐紀律

服務生取餐時有三種可能的規定。在 "auto" 模式下,服務生可以在點餐本上寫,也可以只是跟客人聊聊而不寫任何東西——當客人還沒決定時很有用。在 "any" 模式下,服務生必須在某個本子上寫,但可以選擇是餐點本還是飲料本——當客人可能點任一樣時很有用。在 forced 模式{"type": "tool", "name": "food_order"})下,服務生必須在餐點本上寫——當這桌已點完飲料只剩餐點待確認時很有用。

一個期望每桌都能交回完整餐點訂單的廚房,無法容忍 "auto" 模式,因為服務生可能空手而回。同理,當結構化資料擷取 pipeline 需要每份文件都保證有 JSON 輸出時,就無法容忍 tool_choice: "auto"。模式選擇,就是讓點餐本的紀律與廚房的可靠性需求相匹配。

類比三:工廠品管人員 — 語法錯誤 vs 語意錯誤

想像一間生產密封麥片盒的工廠。語法品管員在產線末端檢查每個盒子:形狀對不對、重量在不在範圍內、條碼有沒有、保存期限格式正不正確。這位品管員能抓出格式不對的盒子,卻無法察覺盒子裡裝的是玉米片而非小麥片,或是淨重標示比實際內容物多了 10 克。那種深層的檢查需要語意品管員——他打開盒子、實際稱重、核對成分。

Strict JSON schema 就是語法品管員:保證盒子從外面看起來沒問題。語意正確性——加總與 line items 吻合、客戶名稱歸屬正確、日期內部一致——需要在應用程式端進行另一道驗證,或由第二個 Claude 進行審查。考試的陷阱就在於讓你誤以為語法品管員的章蓋了,貨物就可以放行。

考試當天選用哪個類比

  • 關於 required、optional、nullable 欄位的題目 → 報稅表格類比。
  • 關於 tool_choice 模式的題目 → 點餐本類比。
  • 關於 strict schema 無法修復總計 / 跨欄位不變式的題目 → 工廠品管員類比。

端到端結構化資料擷取 Pipeline 架構

使用 Tool Use 與 JSON Schema 實現結構化輸出的每個部分組合在一起,就得到一個可靠的端到端 pipeline。CCA-F 考試頻繁要求你找出一個損壞 pipeline 中缺少的元件;了解參考架構讓這類題目變成模式配對。

參考架構

  1. 資料接收 — 來源文件到達(PDF、OCR 影像、HTML、電子郵件)。
  2. 前處理 — 正規化文字、分割長文件、附加文件 metadata。
  3. 提示建構 — 帶有格式正規化規則的 system prompt、few-shot examples、包含文件的 user 訊息。
  4. 工具定義 — 帶有嚴格 input_schemarecord_<document_type> 工具;分類欄位用 enum + other;可能缺席的欄位用 nullable-required。
  5. API 呼叫 — Messages API,帶有 tools 陣列與 tool_choice: {"type": "tool", "name": "record_<document_type>"}
  6. 回應處理 — 從 Claude 的回應中提取 tool_use.input 物件。
  7. 語意驗證 — 應用程式端驗證跨欄位不變式(總計、日期順序等)。
  8. 重試迴圈(task 4.4)— 語意驗證失敗時,建構帶有 is_error: true 和說明性訊息的 tool_result;讓 Claude 重新嘗試。
  9. 信心路由(task 5.5)— 低信心或反覆失敗的案例轉人工審查。
  10. 下游消費 — 驗證過的 JSON 交給消費者系統。

各考試任務對應的 Pipeline 步驟

  • Task 4.3 — 步驟 4、5、6(本主題)。
  • Task 4.4 — 步驟 7、8。
  • Task 4.2 — 步驟 3(few-shot examples)。
  • Task 4.1 — 步驟 3(明確標準、精確性)。
  • Task 4.5 — 整個 pipeline 透過 Message Batches API 批次處理(適用於延遲不敏感的情況)。
  • Task 4.6 — 多輪審查作為步驟 7 的替代或補強方案。
  • Task 5.5 — 步驟 9。

批次 vs 同步擷取的取捨

結構化資料擷取往往需要大量處理——夜間發票批次、每週合約審查、每月合規掃描。CCA-F 考試習慣將使用 Tool Use 與 JSON Schema 實現結構化輸出的題目與 task 4.5(批次處理)搭配出題。

同步擷取

每次 API 呼叫處理一份文件,透過 Messages API 發送。延遲低(秒級),但每個請求的費用為標準收費,且受限於速率限制的並發量。適用於擷取必須在面向使用者的流程中即時完成、或結果需要立即供消費系統使用的情況。

透過 Message Batches API 進行批次擷取

單次批次最多可提交 100,000 個請求。結果在 24 小時內可取(通常更快),費用降低 50%,且批次端點擁有獨立的速率限制額度。適用於擷取可以離線、在夜間、或對延遲容忍度高的情況。Schema 與工具定義與同步方式完全相同——只有提交路徑不同。

考試陷阱:永遠選批次

考試呈現的情境,有些批次是正確答案(大量、夜間處理),有些批次是錯誤答案(即時面向使用者的擷取)。為了節省費用而永遠選批次,是已知的失分模式。請依情境中的延遲需求決定。

結構化輸出的常見考試陷阱

CCA-F 積極利用一批與使用 Tool Use 與 JSON Schema 實現結構化輸出相關的陷阱模式。逐一熟練每一個。

陷阱一:Strict Schema 能修復所有錯誤

典型陷阱:情境描述語意錯誤(總計不符、日期順序錯誤),而某個答案說「對工具定義加入 strict: true」。錯誤——strict schema 只防止語法錯誤,永遠不防止語意錯誤。正確答案在驗證 + 重試迴圈。

陷阱二:tool_choice: "auto" 保證回傳 JSON

情境說「pipeline 必須永遠收到結構化 JSON」,而某個答案使用 "auto"。錯誤——"auto" 允許文字回覆。單一 schema pipeline 的正確選擇是 forced tool selection。

陷阱三:單一 Schema 用 "any" 而非 Forced Selection

情境只有一個擷取 schema,某個答案使用 "any"。技術上不完全錯,但 forced tool selection 更嚴格,也是 CCA-F 在擷取目標是已知特定工具時的偏好答案。

陷阱四:用 System Prompt 要求 JSON 而不定義工具

某個答案使用 system prompt 說「只以符合此結構的 JSON 回覆」,沒有定義任何工具。錯誤——基於提示的強制是建議性的;基於工具的強制是程式化的。考試一貫偏好程式化強制。

陷阱五:有時缺席的欄位設為 Required 且不允許 Nullable

一個可能不出現在每份來源文件中的欄位,被標記為 required 且沒有 nullable 型別。這個配方會誘發幻覺。解法是 required + nullable,讓 Claude 在來源缺少資訊時可以明確輸出 null

陷阱六:無限擴充 Enum 而不用 Enum + Other

分類欄位偶爾遇到新值,而某個答案建議每次出現新值就擴充 enum。錯誤——enum + other 模式才是正確的可延伸設計。

CCA-F 結構化資料擷取題目中,最高分的單一模式配對: 若情境描述一個損壞的擷取 pipeline,答案選項包含(A)加入 strict: true、(B)切換為 tool_choice: "auto"、(C)修改 system prompt 更強烈地要求 JSON,或(D)加入驗證 + 重試迴圈——而損壞的行為是語意錯誤(總計不符、跨欄位不變式、值歸屬錯誤)——正確答案是 (D) 驗證 + 重試迴圈,而非 (A)。語法錯誤與語意錯誤有不同的修復方式,考試測試你能否分辨兩者。 Source ↗

練習錨點:結構化資料擷取情境模板

使用 Tool Use 與 JSON Schema 實現結構化輸出相關的 CCA-F 練習題,集中在五種題型。每種模板在社群通過報告語料庫中重複出現多次。

模板 A:Schema 強制機制

「一個團隊正在建立發票擷取 pipeline,必須永遠產出符合特定 schema 的 JSON。哪種方式最可靠?」 正確答案:定義以 schema 為 input_schema 的擷取工具,並使用 forced tool_choice。干擾選項:system prompt 要求 JSON;regex 後處理自由格式輸出;fine-tuning(超出 CCA-F 範圍)。

模板 B:tool_choice 模式選擇

「一個擷取 pipeline 有三個工具——record_invoice、record_receipt、record_purchase_order——每份文件必須恰好呼叫其中一個。哪個 tool_choice 設定是正確的?」 正確答案:"any"(模型必須呼叫某個工具,但自行選擇哪個)。干擾選項:"auto"(無法保證);強制選擇某個特定工具(失去路由能力);"none"(完全停用工具)。

模板 C:語意 vs 語法錯誤診斷

「一個擷取 pipeline 每個輸出都成功通過 strict schema 驗證,但 2% 的發票的 line items 加總與 total 不符。最有效的修復方式是什麼?」 正確答案:加入驗證步驟計算加總,並透過帶有 is_error: truetool_result 回饋違規。干擾選項:加入 strict: true(本來就已嚴格);在 schema 中加入更多限制(語意錯誤不是 schema 違規);切換為 "auto"(無關且有害)。

模板 D:Optional 欄位的幻覺防止

「來源發票有時沒有 shipping_tracking_number 欄位,而 Claude 在這種情況下會捏造值。Schema 應如何更新?」 正確答案:將欄位設為 required 且 nullable。干擾選項:設為 optional(失去「Claude 必須處理它」的行為,並引入 key 缺席的模糊性);完全移除欄位(失去下游資訊);加入 system prompt 規則(基於提示,比基於 schema 的強制弱)。

模板 E:可延伸分類

「支援票分類 schema 有五個 enum 類別,但偶爾出現新的票種。團隊不想持續擴充 enum。應採用哪種模式?」 正確答案:enum + other,搭配一個伴隨的自由格式詳情欄位。干擾選項:完全移除 enum(失去受控詞彙表);每次出現新類型就擴充 enum(無界成長);訓練獨立分類器(超出範圍)。

常見問題(FAQ)

為何 tool use 比基於提示的 JSON 強制更可靠?

因為 Messages API 將工具定義視為有型別的合約。當 Claude 輸出 tool_use content block 時,API 在語法層面保證 input 物件符合工具的 input_schema——key 存在、型別正確、required 欄位已填寫、enum 值合法。基於提示的 JSON 強制依賴模型的訓練來產生格式正確的 JSON,常見失敗模式包括 markdown 圍欄、尾隨逗號、幻覺 key,或 JSON 前後夾帶說明文字。考試一貫偏好程式化強制(tool use)勝過基於提示的強制(system prompt 要求 JSON)。

tool_choice: "auto""any" 與 forced selection 有何差異?

"auto" 讓模型決定要呼叫工具還是回傳文字——模型可能回傳文字而不呼叫任何工具。"any" 強制模型呼叫某個工具,但讓模型從可用工具中自行選擇。Forced selection({"type": "tool", "name": "..."})強制模型呼叫一個特定的命名工具。單一 schema 的結構化資料擷取,預設建議使用 forced selection。多 schema 路由 pipeline 使用 "any""auto" 只適用於文字回覆是合法結果的情況,而大多數結構化資料擷取情境並非如此。

Strict JSON schema 能防止 Claude 幻覺欄位值嗎?

不能。Strict schema 防止語法錯誤(缺少 required 欄位、型別錯誤、無效 enum 值),但無法偵測語意錯誤——符合 schema 但在現實世界中是錯的值。加總與 line items 不符、日期順序錯誤、客戶名稱填到錯誤欄位,都能通過 strict schema 驗證。防止欄位值幻覺需要獨立的機制:nullable-required 欄位(讓 Claude 可以明確表達「我不知道」)、提示中的格式正規化規則、驗證 + 重試迴圈,以及多輪審查。

何時應使用 nullable-required 欄位而非 optional 欄位?

對於在 schema 領域中存在、但可能不出現在任何特定來源文件中的欄位,使用 nullable-required——例如發票上的 discount_code。Nullable-required 讓 Claude 必須處理該欄位,並在來源缺少資訊時有合法的方式輸出 null。這防止了幻覺,並消除了 optional 欄位帶來的「key 缺席 vs 忘記填寫」的模糊性。只有當欄位只對特定文件子類型有意義、在其他情況下應缺席時,才使用真正的 optional(不在 required 中)。

什麼是 enum + other 模式?何時應使用它?

Enum + other 模式在 enum 中加入字面值 "other",並搭配一個伴隨的自由格式字串欄位,只在選擇 "other" 時才為 required。每當一個分類欄位有大部分已知的值集合,但偶爾遇到新值時,使用這個模式。它對常見情況保持嚴格的 schema 驗證,保留下游對已知類別的分析能力,並為新類別提供乾淨的逃生出口,而不造成 enum 無界成長。它是 CCA-F 偏好的可延伸受控詞彙表架構。

結構化擷取中語意錯誤與語法錯誤有何差異?

語法錯誤是違反 JSON schema 的輸出——缺少 required 欄位、型別錯誤、無效 enum 值、格式錯誤的 JSON。帶有 forced tool_choice 的 strict tool use schema 在 API 層面消除語法錯誤。語意錯誤是符合 schema 但值在現實世界中是錯的輸出——line items 加總與 total 不符、日期順序錯誤、值填到錯誤欄位。語意錯誤通過 schema 驗證,schema 機制對此無感。修復語意錯誤需要應用程式端驗證、帶回饋的重試迴圈、多輪審查,或人工審查工作流程。這個區別是 CCA-F 結構化資料擷取題目中被利用最頻繁的陷阱。

格式正規化規則應放在 schema 還是提示中?

放在提示中,而非 schema。JSON schema 強制型別與結構;它無法告訴 Claude 如何解析原始日期字串、要去掉哪個貨幣符號,或如何將來源同義詞對應到規範 enum 值。格式正規化規則(ISO 8601 日期、ISO 4217 貨幣代碼、小數分隔符處理、同義詞到 enum 的對應)屬於 system prompt 或工具描述。搭配 few-shot examples(task 4.2),明確的正規化規則能大幅減少語意錯誤,而不需要修改 schema 本身。模式是:schema 負責結構,提示負責語意。

延伸閱讀

Related ExamHub topics: Few-Shot Prompting and Output Consistency, Validation and Retry Loops for Extraction Quality, Tool Definitions and Descriptions, Batch Processing for High-Volume Extraction, Explicit Criteria for Prompt Precision.

官方資料來源