iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
AI Engineering

現代化的 AI 系統設計系列 第 11

[Day11] - AI 出錯後,你能重建它看見了什麼嗎?Production Observability 與 Trace

  • 分享至 

  • xImage
  •  

API 200 OK,但答案用了三天前的規定

昨天談完 Evaluation,我們已經能判斷一個 RAG 或 Agent 系統究竟有沒有做對。
但當 Production 告警真的響起,下一個問題通常更棘手:它究竟從哪一步開始做錯?

假設使用者詢問新版請假規則,AI 卻引用舊規定回答。
API 回傳 200,模型沒有報錯,Citation 也真的連到公司文件;唯一的異常,是答案內容已經過期。

團隊先懷疑模型產生幻覺,於是回頭檢查整次 Request:Retrieval 同時找到新舊規定,Reranker 也正確地把新版排在前面,但 Context Assembly 使用了三天前建立的 Cache。

模型只是忠實地回答了它實際看見的舊 Context。
最後出錯的地方是 Generation,最早讓正確答案變得不可能的地方卻是 Cache。

Observability 的目的不是證明系統曾經執行
而是保留足夠的證據,重建它當時看見什麼、做了什麼,以及哪一步最先偏離。

https://ithelp.ithome.com.tw/upload/images/20260825/20183613rzx5mzw24y.png


Evaluation 告訴你錯了,Trace 告訴你從哪裡開始錯

Day 10 將 Evaluation 拆成

  • Retrieval
  • Context
  • Generation
  • Answerability
  • Task
  • Production

目的是把失敗送回正確的責任層。
Observability 則是在真實流量中,替每一次執行保存可供追查的證據。

這兩者彼此相依,卻不能互相取代:

訊號 回答的問題 無法單獨回答
Logs 某個時間點發生了什麼事件? 整次 Request 的跨服務因果
Metrics 系統是否異常、影響多大? 哪一筆 Request 為什麼失敗
Traces 一次 Request 經過哪些步驟? 回答在語意上是否正確
Evaluation 輸出與過程是否符合標準? Production 的整體可用性與尾端延遲
SLO 什麼水準才符合服務承諾? 單一事故的根本原因

實際的追查順序通常是:

  • Metric 或 SLO 發現異常,
  • 透過代表性 Trace 找到受影響的 Request,
  • 再從 Spans 定位問題、用 Logs 查看局部細節,
  • 最後由 Evaluator 或人工確認品質,並將事故加入 Regression Suite。

如果這些資料沒有共用 Trace ID、版本與 Artifact Reference,Dashboard 再漂亮,也只能看到症狀。

https://ithelp.ithome.com.tw/upload/images/20260825/20183613ktBj9VOnxB.png


一條 RAG Trace,不只是一次 Model Call

傳統 Web 系統常以入口 API、資料庫與下游服務構成 Trace;RAG 還必須呈現證據如何一路流向答案:

request
├─ input_policy
├─ query_understanding
│  ├─ query_rewrite
│  └─ query_decomposition
├─ retrieval
│  ├─ metadata_filter
│  ├─ sparse_search
│  ├─ dense_search
│  └─ fusion
├─ rerank
├─ context_assembly
├─ cache_lookup
├─ model_generation
├─ citation_binding
├─ verifier
└─ outcome_record
  • Root Span 應記錄 Request、Environment、Application 與 Pipeline Version、總延遲、Token、成本、結果狀態與採樣原因。
  • 每一層 Span 則保存足以解釋其輸入、輸出與決策的 Metadata。
  • Query Rewrite 要知道改寫前後的 Fingerprint、使用的 Prompt 與 Model Version,以及是否遺失錯誤碼、否定、日期或範圍;
  • Retrieval 要記 Index Snapshot、Filter、Top-K、候選文件與排名;
  • Reranking 除了最後結果,還要記候選如何被重新排序
  • Context Assembly 則要保存最終 Evidence 的順序、Token Budget、去重、壓縮與裁切結果。
  • Generation 需要 Provider、實際 Model Deployment、Prompt Template、輸入輸出 Token、TTFT、Retry、Stop Reason 與 Cache Usage。
  • Citation 與 Verifier 則應將 Claim、Evidence、判定結果、Rubric 和 Judge Version 串回原本的 Spans。

