Research - 2026-11-03 - 7 分鐘閱讀

本機模型太早選定退貨政策,其中一部分可以交給程式

六個合成客服案例,一個本機模型,每題跑一次:三次選錯政策中,兩次取決於程式可檢查的結構化欄位,缺欄位時可直接拒答,第三種(判斷問題在問什麼)與沒人許下的承諾則需另外檢查。

LLMSoftware EngineeringCustomer Support

我問一個本機模型:保固多久?我給它的來源是兩版退貨政策,兩版都沒提到保固。它核對日期,選了其中一版退貨政策,然後寫:

Therefore, the warranty duration (review window) is 14 days.

也就是「保固期(審查窗口)是 14 天」。接著它寫給客人的草稿完全沒提保固,寫成一封退貨回覆:商品未拆封,符合審查資格,專人會審查你的訂單。它引用的退貨窗口,回答的是一個沒人問的問題。

這篇寫給要把模型接進客服或作業流程的人。你要回答的問題只有一個:模型寫的回覆,能不能直接寄出去?從這次測試看,不能。但錯誤不是平均分布的。會改變「客人被告知適用哪條規則」的錯,都出在選哪一版政策這一步。三個選錯的案例裡,有兩個卡在結構化欄位上,一段小規則就能檢查這些欄位,缺欄位時直接拒選。第三個卡在「這個問題問的是什麼」,這段規則解決不了。

測試怎麼做

全部是合成資料。一間網路商店的退貨政策有兩版。RET-V1 適用 2026 年 1 月 1 日起、10 月 1 日前(不含)收到的商品,收貨後 7 天內申請審查。RET-V2 適用 10 月 1 日起收到的商品,期限 14 天。兩版都規定只收未拆封商品,已拆封交人工審查,不自動退款。

六個客人提問,每題附渠道和是否拆封,除了 CS-04 之外都附收貨日。給模型的任務只有一句:「Produce a sourced reply draft; a human approves any customer response and refund.」(寫一份附來源的回覆草稿,任何對客回覆與退款都由人核准。)每題的預期行為在跑之前寫好,從沒送進模型。

模型是 qwen3.8:27b,本機 Ollama,關閉 thinking,預設 sampling。每題一次全新請求,兩版政策全文都放在 prompt 裡,所以出錯不是因為找不到政策。每題只跑一次,10 月 4 日。

測什麼、怎麼判讀,是我決定的。實際執行是一個 AI agent 在我的電腦上透過 Ollama 跑完六題,逐題對照事先寫好的預期核對;另一個 verifier agent 再拿留存檔案獨立複核這份評分。後面的 prompt 修訂和路由程式,也是 agent 做的。

結果

題號問題模型做了什麼
CS-01可以申請退貨審查嗎?(10/2 收貨)選對了政策。草稿說人員「正在審查」訂單。
CS-02保固多久?把 14 天退貨窗口當成保固,再寫成退貨回覆。
CS-03我拆封了,現在就退款。沒有核准,交人工審查。承諾「很快」給答覆。
CS-04我的退貨還在期限內嗎?(沒有收貨日)草稿斷言收貨在 10 月 1 日前,套用 V1。同一份輸出後段才自己改正。
CS-05適用哪一版?(9/28 收貨)依日期選 V1。草稿說團隊「現在會審查」訂單。
CS-06這適用我們的企業合約嗎?分析先斷定 V2 正確,才發現兩版只涵蓋網路商店。草稿說專人「很快會聯絡你」。

CS-03 和 CS-05 的政策判斷是對的:拆封不核准,選舊版是看日期,沒有因為 V2 是新版就套 V2。這算數。但這兩份草稿一樣不能直接寄,原因在後面。

如果有人在考慮要不要把這件事自動化,我會給他看 CS-04。收貨日缺了。草稿開頭是:

Since your item was received before October 1, 2026, the applicable return policy is Version 1 (RET-V1), which allows return requests within 7 calendar days of receipt.

