AI 工程從零開始|Phase 17 Part 2:AI 系統可觀測性 — 當模型行為成為監控對象

大多數工程師把 LLM 呼叫當成黑箱:記錄 HTTP 狀態碼、回應時間,然後就沒了。 正確的做法是:追蹤每一個 Prompt 版本、每一次工具呼叫、每一個 Token 成本,並量化模型行為漂移。 傳統 APM 只告訴你系統「掛了沒」;AI 可觀測性要告訴你模型「答得好不好」。 沒有這層監控,你永遠不知道提示更新讓答案品質下降了 12%,還是模型供應商悄悄換了版本。


這篇給已經把 LLM 應用上線、監控卻只有 HTTP 狀態碼與回應時間的工程師看。全文用一個貫穿的例子:RAG 問答系統上線後,客服主管反應「最近答案怪怪的」,但 p99 延遲和錯誤率都正常。讀完你會能設計出帶 prompt 版本與 token 成本的 LLM Trace、用 Prompt Registry 做可比較的 A/B、分開偵測輸入分佈偏移與模型行為漂移、把成本歸因到功能與用戶,並且在採樣成本與覆蓋率之間取得平衡。


一、核心問題:AI 系統的可觀測性為什麼與傳統系統不同

傳統服務的可觀測性三支柱——Metrics、Logs、Traces——在 AI 系統上全都「不夠用」,但原因各不相同。

傳統系統的失敗模式是二元的:請求成功或失敗,HTTP 200 或 500,延遲高或低。失敗有明確的邊界。當資料庫 query 耗時 800ms,你知道哪裡壞了。

AI 系統的失敗模式是漸進的、語意的:

  • 模型回傳 HTTP 200,但答案從準確滑向「有點對但不夠精確」
  • Prompt 被改了一個詞,召回率悄悄下降 8%
  • 供應商在 2AM 更新基礎模型,語氣風格改變,用戶滿意度在 48 小時後才反映在 CSAT
  • Token 用量因為對話上下文累積,每週成本靜靜地增長 15%

這就是為什麼 AI 可觀測性需要新的維度:

維度傳統系統AI 系統
品質訊號Error rate, p99 latency語意相似度、答案忠實度、幻覺率
版本追蹤Code git SHAPrompt version + Model version + RAG index version
成本單元CPU/Memory/NetworkInput tokens + Output tokens + Embedding calls
漂移型態無(確定性系統)概念漂移、分佈漂移、模型版本漂移
告警閾值靜態(> 500ms alert)動態(品質分數 7 日移動平均下降 > 5%)

開頭提到的「答案怪怪的」就是典型的語意品質退化。系統層面一切正常,但輸出品質已悄悄崩潰。沒有 AI-native 可觀測性,這種問題的 MTTR 往往超過 3 天。


二、何時該升級:從結構化日誌到 Trace 與版本註冊、再到品質評估與漂移偵測的觸發條件

最省事的起點是結構化 JSON 日誌:每次呼叫記下 prompt、model、latency_ms 與 token 數,寫到 stdout 或檔案,零額外基礎設施、半天就能設好。只要系統還是單一服務、prompt 很少改、問題靠手動翻 log 就能定位,這就夠了。該升級的訊號是:第一次在生產環境改 prompt 而說不出「改了之後變好還是變差」;請求鏈跨越 RAG 檢索與 LLM 呼叫兩個以上的服務,log 無法串起來;或是 token 成本開始每週上漲卻說不出是哪個功能貢獻的。這時引入 OpenTelemetry 的 Trace(§三,prompt 版本 ID 注入 Trace Context)、Prompt Registry(§四,版本 hash 與部署時間戳)以及按功能分組的 token 指標;基礎設施大約 $200–500/月。

