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