- AI 代理系統的除錯難度遠超傳統軟體——多步推理、工具呼叫與非確定性輸出構成「黑箱中的黑箱」,可觀測性(Observability)是唯一的系統性解法[3]
- LLM 可觀測性的三大支柱——Traces(追蹤)、Metrics(指標)、Logs(日誌)——需要從傳統 APM 框架延伸,新增 Token 用量、幻覺率、工具呼叫成功率等 AI 原生維度[2]
- OpenTelemetry 已發布 GenAI 語義約定(Semantic Conventions),為 LLM 呼叫追蹤提供廠商中立的標準化基礎,企業應優先採用以避免供應商鎖定[3]
- 工具選擇取決於組織規模與需求:LangSmith[1] 適合 LangChain 生態快速起步,Phoenix[2] 提供開源自建彈性,Helicone[6] 以代理層(Proxy)模式實現零程式碼整合
一、為什麼 AI 代理需要可觀測性
傳統軟體的除錯邏輯是線性的:輸入確定,輸出確定,錯誤可重現。當你的 REST API 回傳 500 錯誤,你可以打開日誌、找到 stack trace、定位到具體的程式碼行數。但 AI 代理系統徹底顛覆了這個假設。
一個典型的 AI 代理工作流可能包含以下步驟:接收使用者查詢、分析意圖、決定呼叫哪些工具、執行多輪 LLM 推理、彙整結果、生成最終回應。每一步都涉及非確定性的語言模型輸出,同樣的輸入可能產生不同的工具呼叫序列,甚至完全不同的推理路徑。當最終輸出出現問題——例如幻覺、不完整的回答、或意外的工具呼叫——你如何定位問題發生在哪一步?
這就是可觀測性(Observability)的核心價值所在。可觀測性不等於監控(Monitoring)——監控是「我預先知道什麼指標重要,然後追蹤它」;可觀測性是「系統內部狀態的任意問題,都能透過外部輸出推斷出來」。對 AI 代理而言,這意味著你需要能夠回答以下問題:
AI 代理可觀測性需要回答的核心問題:
1. 追蹤問題:
- 這個回答經過了幾次 LLM 呼叫?每次的 prompt 和 completion 是什麼?
- 代理為什麼選擇呼叫工具 A 而不是工具 B?
- 多代理協作時,訊息在代理之間如何傳遞?
2. 效能問題:
- 端到端延遲多少?瓶頸在哪個 LLM 呼叫或工具呼叫?
- Token 用量是否異常?是否有不必要的重複呼叫?
- 成本分布如何?哪些使用者或功能消耗最多資源?
3. 品質問題:
- 幻覺發生的頻率和模式是什麼?
- 工具呼叫的成功率如何?失敗時的回退策略是否生效?
- 使用者滿意度與哪些系統指標相關?
4. 營運問題:
- API 速率限制(Rate Limit)是否即將觸頂?
- 模型提供商的回應品質是否發生漂移(Drift)?
- 成本趨勢是否在可控範圍內?
根據我們在超智諮詢的實務經驗,缺乏可觀測性的 AI 代理專案,其問題定位時間平均是具備完整追蹤系統的 8 到 12 倍。更關鍵的是,許多品質問題——例如微妙的幻覺模式、特定 prompt 模式下的效能劣化——在沒有系統性追蹤的情況下根本不會被發現,直到它們在生產環境中造成實質損害。
Anthropic 在其官方文件中明確建議所有生產級 Claude 整合都應實作用量監控與追蹤[5],這不僅是為了成本控制,更是為了確保模型行為符合預期。OpenTelemetry 社群在 2025 年正式發布了 GenAI 語義約定[3],標誌著 LLM 可觀測性從「各家自建」走向「標準化」的轉折點。
二、AI 代理可觀測性的三大支柱
傳統的可觀測性建立在三大支柱之上:Traces(分散式追蹤)、Metrics(指標)、Logs(日誌)。AI 代理系統繼承了這個框架,但在每個支柱上都需要顯著的擴展,以適應 LLM 應用的獨特特性。
2.1 Traces(追蹤):重建 AI 代理的決策路徑
在微服務架構中,一個 Trace 代表一個請求從入口到出口的完整生命週期。在 AI 代理系統中,Trace 的概念需要擴展到涵蓋整個推理鏈路——從使用者輸入,經過多輪 LLM 呼叫、工具呼叫、記憶體檢索,到最終回應的完整路徑。
AI 代理的 Trace 具有以下獨特特徵:
AI Agent Trace 結構 (Span Hierarchy):
Trace: "使用者詢問台北天氣並要求穿搭建議"
│
├── Span: AgentExecutor (root span)
│ ├── Span: LLM Call #1 - 意圖分析
│ │ ├── attribute: gen_ai.system = "anthropic"
│ │ ├── attribute: gen_ai.request.model = "claude-sonnet-4-20250514"
│ │ ├── attribute: gen_ai.usage.input_tokens = 342
│ │ ├── attribute: gen_ai.usage.output_tokens = 89
│ │ └── attribute: gen_ai.request.temperature = 0.1
│ │
│ ├── Span: Tool Call - get_weather
│ │ ├── attribute: tool.name = "get_weather"
│ │ ├── attribute: tool.parameters = {"city": "taipei"}
│ │ ├── attribute: tool.status = "success"
│ │ └── attribute: tool.duration_ms = 230
│ │
│ ├── Span: Tool Call - get_fashion_advice
│ │ ├── attribute: tool.name = "get_fashion_advice"
│ │ ├── attribute: tool.parameters = {"temp": 28, "weather": "sunny"}
│ │ ├── attribute: tool.status = "success"
│ │ └── attribute: tool.duration_ms = 150
│ │
│ └── Span: LLM Call #2 - 綜合回應生成
│ ├── attribute: gen_ai.usage.input_tokens = 1024
│ ├── attribute: gen_ai.usage.output_tokens = 356
│ └── attribute: gen_ai.response.finish_reason = "stop"
│
├── total_duration_ms: 2340
├── total_tokens: 1811
└── total_cost_usd: 0.0127
每個 Span 代表一個獨立的操作單元,父子關係(Parent-Child)反映了呼叫層次。在多代理系統中(例如使用 LangGraph 或 CrewAI),Trace 會進一步擴展為跨代理的呼叫鏈,其中一個代理的 Span 可能成為另一個代理呼叫的觸發源。
2.2 Metrics(指標):量化 AI 代理的健康狀態
指標是對系統行為的數值化摘要,與 Trace 的「全量記錄」不同,Metrics 是聚合後的統計值,適合用於儀表板展示、告警觸發和趨勢分析。AI 代理系統需要追蹤的核心指標包括:
延遲指標(Latency):端到端回應時間(E2E Latency)、單次 LLM 呼叫延遲、工具呼叫延遲、首 Token 時間(Time to First Token, TTFT)。這些指標需要按百分位數(P50、P95、P99)追蹤,因為 LLM 回應時間的分布通常是長尾的。
Token 用量指標:每次請求的 input/output token 數量、每個使用者/功能的累計 Token 用量、Token 效率比(有效輸出 Token / 總消耗 Token)。這些直接關係到成本控制。
錯誤與品質指標:LLM API 錯誤率(4xx/5xx)、工具呼叫失敗率、速率限制命中率(Rate Limit Hit Rate)、幻覺偵測率、使用者回饋評分。
成本指標:每次請求的美元成本、每日/每月總成本、按模型/功能/使用者的成本分布。
2.3 Logs(日誌):AI 代理的完整記憶
日誌在 AI 代理系統中承擔著與傳統系統截然不同的角色。除了記錄系統事件(錯誤、警告)之外,AI 代理的日誌還需要記錄:完整的 prompt 和 completion 文字、工具呼叫的參數和返回值、代理的中間推理過程(Chain of Thought)、以及記憶體存取記錄。
這帶來了一個獨特的挑戰:日誌量的爆炸性增長。一個中等規模的 AI 代理應用(每日 10,000 次請求),如果記錄完整的 prompt/completion,每日可產生數 GB 的日誌數據。因此,企業需要制定明確的日誌策略:
AI 代理日誌分層策略:
Level 1: Always Log(必要記錄)
- Request ID, Trace ID, Timestamp
- Model name, Token counts, Latency
- Error messages, Status codes
- Cost per request
Level 2: Sample Log(取樣記錄,例如 10%)
- Full prompt / completion text
- Tool call parameters and responses
- Intermediate reasoning steps
Level 3: Debug Log(僅在除錯時啟用)
- Raw API request/response payloads
- Memory retrieval details
- Embedding vectors (if applicable)
儲存策略:
- Level 1: 保留 90 天(時序資料庫,如 ClickHouse)
- Level 2: 保留 30 天(物件儲存,如 S3)
- Level 3: 保留 7 天(本地磁碟或臨時儲存)
值得注意的是,日誌中的 prompt/completion 可能包含使用者的敏感資訊。企業在設計日誌系統時必須納入 PII(個人可識別資訊)脫敏機制,這在金融和醫療等受監管產業尤為關鍵。
三、LLM 呼叫追蹤(Tracing)深度解析
追蹤是 AI 代理可觀測性中最關鍵的支柱。它不僅幫助你理解「發生了什麼」,更幫助你理解「為什麼會發生」。本節深入探討 LLM 追蹤的技術實作細節。
3.1 Span 層次結構與語義
在 OpenTelemetry 的 GenAI 語義約定[3]中,LLM 相關的 Span 被歸類為 gen_ai 命名空間。每個 LLM 呼叫產生的 Span 包含以下標準屬性:
OpenTelemetry GenAI Semantic Conventions:
# 必要屬性 (Required)
gen_ai.system = "openai" | "anthropic" | "azure" | ...
gen_ai.request.model = "claude-sonnet-4-20250514"
gen_ai.operation.name = "chat" | "text_completion"
# 用量屬性 (Usage)
gen_ai.usage.input_tokens = 1024
gen_ai.usage.output_tokens = 356
gen_ai.usage.total_tokens = 1380
# 請求參數 (Request Parameters)
gen_ai.request.temperature = 0.7
gen_ai.request.max_tokens = 4096
gen_ai.request.top_p = 0.95
gen_ai.request.stop_sequences = ["\n\nHuman:"]
# 回應資訊 (Response)
gen_ai.response.id = "msg_01XFDUDYJgAACzvnptvVoYEL"
gen_ai.response.model = "claude-sonnet-4-20250514"
gen_ai.response.finish_reason = "stop" | "max_tokens" | "tool_use"
# 工具呼叫 (Tool Calls)
gen_ai.tool.name = "search_database"
gen_ai.tool.call.id = "call_abc123"
這些標準化的屬性名稱使得不同工具和平台之間的追蹤數據可以互通——你可以用 LangSmith 收集追蹤數據,用 Grafana 做視覺化,用自建的分析服務做異常偵測,而不需要每次都處理不同的數據格式。
3.2 多代理追蹤的挑戰
當系統涉及多個 AI 代理協作時,追蹤的複雜度顯著上升。考慮一個典型的多代理架構:一個「協調者」代理接收使用者請求,將子任務分派給「研究員」代理和「撰寫者」代理,最終由「審核者」代理檢查品質。每個代理都可能進行多次 LLM 呼叫和工具呼叫。
多代理追蹤的 Span 傳播:
Trace: multi-agent-report-generation
│
├── Span: Coordinator Agent
│ ├── LLM Call: 任務分解
│ ├── Dispatch to Research Agent ──────┐
│ └── Dispatch to Writer Agent ───────┐│
│ ││
├── Span: Research Agent ◄──────────────┘│
│ ├── LLM Call: 查詢策略規劃 │
│ ├── Tool: web_search (3 calls) │
│ ├── Tool: database_query │
│ └── LLM Call: 資料彙整 │
│ │
├── Span: Writer Agent ◄────────────────┘
│ ├── LLM Call: 大綱生成
│ ├── LLM Call: 段落撰寫 (5 calls)
│ └── LLM Call: 最終潤飾
│
└── Span: Reviewer Agent
├── LLM Call: 品質檢查
└── LLM Call: 修改建議
關鍵追蹤需求:
- Context Propagation: trace_id 必須在代理間正確傳遞
- Causality: 能重建代理之間的因果關係
- Timing: 識別平行執行 vs 序列等待
- Token Budget: 每個代理的 Token 用量獨立計算
實作多代理追蹤時,最常見的陷阱是 Context 丟失——當代理之間透過訊息佇列(如 Redis 或 Kafka)通信時,trace context 可能無法自動傳播。解決方案是在訊息的 metadata 中顯式攜帶 traceparent 和 tracestate header,這是 W3C Trace Context 標準的一部分。
3.3 Tool Call 追蹤的最佳實踐
工具呼叫(Tool Calls / Function Calling)是 AI 代理的核心能力之一——代理透過呼叫外部工具來取得資訊、執行動作。對工具呼叫的追蹤需要特別關注以下面向:
參數驗證:記錄代理傳給工具的參數,與工具實際接收的參數是否一致。LLM 有時會生成格式不完全正確的參數(例如日期格式錯誤),這些「軟錯誤」如果不追蹤就很難發現。
重試與回退:當工具呼叫失敗時,代理可能自動重試或切換到備選工具。追蹤系統需要記錄每次重試的原因和結果,以便事後分析重試策略是否合理。
安全邊界:某些工具呼叫(如資料庫寫入、外部 API 呼叫)具有副作用,追蹤記錄可作為審計日誌(Audit Log),記錄「誰、在什麼時候、透過什麼代理、對什麼資源、執行了什麼操作」。
四、核心監控指標
建立 AI 代理的可觀測性系統,首先需要定義「什麼值得測量」。以下是我們在企業專案中驗證過的核心指標體系。
4.1 延遲指標(Latency Metrics)
延遲是 AI 代理使用者體驗的第一道防線。與傳統 API 不同,AI 代理的延遲來源多元且難以預測。
延遲分解 (Latency Breakdown):
E2E Latency = LLM Latency + Tool Latency + Orchestration Overhead
各環節典型數值 (2026 Q1 實測):
┌─────────────────────────────┬──────────┬──────────┬──────────┐
│ 環節 │ P50 │ P95 │ P99 │
├─────────────────────────────┼──────────┼──────────┼──────────┤
│ Claude Sonnet 4 (單次呼叫) │ 1.2s │ 3.8s │ 8.2s │
│ GPT-4o (單次呼叫) │ 0.9s │ 2.5s │ 6.1s │
│ Tool Call (HTTP API) │ 0.1s │ 0.5s │ 1.2s │
│ Tool Call (DB Query) │ 0.05s │ 0.2s │ 0.8s │
│ Vector Search (RAG) │ 0.08s │ 0.3s │ 0.9s │
│ Agent Orchestration │ 0.02s │ 0.05s │ 0.1s │
├─────────────────────────────┼──────────┼──────────┼──────────┤
│ 典型代理任務 (3 LLM + 2 Tool)│ 4.5s │ 12.0s │ 25.0s │
└─────────────────────────────┴──────────┴──────────┴──────────┘
告警閾值建議:
- P95 > 15s → Warning
- P99 > 30s → Critical
- TTFT > 5s → Warning (使用者感知閾值)
特別值得關注的是 Time to First Token(TTFT)——使用者在提交請求後等待看到第一個回應字元的時間。在串流模式下,TTFT 直接影響使用者對「系統是否當機」的判斷。我們建議將 TTFT 控制在 3 秒以內,超過 5 秒就應顯示明確的「思考中」提示。
4.2 Token 用量與成本監控
Token 是 LLM 的「燃料」,也是成本的直接驅動因素。有效的 Token 監控需要多維度的追蹤:
Token 監控維度:
1. 請求級別 (Per Request):
input_tokens, output_tokens, total_tokens
cache_read_tokens (Anthropic prompt caching)
cost_usd = f(model, input_tokens, output_tokens)
2. 使用者級別 (Per User):
daily_token_usage, monthly_token_budget
token_efficiency = useful_output / total_consumed
3. 功能級別 (Per Feature):
feature_a_avg_tokens = 2,500
feature_b_avg_tokens = 8,700
→ 識別 Token 消耗最高的功能,優先優化
4. 模型級別 (Per Model):
model_a_cost_per_1k_tokens = $0.003
model_b_cost_per_1k_tokens = $0.015
→ 評估是否可用較便宜的模型替代
成本計算公式 (以 Claude Sonnet 4 為例):
cost = (input_tokens × $3.00 / 1M)
+ (output_tokens × $15.00 / 1M)
- (cache_read_tokens × $2.70 / 1M) # 快取折扣
一個常見的成本異常模式是「Token 迴圈」——代理因推理錯誤而反覆呼叫相同的工具或重複生成類似的回答,導致 Token 用量異常飆升。我們曾在一個客戶專案中發現,某個代理在處理特定類型的查詢時會進入「反思迴圈」(reflection loop),單次請求消耗超過 50,000 個 Token(正常應為 3,000),而這個問題在沒有 Token 監控的情況下持續了兩週才被發現。
4.3 錯誤率與品質指標
錯誤率需要區分「硬錯誤」和「軟錯誤」。硬錯誤是 API 回傳的 HTTP 錯誤碼(429 Rate Limit、500 Server Error);軟錯誤是模型回應在語義層面的問題(幻覺、格式錯誤、不完整回答)。
硬錯誤追蹤:按錯誤類型分類統計(429、500、503 等),追蹤速率限制的剩餘配額(x-ratelimit-remaining header),記錄錯誤發生的時間分布以識別模式。
軟錯誤追蹤:這更具挑戰性,需要自動化的品質評估機制。可行的方法包括:使用另一個 LLM 作為 Judge 評估回應品質、比對 RAG 系統中的引用來源與回答是否一致、追蹤使用者的顯式回饋(拇指向上/向下)和隱式回饋(是否重新提問、是否放棄對話)。
五、工具比較:LangSmith vs Phoenix vs Helicone vs W&B Weave
市場上已有多個成熟的 LLM 可觀測性平台,各有定位和優劣。以下是基於我們實際測試的全面比較。
| 特性 | LangSmith[1] | Phoenix[2] | Helicone[6] | W&B Weave[4] |
|---|---|---|---|---|
| 部署模式 | SaaS / 企業自建 | 開源自建 / SaaS | SaaS / 開源代理 | SaaS |
| 整合方式 | SDK(LangChain 原生) | SDK + OpenTelemetry | Proxy Layer(零程式碼) | SDK(Python 裝飾器) |
| LangChain 整合 | 原生深度整合 | 透過 Instrumentor | 無直接整合 | 透過 Instrumentor |
| OpenTelemetry 支援 | 有限 | 原生支援 | 不支援 | 有限 |
| 追蹤可視化 | 優秀(樹狀圖) | 優秀(瀑布圖) | 良好(列表式) | 優秀(DAG 圖) |
| 評估(Eval)框架 | 內建完整 | 內建(LLM-as-Judge) | 基礎 | 內建完整 |
| Prompt 管理 | 內建(Hub) | 不支援 | 不支援 | 不支援 |
| 數據匯出 | API / CSV | OpenTelemetry / Parquet | API / CSV | API |
| 成本追蹤 | 基礎 | 基礎 | 優秀(核心功能) | 基礎 |
| 自建可行性 | 企業版(付費) | 完全開源(Apache 2.0) | 代理層開源 | 不支援 |
| 免費額度 | 5,000 traces/月 | 無限(自建) | 10,000 requests/月 | 有限免費層 |
| 適合場景 | LangChain 生態團隊 | 數據主權要求高的企業 | 快速整合、成本優先 | 已用 W&B 的 ML 團隊 |
5.1 LangSmith:LangChain 生態的首選
LangSmith[1] 是 LangChain 團隊打造的端到端 LLM 開發平台,涵蓋追蹤、評估、Prompt 管理和數據集管理。如果你的技術棧已經以 LangChain 或 LangGraph 為核心,LangSmith 提供了最低摩擦力的整合路徑——只需設定兩個環境變數即可啟用完整追蹤:
# LangSmith 啟用(LangChain/LangGraph 專案)
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=ls-your-api-key
# 追蹤自動捕獲所有 LLM 呼叫、工具呼叫、Chain 執行
# 無需修改任何程式碼
LangSmith 的強項在於其追蹤可視化——它能以樹狀結構完整呈現 LangGraph 中每個節點的執行過程,包括條件分支、迴圈和人工介入點。內建的評估框架支持自定義評估函數、LLM-as-Judge 和參考答案比對,可直接從追蹤記錄建立回歸測試數據集。
局限性在於:LangSmith 與 LangChain 生態的耦合較深,如果你使用的是自建的代理框架或其他框架(如 Semantic Kernel、AutoGen),整合成本會顯著上升。此外,SaaS 版本的數據存儲在美國,這對某些地區的企業可能是合規障礙。
5.2 Phoenix:開源與標準化的先鋒
Arize AI 的 Phoenix[2] 是目前最成熟的開源 LLM 可觀測性平台。它的核心設計理念是「OpenTelemetry-native」——所有追蹤數據以 OpenTelemetry 格式收集和存儲,這意味著你可以將 Phoenix 作為 OTLP(OpenTelemetry Protocol)的接收端,同時將數據轉發給任何支持 OTLP 的後端(如 Jaeger、Grafana Tempo)。
# Phoenix 本地部署(Docker)
docker run -p 6006:6006 -p 4317:4317 arizephoenix/phoenix:latest
# Python 整合(框架無關)
from openinference.instrumentation.openai import OpenAIInstrumentor
from phoenix.otel import register
tracer_provider = register(endpoint="http://localhost:4317")
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)
# 現在所有 OpenAI 呼叫都會被自動追蹤
# 也支援 Anthropic、Mistral、LangChain、LlamaIndex 等
Phoenix 的優勢在於:完全開源(Apache 2.0 授權)、可自建部署、支援 OpenTelemetry 標準、與框架解耦。對於有數據主權需求(例如金融業、政府單位)或需要將 LLM 追蹤整合進現有可觀測性堆疊的企業,Phoenix 是最理想的選擇。
5.3 Helicone:零程式碼的代理層方案
Helicone[6] 的差異化在於其「代理層」(Proxy Layer)架構——你只需要將 LLM API 的 base URL 改為 Helicone 的端點,所有請求會被透明地攔截、記錄和轉發,完全不需要修改應用程式碼。
# Helicone 整合:僅需修改 base_url
import openai
client = openai.OpenAI(
api_key="sk-your-key",
base_url="https://oai.helicone.ai/v1", # 原本是 https://api.openai.com/v1
default_headers={
"Helicone-Auth": "Bearer hlc-your-key",
}
)
# 所有請求自動被追蹤,包括延遲、Token、成本
# 支援 OpenAI、Anthropic、Azure OpenAI、Gemini
Helicone 特別擅長成本追蹤和分析——它能自動計算每個請求的美元成本,提供按使用者、功能、模型的成本分布報表,並支持成本告警(例如「當日成本超過 $100 時通知」)。這使得 Helicone 特別適合作為「成本管控層」嵌入現有系統。
5.4 W&B Weave:ML 團隊的延伸
Weights & Biases 的 Weave[4] 是從傳統 ML 實驗追蹤(Experiments Tracking)自然延伸到 LLM 應用監控的產品。如果你的團隊已經在使用 W&B 進行模型訓練追蹤,Weave 提供了無縫的體驗——追蹤數據、評估結果和模型版本管理在同一個平台上統一管理。
Weave 使用 Python 裝飾器的方式追蹤函數呼叫,這讓它可以追蹤任何 Python 函數,而不限於 LLM 呼叫。但相對地,它缺乏 Proxy 模式的零程式碼整合能力,且不支援自建部署。
5.5 選擇建議
基於我們的實際部署經驗,我們建議以下選擇路徑:
快速啟動(1-2 天):如果你使用 LangChain,選 LangSmith;如果不是,選 Helicone(零程式碼整合)。
標準化部署(1-2 週):選擇 Phoenix + OpenTelemetry,確保未來可以切換任何後端。
企業級完整方案(1-2 月):Phoenix 自建 + OpenTelemetry Collector + ClickHouse + Grafana,完整掌控數據流。
六、企業級部署架構
對於認真對待 AI 代理可觀測性的企業,單一工具往往不足以覆蓋所有需求。本節描述一個經過驗證的企業級部署架構。
6.1 OpenTelemetry 集成架構
OpenTelemetry[3] 是 CNCF(Cloud Native Computing Foundation)孵化的可觀測性標準,已成為業界事實標準。在 AI 代理系統中,OpenTelemetry 扮演著「統一數據收集層」的角色。
企業級 AI 代理可觀測性架構:
┌──────────────────────────────────────────────────────┐
│ AI Agent Application │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │LangGraph│ │ Custom │ │ OpenClaw│ │
│ │ Agent │ │ Agent │ │ Agent │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ ┌────┴────────────┴────────────┴────┐ │
│ │ OpenTelemetry SDK + GenAI │ │
│ │ Instrumentation Libraries │ │
│ └────────────────┬──────────────────┘ │
└───────────────────┼──────────────────────────────────┘
│ OTLP (gRPC/HTTP)
▼
┌───────────────────────┐
│ OpenTelemetry │
│ Collector │
│ ┌─────────────────┐ │
│ │ Receivers: │ │
│ │ - OTLP │ │
│ │ - Prometheus │ │
│ │ │ │
│ │ Processors: │ │
│ │ - Batch │ │
│ │ - PII Redact │ │
│ │ - Sampling │ │
│ │ │ │
│ │ Exporters: │ │
│ │ - ClickHouse │ │
│ │ - Phoenix │ │
│ │ - Grafana Tempo│ │
│ └─────────────────┘ │
└───────────┬───────────┘
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ClickHouse│ │ Phoenix │ │ Grafana │
│(長期儲存) │ │(追蹤 UI) │ │(儀表板) │
└──────────┘ └──────────┘ └──────────┘
這個架構的核心設計原則是「收集一次,分發多處」(Collect Once, Export Everywhere)。應用層只需要整合 OpenTelemetry SDK,所有追蹤數據透過 OTLP 協議發送到 OpenTelemetry Collector。Collector 負責數據的批次處理(Batching)、敏感資訊脫敏(PII Redaction)和取樣(Sampling),然後分發到不同的後端系統。
6.2 數據管線設計
AI 代理可觀測性數據的管線設計需要考慮幾個關鍵因素:
高基數問題(High Cardinality):AI 代理的每個請求都可能有獨特的 prompt 和 completion 文字,這導致數據的基數(Cardinality)極高。傳統時序資料庫(如 Prometheus)不適合存儲這類數據,建議使用列式儲存(如 ClickHouse)或物件儲存(如 S3 + Parquet)。
寫入吞吐量:一個處理 1,000 QPS 的 AI 代理系統,如果每個請求平均涉及 5 個 Span,每秒就有 5,000 個 Span 需要寫入。ClickHouse 在這個量級上游刃有餘,但需要合理設計表結構和分區策略。
# ClickHouse 表結構示例:AI Agent Traces
CREATE TABLE ai_agent_traces (
trace_id String,
span_id String,
parent_span_id String,
operation_name String,
start_time DateTime64(9),
end_time DateTime64(9),
duration_ms Float64,
-- GenAI 屬性
gen_ai_system LowCardinality(String), -- 'anthropic', 'openai'
gen_ai_model LowCardinality(String), -- 'claude-sonnet-4-20250514'
input_tokens UInt32,
output_tokens UInt32,
cost_usd Float64,
finish_reason LowCardinality(String),
-- Tool Call 屬性
tool_name Nullable(String),
tool_status Nullable(LowCardinality(String)),
-- 業務屬性
user_id String,
session_id String,
feature_name LowCardinality(String),
-- Prompt/Completion(取樣存儲)
prompt_text Nullable(String),
completion_text Nullable(String)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(start_time)
ORDER BY (trace_id, start_time)
TTL start_time + INTERVAL 90 DAY;
6.3 Grafana 儀表板設計
一個有效的 AI 代理可觀測性儀表板應包含以下面板:
總覽面板(Overview):當前 QPS、活躍使用者數、錯誤率、平均延遲。這些指標應以即時數據(過去 5 分鐘)和趨勢圖(過去 24 小時)兩種方式呈現。
成本面板(Cost):今日累計成本、本月累計成本、按模型的成本分布、按功能的成本分布、成本預測(基於當前趨勢的月底預估)。
效能面板(Performance):延遲百分位數趨勢圖(P50/P95/P99)、Token 用量分布直方圖、TTFT 趨勢、各模型的回應時間比較。
品質面板(Quality):工具呼叫成功率、LLM 錯誤率(4xx/5xx)、速率限制命中率、使用者回饋分數趨勢。
七、異常偵測與告警
可觀測性的最終目標不是產生更多數據,而是在問題發生時快速發現和響應。AI 代理系統有幾類特有的異常模式,需要專門的偵測策略。
7.1 幻覺偵測(Hallucination Detection)
幻覺是 LLM 應用中最具破壞性的品質問題之一。在可觀測性的語境下,幻覺偵測通常採用以下方法:
基於引用的驗證:在 RAG 系統中,比對模型回答中的事實聲明與檢索到的原始文件。如果回答包含文件中不存在的資訊,標記為潛在幻覺。這可以用另一個 LLM(如 LLM-as-Judge)自動完成。
一致性檢查:對同一問題進行多次推理(temperature > 0),如果不同次的回答在事實層面不一致,表示模型對該主題的信心不足,幻覺風險較高。
模式偵測:透過歷史追蹤數據,識別哪些類型的查詢更容易觸發幻覺(例如涉及特定時間範圍的事實查詢、需要精確數值的問題)。
幻覺偵測管線:
User Query → AI Agent → Response
│
▼
┌───────────────┐
│ Hallucination │
│ Detector │
│ │
│ 1. 引用比對 │ → 引用覆蓋率 < 0.5 → Flag
│ 2. 實體驗證 │ → 不存在的實體 → Flag
│ 3. 數值範圍 │ → 超出合理範圍 → Flag
│ 4. 時間一致 │ → 時間矛盾 → Flag
└───────┬───────┘
│
▼
hallucination_score: 0.0 ~ 1.0
→ score > 0.7 → Alert + Human Review
→ score > 0.3 → Log for Analysis
→ score < 0.3 → Pass
7.2 成本異常偵測
成本異常通常源自以下幾種模式:
突發性成本飆升:某個使用者或功能的請求量突然增加(可能是爬蟲、DDoS、或上游系統的重試風暴),導致 Token 用量和成本急劇攀升。偵測方法:設定成本的滑動窗口基線(例如過去 7 天同時段的平均值),當當前時段的成本超過基線的 3 倍時觸發告警。
漸進性成本漂移:由於 prompt 模板的修改、使用者行為的變化、或模型版本的更新,平均每次請求的成本逐漸上升。偵測方法:追蹤每次請求的平均成本趨勢,設定每週/每月的成本增長率閾值。
Token 迴圈:如前所述,代理進入無限循環或不必要的重試。偵測方法:設定單次請求的 Token 上限(Hard Limit),並追蹤每次請求的 LLM 呼叫次數分布。
成本告警規則示例 (Grafana Alerting):
# 規則 1: 突發成本
Alert: cost_spike
Condition: sum(cost_usd) OVER 1h > avg(cost_usd) OVER 7d_same_hour * 3
Severity: Critical
Action: Slack notification + PagerDuty
# 規則 2: Token 迴圈
Alert: token_loop
Condition: single_request_tokens > 20000
Severity: Warning
Action: Slack notification + 自動中斷該請求
# 規則 3: 預算預警
Alert: monthly_budget
Condition: projected_monthly_cost > budget * 0.8
Severity: Warning
Action: Email to finance team
# 規則 4: 速率限制逼近
Alert: rate_limit_approaching
Condition: rate_limit_remaining / rate_limit_total < 0.1
Severity: Warning
Action: 啟動請求佇列 / 降級到備用模型
7.3 延遲異常偵測
延遲異常可能源自 LLM 提供商的服務降級、網路問題、或代理邏輯中的效能瓶頸。有效的延遲告警需要考慮 LLM 回應時間的高變異性——同一個模型在不同時間、不同 prompt 長度下的回應時間可能相差數倍。因此,告警閾值不應使用固定值,而應基於歷史分布的百分位數。
推薦的做法是:追蹤 P95 延遲的 30 分鐘移動平均值,當它超過過去 24 小時同時段 P95 的 2 倍時觸發告警。這種方法既能捕捉真正的效能劣化,又能避免因 LLM 正常的延遲波動而產生過多假警報。
八、實戰:為 OpenClaw 建立可觀測性
本節以 OpenClaw(超智諮詢的開源 AI 代理框架)為例,展示如何從零建立完整的可觀測性系統。
8.1 環境準備
OpenClaw 代理系統通常包含以下元件:代理核心(Agent Core)、MCP 工具伺服器(Tool Servers)、記憶體儲存(Memory Store)、以及對外的 LLM API 呼叫。我們的可觀測性方案需要覆蓋所有這些元件。
# 1. 安裝可觀測性依賴
pip install opentelemetry-api opentelemetry-sdk \
opentelemetry-exporter-otlp \
openinference-instrumentation-openai \
openinference-instrumentation-anthropic \
arize-phoenix
# 2. 啟動 Phoenix(本地開發環境)
python -m phoenix.server.main serve
# 3. 啟動 OpenTelemetry Collector(生產環境)
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
attributes:
actions:
- key: gen_ai.prompt
action: hash # PII 保護:雜湊而非明文
- key: user.email
action: delete
exporters:
otlp/phoenix:
endpoint: phoenix:4317
tls:
insecure: true
clickhouse:
endpoint: tcp://clickhouse:9000
database: ai_observability
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, attributes]
exporters: [otlp/phoenix, clickhouse]
8.2 程式碼層級整合
在 OpenClaw 代理的應用程式碼中,我們使用 OpenTelemetry SDK 和對應的 Instrumentor 自動追蹤 LLM 呼叫:
# openclaw_observability.py
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from openinference.instrumentation.anthropic import AnthropicInstrumentor
def setup_observability():
"""初始化 OpenClaw 的可觀測性系統"""
# 設定 TracerProvider
provider = TracerProvider()
# 設定 OTLP 匯出器
otlp_exporter = OTLPSpanExporter(
endpoint=os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", "localhost:4317"),
insecure=True
)
# 批次處理器:緩衝 Span 後批次發送
provider.add_span_processor(
BatchSpanProcessor(
otlp_exporter,
max_queue_size=2048,
max_export_batch_size=512,
schedule_delay_millis=5000
)
)
trace.set_tracer_provider(provider)
# 自動追蹤 Anthropic API 呼叫
AnthropicInstrumentor().instrument(tracer_provider=provider)
return trace.get_tracer("openclaw-agent")
# 在代理程式碼中使用自定義 Span
tracer = setup_observability()
async def handle_user_request(user_query: str, user_id: str):
with tracer.start_as_current_span(
"openclaw.agent.handle_request",
attributes={
"user.id": user_id,
"openclaw.query_length": len(user_query),
"openclaw.agent_version": "1.4.2"
}
) as span:
# Step 1: 意圖分析
with tracer.start_as_current_span("openclaw.intent_analysis"):
intent = await analyze_intent(user_query)
span.set_attribute("openclaw.intent", intent)
# Step 2: 工具選擇與執行
with tracer.start_as_current_span("openclaw.tool_execution") as tool_span:
tools = select_tools(intent)
tool_span.set_attribute("openclaw.tools_selected", str(tools))
results = await execute_tools(tools, user_query)
# Step 3: 回應生成
with tracer.start_as_current_span("openclaw.response_generation"):
response = await generate_response(user_query, results)
# 記錄最終指標
span.set_attribute("openclaw.total_tools_called", len(tools))
span.set_attribute("openclaw.response_length", len(response))
return response
8.3 自定義指標收集
除了自動追蹤的 LLM 呼叫之外,OpenClaw 還需要收集業務層面的自定義指標。我們使用 OpenTelemetry Metrics API 來實現:
# openclaw_metrics.py
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
# 初始化 Meter
exporter = OTLPMetricExporter(endpoint="localhost:4317", insecure=True)
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=30000)
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)
meter = metrics.get_meter("openclaw-agent")
# 定義自定義指標
request_counter = meter.create_counter(
"openclaw.requests.total",
description="Total agent requests",
unit="1"
)
token_histogram = meter.create_histogram(
"openclaw.tokens.per_request",
description="Token usage per request",
unit="tokens"
)
cost_counter = meter.create_counter(
"openclaw.cost.total",
description="Cumulative cost in USD",
unit="usd"
)
latency_histogram = meter.create_histogram(
"openclaw.latency.e2e",
description="End-to-end latency",
unit="ms"
)
# 在請求處理中記錄指標
def record_request_metrics(
model: str, feature: str, user_id: str,
input_tokens: int, output_tokens: int,
cost: float, latency_ms: float
):
labels = {"model": model, "feature": feature}
request_counter.add(1, labels)
token_histogram.record(input_tokens + output_tokens, labels)
cost_counter.add(cost, labels)
latency_histogram.record(latency_ms, labels)
8.4 告警與 Runbook
可觀測性的最後一哩路是告警和自動化響應。以下是我們為 OpenClaw 建立的告警層級和對應的 Runbook:
OpenClaw 告警矩陣:
┌─────────────────┬──────────┬───────────────────────────────────┐
│ 告警名稱 │ 嚴重度 │ 自動化響應 (Runbook) │
├─────────────────┼──────────┼───────────────────────────────────┤
│ E2E P99 > 30s │ Critical │ 1. 檢查 LLM API 狀態頁 │
│ │ │ 2. 切換到備用模型 │
│ │ │ 3. 通知 on-call 工程師 │
├─────────────────┼──────────┼───────────────────────────────────┤
│ Error Rate > 5% │ Critical │ 1. 檢查 API Key 配額 │
│ │ │ 2. 啟動請求限流 │
│ │ │ 3. 通知 on-call 工程師 │
├─────────────────┼──────────┼───────────────────────────────────┤
│ Token Loop │ Warning │ 1. 中斷異常請求 │
│ (> 20K tokens) │ │ 2. 記錄 Trace ID 供除錯 │
│ │ │ 3. 加入黑名單規則 │
├─────────────────┼──────────┼───────────────────────────────────┤
│ Daily Cost │ Warning │ 1. 分析成本來源 │
│ > Budget × 120% │ │ 2. 通知團隊負責人 │
│ │ │ 3. 考慮降級模型或限流 │
├─────────────────┼──────────┼───────────────────────────────────┤
│ Hallucination │ Info │ 1. 記錄到品質追蹤表 │
│ Score > 0.7 │ │ 2. 每日匯總報表 │
│ │ │ 3. 當累計超過閾值時升級為 Warning │
├─────────────────┼──────────┼───────────────────────────────────┤
│ Rate Limit │ Warning │ 1. 啟動請求佇列 │
│ Remaining < 10% │ │ 2. 評估是否需要升級 API 方案 │
└─────────────────┴──────────┴───────────────────────────────────┘
一個經常被忽略的實務要點是:告警的「靜默策略」(Silence Policy)。在 LLM 提供商進行計畫性維護(例如 OpenAI 的週期性服務更新)時,預先設定告警靜默,避免 on-call 工程師被預期內的告警打擾。同樣地,新功能上線初期的「燒入期」(Burn-in Period)也應有對應的告警寬限機制。
九、結語
AI 代理可觀測性不是一個「有最好」的功能——它是將 AI 代理從實驗室原型推進到生產級系統的必要基礎設施。沒有可觀測性,你就是在黑暗中飛行:不知道代理為什麼做出某個決定、不知道成本是否在控制之內、不知道品質是否在漂移。
本文涵蓋的核心要點可以總結為以下行動清單:
第一步:建立追蹤基礎。選擇一個追蹤工具(LangSmith、Phoenix 或 Helicone),讓每個 LLM 呼叫和工具呼叫都被記錄。這通常只需要半天到一天的工作。
第二步:定義核心指標。至少追蹤延遲(P50/P95/P99)、Token 用量、錯誤率和成本四個維度。建立 Grafana 儀表板讓團隊可以即時查看。
第三步:設定告警。從最關鍵的告警開始——成本異常和錯誤率飆升。逐步增加延遲告警和品質告警。
第四步:標準化。採用 OpenTelemetry GenAI 語義約定[3]作為數據標準,確保未來能夠切換或組合不同的工具。
第五步:持續優化。利用追蹤數據識別效能瓶頸和成本熱點,建立品質回歸測試,將可觀測性數據回饋到代理開發流程中。
在超智諮詢,我們在每一個企業 AI 代理專案中都將可觀測性作為「Day 1 需求」而非「Day 2 優化」。我們的經驗表明,前期在可觀測性上投入的每一小時,都能在後續的營運和除錯中節省十倍以上的時間。如果你正在規劃或已經部署了 AI 代理系統,現在就是建立可觀測性的最佳時機。