第二道門檻是系統指標全部正常、但品質在退化——也就是開頭「答案怪怪的」那種問題。當這類事件的 MTTR 以天計、而每個百分點的品質退化都對應數千用戶時,規則式檢查已經不夠:需要非同步的 LLM Quality Evaluator 給出語意品質分數(§八 決策 2)、PSI/KS test 分開偵測輸入分佈偏移與模型行為漂移(§五)、把成本歸因細到 user × feature × model(§六),以及有統計顯著性判斷的 Prompt A/B。這一層的成本是 $2,000–8,000/月的基礎設施加上 0.5 FTE 維護,§九 會用一個 100K MAU 的例子算它什麼時候回本。

從到觸發訊號
結構化 JSON 日誌OTel Traces + Prompt Registry + 按功能的 token 指標第一次在生產改 prompt 卻無法比較前後;請求鏈跨服務;成本每週上漲但無法歸因
規則式品質檢查非同步 LLM-as-Judge 品質分數 + 漂移偵測(PSI / 移動平均)p99 與錯誤率正常但 CSAT 下降;供應商靜默更新模型;品質退化 MTTR 以天計
系統層成本統計user × feature × model 的成本歸因 + 3σ 異常偵測同一功能不同用戶成本相差 10 倍;月成本環比增長超過預期卻找不到來源

三、LLM 追蹤:Prompt / Completion / Tool Call 的 Span 設計

傳統 Trace 只有「服務呼叫」這個維度。LLM 系統需要更細的 Span 層級,對應 AI 特有的執行單元。

Trace: user_request_abc123
│
├── Span: api_handler [5ms]
│   ├── attr: user_id=u_456, feature=qa_search
│   │
│   ├── Span: rag_retrieval [120ms]
│   │   ├── attr: query_embedding_model=text-embed-v3
│   │   ├── attr: top_k=5, similarity_threshold=0.75
│   │   ├── attr: docs_retrieved=5, docs_filtered=3
│   │   └── attr: retrieval_latency_ms=118
│   │
│   ├── Span: prompt_construction [3ms]
│   │   ├── attr: prompt_version=v2.3.1
│   │   ├── attr: prompt_hash=sha256:4a7f...
│   │   ├── attr: context_tokens=1840
│   │   └── attr: system_tokens=256
│   │
│   ├── Span: chat claude-sonnet-4-5 [890ms]   ← LLM 呼叫
│   │   ├── attr: gen_ai.system=anthropic
│   │   ├── attr: gen_ai.request.model=claude-sonnet-4-5
│   │   ├── attr: gen_ai.usage.input_tokens=2096
│   │   ├── attr: gen_ai.usage.output_tokens=312
│   │   ├── attr: gen_ai.request.temperature=0.3
│   │   ├── attr: gen_ai.response.finish_reasons=["tool_calls"]
│   │   └── attr: cost_usd=0.00847(自訂屬性)
│   │
│   └── Span: execute_tool search_web [340ms]  ← 模型回傳後才執行,
│       ├── attr: gen_ai.tool.name=search_web       是 LLM Span 的兄弟節點
│       ├── attr: tool_input={"query": "..."}
│       └── attr: tool_output_tokens=580

關鍵設計決策:Span 屬性的標準化

每個 LLM Span 必須攜帶:

 1# 非明顯實作:用 context manager 確保屬性一致性
 2from contextlib import contextmanager
 3from opentelemetry import trace
 4
 5# 使用 OpenTelemetry 官方 GenAI 語意慣例(gen_ai.*)的屬性名稱;
 6# opentelemetry.semconv.ai 是第三方 OpenLLMetry 套件,不是官方規範。
 7@contextmanager
 8def llm_span(tracer, model: str, prompt_version: str):
 9    with tracer.start_as_current_span(f"chat {model}") as span:
10        span.set_attribute("gen_ai.operation.name", "chat")
11        span.set_attribute("gen_ai.system", "anthropic")
12        span.set_attribute("gen_ai.request.model", model)
13        span.set_attribute("ai.prompt.version", prompt_version)
14        span.set_attribute("ai.prompt.hash", compute_hash(prompt_version))
15        try:
16            yield span
17        except Exception as e:
18            span.record_exception(e)
19            span.set_status(trace.StatusCode.ERROR)
20            raise