但最有價值的並不是欄位越多越好,而是每個元件都能回答三件事:

  1. 我收到什麼?
  2. 我做了什麼決定?
  3. 我交給下一層什麼?

Evidence Survival:正確資料在哪一步消失?

只保存「模型最後看到的 Context」仍然不夠。當必要文件沒有出現在最後的 Evidence Packet,我們無法判斷它是根本沒被找到,還是在後續處理中消失。

因此 RAG Trace 應替每一份候選 Evidence 保存 Lineage:

階段 必須知道的事
Retrieval 文件是否被找到?原始排名與分數是什麼?
Fusion 來自哪條召回路徑?融合後排到哪裡?
Reranking 排名如何改變?是否被截斷?
Context Assembly 是否被去重、壓縮、裁切或判定衝突?
Generation 是否真正進入模型輸入?回答是否使用?
Citation Claim 是否綁定到支持它的 Evidence?

這就是 Day 10 的 Evidence Survival Rate 在 Production 中需要的原始證據。
它不只告訴我們成功率,還能指出每個必要 Facet 究竟死在哪一層。

此外,不能只保存最後的 Top-K。若正確文件在 Retrieval 排名第 12,Reranking 前只取前 10 筆,事後留下的最終五筆無法讓人辨認是 Retriever 排得太後面,還是 Reranker 判錯。

https://ithelp.ithome.com.tw/upload/images/20260825/20183613bDFCHolyp6.png


找 First Bad Span,不要只找最後一個紅燈

一般 Trace UI 容易讓人先點開標成 Error 的 Span,但 AI 系統最終產生錯誤的節點,未必是根本原因。

可以將 First Bad Span 定義成:第一次讓正確結果不再可達,或顯著降低其可能性的上游步驟。

  • Parser 漏掉表格,最後卻由 Generation 產生錯誤答案
  • Query Rewrite 移除產品版本,最後由 Retrieval 找到舊文件
  • Handoff 遺失 Authorization Scope,最後由 Tool 回傳 403
  • Context Cache 沒有隨 Corpus 更新失效,最後由模型回答舊規定

診斷時,從失敗 Outcome 逆向查看 Assertions:這一層的 Input 是否仍足以得到正確結果?如果已經不足,就繼續往上游查;直到找到「輸入仍然正確,輸出第一次違反條件」的 Span。

接著進行 Counterfactual Replay:只把該 Span 的輸出替換成已知正確的 Artifact,其他條件盡量固定。若下游結果恢復,才提高它是 Root Cause 的信心。

Trace 能證明先後與關聯,不能自動證明因果。First Bad Span 是診斷框架,不是系統自動吐出的絕對真相。

https://ithelp.ithome.com.tw/upload/images/20260825/20183613FUpEIdqwLB.png


版本與 Hash,決定事故能不能被重建

如果 Trace 只寫著 model=latestprompt=prodindex=main,幾天後幾乎不可能重現同一次 Request。

至少需要版本化:

  • Application、Pipeline 與 Configuration
  • Prompt Template、Tool Schema 與 Policy
  • Parser、Chunker、Embedding、Retriever 與 Reranker
  • Corpus、Index 與 Context Packet Snapshot
  • Model Deployment、Evaluator 與 Rubric

Artifact 可以用 Hash 確認內容是否相同,再以受控 Reference 指向快照。
若 Model Provider 的後端版本無法鎖定,就只能稱為「近似重播」,不能宣稱能做到完全相同的結果。

Cache 也必須是一級公民。
Trace 應記錄 Cache 類型、Key Hash、Tenant Scope、Hit/Miss、Age、TTL、Source Version、失效原因,以及節省的 Token 與延遲。
否則 Cache Hit 看似是效能改善,也可能正是答案過期的原因。


Agent 讓 Trace 多了 State、Approval 與副作用

RAG 的主要產物是 Evidence 與 Answer;Agent 還會呼叫 Tool、委派任務、等待批准,甚至改變外部世界。

除了 Model 與 Tool Spans,Agent Trace 還需要:

  • State Transition:事件前後的 State Version
  • Retry:原因、次數、Idempotency Key 與補償操作
  • Approval:準備執行的動作、參數、決策與期限
  • Handoff:誰把什麼任務與 Context 交給誰
  • Checkpoint:可恢復的 State Snapshot
  • Stop Reason:完成、取消、超時、等待批准或 Budget 用盡
  • Final State Assertions:真實世界是否達到預期狀態

