iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
AI Engineering

AI Agent 系統開發 30 天系列 第 28 篇

用 Langfuse 從線上 Trace 評估 Agent 正確率

  • 分享至 

  • xImage
  •  

在上線前,我們透過離線評估(Offline Eval)拿固定的測試集驗證 Agent;測試集裡每一題都自帶標準答案(expected_output),因此程式能自動比對並計算出分數。

但當 Agent 正式部署上線後,情境完全不同:真實使用者的問法千奇百怪,且線上系統產生的執行紀錄(Trace)只會記錄「使用者說了什麼、模型做了什麼決策」,資料庫裡不會自帶客人的真實意圖與標準答案(Ground Truth)。

如果沒有標準答案,就無法透過程式自動計算線上正確率。要掌握 Agent 在正式環境的真實表現,必須從線上流量中抽樣 Trace,由客服團隊或人工標註員審核並補上標準答案。

這篇介紹如何透過 Langfuse 的人工標註工作流(Annotation Queue)評估線上 Agent 的意圖分類正確率,並將線上發現的失敗案例回補至離線測試集,形成持續改善的評估閉環:

https://ithelp.ithome.com.tw/upload/images/20261009/20111896fxsNlbWiGq.png

模擬線上流量產生 Trace

對應的範例程式位於 langgraph-pydantic-intent-routing。進入專案目錄並安裝依賴:

$ cd ai-agent-sample/langgraph/langgraph-pydantic-intent-routing
$ uv sync

在正式環境中,Trace 是使用者與 Agent 真實對話時由系統自動記錄下來的。我們藉由四筆不同類型的客服提問,模擬真實客人的提問流量,並在 Langfuse 產生待審核的原始對話紀錄。

先執行 sync 確認最新 Prompt 已同步至 Langfuse:

uv run intent-eval sync

接著發送四筆模擬提問:

uv run intent-routing "請問 ORD-2001 配送到哪了?"
uv run intent-routing "我要退款訂單 ORD-2002。"
uv run intent-routing "通勤用的後背包,十五吋筆電應該選哪一款?"
uv run intent-routing "請幫我寫一個 Python 程式,印出九九乘法表。"

每次執行 intent-routing 都是一個獨立的 Agent run。Langfuse 會保存使用者的訊息、模型的意圖分類、路由路徑與最後的回覆。

因為這些命令模擬的是線上即時互動,而不是在跑離線測試集,所以 Trace 紀錄中只有使用者的問題與模型的回答,系統不會自帶標準答案(沒有 expected_output)。

執行完後,開啟 Langfuse 介面:

  1. 點選左側選單的 Tracing。
  2. 將時間範圍設為當前區間,篩選 Name 為 intent-routing,即可看到剛才送入的四筆 Trace。
  3. 點開其中一筆 Trace,確認能看到使用者訊息、模型判斷的 intent 與路由節點 handled_by。人工審核時必須同時比對輸入與輸出,才能客觀判定分類是否正確。

https://ithelp.ithome.com.tw/upload/images/20261009/20111896EH6R1KaWWL.png

先定義人工標註的判斷標準

人工標註不能只問「這筆看起來好不好」。這個 Agent 的 intent 已經是固定 enum,因此標註員應使用與 Offline Dataset 相同的定義:

expected_intent 人工判斷標準
order_status 使用者要查詢訂單、出貨或配送進度
refund 使用者要求退款或退貨
product_advice 使用者詢問商品選擇、規格或推薦
unsupported 請求不屬於上述電商客服範圍

intent_correct 只有兩種值:

  • True:模型的 decision.intent 與人工判斷的 expected_intent 完全相同。
  • False:兩者不同。標註 comment 應寫出「預期 intent」與「實際 intent」。

訊息若無法由當前內容確定唯一 intent,不要強迫標註員猜答案。先將 trace 留下 comment 並排除於正確率分母之外,再由產品與客服負責人補充分類規則。

在 Langfuse 建立 Score Config

先建立兩個人工標註欄位。將左側選單點選 Settings,再進入 Scores Config。也可以點選左上角 Go to...,搜尋 Project Settings > Scores Configs,直接開啟設定頁。

Evaluation > Scores 顯示已經產生的 score 記錄。進入 Scores Configs 後,點選 Add new score config。

第一個 Score Config 記錄模型是否分類正確:

欄位 設定值
Score name intent_correct
Data type BOOLEAN
Description True 表示 decision.intent 與人工確認的 expected_intent 相同

選擇 BOOLEAN 後不需要填寫 Minimum 與 Maximum,點選 Submit 建立。接著再點選一次 Add new score config,建立 expected_intent。

第二個 Score Config 保存人工確認的正確類別:

欄位 設定值
Score name expected_intent
Data type CATEGORICAL
Categories order_status、refund、product_advice、unsupported
Description 根據使用者訊息由人工確認的正確 intent

https://ithelp.ithome.com.tw/upload/images/20261009/20111896ljmNhtbHXq.png

建立 Annotation Queue 並加入 trace

在左側 Human Annotation 頁面點選 New Queue,建立一個人工審核佇列:

欄位 設定值
Queue name intent-review-queue
Description 人工審核 trace 的意圖分類
Score Configs intent_correct、expected_intent