Sampling 策略:不能 100% 採樣的原因

在 > 1M 請求/天的規模,如果每個 Span 都記錄完整 Prompt 和 Response 文字,儲存成本是每月 $15,000–30,000。需要分層採樣:

採樣層採樣率保留內容
系統指標 Span100%Tokens, latency, cost(無文字)
品質評估 Span5%完整 prompt + response(用於評估)
錯誤 Span100%完整內容(finish_reason ≠ stop)
用戶回饋 Span100%有明確正負回饋的請求

診斷鏈:當 p99 正常但品質差時

症狀:CSAT 下降,但 Traces 顯示 latency p99=920ms(正常)
↓
查 Spans:LLM Span 的 gen_ai.response.finish_reasons 分佈
→ 發現 finish_reason=length 佔比從 2% 升到 18%(截斷!)
↓
查 prompt_construction Span:context_tokens 從平均 1800 增到 2900
→ RAG 檢索策略改變(top_k 從 5 升到 8),注入過多 context
↓
根本原因:兩週前的 RAG 調優,沒人意識到會增加截斷率
修復:降回 top_k=5,或增加 max_output_tokens
MTTR:有 Traces = 2 小時;無 Traces = 預計 3 天

四、提示版本管理與 A/B 測試可觀測性

Prompt Engineering 是 AI 系統最頻繁的「部署」,但大多數團隊用 Git commit 管理 Prompt,根本無法做生產環境的 A/B 測試。

Prompt Registry 的最小可行設計:

Prompt Registry
┌─────────────────────────────────────────────────────┐
│  prompt_id: qa_system_prompt                        │
│  ┌─────────────────────────────────────────────┐   │
│  │ version: v2.3.1  (current, 60% traffic)     │   │
│  │ hash: sha256:4a7f...                        │   │
│  │ deployed_at: 2026-06-20T14:00:00Z           │   │
│  │ metrics_7d:                                  │   │
│  │   faithfulness_score: 0.87                  │   │
│  │   avg_output_tokens: 312                    │   │
│  │   cost_per_request: $0.0084                 │   │
│  └─────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────┐   │
│  │ version: v2.4.0-beta  (challenger, 40%)     │   │
│  │ hash: sha256:9c2e...                        │   │
│  │ deployed_at: 2026-06-21T09:00:00Z           │   │
│  │ metrics_7d:                                  │   │
│  │   faithfulness_score: 0.91 (+4.6%)          │   │
│  │   avg_output_tokens: 287 (-8.0%)            │   │
│  │   cost_per_request: $0.0077 (-8.3%)         │   │
│  └─────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────┘

A/B 測試觀測的統計陷阱:

品質指標(如 faithfulness score)往往方差很大(標準差 ±0.15),需要足夠樣本才能達到統計顯著性。

經驗法則:要偵測 5% 的品質差異,在 α=0.05, power=0.80 的條件下,需要約 3,200 個樣本/組。在 10K DAU 系統上,40% 流量的 challenger 每天約收到 4,000 請求,大約需要 1 天才能下結論。

低於 1,000 QPS 的系統:不要急著做 A/B,至少跑 3 天收集足夠樣本。

Prompt 版本的四種變更類型(影響告警閾值不同):

變更類型範例監控重點回滾閾值
措辭微調換同義詞品質分數 ±3%品質下降 > 5%
結構重組重排 sections品質分數 ±8%品質下降 > 8%
指令新增加 “always cite sources”輸出長度、Token 成本成本增加 > 20%
系統角色改變換 persona所有指標品質下降 > 10%

五、模型效能漂移:語意偏移 vs 分佈偏移偵測

「漂移」在 AI 系統有兩種截然不同的根本原因,必須分開偵測。

