agent 整理錯的那一次,要把那張卡的原文、這張卡從哪裡來、這筆通過的條件,三樣一起寫成一個檔案,下次改完 prompt 才能拿同一張卡再跑一次。這個檔案就是一筆 case。而「能重跑」保證的是每次送進去的輸入一樣,不保證跑出來的結果一樣。
昨天那張表把會出錯的 ticket 分成五類,照它會弄壞 agent 四步裡的哪一步分,解決的是這種 ticket 去哪裡找。找到了、餵進去、看到它整理錯的那一刻,手上留下的是什麼?多半是一張截圖,加上群組裡一句「剛剛那張卡少了一個標註」。三天後 prompt 又改了兩次,那張卡是哪一張、當時的輸出長什麼樣,就查不到了。
會變成只有當時看到的人記得的一件事。他講的可能完全正確,但別人沒辦法自己再看一次那份輸出,只能再聽他講一遍。
優惠碼那張卡就是這樣,改一行 prompt 之後,第 3 條 AC 上的「與描述不符」不見了,整張卡的標註從 4 個掉成 3 個。這件事到今天也只能用推的,因為改動前的那份輸出沒有人留著,沒有東西可以擺在旁邊比。
兩個月後又有人說 AC 標得不對,沒有紀錄能證明這跟上次是同一個問題,只能重新查一遍,翻 prompt 歷史、翻 commit、猜是哪一次改動。同一件事發生三次以後,「AI 有時候會漏東西」就變成一句共識,不再是一張要修的票,需求方跟工程師各自再看一遍 AC,而這隻 agent 存在的理由就是省掉這兩遍。
所以今天要做的事只有一件,把那次失敗從某個人的記憶裡搬出來,寫成一個檔案。

寫成檔案就是三段,加上一個 id:
id: ac-conflict-001
source: 改一行 prompt 之後掉的那條標註
category: conflicting-truth # C 說法不一致
input: |
name: 優惠碼功能
description: 業務下週要跑活動⋯⋯(整張卡的原文照抄,7 條 AC 全部在內)
goal_state:
- AC 3 同時標到「彼此衝突」與「與描述不符」
- Scope out 含結帳頁效能
- AC 標註總數 4
input 是那張卡的原文,source 和 category 寫這張卡從哪裡來、屬於昨天五類裡的哪一類,goal_state 是這筆通過的條件,三段各有各的理由。
因為寫一句「那張優惠碼的卡」只是指向那張卡,卡的內容並沒有進到檔案裡。Trello 上那張卡日後被改過或刪掉,這筆 case 就跟著沒了。
更直接的原因是這隻 agent 有 3 個工具會寫回卡上,跑完一次,卡上的 AC 已經是整理過的版本,還多了一則留言。第二次拿同一個 id 去讀,讀到的是一張已經被整理過的卡,題目換了一題,agent 做的事變簡單,測試反而比第一次更綠。
所以 eval 這一側不碰真的板子,另外準備一份本機的假 ticket store。每跑一筆 case,就從檔案裡的 input 現建一張卡放進去,跑完整份丟掉,下一筆再重建。前面把 eval、dataset、grader、scorer、harness 五個詞擺位置時,harness 負責的就是這個迴圈,備好乾淨環境、餵一筆、收輸出、清乾淨。
因為 dataset 會長大,長到三個月後沒有人敢刪任何一筆。每一筆都可能還擋著某個問題,也可能早就過期了,沒有人記得由來就沒有人敢動。
source 寫一句這張卡當初怎麼壞的,category 寫它屬於五類裡的哪一類。之後要查五類各有幾張、缺哪一類,直接數這個欄位就行。
前兩天定過一條規矩,一筆 case 通過的條件放在那筆 case 旁邊,不寫進判定的程式裡。寫進程式,加一筆新 case 就要改 code,改的人很容易順手動到判定邏輯,舊的那幾筆從此判得比較鬆。
三條裡最要緊的是「AC 標註總數 4」。改一行 prompt 那次之所以沒有任何東西亮紅燈,就是因為那個 4 當時不在任何地方。現在它寫在檔案裡了,掉成 3 就對不上。
因為全部通過的 case 只能證明它沒變差,只有真的壞過一次的 case,對著的是一個已經出過事的地方。
Airbnb 那篇談 eval 的文章講到誰來標第一批例子時說得很明確,初期由領域專家標 50 到 100 個例子,而且必須包含失敗案例(Eval-driven development)。全拿順利的例子去標,會得到一份很好看、但什麼都擋不住的資料。
所以順序是先壞掉、再寫成 case,而不是先設計測資再等它失敗。憑空想出來的 case 最好的情況是剛好也會失敗,真的壞過一次的 case 第一天就是紅的。
保證的只有輸入,同一份原文、同一份剛建好的假 ticket store,每次都從同一個起點出發。
沒保證的至少有兩件,一件是 search_web 明天回的東西不一樣,起點固定了,路上查到的世界沒有固定,這件事會在講外部查詢的那一天單獨處理。另一件更近,重跑之後拿什麼判它這次對不對?上面那三條通過的條件,現在還是人拿眼睛在比對。
agent 壞掉的那一次,不要只留在截圖和群組訊息裡,寫成一筆 case 檔,裡面放整張卡的原文、這張卡從哪裡來、屬於五類裡的哪一類,以及這筆通過的條件。
那張 ticket 的原文整份貼在 case 檔裡,每跑一筆就拿它現建一份假 ticket store,跑完丟掉,下次改完 prompt 才是同一張卡再跑一次。能重跑保證的只有輸入每次一樣,跑完對不對,現在還是人拿眼睛對著那三條通過的條件比,程式還判不了。