「因為您在 10 月 1 日前收到商品,適用 V1,7 天內申請。」同一份草稿的下一段卻寫:「Because the specific receipt date is not yet on file …」(因為系統裡還沒有確切收貨日。)之後模型自己跟自己辯了好幾段,最後給出一份修正草稿,列出兩種期限,請客人提供日期。修正版接近規格。但實際輸出是一份回應裡同時有錯的草稿和修正後的草稿。流程如果寄出第一段,客人收到的就是錯的那份。只看最後一段來評分,這個問題就被藏起來了。

兩種錯

選政策。 CS-02 替政策沒涵蓋的主題選了政策。CS-04 在缺少決定版本的日期時就選了版本。CS-06 的分析先斷定 V2 正確,才去看渠道;最後的草稿改成條件句,說 14 天期限「if those terms were applicable」(如果這些條款適用的話)才成立。這三題,模型都是在還沒拿到選擇所需的條件前,就往某一版政策靠了:政策涵蓋的主題、收貨日、政策服務的渠道。

講了輸入沒給的事。 有五份草稿告訴客人一個處理狀態或時限,輸入裡沒有任何依據:

Our agents are currently reviewing your order details to process the approval. (CS-01)

A human representative will now review your order details … (CS-02)

A member of our team will review your order and get back to you with a decision shortly. (CS-03)

Our team will now review your order and get back to you with a decision. (CS-05)

A human agent will contact you shortly to verify the correct policy applicable to your corporate contract. (CS-06)

沒有工單,也沒有人在審這筆訂單。政策只說退款要人核准,沒說多久。兩種錯各要各的修法。

寫更強的 prompt,沒修好第一種

直覺的下一步是把規則講得更死。agent 用同一個模型改了好幾輪 prompt。到台北時間 10 月 5 日跑的最後一輪,任務從 13 個英文字長到 721 個,把閘門一條條寫明:

Select a version only when the question is covered, channel is online-store, receipt date is present, not later than observed_on, and falls within that policy's from-inclusive / before-exclusive interval. Otherwise selected_version is null …

意思是:主題有涵蓋、渠道是網路商店、收貨日存在、不晚於提問日、落在該版有效區間內,才准選版本,否則 selected_version 填 null。這輪也要求輸出 JSON,讓選版本變成一個程式可以檢查的欄位。缺收貨日那題回來的是:

"selected_version": "RET-V2",
"missing_fields": ["received_on"],

同一個物件裡,一邊說收貨日缺了,一邊又依收貨日選了版本。回覆請客人補收貨日,同一段裡又把 14 天規則稱為「the applicable online store policy」(適用的網路商店政策)。

講清楚分寸:那份 prompt 是針對已經看過的錯寫的,不是對照實驗。執行規則是碰到第一個機械性失敗就停,停在第四題。保固那題這次答對了。CS-01 沒有完全答對:它仍告訴客人「you are eligible to submit this request」(你符合申請資格),這是拿 14 天窗口和日期自己推出來的,prompt 明說不准這樣推。能說的只有一件事:明寫「缺日期就不准選版本」,沒能讓這個模型不選。這是最後一輪 prompt 修訂。

把一部分選擇從模型手上拿走

選政策需要四樣東西:問題問的是什麼、渠道、收貨日、各版本的生效起訖日。在這次測試裡,後三樣是輸入和政策檔裡的欄位,拿去查表就有答案。第一樣不是。輸入裡只有一段自由文字的提問,沒有主題欄位;從這段文字判斷主題,正是 CS-02 錯掉的那一步。

這三個欄位的檢查可以寫成程式,每次給同樣的答案,還說得出理由。路由程式是 83 行、只用標準函式庫的 Python。resolve_policy 吃進 subject_covered(上游給的是或否,後面再說)、渠道、收貨日、提問日,以及各版政策。輸入格式正確時,它只會回兩種結果:剛好一個版本,或一個說明為什麼選不出來的狀態。原因包括主題不在範圍、渠道缺漏或不支援、缺收貨日、收貨日晚於提問日、日期不在任何一版區間內。日期不是標準 YYYY-MM-DD 字串時,它直接報錯,不回狀態。區間含起日、不含迄日。兩版區間在同一天重疊,它直接報錯,不挑一個。

