可靠的管線與驗證
設計階段契約,找出格式錯誤、無依據解讀與不符合業務規則的結果。
- 作者
- Huang Tzu LinFounder
- 發布日期
- 閱讀時間
- 約 31 分鐘
- 更新於
目錄
- 01本篇在學習路線中的位置
- 02先備知識
- 03學習成果
- 04要建立的成果
- 05可靠的管線具有階段與決策邊界
- 1. 匯入(Ingestion)
- 2. 擷取(Extraction)
- 3. 正規化(Normalization)
- 4. 驗證(Validation)
- 5. 比較與綜合(Comparison and Synthesis)
- 6. 最終格式化與交付(Final Formatting and Delivery)
- 06為何「只靠提示」的編排會瓦解
- 07控制邏輯是可靠性層
- 08結構化輸出有幫助,但無法取代驗證
- 三種輸出模式
- 09階段契約與工具交接邊界必須明確
- 10規則明確時優先採用確定性步驟
- 11完整範例:合約匯入工作流程
- 12實作練習
- 13刻意破壞的案例
- 14常見的營運失敗模式
- 15實務設計指引
- 16完成標準
- 17知識檢核
- 18參考答案
- 19本文不涵蓋的內容
- 20通往檢索與證據錨定的橋梁
- 21接續共用本機實作
- 22來源與延伸閱讀
合約擷取管線既要處理模型錯誤,也要應付一般軟體故障,例如格式錯誤的紀錄、證據缺漏、過期庫存與錯誤路由。本課將這些失敗路徑逐一攤開,確保看似合理的輸出不會未經檢查就變成正式業務紀錄。
可靠性的第一條規則是:符合 schema 不等於內容正確。欄位值即使型別正確,仍可能引錯條款、代表錯誤的房型類別,或違反無障礙需求。管線其餘部分存在的目的,就是讓這些不同類別的失敗保持可見。
延續文章 01 的元件邊界,假設有條管線要從飯店合約擷取欄位、正規化幣別與日期、檢查空房條件,最後產出比較表。系統是否可靠,取決於每個階段的職責定義、允許執行的操作,以及決定能否推進到下一步的檢查條件。
這正是控制邏輯(control logic)登場的地方。在可靠的 LLM 應用程式裡,模型只是更大工作流程中的元件之一。工作流程決定何時呼叫模型、傳入哪些輸入、要求什麼輸出結構、必須通過哪些驗證器、何時重試或停止,以及何時把紀錄轉交人工審查或送入例外佇列。拆解階段能讓失敗路徑易於檢視,但可靠度仍取決於健全的檢查與端對端評估。
虛構的 OptiVerse Travel 範例會匯入飯店合約、擷取費率、正規化數值,再結合另外取得的指定日期庫存證據。文中的合約 ID、費率、日期與預算皆為教學測試資料;合約上的房數配額也不等於即時空房確認。
追蹤資料的驗證流程
格式正確只是第一個檢查。
{
"hotel": "KYO-H12",
"accessible": false,
"rateUSD": 240
}- 01解析 JSON已解析物件
- 02驗證 schema通過:欄位與型別
- 03檢查業務規則失敗:需要無障礙房型
- 04檢查證據尚未執行
Schema 接受布林值 false,但旅客需求不接受。
讀懂目前結果
- 第一個失敗階段
- 旅客需求
- 可信來源房價
- 240 USD
Schema 可能接受 accessible=true 但價格錯誤的紀錄。型別、旅客需求與來源值須分別檢查;未執行的後續階段不能標示通過。
教學測例,不是模型效能量測。
本篇如何銜接前後內容
本篇在學習路線中的位置
帶入前作:01:元件與故障責任圖
本篇新增:具型別的階段契約與無效輸入測例。請將假設、來源 ID 與失敗案例連同成果一併留存。
後續用途:05、03、11、12 與 06 將沿用這些成果。跨主題系列的先備順序請見完整閱讀路線。文章 ID 是固定標籤,編號不代表閱讀順序。
學習目標與實作準備
先備知識
請先完成文章 01。你應能劃出模型步驟與負責路由、驗證及呈現輸出的應用程式元件邊界。
學習成果
完成後,你將能夠:
明確定義各階段的輸入、輸出、不變量與失敗通道;
區分結構有效性、語意有效性與商業規則正確性;
針對格式錯誤、遭拒絕、不完整、符合 schema 但內容錯誤,以及違反商業規則的輸出撰寫測試。
要建立的成果
請為六階段飯店合約管線建立具型別契約,並設計一組能觸發所有失敗通道的測試資料。階段契約必須攜帶穩定的紀錄 ID、來源參照、階段狀態與版本識別碼,讓下一階段無須回頭解析對話紀錄即可直接判讀。
可靠的管線具有階段與決策邊界
定義明確的階段與決策邊界,就能讓控制邏輯變得具體。以 OptiVerse Travel 旅行 Copilot 為例,考慮這項任務:匯入合作飯店合約 KYO-H12,並為 10 天日本無障礙行程(訂單編號 JPN-2026-0417)產出費率與空房比較表。
這項工作可拆解為六個階段。
1. 匯入(Ingestion)
系統接收合約 PDF 及基本中繼資料,例如來源、上傳時間戳記與文件識別碼。匯入階段的任務是以受控方式將文件交付後續階段,而非在此時解讀合約語意。
典型輸出:
文件 ID(例如 KYO-H12)
來源中繼資料(合作夥伴名稱、合約生效期間)
檔案類型與總和檢查碼
處理狀態
決策邊界:
若檔案無法讀取或缺少必要中繼資料,應停止並回報缺漏的輸入。遇到重複送入的檔案時,唯有在內容、存取權限範圍與相關處理版本都一致時,才沿用既有結果;否則應明確重新處理,因為重複送件本身不等於檔案損毀。
2. 擷取(Extraction)
系統從合約抽出季節性費率表、房型說明、無障礙標註、餐食方案與取消條款。其中一部分可以用確定性解析器處理;若版面不規則,或擷取目標需要依語意界定,則可能需要模型協助。
典型輸出:
原始擷取文字區塊
候選表格(費率表、房型配額表)
條款參照(例如第 4.3 條:含無障礙房型配額的季節性費率表)
候選欄位,涵蓋房型、每晚費率、季節日期區間、餐食內容與無障礙房數
決策邊界:
系統會檢查擷取結果是否具備任務所需的最低限度證據。若合約中沒有可還原的費率表,或缺少無障礙相關段落,工作流程就不應該把這筆紀錄當成完整資料,默默繼續往下傳。
3. 正規化(Normalization)
原始擷取結果還不能直接供系統使用:費率可能使用不同幣別,日期區間的格式可能不一致,房型名稱在各家合作合約中也可能有不同別名。正規化負責把擷取出的值轉換成系統其餘部分預期的標準形式。
典型輸出:
正規化幣別(同時保留原始金額與幣別,並附註美元估算值、具日期的匯率來源、換算方向與捨入規則)
標準日期格式(ISO 8601)
標準化房型名稱
無法解析欄位的明確空值(null)
決策邊界:
正規化必須能夠標示「未解析」,而不是硬猜一個值。附註與費率表可以合理地針對不同房型類別、日期、稅務處理或折扣條件列出不同價格;但若兩個數字在相同的適用條件下互相衝突,就要把衝突呈現出來,而不是當成格式差異處理。
4. 驗證(Validation)
驗證階段結合 schema 約束、證據比對與商業規則,判斷正規化後的紀錄能否交給下游使用。若路由決策會參考信心分數,就要用已標註的範例校準所選門檻;模型自報的信心值,並不自動等於正確的機率。
典型檢查:
必填欄位齊備(房型、每晚費率、季節日期、無障礙旗標)
數值範圍符合明確的異常值政策(在本測試資料中,5 美元或 50,000 美元會觸發人工審查,但本身不直接等同錯誤)
幣別符合標準 schema
來源追溯連結明確指向具體條款、表格儲存格或合約段落
標記互相矛盾的欄位值(例如同一日期與庫存快照下,
availability_confirmed=true卻同時出現available_accessible_room_count=0;單憑無障礙設施旗標,並不代表有空房)
決策邊界:
只有通過驗證的紀錄才能進入比較階段;未通過者則依失敗類別分流至重試、修補或人工審查。
5. 比較與綜合(Comparison and Synthesis)
取得清理完畢且通過驗證的證據資料包之後,才交由綜合模型發揮所長,撰寫精練的費率與空房比較。不應讓綜合模型被迫替管線在上游已偵測到的模糊之處善後。
典型輸出:
符合指定旅遊日期的跨房型、跨季節費率比較表
由獨立庫存來源佐證、涵蓋所需住宿晚數的無障礙空房狀態;未確認時標示為
unknown飯店費用小計;唯有交通、餐飲、稅金、各項費用及其他必要支出皆齊備時,才評估是否符合 13,000 至 15,000 美元的家庭總預算
連回擷取證據資料包的來源參照
決策邊界:
若模型必須憑空假設房況或價格才能寫出比較結果,系統就應拒答,或僅回傳明確標示資訊缺口的部分摘要。
6. 最終格式化與交付(Final Formatting and Delivery)
最後一個階段將結果整理後送往目標通道,例如顧問儀表板、客戶提案單或訂房服務。格式化不只是外觀:它決定哪些中繼資料、警示與來源追溯連結會隨輸出結果一併交付。
典型輸出:
排版完成的比較表
附帶連結的佐證(合約條款、費率表出處)
處理紀錄
最終狀態
決策邊界:
若目標輸出通道規定必須附帶來源追溯連結或核准狀態,交付階段就要在此強制執行這項契約,不能假設上游步驟已經滿足。
為何「只靠提示」的編排會瓦解
「只靠提示的編排」是指把更多工作流程職責塞進單次模型呼叫,而不是圍繞模型設計明確的階段。這聽起來往往很有效率:要求模型讀完合約、擷取費率、正規化幣別、判斷空房是否足夠、視需要呼叫工具,再一次寫出比較結果。
這拿來做展示或許行得通,放進正式系統卻很脆弱。
模型幻覺只是問題的一部分。下游需求通常比自然語言更嚴格:解析器預期某個欄位存在,路由步驟預期少數幾種狀態值之一,驗證器預期幣別已統一為單一標準,審查佇列預期附有信心分數與來源追溯中繼資料,合規或稽核流程則要求系統說明每個費率或空房數字的出處。只靠提示的編排會模糊這些邊界。
邊界一旦模糊,故障就更難看見,也更難圍堵。模型可能回傳看似有效、幣別換算卻錯誤的 JSON;產出看似合理、卻不符合旅行社標準命名的房型名稱;漏掉必填欄位,再用流暢的文字彌補;或把擷取與解讀綁得太緊,讓系統無法分辨錯誤來自合約解析、正規化還是綜合。
把提示寫得更強,不等於架構更好。提示品質很重要,但無法取代明確的工作流程設計。當任務包含多個正確性標準不同的轉換時,比較安全的做法是把這些轉換拆開,逐一檢查。
控制邏輯是可靠性層
控制邏輯是決定系統下一步會發生什麼事的一組規則。在傳統軟體管線中,這些規則直接寫在程式碼裡。在 LLM 系統中,有些決策仍可能是確定性的,有些則可能委派給模型,但工作流程仍由應用程式掌握。
這份主導權很重要。使用工具並不會把控制邏輯從應用程式中移走。模型可以提議呼叫工具,或替工具呼叫產生結構化引數,但開放哪些工具、引數必須遵循什麼 schema、引數是否可接受、工具結果是否應觸發下一步,以及結果缺漏或不一致時怎麼處理,都由應用程式決定。
實務上,控制邏輯要回答的是這類問題:
合約解析出的結構是否足以繼續往下跑?
面對這份文件版面,應該走哪一條擷取路徑?
所有必填欄位是否都已齊備?
幣別正規化是否在毫無歧義的情況下完成?
這筆紀錄是否已通過檢查,可安全送入比較步驟?
管線應該重試、拒答,還是提報人工審查?
這些都是一般的系統問題。模型可以協助回答其中一部分,但不會讓這些問題消失。
結構化輸出有幫助,但無法取代驗證
許多團隊會要求模型回傳符合 schema 的結構化輸出,藉此提升可靠度。這是好做法:它能收斂輸出形狀、讓下游解析更穩健,也迫使應用程式定義自己真正需要哪些欄位。
三種輸出模式
不要把以下三種不同的機制,籠統地稱為「模型回傳了 JSON」:
用提示要求 JSON:僅以自然語言要求輸出 JSON,沒有結構上的強制。
JSON mode:把輸出限制為語法有效的 JSON,但不會強制符合你的 schema。
嚴格 schema 約束輸出:在解碼階段強制輸出符合受支援 schema 的結構形狀。以 OpenAI 目前的嚴格 Structured Outputs 為例,受支援 schema 的結構符合度可靠,但語意錯誤依然可能發生,應用程式也仍須處理拒絕回應、內容過濾與不完整回應(OpenAI, 2026)。
請依實際部署的供應商所提供的確切能力與失敗契約來設計,而不是把嚴格約束解碼的保證,套用到盡力而為的 JSON 提示上。
即便有嚴格的 schema 約束,保障範圍也僅止於結構形狀。
符合 schema 的紀錄在語意上仍可能出錯:必填欄位可能填了錯誤的值,看似合理的數字可能來自相鄰的費率項目,合法的標籤可能套到錯誤的房型類別,或在證據薄弱、模稜兩可時,欄位仍被標成已完成。
Schema 與驗證器回答的是不同的問題:
Schema 問的是:「輸出是否符合要求的形狀?」
驗證器問的是:「這份輸出能否被這個工作流程接受?」
這兩個問題不能互換。
舉例來說,假設一筆紀錄定義了 room_type、nightly_rate_usd、accessibility_flag 與 source_clause。Schema 可以要求費率必須是數值、條款參照不得為空,且 room_type 必須來自固定的列舉值;但單靠 schema,無法確認引用的條款是否支持這個費率、幣別換算是否正確,或來源房型是否對應到正確的標準類別。合法的標籤,仍可能是這筆紀錄的錯誤標籤。
在正式環境中,驗證通常會結合三個層次:
結構驗證:檢查型別、必填欄位、列舉值與整體形狀。
語意驗證:檢查數值合理性、跨欄位一致性與來源內容對齊程度。
商業規則驗證:檢查紀錄是否符合組織作業規範與行程限制條件。
最後這一層的重要性,往往超出許多原型開發者的預期。旅行社的工作流程可能要求每筆擷取出的費率都連到具體的合約條款與日期區間,而不只是連到自由文字。這項要求是工作流程契約,不是語言問題。
階段契約與工具交接邊界必須明確
模型步驟與應用程式程式碼之間的交接契約,同樣左右系統可靠度。只要允許模型提議工具呼叫,工具 schema 就成為可靠性邊界的一環。
設計良好的工具 schema 能限制模型可提出的請求,並讓應用程式端的契約可以測試。諸如 normalize_currency、lookup_room_type_alias 或 fetch_prior_bookings 等工具,都應提供範圍窄、具型別的介面,以及清楚的失敗行為。
舉例而言,如果應用程式需要精確換算,幣別正規化工具就不該接受含糊的自由形式指令,而應接受定義明確的金額、來源與目標幣別代碼、具日期的匯率來源或指定匯率,以及捨入規則。它應保留原始數值,並回傳可追溯的正規化結果或明確的錯誤狀態。如果模型傳入格式錯誤的引數,應用程式應拒絕這次呼叫,而不是自行猜測。
許多團隊正是在這道邊界上才發現,「模型可以呼叫工具」本身並不是一種設計。設計存在於 schema、引數檢查、重試策略、備援路徑,以及判定工具失敗屬於可恢復或終止性錯誤的決策之中。
本篇負責管線階段之間的契約;執行期的工具迴圈、重試、冪等性與核對機制,則由文章 06 負責。函式呼叫仍是多步驟的交換:應用程式接收模型提議的呼叫、執行程式碼,再把結果傳回模型(OpenAI, 2026)。
階段之間的交接也適用相同邏輯。每個階段都應產出輸出契約,讓下一階段不必重新解讀整段歷史就能檢查。這能減少隱藏狀態,讓失敗留在局部。如果比較步驟得讀完冗長的對話紀錄,才能推斷正規化是否成功,系統就已經失去了重要的控制。
規則明確時優先採用確定性步驟
把每一項轉換都交給模型負責,看起來比較有彈性,因此很誘人。但實務上,一旦問題已經釐清,許多高價值的工作流程步驟改用確定性方式處理會更好。
適合採用確定性邏輯的情境:
轉換規則明確且固定
合法輸出的集合很窄
錯誤條件容易定義
可重現性比彈性更重要
常見做法包括檔案類型路由、幣別換算、ISO 日期格式轉換、列舉別名對應、重複偵測、門檻檢查,以及依輸出通道調整排版格式。
適合採用模型引導步驟的情境:
輸入格式混亂或結構鬆散
任務仰賴上下文語意判讀
合法輸出無法事先完整列舉
資訊壓縮或綜合整理能帶來明確價值
常見做法包括從版面不規則的合約抽出費率表、把附註連到周邊條款,或根據通過驗證的證據資料包起草易讀的比較摘要。
這種區分無關意識形態,而是營運上的考量。過度使用模型,會增加原本可以避免的延遲、成本與失敗面;模型用得太少,則可能讓雜亂的任務變得脆弱。可靠的架構會把每個步驟交給最適合它的機制。
完整範例:合約匯入工作流程
為了具體呈現上述邊界,假設 OptiVerse Travel 團隊上傳合作飯店合約 KYO-H12,準備為訂單編號 JPN-2026-0417 製作費率比較表;該訂單是櫻花季期間的四口之家(含一位輪椅使用者)10 天日本無障礙行程,總預算為 13,000 至 15,000 美元。
脆弱的原型做法會把整份合約文字連同一長串指令直接丟進單次模型呼叫:
「讀取這份合約,擷取季節性費率與無障礙房空房狀況,將金額換算為美元,挑出最符合指定日期的選項,並撰寫比較摘要。」
如果輸出看起來合理,原型似乎就成功了;但工作流程已經把太多決策藏在同一個地方:
擷取時是否漏掉了第 4.3 條的費率表?
日圓換算美元是否套用了正確匯率與捨入規則?
模型是否把一般房配額與無障礙房配額混為一談?
是否漏看合約不適用日(blackout dates)或最少連住晚數限制?
有沒有人能檢查實際用了哪些資料?
分階段的管線則讓每次交接都能被檢查。
首先,系統解析合約 PDF,抽出候選表格、條款與段落。接著針對一組有限的目標欄位執行擷取:房型、每晚費率、幣別、季節日期區間、無障礙房數、餐食方案與來源條款參照。然後正規化幣別與日期格式,並驗證紀錄的結構、語意與商業規則。直到這一步之後,系統才請模型以通過驗證的紀錄作為來源資料包,產出比較表。
這個版本讓失敗邊界清楚可見。若某筆費率缺少來源追溯,工作流程可以在比較前停下;若正規化發現幣別或日期區間互相衝突,可以把紀錄標記送審;若比較步驟失敗,結構化的擷取結果仍然保留,可供檢查或重新處理。
這就是 LLM 管線中可靠度的樣貌:不是完美的輸出,而是有邊界的失敗與清楚可讀的狀態。
實作練習
請定義包含 record_id、source_version、stage、status、payload 與 errors 欄位的階段封套(stage envelope),再為以下候選擷取紀錄撰寫測試:
{
"record_id": "KYO-H12-rate-04",
"source_version": "contract-v3",
"room_type": "accessible_twin",
"nightly_rate_usd": 240,
"accessibility_flag": true,
"source_clause": "KYO-H12#4.3"
}請將 contract-v3 視為教學測試用的符號版本,而不是 SHA-256 摘要。在本練習的虛構來源表中,條款 KYO-H12#4.3 載明 room_type=accessible_twin、nightly_rate_usd=280、accessibility_flag=true,有效住宿夜晚的區間為 2026-04-01 至 2026-04-10(含首尾)。這些美元數值皆已預先正規化,不代表任何真實匯率。上方候選紀錄是刻意寫錯的:正確費率是 280,而且即使修正了費率,若請求的是 2026-04-11 當晚的住宿,仍會違反日期規則。這組驗證測試資料與文章 03 的語料庫(fixture-v1)及連動的本機實作不同,後兩者中 KYO-H12 的費率為 240 USD。請把它們的資料集與版本識別分開,也不要只因飯店 ID 相同就合併範例。
請建立五組測試資料:
盡力而為的 JSON 提示產出語法錯誤的 JSON;
供應商回傳拒絕回應(refusal);
因觸及輸出上限而遭截斷的不完整回應;
結構符合 schema,但來源條款載明
280而非240的紀錄;費率語意正確,卻違反指定旅遊日期商業規則的紀錄。
你的測試必須回報五種不同的失敗類別;籠統的 model_error 結果不算通過。
刻意破壞的案例
先定義欄位:accessibility_flag 描述房型;available_accessible_room_count 是指定日期的庫存;availability_confirmed 表示在請求的區間內,目前已確認有符合條件的房間可用。無障礙房型的可用房數為零是有效資料,不是矛盾;但商業規則仍必須避免提出任何有空房的宣稱。
製作刻意破壞的測試資料時,請在 schema 中明確允許這三個欄位,並針對同一飯店、房型、區間與庫存快照,將 available_accessible_room_count 設為 0,同時將 availability_confirmed 設為 true。只檢查形狀的 schema 可能接受這些值;跨欄位的語意檢查則必須拒絕它們。此外,有空房也不等於已完成訂房。
修補方式不是把提示寫得更嚴格。請加入跨欄位不變量、保留產生這兩個值的來源儲存格,並把紀錄送往審查或重新擷取。
常見的營運失敗模式
正式環境的失敗,通常源自各階段假設之間不起眼的落差。
以提示要求 JSON 或使用非嚴格模式時,常見的失敗之一是結構化輸出格式錯誤。嚴格的約束輸出會改變這種失敗面,但應用程式仍須明確處理拒絕回應、過濾、生成不完整、不支援的 schema,以及語意錯誤的值。
另一種是有效結構內的語意漂移。欄位可能存在、型別也正確,卻代表了錯誤的東西。由於管線看起來一切正常,這類錯誤很容易被忽略。
第三種是部分有效紀錄造成的無聲損毀。若某個關鍵欄位正規化失敗,系統卻仍讓比較繼續進行,最終答案可能讀起來很有把握,但證據資料包其實並不完整。
路由錯誤也很重要。工作流程可能把低信心的擷取結果送進正常的比較路徑,而不是修補佇列。這類控制邏輯錯誤看起來可能像模型問題,原因其實出在階段政策。
重複呼叫模型可能增加成本與延遲。若任務有合適的確定性實作,就把它當成基準,與模型方案比較,並要求有證據顯示額外的呼叫改善了相關結果。單靠重複執行,不足以證明可靠度提升。
例外路徑應與正常路徑一起設計。擷取管線可能遇到無法讀取的檔案、互相衝突的欄位、不支援的版面,或語意含糊的合約文字。在下游依賴輸出之前,先定義如何偵測、拒絕、重試或提報這些情況。
實務設計指引
從可靠性目標出發,而不是從功能清單出發。先問清楚:哪些內容必須正確到什麼程度,工作流程才有用;哪些類型的失敗可以接受。
依轉換類型拆解任務。擷取、正規化、驗證、比較與交付通常有不同的錯誤模式,沒有理由就不應合併。
為每個階段定義輸出契約。每個階段產出的內容,都應該讓下一階段能直接檢查,包括失敗狀態。
模型輸出要使用 schema,但應把它視為驗證的輸入,而不是最終保證。
工具介面要保持精簡。只要某個工具在營運上很重要,就要為它提供具型別的 schema、明確的錯誤行為與應用程式端檢查。
及早設計例外路徑。事先決定何時重試、何時拒答、何時揭露不確定性,以及何時轉交人工審查者。
量測成本與延遲實際花在哪裡。可靠的系統常常是靠移除不必要的模型呼叫而改善,而不是靠加入更大的模型呼叫。
最重要的是,在每次交接時保留證據。精美的比較表,應該永遠能追溯回產生它的那筆紀錄。
完成標準
成果必須滿足以下所有條件才算完成:
每個階段都有具型別的成功與失敗輸出;
結構驗證、語意驗證與商業規則驗證各自擁有獨立測試;
拒絕回應與不完整回應,都不會以紀錄的形式進入比較階段;
結構符合 schema 但跨欄位矛盾的紀錄,會在進入綜合前被拒絕;
每個通過驗收的欄位都能追溯至明確的來源版本與位置;
任何階段失敗時,都能直接恢復執行或轉交審查,無須從自然語言文字重建狀態。
知識檢核
請不回頭翻閱文章,直接回答:
嚴格符合 schema 保證了什麼,又不保證什麼?
為什麼供應商拒絕回應與截斷的不完整輸出,必須與結構無效分開處理?
accessibility_flag=true且可用房數為零是否矛盾?若同一份庫存快照同時標示availability_confirmed=true呢?為什麼重試與冪等性機制歸文章 06 而非本篇負責?
參考答案
它保證輸出符合受支援的結構形狀,但不保證欄位數值為真、具備來源佐證、彼此一致,或符合商業規則。
兩者代表不同的供應商回應或生成終止狀態,各自需要不同的復原路徑與面向使用者的處理方式。
第一種組合可以代表已售罄的無障礙房型,應該通過語意驗證。第二種情況是在同一份零庫存快照上標示
availability_confirmed=true,違反了既定的欄位定義,必須由語意驗證拒絕;商業政策則另外阻擋缺乏依據的空房宣稱。本篇定義階段契約;文章 06 則負責模型與工具迴圈在執行期的執行與復原。
五組測試資料預期的失敗類別依序為 invalid_structure、refused、incomplete、unsupported_value 與 business_rule_failed。接受解析後的紀錄之前,先檢查供應商的完成與拒絕狀態,再把欄位值與來源條款及指定日期比對。不要把不完整的 JSON 拼接成成功紀錄,也不要把拒絕回應當成解析錯誤重試。
本文不涵蓋的內容
本文並不是主張每個 AI 系統都應該是僵化的確定性管線。有些任務確實需要更開放的模型控制,本系列後續文章會談檢索、記憶與代理迴圈。
本文也不是主張結構化輸出本身就能解決可靠性問題。它改善的是其中一道邊界,無法取代驗證、監控或工作流程設計。
在問系統是否需要代理之前,先檢查它的管線是否具備清楚的階段、明確的 schema、驗證規則與受控的交接。接著再評估模型引導控制會帶來哪些額外的選擇與失敗模式。自主性是一種設計選擇,它的效益必須針對任務加以證明。
通往檢索與證據錨定的橋梁
結構良好的管線仍有一個主要限制:它掌握的資訊,最多只能和收到的證據資料包一樣多。如果系統必須回答取決於外部合作合約、內部訂房紀錄、無障礙資料庫或過往客戶行程的問題,可靠度也取決於如何找到正確的證據,並把它接入工作流程。
這就是檢索登場的地方。檢索教學會從管線內部的控制轉向證據錨定(grounding):系統如何檢索正確的上下文、保留來源追溯,並知道何時應該拒答而不是猜測。控制邏輯與驗證在那裡不會消失,反而更加重要,因為檢索又多了一個階段,劣質輸入可能在此悄悄拉低最終答案的品質。
接續共用本機實作
下載並解壓縮旅行 Copilot 實作包,或直接使用儲存庫中的 examples/travel-copilot 目錄,並在該目錄下執行指令。環境只需 Python 3.9+;請先閱讀 README.zh-TW.md,且跨篇章共用同一個 out 目錄。接著驗證來源契約,再刻意製造一筆重複的來源 ID,確認匯入階段會中止。
python3 lab.py pipeline --out out進入動作執行階段前,請依序執行 pipeline、retrieve 與 evaluate。本實作採用虛構紀錄、小型雙語詞彙字典、摘錄式回答與本機 SQLite 供應商資料庫;核准流程為模擬性質,不會呼叫任何模型 API,也不會觸發真實訂房、扣款、OCR 或影像分析。它實作了整體架構中一段可供檢視的切片,README 也明確標示了擴充邊界。
來源與延伸閱讀
本文參考以下一手資料與官方文件:
BAIR. "The Shift from Models to Compound AI Systems." 說明控制邏輯是複合式 AI 系統核心設計選擇的參考資料。bair.berkeley.edu/blog/2024/02/18/compound-ai-systems
OpenAI. "Function calling." 說明模型輸出與應用程式端程式碼如何透過結構化介面協作執行工具呼叫的官方文件。developers.openai.com/api/docs/guides/function-calling
OpenAI. "Structured model outputs." 說明 schema 約束輸出的官方文件;本文引用時附帶一項但書:符合 schema 不保證語意正確。developers.openai.com/api/docs/guides/structured-outputs
National Institute of Standards and Technology. "Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile." 關於風險控制、評估、監控、來源追溯與可信任部署框架的參考資料。nist.gov/publications/artificial-intelligence-risk-management-framework-generative-artificial-intelligence
閱讀順序
完整閱讀路線
章節 06 / 25
Huang Tzu Lin
富宇資訊科技創辦人。撰寫 AI 系統設計、證據與工程取捨的文章。
