還記得你小時候做科學實驗嗎?老師總是苦口婆心地說:「一定要寫實驗記錄!」當時你可能覺得很煩,心想「記這些幹嘛,我又不會忘」。
直到某天實驗出了意外,你卻突然一片茫然,忘記了自己剛剛的操作。
這就是沒有 Logging 的 AI 系統。
昨天我們聊到可觀測性的三個好朋友:Logs、Metrics、Traces。今天要深入第一位——Logs (日誌),這位煉金師實驗記錄本的忠實記錄者。
傳統軟體的日誌很簡單:
2024-10-08 14:30:15 [INFO] User logged in
2024-10-08 14:30:16 [ERROR] Database connection failed
但 AI 系統呢?它需要記錄的不只是「發生了什麼」,更要記錄「AI 看到了什麼、想了什麼、說了什麼」。
想像你是法醫,面對一個複雜的案件。你需要知道:
這就是 AI Logging 的複雜之處。由於 LLM 的非確定性特性和開放式輸入,它們的行為比傳統軟體更難預測,這讓日誌變得更加重要。
[2024-10-08 14:30:15] User asked about pricing, model responded in 3.2s, used 1234 tokens, cost $0.05
看起來還可以?但當你有 10 萬條這樣的日誌,想要回答以下問題時:
你就會發現...需要寫一堆正規表達式來解析這些文字。這就像用小刀一個字一個字挖出你要的資訊,又慢又容易出錯。
JSON 格式的結構化日誌讓資料查詢和分析變得簡單,因為它提供了一致的 Schema 和機器可讀的格式:
{
"timestamp": "2024-10-08T14:30:15.123Z",
"level": "INFO",
"event": "llm_request_completed",
"user_id": "user_12345",
"session_id": "sess_abc123",
"prompt": {
"text": "請幫我分析這份財報",
"length": 156,
"template_version": "v2.3"
},
"response": {
"text": "根據財報顯示...",
"length": 892,
"finish_reason": "stop"
},
"model": {
"name": "claude-sonnet-4.5",
"temperature": 0.7,
"max_tokens": 2048
},
"performance": {
"latency_ms": 3200,
"ttft_ms": 450,
"tokens_per_second": 25.3
},
"usage": {
"prompt_tokens": 156,
"completion_tokens": 892,
"total_tokens": 1048,
"cost_usd": 0.0524
},
"metadata": {
"retrieval_sources": ["doc_001", "doc_045"],
"guardrail_checks": ["toxicity", "pii"],
"cache_hit": true
}
}
現在你想知道平均回應時間?簡單:
SELECT AVG(performance.latency_ms) FROM logs WHERE event = 'llm_request_completed'
想知道哪個模型最省錢?
SELECT model.name, AVG(usage.cost_usd) FROM logs GROUP BY model.name
結構化日誌不只幫助除錯,更提供了應用程式整體健康狀況和效能的寶貴洞察。
根據 OpenTelemetry 社群的建議,有效的 LLM 日誌應包含幾個關鍵維度:
這是最基本的,記錄「AI 看到了什麼」和「AI 說了什麼」:
{
"prompt": {
"text": "分析這份合約的風險",
"tokens": 156,
"source": "user_input"
},
"response": {
"text": "主要風險包括...",
"tokens": 892,
"finish_reason": "stop"
}
}
記錄模型參數非常重要,因為像 temperature 和 top_p 這些設定會顯著影響回應品質和成本:
{
"model": "claude-sonnet-4.5",
"temperature": 0.7,
"top_p": 0.9,
"max_tokens": 2048,
"version": "20241022"
}
還記得 Day 20 的 TTFT 和 TPS 嗎?通通記下來:
{
"latency_ms": 3200,
"ttft_ms": 450,
"tokens_per_second": 25.3,
"queue_time_ms": 120
}
Day 22 我們聊過成本優化,沒有記錄就無法優化:
{
"prompt_tokens": 156,
"completion_tokens": 892,
"total_tokens": 1048,
"cost_usd": 0.0524,
"cached_tokens": 5000,
"cache_cost_usd": 0.0052
}
Day 6-9 的 Context Engineering 教我們:上下文很重要!
{
"retrieval_sources": ["財報_Q3", "公司政策_v2.1"],
"guardrail_results": {
"toxicity_score": 0.02,
"pii_detected": false
},
"cache_hit": true,
"agent_chain": ["router", "analyst", "writer"]
}
記錄日誌時,必須遵循安全最佳實踐,確保不會記錄敏感資料,或者如果需要記錄,要確保這些日誌是安全的。
想像你是一位醫生,病人的隱私是你的職業道德底線。
AI 系統也是一樣,使用者的資料需要保護。
但問題是我怎麼知道使用者會輸入什麼?
我們確實無法預測使用者會說什麼,所以需要自動偵測和遮罩機制。
三大公有雲皆有提供類似服務:
常見的敏感資訊類型:
不應依賴開發者「記得要遮罩」,而是在架構層面就建立自動防護機制。就像汽車的安全氣囊,不是要你記得碰撞時手動觸發,而是自動啟動保護你。
當你建立了完善的日誌系統,它不只是「記錄發生了什麼」,更是一台時光機,賦予你四種超能力。
還記得半夜三點被叫醒的慘況嗎?「系統掛了!」老闆在電話那頭咆哮。
有了完整的日誌,你可以像偵探一樣重建現場:
問題第一次出現在哪裡?
當時 AI 看到了什麼資料?
哪個環節出錯了?
例如:三週前就有駭客入侵,只是當時沒人注意到日誌裡的異常。透過日誌追溯,重建了整個攻擊過程,找出了被入侵的帳號。
「下個月的 API 帳單會爆掉嗎?」這個問題困擾著每個用 AI 的團隊。
透過日誌分析過去三個月的使用趨勢,你可以在帳單爆炸前就知道:
哪些使用者特別耗錢
哪個時段使用量最高
成本會以什麼速度成長
「為什麼有些使用者的回應特別慢?」這種問題最煩人,因為你看不到明顯的錯誤。
日誌可以幫你找出隱藏的模式:
某個 Prompt 模板特別慢 (因為觸發太多 RAG 檢索)
某些時段特別卡 (因為背景任務在搶資源)
某個使用者的請求特別大 (因為上傳了 50 頁文件)
「新的 Prompt 版本比較好嗎?」不要用感覺猜,用資料說話。
透過日誌比較不同版本的表現:
哪個版本回應更快?
哪個版本更省錢?
哪個版本使用者更滿意?
這就是 A/B 測試的精髓。有資料支撐,你就不用再當「碰運氣的賭徒」,而是「用數據煉金的科學家」。
今天我們學會了如何寫好「實驗記錄本」,但光有記錄本還不夠。明天我們再來看看 Tracing