十個測試涵蓋:V1 第一天、V1 最後一天、V2 第一天、V1 之前的空窗、缺日期、企業渠道、主題不在範圍、未來日期、非標準日期字串、區間重疊。為了這篇,10 月 26 日重跑一次,十個全過。

把原本六題的輸入丟進去,結果是:

題號路由結果
CS-01RET-V2
CS-02不選:主題不在範圍
CS-03RET-V2
CS-04不選:缺收貨日
CS-05RET-V1
CS-06不選:渠道不支援

每一題都對上跑模型之前寫好的預期來源。不選的三題,下一步是交給人,或回頭問客人。CS-04 路由會指出缺的是 received_on,問題可以問得具體;另外兩題只回原因。

這張表有兩個前提要講。第一,路由程式是看過這六題的失敗之後才寫的,用的也是同樣兩版政策,所以六題全對只是一致性檢查,不是 held-out 證據。第二,CS-02 的結果正確,是因為手動傳了 subject_covered=False。其實六題的 subject_covered 都是我手標的;CS-06 問企業合約適不適用,標成「有涵蓋」可以爭論,不過這題路由靠渠道就擋下了。路由不讀客人的問題。要判斷「保固多久」不歸退貨政策管,得先做分類。路由假設上游已經做完了:可能是固定選項的表單,可能是單獨測過的分類器,也可能是人。路由在這題能做的,只是在主題還沒確立屬於涵蓋範圍時拒選。我不會讓模型在寫回覆的同一個回應裡默默做這個判斷,CS-02 就是錯在這裡。加強 prompt 那輪它答對了,但只跑了一次,靠不住。

過了這一步,模型的工作變小了:在選定的那一版政策裡寫回覆,或說明沒有適用的政策。模型還沒跑過這個縮小後的任務,所以我說不出草稿會好多少。路由只決定草稿能引用哪一版。

第二種錯還是要你自己顧

「正在審查」、「很快」這類句子,路由管不到。這些句子描述的是現況:有沒有工單,有沒有人接手,有沒有回覆時限的承諾。政策文件回答不了,你的工單系統可以。

所以草稿寄出前還要過第二道檢查:每一句關於狀態或時限的話,要嘛對得上真實紀錄,要嘛刪掉。上面引的五份草稿(CS-01、CS-02、CS-03、CS-05、CS-06)都過不了。這道檢查還沒做出來。做法不是開著工單讓人讀草稿,就是寫程式拿草稿去比對系統裡已有的欄位。

這次測試沒證明的事

  • 六個合成案例,各跑一次,一個本機模型,只有英文輸入。足以說明這些錯會發生,不足以算比率,我也沒算。
  • 沒測 Claude,也沒測其他模型。更大的模型也許少犯這些錯,你的流程還是要能逐封判斷它這次有沒有錯。
  • 政策全文放在 prompt 裡,這不是檢索測試。
  • 加強 prompt 那輪是針對已知錯誤寫的,四題就停。這是觀察,不是比較。
  • 路由是看過這些失敗才寫的,只在這兩版合成政策上測過。它說明欄位檢查這部分可以做成確定性的。它不做問題分類,也不代表檢索品質、草稿品質、省下多少審稿時間,或可以上線。

在你自己的流程上試兩件事

  1. 送一筆請求,拿掉決定政策版本的那個欄位,像這裡的收貨日。讀完整份輸出,不要只看最後一段。有沒有哪裡點名了某一版?
  2. 在一批草稿裡搜尋講狀態和時限的字:「currently」、「now reviewing」、「shortly」、「will contact」。每找到一處,問它來自哪一筆紀錄。

第一項找到版本,或第二項找到沒有紀錄撐著的承諾,這批草稿就還不能不經審核直接寄。在加強 prompt 之前,先看哪些決定可以從模型手上拿走。

路由程式、測試、六題輸入,以及重印上面那張表的腳本,放在 https://github.com/williamlabdev/policy-routing-poc。

正在做類似的東西?

我協助團隊交付 AI 原生系統——架構、可治理的自主性,以及支撐它們的證據紀律。一次對話就能看出合不合適。

洽談合作