AI可觀測性的四個訊號
透過實際案例,介紹AI應用可觀測性的四個關鍵訊號:版本化提示詞、trace記錄、使用者評分和模型評分。
幾個月前,我們團隊將一個聊天功能上線到生產環境。使用者提問,應用透過LLM模型路由問題,模型呼叫幾個內部工具,然後返回答案。它勉強能工作,但當我們不知道模型為何回答得好或差時,唯一的除錯工具就是閱讀日誌和猜測。我們意識到應用無法回答一個最基本的問題:顯示所有使用者反饋差的聊天記錄,按系統提示詞的版本分組,並讓我們檢視完整對話,包括模型呼叫了哪些工具。這相當於AI版“顯示部署X後此端點的所有500錯誤”,但我們的應用做不到。
這促使我們放棄尋找更聰明的模型,轉而尋求新增可觀測性層。我們最終使用了Langfuse,但具體供應商並不重要,Helicone、Arize Phoenix、LangSmith和Braintrust都能解決類似問題。經過幾個月的迭代,我們發現需要的功能有四種,我稱之為每個AI功能必須發出的四個訊號:每個提示詞都有版本(模型今天看到了哪些確切詞彙?);trace形狀符合實際工作(模型呼叫了什麼、順序如何、引數是什麼?);來自使用者的評分(使用者喜歡結果嗎?);來自另一個模型的評分(當使用者沉默時,誰來打分?)。當然,沒有這四個訊號也能構建AI功能,只是無法有目的地改進它。
我們做的第一件事是把每個提示詞從程式碼中移出,放入一個版本化儲存,應用在執行時獲取。程式碼從不引用版本,只請求標籤。例如,PromptRepo.compile(name: "classify_question", label: "production")。透過Langfuse UI,人類可以點選按鈕將“production”標籤移動不同版本之間,回滾也只需點選,無需部署。第一次透過點選按鈕回滾糟糕提示詞,而不是撤銷PR並等待CI時,我們就知道這是正確的方向。一旦提示詞成為內容,最接近問題的人就成為編寫提示詞的人,反饋迴圈大大縮短,質量提升。
一個聊天不是單次呼叫,而是一個小程式:分類問題、載入正確提示詞、呼叫一兩個工具,然後組合答案。如果你的trace只有一行,你只知道發生了某事;而trace樹告訴你實際發生了什麼。如果trace是呼叫樹,你就有了模型決策資料庫。例如,原始日誌只有一行[INFO] chat_completed user_id=123 duration_ms=4200 tokens=1840,而改進後trace樹包含:span: load-prompt (version=production:v12), generation: classify-question (model=haiku, category="billing"), generation: compose-answer, span: tool-call.lookup_invoice (200ms), span: tool-call.lookup_customer (180ms), generation: final-response (model=sonnet, 1.2k tokens)。每個節點都攜帶提示詞名稱和版本、模型ID、token用量以及我們控制的後設資料欄位,比如執行客戶、問題分類類別、呼叫了哪些工具、是否為新對話。這些後設資料最終被證明最重要。當我們第一次過濾出“範圍內所有聊天記錄,其中特定工具執行且使用者反饋差”時,我們意識到trace列表不再是日誌,而是模型決策的可查詢資料庫。經驗法則:用將來可能篩選的維度標記trace,前期成本很低,但事後新增幾乎不可能。
使用者介面中每條助手訊息都有點贊和點踩按鈕。使用者點選時,我們儲存一行並作為評分post回可觀測性工具。單獨的點踩沒有可操作性,但關聯到trace的點踩告訴你模型看到了什麼、呼叫了什麼、哪個提示詞版本產生了它、問題屬於哪個類別。現在你可以問:點踩是否集中在某個類別?某個提示詞版本?某個特定工具呼叫之後?應該審查點踩的trace,雖然有時是噪音,但十分之一可能是真實訊號,會轉化為提示詞更改、新工具或bug修復。所有這些管道的目的是一個查詢:顯示所有使用者標記為差的trace。一旦能執行該查詢並閱讀產生它的完整對話(提示詞版本、工具呼叫、模型、延遲等),你就停止了猜謎遊戲。
人類反饋有用但稀少,大多數使用者不點選任何東西。所以我們新增了第二個模型來評判第一個模型。後臺任務拉取完成的聊天,透過獨立的“評判”提示詞(與生產提示詞在同一個版本化倉庫中)執行,並將結果寫回同一trace作為評分。現在trace攜帶兩路評判資料。當使用者和評委一致時,評委與真實使用者同步;當不一致時,那就是系統中最有趣的trace。無論哪種情況,評委在每次聊天上執行,因此迴歸會在釋出導致它的提示詞當天顯現,而不是一週後有人抱怨時。我們的評委評估事實性、指令遵循、完整性、幻覺、以及助手是否使用了正確的內部上下文。我們低估了這一訊號:一個能在釋出前捕捉迴歸的評委比更快或更聰明的模型更有價值,它是當沒人點選點贊時唯一可擴充套件的訊號。我們學到的教訓:評委只是一個提示詞,可能出錯,它需要版本化、Playground和回滾按鈕,就像面向使用者的提示詞一樣。每個訊號都寫回同一個trace,這就是全部技巧。
四個訊號重疊,這是有意的。提示詞版本顯示在trace上,使用者評分附加到trace,評委評分也附加到trace。它們不是四個獨立的東西,而是從四個不同視角觀察同一個思想:讓AI功能可觀測,然後你就能有目的地改變它。過去我對待AI功能像一類不同的軟體:更難除錯、更難測試、更難控制。但AI功能就是軟體,有輸入、做決策、產生輸出,並且可以像其他事物一樣被觀測。四個訊號有意重疊,它們是一個想法——使系統可觀測——從四個角度展現。一旦擁有了它們,變化不在於模型變得更聰明,而在於你停止猜測。你釋出一個提示詞更改,知道評委會在迴歸時告知;你閱讀一個點踩,知道可以重放產生它的精確對話;你將新提示詞提升到生產,知道可以一鍵回滾。模型是引擎,可觀測性層是儀表盤。沒有儀表盤你也能開車,只是不能有目的地駕駛。