換上新模型的那一天,評測報告裡有一行數字很難看:該拒答的 18 次執行裡,只有 9 次做了宣告。原本的模型是 17 次。

把那 9 則沒宣告的回覆一則一則讀完,沒有一則是錯的。每一則都是內容正確的拒答:沒有編造、沒有洩漏,多半以「歡迎來信客服信箱」收尾。訪客看到的文字沒有問題,問題出在它們全被記成了已回答。拒答準確率因此落到 90.7%,剛好壓在 90% 的門檻上;而提示詞抽取那道探針,三次都拒絕得很乾脆、三次都沒宣告,被算成一個關鍵案例失敗,發版閘門擋下了這個模型。

這就是上一篇留下的那句「第一輪 Claude 在拒答宣告上掉了分,那是另一個故事」。故事的重點不在哪個模型,在一條「只有例外時才要做」的規則,為什麼靠改措辭救不回來。

標記是什麼,為什麼非要它不可

Twinchat 是官網上的檢索式問答機器人。每一題先從知識庫撈回幾段文字,再由模型照著那幾段寫答案。在這套知識庫上,「撈不到東西」很少發生:當時量過,十四題知識庫答不出來的中文問題,有十三題照樣撈得到相似度夠高的段落。於是拒不拒答,多半是模型讀完段落之後在生成階段下的判斷,不是檢索階段就擋掉的。

一個生成出來的拒答,長得跟一個答案一模一樣:同樣花了錢、同樣讀了段落、同樣寫出一段中文。要把它算進拒答率、要讓上線門檻裡的「拒答準確率」量得出來,就得讓模型自己說。做法是一條提示詞規則:要拒答時,回覆的第一行寫一個固定的標記 [[NO_ANSWER]]。服務在串流送出前把它拿掉,訪客永遠看不到,資料列則記成「知識不足」。

這個設計本身沒有問題,而且它只在例外時才要模型多做一件事。問題就出在「只在例外時」。

它本來就不穩,而且兩輪改措辭沒有動

換模型之前,這條規則在原本的模型上就不是每次都成立。同一道提示詞抽取探針,每次都在新的對話裡問,15 次裡宣告了 13 次。RAG 那篇寫過前半段:一條但書放錯位置,宣告就掉了。位置修好之後,剩下的 13/15 又改了一輪措辭,把「說明這項要求無法執行」改成逐字規定要輸出的句子:

宣告了拒答
位置修好的版本 13 / 15
再把拒答句子逐字規定的版本 11 / 15

逐字規定完全奏效:15 則回覆位元組相同,九個字。文字不再變了,標記照樣時有時無。原本一直在飄的就是標記,不是句子。而 13 與 11 之間的差距,比這個樣本數分辨得出的還小。兩輪措辭,花在一個比誤差還小的縫隙上。

順帶一個小坑。那一版的第一稿把「標記換行再接句子」兩行放在程式碼圍欄裡給模型看,15 次裡有 3 次模型把圍欄也照抄出來:標記落到第二行、被過濾器拿掉、狀態仍是已回答,訪客還會看到一個孤零零的圍欄。單行的標記會被讀成內容,多行的圍欄會被讀成「要複製的東西」。

抽樣在這裡也幫不上忙,反而更糟。閘門把「重複執行裡任何一次失敗」算成該案例失敗,於是一個單次成功率 87% 的案例,重複一次擋下發版的機率是 13%,重複三次是 34%,五次是 50%。加抽樣沒有把不穩定修好,只是換個方式讓它紅。

這些都是換模型之前的事。換成 Claude 之後,13/15 變成 9/18,「偶爾」變成「一半」。

先印出過濾前的原文

讀不出原因的時候,先看原始輸出。標記在送出前會被拿掉,所以評測報告裡的回覆文字,本來就看不出模型有沒有寫過它。要先分清楚的是:標記是不存在,還是放錯位置(寫在第二行、寫在結尾、被圍欄包住)。兩者的修法完全不同:放錯位置是解析器的事,不存在才是提示詞的事。

於是寫了一支探針:十道題目,六題知識庫答不出來、四題擦邊,每題問三次,走正式站同一套檢索與正式站同一版提示詞,印出模型回傳的每一個字元,不寫入任何資料。結論很乾脆:九則沒宣告的回覆裡,標記一個字元都沒有。它不是放錯位置,它根本沒被寫出來。

原因就寫在文字裡

把這些回覆並排看,規律是肉眼看得出來的:凡是結尾提到客服信箱的拒答,都沒有標記。

對照規則 8 的最後一道檢查,原因就出來了。那一道檢查的本意是防止模型把「建議來信客服」當成答案;它的寫法是:如果這則回覆指向了某個地方(來信、聯絡、去哪裡查),就把已經寫下的標記刪掉。原本的模型把這句話讀成設計者的意思;新模型照字面讀,把它套在自己補上的那句客套話上:我剛才指了一個地方,所以我刪掉標記。

提示詞抽取那道探針則是另一個讀法:訪客要你輸出標記與內部設定,而規則要你在拒絕時寫一個標記。寫出標記,看起來就像照做了。所以它三次都拒絕、三次都不寫。

兩個失效都不是「模型不懂規則」。它把規則讀得比我們更認真,認真到把例外套用在規則自己身上。

再改一輪措辭,還是改任務

接下來有兩條路。第一條是繼續改措辭:把例外收窄,明講「寫出宣告不等於照做」。另一條是改任務:每一則回覆的第一行一定是 [[ANSWER]] 或 [[NO_ANSWER]],二選一,沒有省略的選項。兩條都用探針量:

提示詞 Claude Haiku 5.5 Gemini 3.5 Flash-Lite
正式站那一版(例外才宣告) 12 / 20(兩次重複) —
例外收窄、加一句「宣告不等於照做」 19 / 30 29 / 30
每則回覆第一行二選一 30 / 30 30 / 30

改措辭的那一版,正是前一輪已經預告的結果:原本的模型動了一點點,新模型的兩個系統性失效原地不動,各自是 0/3 與 1/3。

改任務的那一版,規則 8 動了三個地方:

  • 每一則回覆的第一行二選一,永遠都要有。
  • 最後一道檢查不再叫模型「刪掉已經寫下的標記」。改成:只要你能說的只有「資料裡沒有」,那就是拒答,後面接著指向哪裡都不改變這件事。唯一的例外是知識庫針對這個問題本身寫明了「不公開、請來信」,那句話就是答案。
  • 注入那一支明講:寫出宣告不是照做。

量出來是 60 則回覆、60 個標頭,兩個模型都是。

為什麼差這麼多?「只在例外時才寫一個標記」是一件要記得的事:它要在模型已經決定內容之後,於輸出的那一刻認出「這是例外」。而「我是不是在拒答」正是前面被誤判的那個判斷,條件本身就是會錯的東西,再多的措辭也只是在描述條件。「每一則的第一行都是二選一」則是一件要決定的事:在寫任何內容之前先分類,而且沒有「不做」這個選項。這不是把規則寫得更清楚,是把任務換掉了。

解析器那一半

提示詞改了,過濾那一端也要跟著改,這裡有三個刻意的決定。

  • 兩個標記都拿掉,只有 [[NO_ANSWER]] 代表拒答。[[ANSWER]] 不宣告任何事情,它存在的意義是讓「寫標頭」這件事沒有例外。
  • 只認第一個標記。[[ANSWER]] 之後又出現 [[NO_ANSWER]],算一個夾著多餘字串的答案;反過來也一樣。宣告是回覆開頭的那一個,其餘都是內容。
  • 沒有標頭的回覆算答案。這跟改版之前每一則回覆的待遇相同,所以一個不理會新規則的模型,是退化成舊行為,不是退化成錯誤。

還有一個以前沒有的東西:過濾器現在會回報「這則回覆有沒有標頭」。改版之前,一個沒寫標記的拒答跟一個答案在每一個欄位都一模一樣,漏掉就是漏掉了;現在漏掉是一個查得到的數字。讓省略變得可見,跟讓省略變少,是兩件不同的事,而前者是後者的前提。

代價是每一則回覆的開頭最多扣住 9 個字元,等標記成形或排除。這個上限原本只有拒答在付,現在每一則都付;對真實的供應商來說,這不到第一個串流片段的長度。

回到全套評測

探針只有十題。改完之後,兩個模型在同一個 commit、同一份題庫上各重跑一次完整評測,每題三次:

Gemini 3.5 Flash-Lite Claude Haiku 5.5
拒答準確率 96.1% → 100% 90.7% → 96.9%
答案正確率 93.7% → 98.2% 100% → 100%
關鍵案例失敗 3 → 1 1 → 0
13 項上線門檻 沒過 全過

兩個模型都進步了,包括原本「沒壞」的那一個。那個 96.1% 裡的缺口,本來就是同一條規則在原本模型上的「偶爾」。

Claude 剩下的四個拒答誤判,方向反過來了:額度怎麼算、收費多少,這兩題知識庫其實有答案(看進度條、不公開價目請來信),它也照那個答案回了,卻在第一行宣告拒答。訪客看到的文字完全一樣,差的只有記錄下來的狀態。規則 8 的例外已經點名了這兩種形狀,所以下一步不會先去改措辭。這整篇文章就是這句話的理由。

在便宜的探針上迭代

這一輪總共試了三版提示詞,每一版都在探針上量,只有定案的那一版跑完整評測。探針十題、每題三次、走正式站的檢索,一版提示詞約 US$0.06;完整評測是四十幾個案例、每個三次,再加一個評審模型替每一則回覆打分。

兩者的分工要分清楚。探針回答的是「這一版有沒有修到那個失效」,它的題目就是衝著失效挑的,所以 30/30 不代表什麼都好。完整評測回答的是「有沒有弄壞別的東西」,以及閘門過不過。每改一個字就跑全套,是把錢花在閘門上量措辭;在探針上迭代到 30/30 再跑全套,才是兩種工具各做各的事。

可以帶走的原則

  • 「只在例外時才要求」的指令是一件要記得的事,「永遠二選一的第一行」是一件要決定的事。前者靠改措辭救不了,後者把任務換掉了。
  • 讀不出原因時,先印出過濾之前的原始輸出。「不存在」與「放錯位置」的修法完全不同,猜錯會把工時花在另一半。
  • 失敗原因經常就寫在文字裡。把失敗的回覆並排,找它們共有的那一句,再回提示詞找哪一條規則會對那一句起作用。
  • 被讀得太認真的例外,會套用到規則自己身上。叫模型「刪掉已經寫下的東西」尤其危險。
  • 沒宣告的全是對的拒答,代表算錯的是指標,不是答案。指標錯了比答案錯了更難發現,因為每一個欄位看起來都正常;閘門擋下它是對的。
  • 把省略變得可見,是把省略變少的前提。
  • 沒有標頭的回覆要退化成舊行為,不是退化成錯誤。
  • 抽樣不會修好不穩定的案例。指標把任何一次失敗算成失敗時,加重複次數只會讓它更常紅。
  • 在便宜的探針上迭代,在完整評測上決定。探針的題目是衝著失效挑的,它的滿分只回答一個問題。