iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
AI Engineering

你的 AI Demo 為什麼不能上線?從 Prompt 到 Production 的 AI Engineering系列 第 11

Day 11 : Eval 有分數之後,我開始看 AI 到底錯在哪裡

  • 分享至 

  • xImage
  •  

昨天把固定的 Eval Dataset 建起來之後,我終於可以比較不同版本的 AI Pipeline,每次換 Prompt、調 Retrieval 或改模型,都能重新跑同一批問題,再看看結果到底變好還是變差,不過真的開始累積結果之後,我很快又遇到一個問題,如果最後只得到一個 78% 或 85% 的 Accuracy,其實我還是不太知道下一步該改哪裡。

因為兩個系統就算最後都是 80 分,失敗原因可能完全不同,一個可能經常找錯文件,另一個可能文件找對了,但模型最後整理答案時產生幻覺,如果全部都只被記成「錯誤」,最後看到的就只是一個數字,所以今天我開始把 Eval 的錯誤再往下拆。

先不要急著改 Prompt

以前看到 AI 回答錯誤,我第一個反應很常是打開 Prompt,想看看是不是指令寫得不夠清楚,但現在有了完整 Pipeline 之後,這個做法其實很容易改錯地方。

目前我的簡化流程大概是:

User Question
↓
Retrieval
↓
Context
↓
Prompt
↓
LLM
↓
Answer

假設今天問:

會員取消訂單後,退款需要幾個工作天?

標準答案是:

退款會在 5~7 個工作天內完成。

結果 AI 回答:

通常會在 3 個工作天內完成退款。

以前看到這個結果,我可能直接開始修改 Prompt,加上「請嚴格依照文件回答」「禁止自行推測」之類的規則,但現在我會先去看 Retrieval 到底拿回什麼資料。

如果 Retriever 根本沒有抓到退款政策,而是抓到另一份「取消訂單處理時間」的文件,那 LLM 後面再怎麼調都很難回答正確,真正要修的是 Retrieval;相反地,如果正確文件明明已經在 Context 裡面,模型卻還是自己產生 3 天,那問題才比較可能落在 Prompt 或 Generation。

我開始替錯誤貼標籤

所以今天我先做了一個很簡單的 Error Type:

Retrieval Error
Context Error
Generation Error
Format Error
Unsupported Answer

Retrieval Error 代表需要的資料根本沒有被找到,Context Error 則是資料有找到,但 Context 組裝時被截掉或排序太後面,Generation Error 是正確資料已經存在,模型最後還是回答錯,Format Error 則是內容本身可能正確,但 JSON、欄位或輸出格式不符合系統要求。

最後一個 Unsupported Answer 我覺得特別重要,因為有時候模型的回答讀起來很合理,甚至剛好跟正確答案差不多,但從提供給模型的文件裡根本找不到這個資訊,這種答案如果只看文字可能會被當成成功,但真正放到 Production 裡其實風險很高。

同樣是錯,修法完全不同

開始分類之後,原本一整排紅色的 Failed Case 突然變得比較有意義。

假設我跑 100 題:

Correct                78
Retrieval Error         9
Context Error           3
Generation Error        5
Format Error            2
Unsupported Answer      3

看到這個結果之後,我就不會馬上去換模型,因為目前最大的問題其實是 Retrieval,如果先處理搜尋品質,很可能一次就能改善最多題目。

如果下一個版本變成:

Correct                84
Retrieval Error         3
Context Error           2
Generation Error        7
Format Error            1
Unsupported Answer      3

那就代表前一輪調整確實有讓 Retrieval 變好,只是現在主要瓶頸慢慢跑到 Generation,接下來才值得花時間處理 Prompt、Context 表達方式或模型本身。

這種做法讓我第一次很明顯感覺到 AI Engineering 跟單純「調 Prompt」的差別,因為我不需要一直靠感覺猜是哪裡壞掉,每一次調整都有比較明確的方向。

Eval Dataset 也開始變成除錯工具

原本我做 Eval Dataset,只是想知道新版到底有沒有比舊版好,今天做到這裡之後,我才發現它其實還可以直接拿來 Debug。

每一題現在除了 Question、Expected Answer,我還想慢慢補上:

{
  "question": "會員取消訂單後,退款需要幾個工作天?",
  "expected_answer": "5~7 個工作天",
  "retrieved_docs": [],
  "model_answer": "",
  "result": "",
  "error_type": "",
  "notes": ""
}

這樣之後每次跑 Evaluation,我留下的就不只是最後一個 Score,而是一批可以重新追蹤的錯誤紀錄,哪一題找錯文件、哪一題模型亂補資訊、哪一題格式壞掉,都可以慢慢累積。

等資料量開始增加之後,我甚至可以直接看某個版本到底解掉了哪些舊問題,又新增了哪些新的錯誤。

分數終於開始有上下文

做到 Day 11,我現在比較不會看到 Accuracy 從 82% 升到 85% 就立刻覺得新版一定比較好,因為如果新增的 3% 是簡單題答對,但同時出現更多 Unsupported Answer,那在實際產品裡可能反而更危險。

所以接下來 Eval 對我來說會開始有兩層,第一層還是整體指標,用來快速看版本變化,第二層則是錯誤類型與失敗案例,讓我知道分數變化到底是從哪裡來。

這樣每一次改 Prompt、調 Chunk、改 Top-K 或換模型,都可以留下比較完整的紀錄,而不是試完覺得「好像比較好」就直接上線。

明天我想再把這套 Evaluation 往 Production 靠近一點,開始加入 Latency、Token Cost 這些指標,因為真正上線之後,答案答得準只是其中一件事,如果每個問題都要等十幾秒,而且成本一直往上堆,系統一樣很難真的拿來用。


上一篇
Day 10 : AI 回答看起來很正常,我要怎麼知道它真的答對了?
下一篇
Day 12 : 回答正確還不夠,上線後我開始看 Latency 和 Token Cost
系列文
你的 AI Demo 為什麼不能上線?從 Prompt 到 Production 的 AI Engineering15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言