昨天談完 Evaluation,我們已經能判斷一個 RAG 或 Agent 系統究竟有沒有做對。
但當 Production 告警真的響起,下一個問題通常更棘手:它究竟從哪一步開始做錯?
假設使用者詢問新版請假規則,AI 卻引用舊規定回答。
API 回傳 200,模型沒有報錯,Citation 也真的連到公司文件;唯一的異常,是答案內容已經過期。
團隊先懷疑模型產生幻覺,於是回頭檢查整次 Request:Retrieval 同時找到新舊規定,Reranker 也正確地把新版排在前面,但 Context Assembly 使用了三天前建立的 Cache。
模型只是忠實地回答了它實際看見的舊 Context。
最後出錯的地方是 Generation,最早讓正確答案變得不可能的地方卻是 Cache。
Observability 的目的不是證明系統曾經執行
而是保留足夠的證據,重建它當時看見什麼、做了什麼,以及哪一步最先偏離。

Day 10 將 Evaluation 拆成
目的是把失敗送回正確的責任層。
Observability 則是在真實流量中,替每一次執行保存可供追查的證據。
這兩者彼此相依,卻不能互相取代:
| 訊號 | 回答的問題 | 無法單獨回答 |
|---|---|---|
| Logs | 某個時間點發生了什麼事件? | 整次 Request 的跨服務因果 |
| Metrics | 系統是否異常、影響多大? | 哪一筆 Request 為什麼失敗 |
| Traces | 一次 Request 經過哪些步驟? | 回答在語意上是否正確 |
| Evaluation | 輸出與過程是否符合標準? | Production 的整體可用性與尾端延遲 |
| SLO | 什麼水準才符合服務承諾? | 單一事故的根本原因 |
實際的追查順序通常是:
如果這些資料沒有共用 Trace ID、版本與 Artifact Reference,Dashboard 再漂亮,也只能看到症狀。

傳統 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
但最有價值的並不是欄位越多越好,而是每個元件都能回答三件事:
只保存「模型最後看到的 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 判錯。

一般 Trace UI 容易讓人先點開標成 Error 的 Span,但 AI 系統最終產生錯誤的節點,未必是根本原因。
可以將 First Bad Span 定義成:第一次讓正確結果不再可達,或顯著降低其可能性的上游步驟。
診斷時,從失敗 Outcome 逆向查看 Assertions:這一層的 Input 是否仍足以得到正確結果?如果已經不足,就繼續往上游查;直到找到「輸入仍然正確,輸出第一次違反條件」的 Span。
接著進行 Counterfactual Replay:只把該 Span 的輸出替換成已知正確的 Artifact,其他條件盡量固定。若下游結果恢復,才提高它是 Root Cause 的信心。
Trace 能證明先後與關聯,不能自動證明因果。First Bad Span 是診斷框架,不是系統自動吐出的絕對真相。

如果 Trace 只寫著 model=latest、prompt=prod、index=main,幾天後幾乎不可能重現同一次 Request。
至少需要版本化:
Artifact 可以用 Hash 確認內容是否相同,再以受控 Reference 指向快照。
若 Model Provider 的後端版本無法鎖定,就只能稱為「近似重播」,不能宣稱能做到完全相同的結果。
Cache 也必須是一級公民。
Trace 應記錄 Cache 類型、Key Hash、Tenant Scope、Hit/Miss、Age、TTL、Source Version、失效原因,以及節省的 Token 與延遲。
否則 Cache Hit 看似是效能改善,也可能正是答案過期的原因。
RAG 的主要產物是 Evidence 與 Answer;Agent 還會呼叫 Tool、委派任務、等待批准,甚至改變外部世界。
除了 Model 與 Tool Spans,Agent Trace 還需要:
這些資料不等於保存模型的 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,多個結果如何合併,以及取消後是否仍有孤兒任務繼續執行。

W3C Trace Context 已定義 traceparent 與 tracestate,讓 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 AgentCore、Google ADK、Microsoft Foundry、OpenAI Agents SDK 與 Anthropic Managed Agents 都提供不同程度的 Trace 能力;Langfuse、LangSmith、Phoenix、OpenLLMetry、OpenLIT 與 AgentScope 也各自處理平台、Evaluation、Instrumentation 或視覺化問題。真正的選型測試不該先比較 Dashboard,而是拿同一份 Trace Contract 驗證:Span 是否完整、Async Link 是否保留、欄位如何映射、敏感內容能否遮蔽、Tenant 權限是否隔離,以及資料能不能匯出與重播。
完整 Observability 不代表把每個 Prompt、Response、Retrieved Document 與 Tool Argument 永久保存。這些內容可能包含個資、憑證、客戶文件、跨 Tenant 資料與 Prompt Injection Payload;Telemetry Backend 本身就是高價值的敏感資料庫。
因此要把兩個問題分開:
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、成本與抽樣機率,否則被刻意挑出的低品質案例,不能直接推估成整體失敗率。

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 回答「這次為什麼壞」;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。
把今天的設計收斂成一份 Checklist:
Observability 不是「把所有東西都記下來」,也不是採購一套能畫 Trace 的平台。真正困難的是決定哪些狀態必須被版本化、哪些證據必須保留 Lineage、哪些內容不該離開應用程式,以及如何從最終錯誤逆推到 First Bad Span。
成熟的 AI 系統不只會在出錯時告訴你哪裡亮紅燈;它還能重建當時的資料、版本、決策與狀態,讓團隊用受控實驗證明是哪一步先出了錯。
做到這一步,Day 10 的 Evaluation 才真正接上 Production:不是等事故發生後憑感覺調 Prompt,而是讓每次失敗都能被定位、重播,最後成為系統下一次不再犯錯的測試案例。