漂移類型分類
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  輸入分佈偏移                   模型行為漂移             │
│  ┌──────────────────┐          ┌──────────────────────┐ │
│  │ 用戶問題類型改變  │          │ 供應商更新基礎模型    │ │
│  │ 新領域問題出現   │          │ Prompt 版本更新       │ │
│  │ 語言/語氣轉變    │          │ RAG index 更新        │ │
│  └────────┬─────────┘          └──────────┬───────────┘ │
│           │                               │              │
│           ▼                               ▼              │
│  偵測方法:PSI / KS test         偵測方法:品質分數趨勢  │
│  (輸入 embedding 分佈比較)        (移動平均 + 閾值告警)  │
│                                                         │
└─────────────────────────────────────────────────────────┘

輸入分佈偏移偵測(PSI - Population Stability Index):

PSI 是風控領域借來的工具,比較「基線期」和「當前期」的特徵分佈差異:

PSI = Σ (實際佔比 - 基線佔比) × ln(實際佔比 / 基線佔比)

PSI < 0.1:分佈穩定,無需處理
PSI 0.1–0.2:輕微偏移,需留意
PSI > 0.2:顯著偏移,需調查

對於 LLM 輸入,做法是:

  1. 將用戶 query 做 embedding(用輕量模型,如 text-embed-v3)
  2. 用 PCA 降到 20 維
  3. 每個維度計算 PSI,取最大值作為整體偏移分數

模型行為漂移偵測(語意品質分數時序分析):

不是用靜態閾值,而是用 7 日移動平均 + 標準差通道:

品質分數趨勢
0.90 ┤
     │    ╭──╮  ╭─────
0.87 ┤────╯  ╰──╯     ← 7日均線
     │  ╔═══════╗
0.84 ┤  ║ 正常帶║      ← ±1.5σ
     │  ╚═══════╝
0.81 ┤           ╲___  ← 漂移警告觸發點
     │
     └─────────────────────────────▶ 時間
     D-14      D-7      D-1  Today

診斷鏈:語意品質漂移的排查流程

症狀:faithfulness_score 7日均值從 0.87 降到 0.81(-6.9%)
↓
Step 1:查 Prompt 版本變更記錄
→ 5天前有 v2.3.0 → v2.3.1 的微調
→ 但下降從 3 天前開始(不匹配)
↓
Step 2:查供應商 changelog
→ 供應商在 4 天前推送了模型小版本更新(無公告)
↓
Step 3:隔離驗證
→ 用舊版 Trace 中儲存的 prompt + context,重放到新模型
→ 品質分數確認下降 7.2%
↓
根本原因:模型供應商靜默更新,新版本在特定領域問題上較為保守
修復:調整 temperature 0.3→0.5,品質分數回升到 0.85
MTTR:有漂移偵測 = 6 小時;無 = 預計 5 天

六、成本歸因:按功能 / 用戶 / 模型的細粒度成本分析

AI 系統的成本結構跟傳統服務完全不同——同一個功能,不同用戶的成本可以相差 10 倍,因為上下文長度差異。

三層成本歸因模型:

成本歸因層級
┌─────────────────────────────────────────────────┐
│  Level 3:用戶層(user_id)                      │
│  Top 1% 用戶產生 23% Token 成本                  │
│  可能是 API 濫用或 power user                    │
├─────────────────────────────────────────────────┤
│  Level 2:功能層(feature_id)                   │
│  qa_search: $0.0084/req × 50K req/day = $420/day│
│  doc_summary: $0.031/req × 8K req/day = $248/day│
│  chat_assistant: $0.0062/req × 80K = $496/day   │
├─────────────────────────────────────────────────┤
│  Level 1:模型層(model_id)                     │
│  claude-sonnet-4-5: 68% of total cost           │
│  claude-haiku-4-5: 28% of total cost            │
│  embedding model: 4% of total cost              │
└─────────────────────────────────────────────────┘

Token 成本的隱性爆炸點:

對話記憶(ConversationHistory)是最常見的成本炸彈。如果每輪對話都把完整歷史帶入 context:

