「AI 系統出問題了」不是問題描述,是症狀描述。
在沒有找到根因之前,任何修復都是猜測。
結構化的故障排查不是把所有可能都試一遍,
而是用最少的資訊快速縮小到一個節點。
面試情境
面試官:「你們的 AI 客服系統,今天早上 9 點開始,客戶回報:系統變慢了,有時候會給出奇怪的答案。你不在現場,只能遠端處理。請一步一步說明你的排查思路,以及你平時會怎麼設計可觀測性來讓這類問題更快被找到。」
一、AI 系統故障排查的特殊性
傳統系統 vs AI 系統的故障特性對比:
維度 傳統系統 AI 系統
──────────────────────────────────────────────────────────────
確定性 相同輸入 = 相同輸出 LLM 輸出有隨機性,問題可能間歇出現
錯誤信號 明確 Error Code(500/404) 品質問題沒有 Error Code,只有「感覺不對」
根因數量 通常在代碼或配置 分佈在:模型、Retrieval、Tool、基礎設施
「正確」定義 有明確的正確答案 需要評估,不是二元對錯
──────────────────────────────────────────────────────────────
最重要的 AI 特有洞察:
┌──────────────────────────────────────────────────────────────┐
│ Retrieval 失敗 → 「奇怪的答案」 │
│ │
│ Vector Search 返回 0 個結果 │
│ ↓ │
│ LLM Context 是空的 │
│ ↓ │
│ LLM 沒有 Context,靠「自己的知識」猜測 │
│ ↓ │
│ 症狀:「答非所問」「答案不基於我們的資料」 │
│ Error Log:沒有任何錯誤 ← 這就是難以發現的原因 │
│ │
│ 只有 Trace 才能發現: │
│ vector_search Span → result_count=0(返回 0 結果) │
└──────────────────────────────────────────────────────────────┘
三個常見的排查誤區:
誤區 1:「LLM 模型一定有問題」
→ 不一定。延遲問題通常是基礎設施;品質問題可能是 Retrieval 失敗
誤區 2:「昨天還好,一定是昨晚的部署造成的」
→ 不一定。流量模式改變(如特定類型查詢增多)也能觸發潛在問題
誤區 3:「重啟一下試試」
→ 可能暫時緩解(Cold Start 問題除外),但根因沒找到必定再發
二、三個可觀測性成熟度階段
╔══════════════════════════════════════════════════════════════╗
║ Phase 1:基礎可觀測性(POC / 初期上線) ║
║ 「能知道系統壞了」 ║
╚══════════════════════════════════════════════════════════════╝
元件:
├── 結構化日誌(JSON 格式,帶 timestamp、level、service 欄位)
├── 基本 Metrics(Error Rate、P50 Latency、Uptime)
└── 簡單 Alert(Error Rate > 5% → 發 Email)
能解決的問題:
├── 「系統是不是掛了?」(Uptime 告警)
└── 「有沒有大量錯誤?」(Error Rate 告警)
無法解決的問題:
├── 「哪個 Step 慢?」(沒有 Trace)
└── 「品質退化了嗎?」(沒有 Eval 指標)
╔══════════════════════════════════════════════════════════════╗
║ Phase 2:生產級可觀測性(正式上線後) ║
║ 「能知道系統為什麼慢,慢在哪裡」 ║
╚══════════════════════════════════════════════════════════════╝
新增元件(在 Phase 1 基礎上):
├── Distributed Tracing(OTel + Cloud Trace)
│ 每個 LLM 呼叫、Tool 呼叫、Vector Search 都有獨立 Span
├── 完整 Metrics 儀表板
│ P50/P95/P99 延遲、Token 消耗趨勢、快取命中率、Error Rate by type
├── 告警精細化
│ P95 > 5s 持續 5 分鐘 → PagerDuty
│ Error Rate > 1% 持續 2 分鐘 → Slack
└── 日誌結構化增強(加入 trace_id,可與 Trace 關聯)
能解決的問題:
├── 「哪個 Span 是延遲瓶頸?」(瀑布圖)
├── 「哪個 Tool 最常失敗?」(tool.success=false 的 Span 統計)
└── 「Token 在哪裡被消耗?」(input_tokens Span Attribute)
╔══════════════════════════════════════════════════════════════╗
║ Phase 3:SLO 驅動的可觀測性(企業級) ║
║ 「能預測系統什麼時候會壞,並主動防止」 ║
╚══════════════════════════════════════════════════════════════╝
新增元件(在 Phase 2 基礎上):
├── SLO 定義與 Error Budget 追蹤
│ SLO:P95 < 5s,99% 的 30 天窗口內
│ Error Budget:允許 1% = 432 分鐘/月 的違規
├── Shadow Eval Pipeline(線上品質監控)
│ 3% 流量自動評估 Faithfulness + Safety
│ 7 日移動平均低於閾值 → 告警
├── 容量預測(Capacity Planning)
│ 基於流量趨勢預測何時需要升級
└── Anomaly Detection
異常流量模式(如特定查詢類型突然增多)主動告警
能解決的問題:
├── 「Error Budget 還剩多少?」(決定是否可以部署新功能)
├── 「品質是否在緩慢退化?」(Shadow Eval 趨勢)
└── 「容量什麼時候會到瓶頸?」(Capacity Planning)
三、五步驟結構化診斷框架
步驟 1:釐清症狀(Clarify Symptoms)|目標時間:2 分鐘
必問六個問題(把模糊描述轉化為可測量指標):
問題 目標 示例回答
──────────────────────────────────────────────────────────────
「多慢?」 P50/P95/P99 的具體數字 「P95 從 3s 升到 12s」
「多奇怪?」 品質問題的具體類型 「答非所問、沒有引用我們的資料」
「什麼時候開始?」 精確時間點,對應部署記錄 「09:00,昨晚 20:00 有部署」
「影響範圍?」 全部用戶 or 特定場景 「所有查詢都有問題」
「頻率?」 100% or 間歇性 「每次都這樣」
「最近有變化?」 部署、資料更新、流量異常 「昨晚更新了 RAG 索引」
──────────────────────────────────────────────────────────────
目標:把「系統很慢,答案很奇怪」轉化為:
「從 09:00 開始,P95 延遲從 3s 升到 12s,
所有用戶都有,答案品質差(答非所問),
昨晚 20:00 更新了 RAG 索引。」
步驟 2:確認可觀測性資料(Check Observability Data)|目標時間:3 分鐘
按順序看(不要跳步):
① Metrics Dashboard(1 分鐘)
確認問題確實存在(不只是用戶主觀感受)
找到問題開始的精確時間點
看哪個 Metrics 異常:P95 Latency?Error Rate?Throughput?
② Trace 瀑布圖(2 分鐘,看 3-5 條問題請求)
找哪個 Span 佔了最多時間
看 vector_search 的 result_count(返回幾個結果?)
看 LLM Span 的 input_tokens 和 finish_reason
③ Logs(有針對性,不是 grep 全部)
在問題開始的時間點,有沒有新的 Error Type?
有沒有 Warning 訊息(如 vector_search result_count=0)?
步驟 3:建立假說(Form Hypotheses)|目標時間:1 分鐘
基於步驟 2 的發現,提出 2-3 個最可能的假說
優先選能快速驗證的假說(不是最可能的,而是最容易驗證的)
步驟 4:測試假說(Test Hypotheses)|目標時間:5-15 分鐘
快速測試(< 1 分鐘):直接呼叫疑似問題的服務,測一個標準查詢
比較測試:今天的 Trace vs 昨天的 Trace,找差異
隔離測試:繞過疑似元件(用 Mock 替代),看症狀是否消失
步驟 5:根因確認與修復(Fix and Verify)
在 Staging 環境驗證修復方案(不要直接在 Production 試)
修復後,確認 Metrics 回到正常水位(數字說話,不是「感覺好了」)
寫 Post-Mortem:根因、時間線、影響範圍、預防措施
四、症狀分類矩陣
症狀 → 最可能根因 → 第一步看什麼:
┌──────────────┬─────────────────────────────┬────────────────────────┐
│ 症狀 │ 最可能根因(按概率排序) │ 第一步看的資料 │
├──────────────┼─────────────────────────────┼────────────────────────┤
│ P95 延遲 │ 1. Vector DB Cold Start │ Trace 瀑布圖 │
│ 突然升高 │ 2. 外部 API 變慢(特定時段) │ vector_search Span 時長│
│ │ 3. Context Window 膨脹 │ LLM input_tokens 趨勢 │
│ │ 4. Cold Start(Scale-Out) │ │
├──────────────┼─────────────────────────────┼────────────────────────┤
│ Error Rate │ 1. 外部 API 故障/Rate Limit │ Error Log error_type │
│ 升高 │ 2. LLM API 配額耗盡 │ HTTP Status 分佈圖 │
│ │ 3. Token 超限(輸入太長) │ LLM input_tokens 峰值 │
│ │ 4. DB 連接數耗盡 │ │
├──────────────┼─────────────────────────────┼────────────────────────┤
│ 品質退化 │ 1. Retrieval 失敗(result=0)│ Shadow Eval 分數趨勢 │
│ 答案奇怪 │ 2. Embedding Model 版本不一 │ vector_search │
│ │ 3. LLM 模型版本靜默更新 │ result_count 分佈 │
│ │ 4. Knowledge Base 資料過期 │ │
├──────────────┼─────────────────────────────┼────────────────────────┤
│ 間歇性錯誤 │ 1. 外部依賴特定時段不穩定 │ 錯誤的時間分佈 │
│ │ 2. Memory Leak → OOM 重啟 │ 是否有規律?(每小時?)│
│ │ 3. Race Condition │ 服務重啟記錄 │
├──────────────┼─────────────────────────────┼────────────────────────┤
│ 對話記憶 │ Session State 配置問題 │ Session 儲存 │
│ 消失 │ Scale-Down / Scale-Out │ 讀寫成功率 │
│ │ Redis 連接中斷 │ 服務重啟時間點 │
└──────────────┴─────────────────────────────┴────────────────────────┘
五、診斷決策樹
AI 系統故障的診斷決策樹:
收到故障報告
│
▼
【釐清:是延遲問題、品質問題、還是兩者?】
│
├──→ 只有延遲問題(答案正常,但很慢)
│ │
│ ▼
│ 【打開 Trace 瀑布圖,找最長 Span】
│ │
│ ├──→ vector_search 最長
│ │ │
│ │ ├──→ 持續高延遲 → Vector DB 效能問題(索引大小、配置)
│ │ └──→ 間歇性尖峰 → Cold Start → 設定 min-instances
│ │
│ ├──→ llm.generate 最長
│ │ │
│ │ ├──→ input_tokens 異常多 → Context 膨脹或對話 History 太長
│ │ └──→ input_tokens 正常 → LLM API 本身變慢(查 Status Page)
│ │
│ └──→ tool.call 最長
│ │
│ └──→ 外部 API 問題(查 API Status Page 或直接呼叫測試)
│
└──→ 品質問題(答案奇怪、答非所問)
│
▼
【看 Trace 的 vector_search result_count】
│
├──→ result_count = 0(搜尋無結果)
│ │
│ ├──→ 最近有部署 Embedding Model 更新?
│ │ └──→ 是 → Embedding Model 版本不一致 → 降回舊版
│ │
│ └──→ 沒有更新 → 索引損壞或資料不足 → 檢查 Vector DB 健康狀態
│
└──→ result_count > 0(有找到文件,但答案還是奇怪)
│
├──→ 找到的文件相關嗎?(抽樣幾條 Trace 看 retrieved_docs)
│ └──→ 不相關 → Retrieval 精確度問題 → 檢查 Embedding 品質
│
└──→ 文件相關,但 LLM 沒有正確使用
│
├──→ LLM 模型版本有沒有靜默更新?
└──→ Prompt 版本有沒有變動?
六、五種 AI 系統常見失效模式
失效模式 1:Vector DB Cold Start(冷啟動延遲)
┌──────────────────────────────────────────────────────────────┐
│ 症狀:每隔一段閒置後的第一個請求極慢(10-50x 正常延遲) │
│ 之後第二個、第三個請求恢復正常 │
└──────────────────────────────────────────────────────────────┘
特徵信號(Trace 中可見):
vector_search Span 有規律的尖峰(不是持續高延遲):
時間軸:
08:00 req_1: vector_search = 8,500ms ← 冷啟動後第一個請求
08:00 req_2: vector_search = 180ms ← 正常(已載入)
08:00 req_3: vector_search = 175ms ← 正常
...(閒置 30 分鐘)
08:30 req_4: vector_search = 9,200ms ← 再次冷啟動
08:30 req_5: vector_search = 182ms ← 正常
根因:Vector DB 實例閒置後進入低功耗狀態,第一個查詢觸發索引重新載入記憶體
修復策略:
├── 短期(30 秒):設定 min-instances = 1
└── 長期:Warmup 排程(每 10 分鐘一個空查詢保持活躍)
─────────────────────────────────────────────────────────────────
失效模式 2:Context Window 累積膨脹
┌──────────────────────────────────────────────────────────────┐
│ 症狀:新對話的請求正常,長對話的請求逐漸變慢 │
│ 重啟 Session 後問題消失 │
└──────────────────────────────────────────────────────────────┘
特徵信號(Trace + Metrics):
llm.generate Span 的 input_tokens 隨對話輪次增長:
第 1 輪:input_tokens = 1,200
第 5 輪:input_tokens = 4,800 (4 倍)
第 10 輪:input_tokens = 9,500 (8 倍)
第 15 輪:input_tokens = 14,300(12 倍)→ 接近模型上限
LLM 延遲 ∝ input_tokens → 第 15 輪比第 1 輪慢 5 倍
根因:Conversation History 沒有截斷策略,每輪都把所有歷史加入 Context
修復策略:
├── 設定 Token Budget(History 超過 30% Budget → 截斷最舊輪次)
└── 超過 10 輪的 History → 先壓縮成摘要,再繼續對話
─────────────────────────────────────────────────────────────────
失效模式 3:外部 API 間歇性超時(Circuit Breaker 缺席)
┌──────────────────────────────────────────────────────────────┐
│ 症狀:Error Rate 升高,但不是 100%;特定時段更嚴重 │
│ 某些查詢等很久才出錯(timeout 後才失敗) │
└──────────────────────────────────────────────────────────────┘
特徵信號:
tool.call Span:success=false,latency 集中在 timeout 附近(如 5,000ms)
錯誤有時間規律:09:00-10:00、月底最後一週更嚴重(月結日)
根因:外部 API(SAP、Oracle)在月結、備份等特定時段負載高,頻繁超時
完整修復策略:
層次 做法
──────────────────────────────────────────────────────────────
Timeout 每個 Tool 呼叫設定明確 timeout(不用系統預設)
SAP=5s, Oracle=3s, 外部API=8s
──────────────────────────────────────────────────────────────
Retry 指數退避重試:1s → 2s → 4s(最多 3 次)
不要立刻重試(可能讓 API 更過載)
──────────────────────────────────────────────────────────────
Circuit Breaker 連續失敗 5 次 → 斷路 30 秒
30 秒後:放行 10% 探測請求
探測成功 → 逐漸恢復;探測失敗 → 繼續斷路
──────────────────────────────────────────────────────────────
Fallback Circuit 開路時:返回快取的上次結果
或告知用戶「xxx 系統暫時不可用,請稍後再試」
──────────────────────────────────────────────────────────────
─────────────────────────────────────────────────────────────────
失效模式 4:Embedding Model 版本不一致
┌──────────────────────────────────────────────────────────────┐
│ 症狀:Retrieval 品質下降,但 Vector DB 查詢延遲正常 │
│ Shadow Eval 的 Context Recall 指標突然下降 │
│ 沒有任何 Error(最難發現的失效模式之一) │
└──────────────────────────────────────────────────────────────┘
根因示意圖:
建立索引時: 文件 → Embedding Model v1 → 向量 A
查詢時: Query → Embedding Model v2 → 向量 B
↑ 不同向量空間!
餘弦相似度計算(A ⋅ B)= 接近 0(沒有語義關係)
→ vector_search 找不到相似向量 → result_count = 0 或很少
→ LLM 沒有 Context → 靠自己猜
觸發場景:
└── 部署時更新了 Query 使用的 Embedding Model 版本,
但 Vector Index 是用舊版 Model 建立的,忘記同步更新
修復策略:
├── 短期(30 秒):把 Query Embedding 改回舊版(改環境變數)
└── 長期:建立版本綁定機制
EMBEDDING_MODEL_VERSION=v1
INDEX_BUILT_WITH=v1 // 兩個必須一致,CI 檢查
─────────────────────────────────────────────────────────────────
失效模式 5:LLM 模型版本靜默更新
┌──────────────────────────────────────────────────────────────┐
│ 症狀:品質緩慢退化,沒有明顯 Error,持續幾天才被注意到 │
│ Shadow Eval Faithfulness 7 日移動平均緩慢下降 │
└──────────────────────────────────────────────────────────────┘
特徵信號:
Faithfulness:0.87 → 0.85 → 0.82 → 0.79(2 週緩慢下滑)
用戶 Thumbs Down:3% → 4% → 5% → 7%(同步上升)
但 Error Rate = 0,P95 Latency 正常(沒有任何技術錯誤)
根因:使用了 model alias(如 gemini-pro)而非具體版本號
服務商靜默更新了模型行為,新版本對現有 Prompt 效果不同
預防策略:
├── 使用具體版本號(gemini-2.0-flash-001)而非 alias
├── Shadow Eval 7 日移動平均低於 0.83 → 自動告警
└── 新模型版本升級流程:Staging → Eval Pipeline → Canary 10% → 全量
七、SLO 與 Error Budget 設計
為什麼 SLO 比「我們要系統穩定」更有用:
「要系統穩定」:沒有量化 → 無法判斷是否可以部署新功能
SLO + Error Budget:量化 → 工程師和業務可以做出有依據的決策
SLO 定義(AI 系統示例):
維度 SLO 定義 測量方式
──────────────────────────────────────────────────────────────
延遲 SLO P95 < 5s,99% of rolling 30-day Cloud Trace 分位數
──────────────────────────────────────────────────────────────
可用性 SLO Availability > 99.5% Error Rate < 0.5%
──────────────────────────────────────────────────────────────
品質 SLO Shadow Faithfulness > 0.85(7日MA) Eval Pipeline
──────────────────────────────────────────────────────────────
Error Budget 計算:
延遲 SLO(P95 < 5s,99% of 30 days)的 Error Budget:
= 30 天 × 24 小時 × 60 分鐘 × 1% 允許違規
= 432 分鐘/月
解讀:
├── 本月已用 200 分鐘 Error Budget(P95 > 5s 的時間累計)
└── 剩餘 232 分鐘
Error Budget 驅動的工程決策:
Error Budget 剩餘 決策
──────────────────────────────────────────────────────────────
> 50%(> 216 分鐘) 可以正常部署新功能(Risk OK)
25-50%(108-216 分鐘) 謹慎部署(做好 Rollback 準備)
< 25%(< 108 分鐘) 暫停非緊急部署,專注穩定性
耗盡(0 分鐘) 凍結所有非緊急部署,全力修復
──────────────────────────────────────────────────────────────
這讓「能不能部署」從爭論變成數據決定:
Error Budget 耗盡 → 不是 PM 的需求和工程的穩定性之間的爭論,
而是一個客觀的數字決定優先順序。
Alert 設計(避免 Alert Fatigue):
原則:不同嚴重度的 Alert 用不同的通知方式
嚴重度 觸發條件 通知方式 行動
──────────────────────────────────────────────────────────────
P1 Error Rate > 10% 持續 2 分鐘 PagerDuty 電話 立刻處理
P2 P95 > 8s 持續 5 分鐘 PagerDuty 訊息 30 分鐘內
P3 Shadow Faithfulness < 0.83 Slack Channel 工作時間處理
P4 Error Budget < 25% 週報 Sprint 計劃
──────────────────────────────────────────────────────────────
避免 Alert Fatigue 的設計:
├── 每個 Alert 必須有明確的 Runbook(收到告警知道第一步做什麼)
├── P3/P4 不在非工作時間通知(避免夜間驚擾)
└── 每季 Alert Review:找出從未觸發的 Alert(可能閾值設錯了)
八、為什麼選 X 不選 Y:可觀測性技術選型
決策 1:OpenTelemetry(OTel)vs 廠商專有 SDK
┌──────────────────┬──────────────────────┬──────────────────────┐
│ │ OTel(✅ 選擇) │ 廠商專有 SDK │
├──────────────────┼──────────────────────┼──────────────────────┤
│ 廠商鎖定 │ 低(標準協議) │ 高(換後端要改代碼) │
├──────────────────┼──────────────────────┼──────────────────────┤
│ 後端選擇 │ Cloud Trace、Jaeger、│ 只能用指定後端 │
│ │ Datadog 等任意選擇 │ │
├──────────────────┼──────────────────────┼──────────────────────┤
│ 社群生態 │ 豐富(自動 Instrument)│ 依廠商支援 │
├──────────────────┼──────────────────────┼──────────────────────┤
│ AI/ADK 整合 │ ✅(ADK 有 OTel 整合)│ 可能支援,看廠商 │
└──────────────────┴──────────────────────┴──────────────────────┘
結論:OTel 是業界標準,AI 系統應該優先採用,避免廠商鎖定。
決策 2:Distributed Tracing vs 純 Log 分析
純 Log 的問題(在 Multi-Agent 系統中):
Log 1: [09:00:00.001] Agent received query
Log 2: [09:00:00.050] LLM call started
Log 3: [09:00:00.002] Sub-Agent A started ← 時間序列混亂
Log 4: [09:00:12.300] LLM call completed
Log 5: [09:00:00.003] Sub-Agent B started
從 Log 重建「哪個 Sub-Agent 佔了多少時間」需要手動 JOIN → 很難
Trace 的優勢:
├── 瀑布圖直觀顯示每個 Span 的時間
├── 自動計算每個 Span 佔總延遲的比例
└── 支援跨服務的請求追蹤(Multi-Agent 必要)
結論:有 Multi-Agent 的系統必須有 Distributed Tracing;Log 作為補充。
決策 3:Shadow Eval(線上品質評估)vs 純用戶信號
純用戶信號的問題:
├── 用戶可能不按 Thumbs Down(即使對結果不滿意)
├── 用戶回饋有延遲(不是即時品質指標)
└── 法律場景:「AI 給了錯誤的法律建議」用戶可能不知道是錯的
Shadow Eval 的優勢:
├── 主動評估(不依賴用戶行為)
├── 即時(每個請求可選擇性評估)
└── 可以偵測「看起來合理但實際上錯的」答案(用戶信號偵測不到)
最佳組合:Shadow Eval(客觀、即時)+ 用戶信號(真實感受、補充)
決策 4:P95 vs P50 vs P99 作為主要延遲 SLO 指標
P50(中位數):50% 的請求這麼快
└── 問題:如果 50% 請求 < 2s,50% 請求 > 20s,P50=2s 但體驗很差
P99(99th 百分位):99% 的請求這麼快
└── 問題:受極端異常值影響大,可能被 1% 的特殊請求拉高,
讓日常優化難以看出效果
P95(95th 百分位):最佳平衡點
└── 代表 95% 用戶的體驗,排除了最極端的 5% 異常請求
足夠代表大多數用戶,又不被少數異常值主導
→ AI 系統 SLO 推薦 P95 作為主要指標
九、實際診斷流程示例
症狀:「今天早上 9 點開始,系統變慢了,有時候給出奇怪的答案」
步驟 1:釐清症狀(2 分鐘)
「多慢?」→ P95 從 3s 升到 12s,有時 30s timeout
「奇怪答案是哪種?」→ 答非所問,好像沒有查到資料就在猜
「什麼時候開始?」→ 09:00,昨晚 20:00 有更新 RAG 索引
「影響全部用戶?」→ 是的,所有查詢都有
步驟 2:查可觀測性資料(3 分鐘)
Metrics:P95 延遲確實從 09:00 開始升高 ✓
Trace(打開一條慢請求的瀑布圖):
├── vector_search Span:9,800ms(正常:200ms)✗
├── vector_search result_count:0(!)
└── llm.generate Span:280ms(正常)✓
關鍵發現:Vector DB 搜尋返回 0 結果 → LLM 在沒有 Context 下猜測
步驟 3:建立假說(1 分鐘)
假說 A:昨晚索引重建失敗,索引損壞
假說 B:Embedding Model 版本不一致(假說 B 更可能,因為有部署)
步驟 4:測試假說(5 分鐘)
測試:查昨晚 20:00 的部署記錄
發現:同時更新了 Embedding Model v1 → v2 和 Vector Index 重建
但 Agent Query Embedding 也被更新到 v2,
而 Index 是用 v2 重建的... 等等
進一步確認:Vector Index 的重建失敗了(磁碟空間不足),
Index 還是舊的(v1),但 Query 已經在用 v2
→ Embedding Model 版本不一致 ✓
步驟 5:修復(立即 + 長期)
立刻(30 秒):把 Query Embedding 改回 v1(改環境變數,重啟 Agent)
確認:P95 延遲在 5 分鐘內回到 3s;品質指標恢復
長期:
├── 擴大 Vector DB 磁碟空間(根本原因)
├── 建立 Embedding Model 版本和 Index 版本綁定檢查
└── 部署 Vector Index 時,先驗證 result_count > 0 才切換流量
十、系統效應
維度 有結構化診斷 + Phase 3 可觀測性 基礎可觀測性(Phase 1)
──────────────────────────────────────────────────────────────────
找到根因時間 3-15 分鐘(Trace 直接指向問題) 1-4 小時(Log 慢慢找)
──────────────────────────────────────────────────────────────────
品質問題發現 主動(Shadow Eval 發現) 被動(用戶抱怨後才知道)
──────────────────────────────────────────────────────────────────
修復有效性 根因確認後修復,不再復發 猜測修復,可能再發
──────────────────────────────────────────────────────────────────
Error Budget 量化決策(Budget 剩餘指導部署) 主觀決策(「我感覺可以上」)
管理
──────────────────────────────────────────────────────────────────
Embed. Model 版本綁定機制,CI 檢查 靠人記得
版本問題 → 不會再發 → 月月都在犯同樣的錯
──────────────────────────────────────────────────────────────────
可觀測性建設成本 Phase 2:1-2 週工程工時 Phase 1:~3 天
Phase 3:3-4 週工程工時 每次 Debug 節省 2-4 小時
──────────────────────────────────────────────────────────────────
十一、面試答題要點
「聽到『慢了』和『奇怪的答案』,我的第一反應是:這是兩個獨立問題,還是同一個根因?我不會同時追兩個方向。AI 系統有一個特殊的診斷模式:品質問題的根因往往是 Retrieval 失敗(vector_search result_count=0),而不是 LLM 本身的問題——LLM 在沒有 Context 的情況下靠自己猜,症狀是「答非所問」,但 Error Log 完全沒有錯誤,只有 Trace 才能發現。
診斷流程:五步驟——釐清症狀(2 分鐘,把模糊描述轉化為具體數字)→ 查可觀測性資料(3 分鐘,先 Metrics 確認問題存在,再 Trace 瀑布圖定位到哪個 Span)→ 建立假說 → 測試假說 → 確認根因後修復並用指標驗證。
可觀測性設計:我會按三個階段推進。Phase 1(上線前必備):結構化日誌 + 基本告警。Phase 2(正式上線後):OTel Distributed Tracing,每個 LLM 呼叫、Tool 呼叫、Vector Search 都有獨立 Span,帶 result_count、input_tokens、finish_reason 等 Attribute。Phase 3(企業級):SLO + Error Budget,讓部署決策量化,Shadow Eval 主動監控品質退化。
為什麼選 OTel 不選廠商專有 SDK:OTel 是業界標準,換 Trace 後端不需要改代碼。為什麼選 P95 不選 P50 或 P99:P95 在代表大多數用戶和排除極端異常值之間最平衡,是 AI 系統 SLO 的最佳指標。」
系列導覽:
← (四十)AI 系統的 PII 保護:資料脫敏與合規稽核
→ (四十二)顧問技能:從客戶對話挖掘真實需求到 POC 範圍定義