如果有多位客服專家參與,可以在建立 Queue 時指派負責人。Queue 決定標註時要填哪些 score,trace 本身仍保留在 Tracing 頁面。

https://ithelp.ithome.com.tw/upload/images/20261009/20111896Oa3MZbVKDU.png

新建的 Queue 會顯示 Pending Items = 0,因為它還沒有收到任何 trace。此時點選 Process queue 不會出現可標註的任務。

回到 Tracing,勾選剛才執行的四筆 intent-routing trace,再點選:

Actions → Add to queue → intent-review-queue

https://ithelp.ithome.com.tw/upload/images/20261009/20111896VdiDBeyvZm.png

回到 Human Annotation 後,確認 intent-review-queue 的 Pending Items 已變成 4,再點選 Process queue。

正式環境不應只挑看起來有問題的 trace。如果要估計整體正確率,應從目標時間區間隨機抽樣;每種 intent 的流量差距很大時,可以按預測 intent 分層抽樣,報表中再保留各類樣本數。

逐筆標註正確 intent

點選 Process queue 後,每筆任務先讀取使用者訊息,再展開 trace 內的結構化輸出與 Graph 節點:

  1. 根據使用者訊息選擇 expected_intent。
  2. 比較 expected_intent 與 decision.intent。相同時將 intent_correct 設為 True,不同時設為 False。
  3. False 案例在 comment 寫出預期與實際 intent,例如「預期 order_status,實際 refund」。
  4. 點選 Complete + next 保存並移到下一筆。

https://ithelp.ithome.com.tw/upload/images/20261009/20111896Qi6wkFmF0y.png

四筆都完成後,Queue 清單應顯示 Completed Items = 4 與 Pending Items = 0。

以「請問 ORD-2001 配送到哪了?」為例,人工確認的 expected_intent 是 order_status。如果 trace 內的 decision.intent 也是 order_status,intent_correct 就標為 True。如果模型輸出 refund,則標為 False。

在 Scores Analytics 計算正確率

標註完成後,點選左側 Scores,進入 Analytics 分頁:

  1. Score 篩選:左上角選擇 intent_correct • ANNOTATION。
  2. 時間範圍:確認右上角的時間區間包含剛才標註的時間(例如 Past 90 days)。

https://ithelp.ithome.com.tw/upload/images/20261009/201118964jNq2ysKWg.png

報表畫面主要分為兩大區塊:

  • 左側 Statistics(統計指標):
    • Total:已標註的樣本總數(圖中為 5 筆)。
    • Mode:最常出現的判定結果與筆數。圖中的 True (4) 代表 5 筆中有 4 筆分類正確。
    • Mode %:該類別所佔的百分比。在二元判定中,這就是這批線上抽樣的分類正確率(Accuracy),圖中直接顯示為 80.0%(計算方式為 4 ÷ 5 = 80.0%)。
  • 右側 Trend Over Time(時間趨勢):
    • 以折線圖呈現 True(深藍線)與 False(淺藍線)在時間軸上的數量分佈。

這裡看到的 80.0% 是針對「已標註樣本」所算出的正確率。如果線上每天有大量流量,抽樣樣本數越充足,這項統計就越能代表整體的真實表現。

從失敗 trace 找到最早錯誤環節

intent_correct = False 只能證明最後結果不符合標準答案,還要點開 trace 找到最早出錯的步驟:

  • classify_intent 的結構化輸出已經是錯誤 intent:檢查 Prompt、模型、訊息措辭與分類邊界。
  • decision.intent 正確,handled_by 卻錯誤:檢查 route_after_classification() 與 Graph edge。
  • classification_error 有值並進入 classification_fallback:檢查模型原始輸出與 IntentDecision schema。
  • intent 與 route 都正確,但客服仍判定整體回應不合格:另外建立 response quality、policy compliance 或 task completion score,不要將所有問題塞進 intent_correct。

評分維度必須分開,否則整體分數失敗時,無法判斷應修改 Prompt、router 還是回覆節點。

將線上失敗補回 Offline Dataset

線上評估的結束條件不是「在 Langfuse 看到一個 False」。已由人工確認的失敗請求,應成為後續 Prompt 與模型變更的固定回歸案例。

在失敗 trace 中點選對應的 observation,使用 + Add to dataset 將候選案例放進獨立的 intent-production-candidates Dataset。不直接寫進 intent-routing-eval Dataset,因為這個 sample 以 Git 裡的 intent-cases.jsonl 當作正式來源。

加入候選 Dataset 時,確認:

  • input 保留去除個人資料後的使用者訊息。
  • expected_output.intent 使用人工確認的 expected_intent。
  • expected_output.handled_by 根據 Graph contract 填入正確節點。
  • metadata 保留案例來源、風險與發現日期,不保留可識別個人的內容。

最後,審核通過後,將相同資料加入 src/langgraph_pydantic_intent_routing/eval/datasets/intent-cases.jsonl,再執行。新案例一旦進入 Git 與 Offline Dataset,之後每次修改 Prompt、模型或 Graph 都會重跑這筆實際發生過的邊界請求。


上一篇
用 LLM Judge 評估 Agent 回覆品質
系列文
AI Agent 系統開發 30 天 共 28 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言