這些資料不等於保存模型的 Private Chain-of-thought。我們需要的是可觀察的決策、工具、Milestone、State 與 Artifact,而不是要求模型吐出私密推理內容。

長時間任務也不應該是一個跨越數小時甚至數天的巨大 Span。比較合理的做法,是用 Session 或 Workflow ID 串起多段獨立 Trace,每次 Resume、Attempt 或 Queue Consumer 建立自己的段落,透過 Link 與 Checkpoint 保存關係。

Multi-agent 系統還必須保留 Delegation Lineage:Coordinator 授予了哪些 Tool、資料與 Budget,子 Agent 收到哪個 Task Contract,多個結果如何合併,以及取消後是否仍有孤兒任務繼續執行。

https://ithelp.ithome.com.tw/upload/images/20260825/20183613BQ3WOkOGFE.png


Trace ID 統一,不代表 AI 語意已經統一

W3C Trace Context 已定義 traceparenttracestate,讓 Request 能跨服務、跨供應商延續 Trace Context。它解決的是「這些 Spans 是否屬於同一次執行」,不是 Retrieval、Prompt、Agent 或 Evaluation 該使用哪些欄位。

OpenTelemetry Semantic Conventions 為 Spans、Metrics 與 Events 提供共同命名方向,但 GenAI 領域仍快速演進。尤其 Agent 相關 conventions 目前仍屬 Development,不能假設每個平台已經零損支援相同語意。

比較穩健的做法,是在企業內部先定義少量 Canonical Concepts:Request、Retrieval、Context、Model、Tool、Handoff、Approval、Evaluation 與 Outcome,再由 Adapter 映射到當時採用的 OpenTelemetry、OpenInference 或 Vendor Schema。每筆資料也應記錄 Telemetry Schema Version,並以 Contract Test 檢查升級前後是否遺失關鍵欄位與 Parent–Child 關係。

AWS AgentCoreGoogle ADKMicrosoft FoundryOpenAI Agents SDKAnthropic Managed Agents 都提供不同程度的 Trace 能力;Langfuse、LangSmith、Phoenix、OpenLLMetry、OpenLIT 與 AgentScope 也各自處理平台、Evaluation、Instrumentation 或視覺化問題。真正的選型測試不該先比較 Dashboard,而是拿同一份 Trace Contract 驗證:Span 是否完整、Async Link 是否保留、欄位如何映射、敏感內容能否遮蔽、Tenant 權限是否隔離,以及資料能不能匯出與重播。


Sampling 與內容保存,是兩個不同的旋鈕

完整 Observability 不代表把每個 Prompt、Response、Retrieved Document 與 Tool Argument 永久保存。這些內容可能包含個資、憑證、客戶文件、跨 Tenant 資料與 Prompt Injection Payload;Telemetry Backend 本身就是高價值的敏感資料庫。

因此要把兩個問題分開:

  1. 這條 Trace 是否需要被保留?
  2. 這條 Trace 可以保留多少內容?

Error、Policy Violation、高權限寫入與極端延遲可以 100% 保留 Metadata Trace,但內容仍然遵循獨立的 Privacy Policy。正常成功流量採低比例隨機 Sampling,再以 Tail-based、Risk-based、Quality-based 與 Rare-path Sampling 補捉少見事件。

內容預設採 Metadata-only:保存長度、Token、Version、Hash、Status 與 Reference。真的需要調查原文時,再由權限更嚴格、保存期更短的 Evidence Store 提供經過遮蔽的內容。

遮蔽必須在 Export 前完成,不能先把秘密送進第三方平台,再期待 Dashboard 幫忙隱藏。traceparent 只是關聯 ID,不是授權憑證;tracestate 也不應放入 PII。Correlation 與 Authorization 是兩套不同的機制。

Online Judge 同樣不能對每個 Span 都呼叫大型模型。可以先以確定性規則和小型分類器篩選,再非同步評估完整案例;同時記錄 Judge、Rubric、Token、成本與抽樣機率,否則被刻意挑出的低品質案例,不能直接推估成整體失敗率。

https://ithelp.ithome.com.tw/upload/images/20260825/20183613reIltLGo23.png


