iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
AI Engineering

30 天 AI eval 實戰:一隻 PM agent,改完之後怎麼確定它還是對的系列 第 17

Day 17|agent 標出來的問題每三個只有一個是真的,該先修的是多標那一邊

  • 分享至 

  • xImage
  •  

這隻需求釐清 agent 該找的問題大多找到了,麻煩的是它額外標出來的比找到的多了將近兩倍,多到看卡的人不會再逐條去翻,所以先讓的是多標那一邊。

需求方翻了三次原文,第四次就不翻了

需求方打開整理好的卡,看到 agent 在某一條 AC 旁邊標「跟 description 說的不一樣」,翻回原文對了一遍,沒有不一樣。下一條又標「沒有寫清楚怎樣算做完」,再翻,那條寫了數字也寫了條件。連著三條都這樣之後他就不會再翻了,連真的有問題的那一條也一起跳過。

被驗收的這隻 agent 做的事,是把需求方寫得雜亂的 ticket 整理成四個區塊,Goal、Scope in、Scope out,以及 AC 標註。最後這個區塊是它在需求方寫的 AC 裡挑出有問題的幾條,標上是哪一類問題。挑問題這種工作,漏掉一條真的跟多標一條不存在的,從來不是同一種錯,上面那個場景就是多標那一種錯走到下游的樣子。

漏掉一條跟多標一條,代價不一樣

昨天那兩個數字,case 通過率跟逐條算的通過率,都把每一條紅當成同樣重的一件錯,不管紅的原因是漏掉還是多標。

漏掉一條真的衝突,那條 AC 會照原文進 sprint,等工程師寫到一半或 QA 驗收時才浮出來,代價是一次返工。多標一條不存在的問題,代價是開頭那個場景,整個 AC 標註區塊被需求方放棄,連真的那幾條也沒有人讀。

兩種錯要分開數,代價才看得出來。對照的答案是每一筆 case 的 goal state 裡事先人工標好的期望標註,讀過每張卡的原文之後一條一條標的。

agent 標出來的每一個標註只有兩種身分,人工標進 goal state 裡也有的,跟人工沒標的,後一種就是多標;人工標的每一個標註也只有兩種下場,被它找到,或被它漏掉,漏掉的叫漏標。前一組算出來的是 precision,它標的有幾成是真的;後一組是 recall,真的有幾成被它找到。

整份 dataset 跑完的數字

整份 dataset 有 16 筆 case,2026-09-16 那趟用 gpt-5.4-mini 每筆跑 3 次,數字在 repo 的 runs/2026-09-16T09-54-50-525Z-all.md

  • precision 34%:它標出來的標註裡,每三個只有一個是人工事先標進 goal state 的。
  • recall 78%:人工標的標註,將近八成被它找到了。
  • 對上 60 個、漏標 17 個、多標 115 個,48 趟通過 3 趟。

數的單位是「條號加類別」,同一條 AC 被標成兩類問題就算兩個,因為漏掉第二類正是最值得看見的失敗。逐列拆開,問題幾乎全在多標那一邊:

case P R 逐列的情況
conflicting-truth-001003 30%/38%/60% 都是 100% 人工標的全找到,另外多標一堆
missing-context-001003 33%/23%/30% 都是 100% 同上,002 多標最兇
merged-concerns-001 33% 100% 同上
noise-over-signal-001 54% 70% 這張表裡 recall 不到八成的一筆

有八筆 case 的 recall 是 100%,precision 只有 23% 到 60%,人工標的它都找到了,卻另外標了一堆。17 個漏報裡 8 個集中在 noise-over-signal-001,那張卡人工標的標註有 9 個,是整份 dataset 最多的,另外 7 個在那張優惠碼功能的 ticket 上。

四張沒有問題的卡,它 11 趟裡標了 10 趟

