Claude 自己捏造了 190 筆資料,又自己拆穿:能自我糾錯,卻過不了「看一眼」這關


這整件事,我沒有插手——抓到錯的是 Claude 自己。

coupons 專案剛部署完,進到資料探索的階段,先看看優惠券彙整站到底裝了什麼。Claude 第一個拿起的工具是 WebFetch,一種讓模型把網頁抓回來、順便摘要的抓取方式。它回了一份看起來很完整的清單:大約 190 筆優惠券,還附帶幾個「發現」——有重複的代碼(26551、26953 各出現兩次)、有一筆價格等於原價(16486 是 138/138)、每一筆都帶著到期日。

Claude 據此向我報告「約 190 筆」,並且已經在準備依這些發現去改 schema。其中重複代碼那一項特別有說服力,因為它正好印證了專案 CLAUDE.md 裡寫死的一條硬規則:code 不是唯一鍵——不同優惠券可能共用同一個代碼,所以不能拿 code 當識別。

如果停在這裡,這就是一個「AI 幻覺差點改動資料庫 schema」的普通故事。但它沒有停在這裡。

Claude 自己回了頭

Claude 換了 curl,取回原始 HTML 自己解析。結果是:

total coupon rows: 114
distinct codes: 114 | codes appearing >1: 0
same code -> DIFFERENT meal: 0
rows with price >= original_price (violates Zod): 0 []
expiry column present?: False

114 筆,不是 190。重複代碼是 0。價格違規是 0。到期日欄位,根本不存在。WebFetch 那份清單,整份是捏造的。它甚至把中文品名整批翻成了英文(原味蛋撻 → original egg tarts),而品名是接下來要做 CP 值迴歸的 key——等於還沒開始,就先把 key 打掉重來。

Claude 把這條教訓寫進了 memory:爬蟲必須解析原始 HTML,用模型摘要過一手,等於把幻覺寫進資料庫。

報 190、準備改 schema、回頭 curl、翻案、寫進 memory——這整條 loop 是 Claude 一個人走完的。我全程沒有介入。

一件事的兩面

我後來反覆想這件事,覺得它有兩面,值得分開講。

一面是,模型的自我糾錯能力,已經很不錯。Claude 對自己 WebFetch 的產出沒有照單全收,回頭用 curl 再驗一次,翻了自己的案。這個動作並不理所當然——很多工具給你什麼就是什麼,不會回頭查自己。光是這一點,就值得肯定。

但另一面是,AI 感知外界的方式,確實還有不足。它一開始會犯的這個錯——把一份幻覺清單當真,還從裡面「發現」了恰好印證專案規則的證據——對人類來說,根本不會發生。

你要問我,為什麼人類不會犯這個錯?我其實說不上來。因為對人來說,那就是「看一眼的事情」——把網頁打開、捲一捲、數字對一對,根本不會有人需要被告知「這份清單可能是捏造的」,一眼就能看出它真不真。但這個「看一眼」,對模型來說,是一道它還過得不太好的檻。

感知、接收、分析資訊這幾件事,對人和對模型,終究有不小的差異。

同一個差異,反過來又出現一次

同一個專案裡還有一件事,把這個差異襯得很清楚。三個來源站的 HTML 裡,全都找不到優惠券的到期日——因為到期日印在優惠券的圖片上。Claude 在 HTML 裡翻了三輪:用寬鬆的日期 regex、找每個表格最近的標題、精確搜尋「期限」字樣,全部空手而歸,因為這個資訊從 HTML 結構裡根本推不出來。

最後是我一句話點破的:「我常看的那個站,他的有效期限是在圖片上。」

這個資訊,AI 從 HTML 裡無論如何看不見;人,看一眼就知道。

邊界看清楚了,才知道怎麼分工

這也是我覺得很多人用不好 AI 的地方。面對一個感知上有落差、卻又確實會自我糾錯的東西,反應往往擺向兩個極端:要嘛把 AI 神化,以為它無所不能;要嘛把 AI 弱化,感覺還不如我自己來。

兩種都是浪費。真正需要的,是搞清楚各自的能力邊界在哪——哪些事「看一眼」是人的特長、該由人來,哪些事爬梳大量資料是它的特長、該交出去。把對的任務分給對的一方,成果才會最大化。

Claude 那天自己抓到自己捏造的數字,是它能力邊界裡「自我糾錯」那一側的展示;它一開始會捏造出那份清單,是同一條邊界「感知外界」那一側的展示。兩側都看清楚,下一次才知道:什麼該交給它,什麼該我自己看一眼。