Replay 是受控實驗,不是重新按一次執行

Production Incident 發生後,最危險的動作就是直接把原 Request 重送一次。對會寄信、退款、刪除資料或修改正式環境的 Agent 而言,重播本身可能製造第二場事故。

安全的 Replay Package 至少包含:

replay_id: inc-2026-0825-17
source_trace_id: ...
sanitized_input_ref: ...
initial_state_snapshot_ref: ...
corpus_snapshot: ...
pipeline_versions: {...}
tool_contract_versions: {...}
recorded_tool_results_ref: ...
model_snapshot_or_mock: ...
network_policy: replay_only
expected_invariants: [...]
known_limitations: [...]

重播預設使用 Recorded Tool Responses 或 Sandbox,禁止碰觸 Production Side Effects。先用原版本重現失敗,再一次只替換一個元件,觀察下游是否恢復;確認修復後,將這次 Incident 轉成 Day 10 所說的永久 Regression Case。

如此一來,Observability 才不是只為了事後看圖,而是把真實事故持續送回開發與 Evaluation 流程。


從單一 Trace,走向真正的 Production SLO

單次 Trace 回答「這次為什麼壞」;Metrics 與 SLO 則回答「整體是否已經壞到不能接受」。AI 系統至少要同時觀察四類 SLI:

面向 例子
Reliability 完成率、Tool Success、Timeout、Checkpoint Recovery
Latency End-to-end p95/p99、TTFT、Retrieval 與 Tool Duration
Quality Grounded Answer、Citation Correctness、Task Success
Cost Cost per Successful Outcome、Token、Tool Calls、Cache Saving

一筆 good_event 可以要求 Transport 成功、Final State 正確、沒有 Critical Policy Violation、品質通過,而且延遲與成本沒有超出 Budget。但 Dashboard 仍應保留各項 Component SLI,不能只剩一個總分,否則告警後依然無法歸因。

品質往往只在抽樣流量中有 Label,因此必須同時顯示 Coverage 與不確定性。ACL Leakage、未授權行動等重大安全事件則是 Hard Gate,不應被平均進一般 Error Budget。

每次 SLO Breach 最後都應連回代表性 Traces、Deployment 變更、確認過的 Root Cause,以及由 Incident 形成的 Regression Case。


Production Observability 的終點,是可重建的證據鏈

把今天的設計收斂成一份 Checklist:

  • 每個 Request 有可跨服務延續的 Trace ID
  • Application、Prompt、Model、Corpus、Tool、Policy 與 Judge 都有版本
  • RAG 保留候選 Evidence 從 Retrieval 到 Citation 的 Survival Lineage
  • Agent 保留 State、Retry、Approval、Handoff、Checkpoint 與 Final State
  • Sampling Policy 與 Content Capture Policy 分開設計
  • 敏感內容在 Export 前遮蔽,並實作 Tenant Isolation、RBAC、Retention 與刪除
  • Incident Replay 使用 Snapshot、Recorded Tool 與 Sandbox
  • SLO 同時呈現 Quality、Reliability、Latency 與 Cost
  • Root Cause 經重播與人工確認後,轉成 Regression Case

Observability 不是「把所有東西都記下來」,也不是採購一套能畫 Trace 的平台。真正困難的是決定哪些狀態必須被版本化、哪些證據必須保留 Lineage、哪些內容不該離開應用程式,以及如何從最終錯誤逆推到 First Bad Span。

成熟的 AI 系統不只會在出錯時告訴你哪裡亮紅燈;它還能重建當時的資料、版本、決策與狀態,讓團隊用受控實驗證明是哪一步先出了錯。

做到這一步,Day 10 的 Evaluation 才真正接上 Production:不是等事故發生後憑感覺調 Prompt,而是讓每次失敗都能被定位、重播,最後成為系統下一次不再犯錯的測試案例。

AI 你怎麼看?

https://ithelp.ithome.com.tw/upload/images/20260825/20183613LxvNwPjfPr.png


上一篇
[Day10] - AI 回答對了系統就真的做對了嗎?淺談 AI Evaluation
下一篇
[Day12] - RAG 已經會找資料了,為什麼還需要 Agent?從固定流程到動態決策
系列文
現代化的 AI 系統設計19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言