Agentic 系統裡,LLM 的輸出通常不是給人看的文字,而是要被程式碼解析的結構化資料:要調用哪個工具、填什麼欄位、抽取哪些資訊。但 LLM 原本是「生成文字的機器」,要它穩定輸出符合 schema 的 JSON,需要明確的技術手段——不然失敗率遠比你預期的高。
JSON Mode vs Structured Outputs:不一樣的東西
這兩個術語常被混用,但它們保證的東西不同:
JSON Mode
只保證輸出是語法有效的 JSON(valid JSON),不保證它符合你的 schema。你要求 {"name": string, "age": number},模型可能回傳 {"name": "Alice", "age": "25", "extra": true}——valid JSON,但不符合 schema。OpenAI 在 2023 年推出,Anthropic 也有類似機制。
Structured Outputs(Strict Mode) 透過 constrained decoding(約束解碼)在 token 生成層強制輸出符合指定 schema。OpenAI 在 2024 年 8 月發布 Strict Mode,保證 schema compliance。Anthropic 以 tool use 的方式達到類似效果(當你定義 tool schema 時,模型必須輸出符合該 schema 的 tool call)。
真實失敗率數據
以下數字來自 Rotascale 和 TianPan.co 等工程部落格整理的 2025 年數據——這些是從生產系統觀察到的數字,非嚴格對照實驗:
| 方式 | 近似失敗率 |
|---|---|
| 無任何強制,只靠 prompt | 8–15% JSON 解析失敗 |
| JSON Mode(valid JSON 保證) | ~2–5% schema mismatch |
| Structured Outputs / Strict Mode | < 0.1% |
| Anthropic tool use | ~0.2% |
| Gemini schema mode | ~0.3% |
每次失敗的代價不只是重試成本:加上 500–2000ms 額外延遲、前端的 spinner 時間、以及需要工程師設計 fallback 路徑。在高頻次的生產系統裡,2–5% 的失敗率已經是顯著問題。
重要提醒:上述數字在不同任務類型(簡單抽取 vs 複雜推理輸出)之間差異很大,不宜直接套用到你的場景。
為什麼 Strict Mode 有代價
Constrained decoding 不是免費的:
- Schema overhead:每個 schema 定義要額外消耗 30–300 tokens,這些 token 每次 API call 都要付費
- 不支援所有 schema 特性:OpenAI Strict Mode 有幾個已知限制——不支援 optional properties(所有欄位都是 required)、不支援
anyOf以外的聯合類型、不支援遞迴 schema。Anthropic tool use 也有類似限制。如果你的業務邏輯需要複雜 schema,這是實際的工程障礙 - Dynamic schema 更難:如果 schema 本身是動態生成的(根據用戶配置),在 Strict Mode 下需要在執行前做 schema 驗證,確保它在 provider 的支援範圍內
Retry/Repair 策略
當使用 JSON Mode 或沒有原生 Strict Mode 支援的場景,parse 失敗時的最佳做法:
一次 retry with error feedback
把 parse error message 和期望的 schema 一起傳給模型,讓它自我修正。大多數情況下一次就夠:"Your previous response failed to parse: {error}. Please respond with valid JSON matching this schema: {schema_example}"。實驗顯示超過 3 次 retry 後模型通常無法自我修正,代表這個 input 本質上難以結構化——應該 escalate 或 fallback。
Instructor(Python)/ Zod(TypeScript)
Instructor library(GitHub)封裝了上述 retry 邏輯,並用 Pydantic model 定義 schema,自動把 validation error 格式化成 retry prompt。Zod 在 TypeScript 生態系有類似角色,配合 zod-to-json-schema 轉換。這些是被廣泛使用的工程工具,不是「最佳實踐主張」。
Repair agent 對於複雜的多欄位輸出,可以用一個獨立的 LLM call 專門做「修復」:傳入破損的 JSON+schema+parse error,要求輸出修復後的 JSON。比直接重跑整個生成成本更低,延遲也更短。
Function Calling 的常見坑
工具描述歧義:模型選擇調用哪個工具取決於 description。兩個功能相似的工具如果描述重疊,模型可能選錯;解法是讓每個工具的描述明確列出「不適用的場景」。
Parallel tool calls 的順序依賴:如果工具 A 的輸出是工具 B 的輸入,但系統讓它們被並行調用,就會出錯。需要在 orchestration 層明確設定依賴關係,而不是假設模型會自己排序。
工具調用的幻覺:模型有時會「幻覺出」一個不存在的工具名稱,或者把 tool argument 填成看起來合理但實際無效的值(例如過去不存在的 ID)。這需要在宿主端驗證每個 tool call 的合法性,而不是直接執行。
過多工具導致選擇困難:當工具清單超過 10–15 個時,模型的調用準確度會下降(沒有公開的精確數字,但多個工程部落格有記錄這個現象)。常見解法是動態工具選擇:先讓 LLM 從大工具庫挑出相關工具集,再用這個子集進行實際調用。
延伸
- 結構化輸出的失敗如何影響 UX → Streaming 與 Agentic UIUX
- Evals 如何量測輸出品質 → 幻覺、Evals 與品質保證
- 全景與閱讀路徑 → AI Agentic SaaS 專欄首頁