為什麼你的 AI 輸出格式總是飄移?
如果你的 AI 工作流程經常因為輸出格式變動而中斷,問題不在你的提示寫得不好。你是用錯工具處理結構化資料問題。大型語言模型逐個 token 生成文字,「格式」對它來說只是一種模仿出來的模式。沒有硬性約束,同一個提示今天回傳 JSON、明天回傳散文。
實踐者最常在串接步驟時注意到這個問題。第一步 AI 產出一個項目清單。第二步本應接收這份清單並執行動作。然後某天一個多餘的逗號、一個被改名的鍵,或一個憑空產生的欄位,就讓整條鏈崩潰。根據 2026 年 DEV Community 一篇針對 LLM 結構化輸出的技術報告,用 regex 解析 AI 文字幾乎是生產環境 AI 流程每一次可靠性事故的根源。
解法不是寫更好的提示,而是在模型層直接約束輸出。這正是 JSON Schema 模式(又稱 Structured Outputs)的設計目的。一旦啟用,模型在數學上就無法生成違反 Schema 的 token。
結構化輸出是什麼?實際運作原理為何?
結構化輸出確保模型每次都產出完全符合你提供的 JSON Schema 的回應。模型不能省略必填欄位、不能憑空增加 Schema 沒有定義的鍵、不能在你要求數字時回傳字串。格式在推論階段透過「受限解碼」強制執行。
受限解碼是技術機制。每一個 token 生成步驟,執行環境都會檢查哪些 token 在當前 Schema 下合法,將不合法的 token 遮蔽。模型只能從合法的子集取樣。所以結構化輸出不是「模型更努力」,而是模型實質上無法生成違規的輸出。
根據 OpenAI 於 2024 年 8 月的官方公告,啟用 Structured Outputs 的 GPT-4o-2024-08-06 在複雜 JSON Schema 遵循評測上達到 100% 滿分,相對於未啟用時的約 40%。同樣機制如今已成為各大模型供應商的標配,名稱不同但底層原理一致。
核心好處是:你可以把 AI 輸出當成一個有型別的物件處理,而不是一堆等待解析的字串。下游程式收到的是你定義好結構的 JSON 物件。這是「穩定運行半年的工作流程」與「每週二崩潰一次的工作流程」之間的差別。
三大供應商如何支援結構化輸出?
三大供應商都支援結構化輸出,但各自的稱呼略有不同。底層機制相似到一個心智模型可以涵蓋全部三家。應該根據你已經在用的模型選擇,而不是僅憑這項功能。
OpenAI GPT-4o 及之後版本。 透過將 response_format 參數設為 json_schema 並附上你的 Schema 即可啟用。GPT-4o、GPT-4o-mini 與後續模型皆支援。Python SDK 對 Pydantic 提供一級支援,意即你寫一個 Pydantic class 直接傳入即可。根據 OpenAI 2024 年發布的官方 cookbook,這個方式在多數抽取使用情境下已取代 function calling 與舊版 JSON mode。
Google Gemini 1.5 Pro 及之後版本。 透過生成設定中的 responseSchema 啟用。Google 在 2026 年初公告所有 Gemini 模型支援完整 JSON Schema 與隱式屬性排序。OpenAI 用的同一份 Pydantic 或 Zod 定義可直接沿用。根據 Google 開發者部落格,有序屬性對於欄位順序敏感的抽取任務特別實用。
Anthropic Claude。 透過工具呼叫(tool calling)實作,而非專屬參數。你定義一個工具,其 input_schema 即為你想要的 JSON Schema,再強制模型呼叫這個工具,工具呼叫的輸入即為你要的結構化資料。機制不同,但可靠性結果一致。
實測 Schema:可直接運作的結構化輸出範本
學習結構化輸出最快的方式,是拿一個真實的文字抽取任務,為它寫一份 Schema。以下是可直接複製貼上 OpenAI playground 或任何呼叫 API 的工具的完整範例。它從一段雜亂的文字(例如電郵簽名或 LinkedIn 簡介)抽取結構化的聯絡資訊。
試用以下 Schema:
{ "name": "extract_contact", "schema": { "type": "object", "properties": { "full_name": { "type": "string", "description": "全名,照原樣輸出" }, "job_title": { "type": "string", "description": "目前職稱" }, "company": { "type": "string", "description": "目前任職公司名稱" }, "email": { "type": "string", "description": "主要電郵,全部小寫" }, "phone_country_code": { "type": "string", "description": "國碼含加號,例如 +852" }, "phone_number": { "type": "string", "description": "本地號碼,不含國碼" }, "linkedin_url": { "type": "string", "description": "完整 LinkedIn URL,若無則回空字串" } }, "required": ["full_name","job_title","company","email","phone_country_code","phone_number","linkedin_url"], "additionalProperties": false }, "strict": true }
搭配一句簡單提示「從這段簽名抽取結構化聯絡資料:[貼上簽名]」,跑 50 次不同簽名。每次的輸出都會是包含這 7 個欄位的有效 JSON。空欄位會回傳空字串而非省略,這正是 required 加上 additionalProperties: false 所保證的行為。
什麼情況該用結構化輸出,什麼情況不該用?
結構化輸出適合以下情境:AI 輸出直接餵給自動化下游程式、需要型別保證、或多個系統消費同一份回應。它不適合自由寫作、腦力激盪,或任何「文字本身就是價值」的任務。
適合用於文件、電郵、會議記錄與網頁的資料抽取。經典案例是發票抽取:供應商名稱、總金額、到期日、每行明細、稅項拆分。根據 OpenAI 結構化輸出 cookbook,這個單一使用情境佔據生產部署的最大比重。
適合用於分流與分類。客服工單貼上類別、優先級與所需動作標籤。銷售線索按行業、案值與跟進時程分類。輸出直接餵入 CRM 或佇列,一致性比表達豐富度更重要。
適合用於建構會執行動作的 AI Agent。每一次工具呼叫都需要嚴格的輸入結構。沒有 Schema 強制,Agent 可能在應傳數字的地方傳字串,或漏掉下一個工具需要的欄位,整條鏈就停下。
不適合用於第一稿寫作、創意發想、給人類閱讀的摘要,或對話式互動。把 JSON 強加在這些任務上會破壞自然語言品質,並增加摩擦而沒有相應的可靠性回報。
使用 JSON Schema 模式的常見錯誤是什麼?
幾乎每個團隊第一次嘗試結構化輸出都會犯三個錯誤。每個錯誤都會偽裝成不同問題,所以一直反覆出現。提前知道可省下一週除錯時間。
第一個錯誤是把應該設為必填且帶空值預設的欄位設為選填。選填欄位可被完全省略,意即下游程式必須處理鍵缺失情況。所有欄位都設為必填、在描述中註明「無值」時的預設(例如空字串或 0),下游程式會簡單得多。
第二個錯誤是過度設計 Schema。深度巢狀物件、條件式 Schema、union 型別都會給模型壓力。Schema 應該在下游程式允許的範圍內盡可能扁平。根據 2026 年 DEV Community 報告,巢狀超過三層的 Schema,失敗率明顯高於扁平設計。
第三個錯誤是把 Schema 合法性當成語意正確性。模型可以回傳一個結構完全合法、但內含錯誤訂單編號或編造信心分數的 JSON。Schema 強制保證結構,不保證真實性。永遠在 Schema 之後加一層語意驗證,特別是數字欄位與識別碼。
如何把結構化輸出整合進真實工作流程?
整合最快的路徑是挑一個經常崩潰的現有 AI 流程重做。多數實踐者至少有一個:每次掉電話的「電郵轉 CRM」步驟、漏掉稅碼的收據解析器、丟失行動項目的會議記錄拆分器。
從用純 JSON Schema 寫出 Schema 開始,先別碰提示。列出下游真正需要的每個欄位、全部標為必填、為每個欄位寫一句描述。先定義 Schema 的紀律通常會揭露原本提示要的太多。
用 10 個真實輸入跑這個結構化提示。和舊做法比較需要人工修正的數量,落差通常很大。根據 多份 2026 年產業報告,從純提示抽取改用 JSON Schema 模式的團隊,在同一份資料集上失敗率從 15 至 25% 降到 1% 以下。
然後加上語意驗證。檢查抽取的電郵是否符合電郵格式、日期是否可解析、金額是否為正數。結構驗證加語意驗證的組合,才是真正的生產級 AI。
對香港實踐者而言,結構化輸出是今年最值得學的高槓桿技術之一。它是「展示時很驚艷」與「真實使用一季仍能存活」的差別。一旦開始用 Schema 思考,你就不再與提示詞糾纏。懂AI,更懂你 UD相伴,AI不冷。
📐 打造真正能在生產環境存活的 AI 工作流程
結構化輸出只是可靠性堆疊的其中一塊。UD 的 AI 工程團隊協助香港組織設計能承受真實負載的 AI 流程:以 Schema 為先的思考、驗證層、人類介入檢查點。我們手把手帶你完成每一步:從你的第一份 Schema 到你第一個上線的 Agent。