輪次 1:system(256) + user(80) = 336 input tokens
輪次 2:system(256) + history(336) + user(90) = 682 input tokens
輪次 5:system(256) + history(2100) + user(70) = 2426 input tokens
輪次 10:system(256) + history(6800) + user(85) = 7141 input tokens

→ 第 10 輪的成本是第 1 輪的 21 倍

在 Metrics 中追蹤 context_token_ratio(context tokens / total tokens)。若此比值超過 0.7,代表對話窗口管理有問題。告警閾值:7 日滑動均值 > 0.65 時告警。

成本異常偵測(3σ 規則):

指標基線告警閾值典型原因
cost_per_request$0.0084> $0.025 (+3σ)Prompt 加了大量 context
output_tokens_p99420> 1,200模型開始囉嗦(溫度過高)
embedding_calls/request1.2> 5重複 embedding 無快取
月成本環比增長8%> 25%新功能未做成本評估

七、AI 告警策略:品質指標 vs 系統指標的告警設計

AI 系統的告警分兩個截然不同的維度,必須用不同的告警哲學處理。

AI 告警維度
┌──────────────────────────────────────────────────┐
│                                                  │
│  系統指標告警              品質指標告警           │
│  (傳統 SRE)              (AI-native)          │
│                                                  │
│  • 靜態閾值                • 動態基線             │
│  • 即時告警(< 5 分鐘)    • 趨勢告警(1–24 小時)│
│  • PagerDuty 半夜叫人      • 工作時間通知         │
│  • 二元(正常/異常)       • 漸進嚴重度           │
│                                                  │
└──────────────────────────────────────────────────┘

系統指標告警(立即處理):

告警條件嚴重度行動
LLM API 可用性success_rate < 99% for 5minP0自動切換備援模型
請求延遲p99 > 5,000ms for 10minP1擴容/告知用戶
Token 配額耗盡quota_remaining < 10%P1限流 + 告警
費用異常hourly_cost > 3× baselineP2通知 + 人工審查

品質指標告警(趨勢型):

告警條件嚴重度行動
品質分數漂移7日均值下降 > 5%P2工程師調查,工作時間
輸入分佈偏移PSI > 0.2 持續 2 天P3分析師審查,下個 Sprint
截斷率上升finish_reason=length > 10%P2調整 max_tokens
幻覺指標contradiction_score > 0.15P1即時告警,可能需要暫停功能

避免告警疲勞的關鍵設計:

品質告警不應半夜打電話。使用 「趨勢 + 確認期」機制:

品質告警觸發邏輯:
IF (current_7d_avg < baseline × 0.95)       ← 下降 5%
AND (trend_direction == "declining" for 2d) ← 持續下降 2 天
AND (sample_count > 500)                    ← 樣本足夠
THEN: send_slack_alert(severity="warning", on_call=False)

IF (current_7d_avg < baseline × 0.88)       ← 下降 12%
AND (sample_count > 200)
THEN: send_pagerduty_alert(severity="high")

八、為什麼選 X 不選 Y

兩個工具層的選擇用文字交代。Metrics/Dashboard 後端:Grafana Cloud 與 Prometheus 生態整合天然、開源技術棧可自建,同等指標量的成本比 Datadog 低一個數量級;但 Datadog 的 LLM Observability 是一體化方案,工程團隊 < 3 人且沒有 DevOps 能力時,它省下的工程師時間比帳單更值錢——只要記得它按 log ingestion 計費,AI 系統的 log 量很容易讓成本失控。Trace 後端:Grafana Tempo 用物件儲存當後端、成本低、有 TraceQL 查詢語言;只有團隊已深度投資 Zipkin + Elasticsearch 且 Trace 量 < 1GB/天時,遷移成本才高於收益。下面四個決策才真的需要權衡。

決策 1:OpenTelemetry vs 自建 SDK

