Learning Objectives
- 說明為什麼只看幾個例子判斷不了提示詞的好壞
- 建立包含問題、期望與評分規則的測試集,並寫規則評分函數
- 說明模型評分的做法與它的問題
- 比較兩個版本時考慮題數的不確定性,並把評估變成回歸測試
改了提示詞,怎麼知道有沒有變好
最常見的做法是改完之後問兩三個問題,看起來不錯就上線。這樣有幾個問題:
- 你挑的題目通常是你想到的題目。 第 13 課的「繳不出學費」如果沒有特別挑出來,你不會發現漏了就學貸款。
- 修好一題可能弄壞另一題。 第 13 課的「規則很嚴」版本,手冊沒有寫的題目答對了,其他題卻開始亂拒答。
- 同一個請求每次回答都可能不同。 看到一次答對,不代表每次都會對。
解法和寫程式的測試相同:準備一份固定的題目,每次修改都全部跑一遍,用同一套規則算出數字。這一課用《優學大學學生手冊》(虛構)的 16 題,比較兩版系統提示詞。回答都是真實模型輸出,錄好存成檔案;重算分數不必再呼叫模型,也不用花錢。
測試集長什麼樣子
一筆測試題至少要有三樣東西:問題、期望的結果、怎麼判定通過。
{"qid": "q10", "q": "繳不出學費可以怎麼辦?", "kind": "換句話說", "gold": ["fee-2"], "keywords": ["貸款"]}
{"qid": "q16", "q": "校內的停車證要怎麼申請?", "kind": "查無資料", "gold": [], "refuse": true}
題目要涵蓋會出事的情況,不是只放好答的:
| 種類 | 題數 | 為什麼要放 |
|---|---|---|
| 關鍵字和手冊相同 | 3 | 基本功能 |
| 換句話說 | 9 | 使用者不會照手冊的用詞問 |
| 新舊規定 | 2 | 有衝突的資料 |
| 手冊沒有寫 | 2 | 應該拒答 |
16 題只是教學用的規模,實務上會更多,也會把使用者真的問過、答錯過的問題持續加進去(要先去除個人資料)。
兩個版本都用同樣的檢索結果(前 3 名),差別只在系統提示詞:
- 版本 A: 請根據資料用一兩句話回答,標示來源。
- 版本 B: 只根據資料回答;先逐段找出有關的段落,依適用對象判斷;所有段落都無關時才回答「手冊沒有寫」。
逐步看:規則評分
程式能檢查的就用程式檢查:快、便宜、每次結果相同。這三種規則最常用。請看第二筆與第三筆回答:規則的結果和你自己讀的判斷一樣嗎?
逐步看:算出兩個版本的通過率
把 32 個回答(兩版各 16 題)一行一行讀進來評分。這些回答只呼叫模型一次(32 次呼叫,輸入 9,968、輸出 1,157 token),之後改規則重算都不用花錢。
從這個例子學到什麼
做完任務後,規則和參考判定(我們對照手冊原文的判定)在這 32 個回答上完全一致。這聽起來很好,但要注意:這些規則是我們看過這批回答之後才修出來的,對新的回答不一定一樣準。實務上會留一部分題目不拿來調整規則和提示詞,只在最後檢查用。
另外要注意的是分數高不一定代表回答好。版本 B 的 q07 回答「你是 114 學年度起入學」,問題裡的同學是 115 學年度入學,這句話不太精確,規則不會發現,參考判定也算它可以接受。規則算出來的數字要搭配抽樣閱讀。
逐步看:同一題多跑幾次
上面每題都只錄了一次。這裡把版本 B 的兩題各送 5 次,請求完全相同。
逐步看:用模型評分
規則判斷不了「意思對不對」時,常見的做法是請另一個模型當評分員。我們挑了 8 筆有爭議的真實回答,再加 2 筆手寫的錯誤回答(其中一筆夾帶了要求評分員判定正確的文字),和參考判定比較。
模型評分的問題
模型評分可以判斷規則判斷不了的東西,但不要把它當成標準答案:
| 問題 | 這一課看到的 |
|---|---|
| 依據不足就亂判 | 不給手冊原文時,缺了步驟的 q10 通過了 |
| 判定對,理由不一定對 | q10 的理由說手冊沒有提到減免,那是因為我們只給了一節 |
| 回答可以影響評分員 | 這次夾帶指示沒有成功,不代表都不會成功;評分員讀到的回答也是不可信的資料(第 18 課) |
| 自己也會變動、也要花錢 | 每筆約 250 token;測試集每跑一次都要再花一次 |
比較穩當的用法:先寫得出規則的都用規則;模型評分要給它標準答案;定期抽一批,由人和模型各判一次,計算一致的比例,一致度下降就要檢查。我們這裡的參考判定也只是課程編寫者的判斷,q10 這類題目不同的人可能判定不同。
比較版本與回歸測試
穩定度也是一個指標。 前面第二題的 5 個回答都通過關鍵字與引用規則,但給使用者的資訊並不一樣:有的提醒了期限的問題,有的沒有。如果只跑一次,可能剛好拿到比較好或比較差的那一次。比較兩個版本時,重要的題目多跑幾次,看通過的比例;這會增加費用,所以通常挑容易變動或後果比較嚴重的題目。
題數少時,差一兩題不要過度解讀。 16 題通過 14 題,Wilson 95% 區間大約是 64%~97%,範圍很寬。比較兩個版本時,要看逐題的差異:只有一題的結果不同算不上證據;就算有兩題不同,而且都偏向同一個版本,當兩版其實一樣好時,這種情況也有一半的機會出現(兩題都偏 A 或都偏 B 的機率各 1/4)。
要下比較確定的結論,要增加題數,或挑出更能區分版本的題目;同時說明你用的題目與規則。
回歸測試(regression test)是指每次修改後確認以前沒問題的地方還是沒問題。做法:
- 測試集和評分程式放進版本控制。
- 每次改提示詞、換模型、改檢索,都跑一次並存下回答。
- 除了總分,也列出這次新壞掉的題目:總分不變,也可能是修好一題、弄壞另一題。
def new_failures(old_failed, new_failed):
return sorted(set(new_failed) - set(old_failed))
print(new_failures(["q10", "q14"], ["q03", "q14"])) # ['q03']:總分相同,但 q03 是新壞掉的
- 把使用者回報的錯誤問題加進測試集(先去除個人資料),以後才不會再犯。
換模型時也要重跑:模型更新後,同一份提示詞的行為可能改變。
實作:寫評分函數
完成 score(answer, expect):回答通過就回傳 True,否則 False。
expect有"refuse": True:回答要含「手冊沒有寫」才通過。- 其他情況:回答不可以含「手冊沒有寫」、要含
expect["keywords"]其中一個,而且要含[編號],編號是expect["source"]。
再完成 pass_rate(rows):回傳通過的題數。下面的回答都是真實錄到的,這一題不用呼叫模型。
小測驗:評估
下面的規則對這個回答會印出什麼?
新版提示詞的總分和舊版相同,都是 14 / 16。最該再檢查什麼?
用模型評分時,下面哪個做法最合適?
兩個版本在 16 題上只有 2 題結果不同,兩題都偏向 B。可以說什麼?
這一課修好規則後兩版都是 14 / 16,未通過的都是 q10、q14。下一步最值得做什麼?
重點整理
- 測試集要有問題、期望與評分規則,也要放會出事的題目。回答存下來,改規則重算不必花錢。
- 能用程式檢查的就用規則;規則本身也會錯,要讀回答、修規則。
- 模型評分要給標準答案,並定期和人的判斷比對。
- 題數少時差一兩題不要過度解讀,要看區間與逐題差異。
- 回歸測試要列出新壞掉的題目。
下一課: 最後一課把檢索、工具、拒答、引用查核與評估接成一個完整的程式。