數字最差的是人工一個標註都沒標的那四筆,dataset/irreversible-push-002.yamlirreversible-push-003.yamlmerged-concerns-002.yamlmerged-concerns-003.yamlac_flags 期望值都是空集合,理由 2026-09-16 標的時候寫在檔案裡。例如那張課程收藏的卡,四條 AC 都寫得具體、驗得了,description 裡順帶提到的排序需求是混進來的第二件事,該由 Scope 拆分處理,不算 AC 的問題,所以期望標註是空的(理由寫在 dataset/merged-concerns-002.yaml 的註解裡)。

agent 對這四筆跑了 11 趟,10 趟標了東西,只有 irreversible-push-002 的第 3 趟回了空集合。merged-concerns-002 三趟合計多標 8 個、irreversible-push-002 多標 6 個,precision 各 0%,recall 那一欄留空,因為人工一個都沒標,沒有東西可以被找到或漏掉。

別的卡上至少還有東西可以找,多標的還能說是找得太寬,這四張卡上卻沒有東西要找,它幾乎每一趟都還是標,一條寫得清清楚楚的 AC 也被標成沒寫清楚怎樣算做完。

要讓的話,改哪一行定義

這隻 agent 跟這支 scorer 裡都沒有信心分數或開關可以調,能動的只有 src/agent/prompt.ts 那份 system prompt 裡三類問題各一行的定義(src/agent/prompt.ts):

三類問題:
- conflict:這條 AC 跟另一條互相打架
- unverifiable:這條 AC 沒有寫清楚怎樣算做完
- mismatch:這條 AC 跟 description 說的不一樣

115 個多標裡有 104 個落在 unverifiablemismatch 這兩類,正好是定義寫得最鬆的兩行。「沒有寫清楚怎樣算做完」對任何一條不含數字的 AC 都成立,「跟 description 說的不一樣」在 description 根本沒提到那條 AC 時也成立。要往 precision 那邊讓,做法是把這兩行寫窄,例如要求 AC 得跟 description 裡某一句具體對得上才算 mismatch。

代價是 recall 會跟著掉,幅度可以從刪掉「每一條 AC 對三類問題各檢查一次」那一行的判別力檢查借來看,docs/day12-discriminative.md 記的是同一張優惠碼的卡三次合計,原版標對 8 個、刪掉那行之後 5 個,recall 掉了 25 個百分點,case 通過率兩邊都是 0/3。那筆是單張卡的數字,分母跟整份跑的 34% 與 78% 不一樣,能借的是方向。

這兩個數字之間的取捨,要當場做完

漏掉一條真的衝突,那條 AC 進 sprint 之後還有人會撞上它;多標到讓人不想看,是整個 AC 標註區塊被放棄,連真的那三分之一也沒有人讀。precision 34% 的意思是看卡的人每讀三個標註只有一個是真的,這個比例已經在放棄的邊緣。

所以往 precision 這邊讓,界線先寫成 recall 不掉破七成,這個數字是先訂下來的,改完重跑之後再看要不要動。ac_flags 判的是集合完全相同,多標一個就沒過,48 趟裡沒過的 45 趟有多少只差在多標,是改完定義之後第一個要重跑來看的。

總結

整份 16 筆 case 合計 45 趟的結果是 precision 34%、recall 78%,對上 60 個、漏標 17 個、多標 115 個,45 趟通過 3 趟。八筆 case 的 recall 是 100% 而 precision 只有 23% 到 60%,另外四筆人工標的期望標註是空集合,agent 11 趟裡標了 10 趟。這隻需求釐清 agent 的問題不在找不到,在它額外標出來的太多。

決定是往 precision 那邊讓,做法是把 src/agent/prompt.tsunverifiablemismatch 那兩行定義寫窄,界線是 recall 不掉破七成。這個決定還沒有數字驗證。定義寫窄之後 precision 會升多少、recall 會掉到哪裡,要等改完把整份 dataset 重跑一次才知道,七成這條界線守不守得住也是那時候才看得到。


上一篇
Day 16|四個欄位過了兩個,這筆 case 算 50% 還是 0?改完 prompt 該看哪個數字
下一篇
Day 18|判斷標準給了滿分,可是產出根本是錯的
系列文
30 天 AI eval 實戰:一隻 PM agent,改完之後怎麼確定它還是對的18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言