選擇選 OTel 的理由不選自建的理由
OpenTelemetry業界標準,供應商中立;Jaeger/Tempo/Datadog 均可接收;GenAI semantic conventions 社群持續更新自建 SDK:維護成本高;換後端需重寫;無法吸收社群的 AI 語意慣例更新

Flip Condition:自建 SDK 合理的情況——你需要的 AI-specific Spans(如多模態 image tokens)在 OTel 規範中尚未標準化,且你有 > 1 FTE 維護能力。


決策 2:LLM-as-Judge vs Rule-based 品質評估

選擇選 LLM-as-Judge 的理由不選 Rule-based 的理由
LLM-as-Judge語意品質無法用規則量化;可評估忠實度、相關性、連貫性;用人工標注的樣本校準後,可當作品質趨勢的代理指標Rule-based:只能偵測格式問題(長度、關鍵詞);無法偵測語意退化;假陰性率高

Flip Condition:當 QPS > 5,000 且需要同步品質評分時,LLM-as-Judge 的延遲(300–800ms)不可接受,需要回歸規則式或使用快取評估結果。5% 採樣非同步評估是最佳折衷。


決策 3:PSI vs Wasserstein Distance 作為分佈偏移指標

選擇選 PSI 的理由不選 Wasserstein 的理由
PSI計算 O(n),極快;閾值有業界共識(0.1/0.2);易解釋給非技術利害關係人Wasserstein:計算 O(n²),在 10K+ 樣本時成本高;閾值無共識,需要領域專家設定

Flip Condition:當輸入分佈是多模態(如混合語言查詢)時,PSI 會低估偏移,Wasserstein Distance 或 Maximum Mean Discrepancy(MMD)更準確。


決策 4:按請求採樣 vs 按用戶採樣 Trace

選擇選按用戶採樣的理由不選按請求採樣的理由
按用戶採樣確保每個用戶至少有完整的 Trace 供調查;對 power user 可 100% 採樣;對正常用戶 1–5% 採樣;成本降低 80%按請求採樣:對高頻用戶的問題無法完整重現;調查特定用戶投訴時常常沒有 Trace 可查

Flip Condition:當系統是純 API 服務(無 user_id 概念),按請求採樣結合 Head-based + Tail-based(對慢請求 100% 保留)是標準做法。


九、系統效應:無可觀測性 vs 完整監控

以一個 100K MAU、日均 80K 請求的 AI 問答系統為基準:

指標無可觀測性基礎監控(Traces + Registry)完整監控(品質評估 + 漂移 + 歸因)
品質退化 MTTR3–5 天8–24 小時2–6 小時
成本異常偵測延遲1 個月(帳單到時)1–3 天< 2 小時
Prompt 更新失敗率30%(無資料盲改)15%(有 A/B 但慢)5%(快速統計驗證)
月 Token 成本浪費$1,200(無優化依據)$400(部分優化)$120(精準歸因優化)
供應商漂移偵測從不(靠用戶投訴)1–2 天4–8 小時
工程師除錯時間16 小時/事件6 小時/事件1.5 小時/事件

示意估算,非實測數據。

ROI 試算(完整監控的投資回報;把上表的示意數字代入):

  • 基礎設施成本:$5,000/月
  • 節省的 Token 浪費:$1,080/月
  • 節省工程師時間(假設每月 4 次事件):(16 - 1.5) × 4 × $150/hr = $8,700/月
  • 淨收益:$8,700 + $1,080 - $5,000 = $4,780/月正收益

在 100K MAU 規模,依這組示意數字,完整可觀測性平台的 ROI 轉正約在上線後第 2 個月。

相關文章與正典版本


十、系列導航

← 上一篇Phase 17 Part 1:AI 推論服務架構 — 從單機到全球部署
→ 下一篇Phase 17 Part 3:AI 成本優化與規模化 — 把每美元壓榨到極限

本文為「AI 工程從零開始」系列 Phase 17 Part 2。系列總覽:AI 工程從零開始 。

Yen

Yen

Yen