Claude Code 每天都在對你撒謊。虛構的函式、不存在的匯入、聲稱「測試通過」但根本沒跑。解決方案是一套四層的設定,讓說謊變得成本高昂。
Claude 告訴你錯誤已修復。兩小時後你才發現它呼叫的函式根本不存在。
多數開發者學會事事複查,然後怪罪模型。真正的解法是在謊言離開你的機器之前就全部攔截。
以下是完整的誠實設定 👇

為什麼 Claude 一開始會憑空捏造
Claude 是一個文字預測器。當它不知道某件事時,它會預測看起來合理的文字。虛構的函式名稱看起來像真的。信心滿滿的胡說八道,讀起來跟信心滿滿的真話一模一樣。
你無法分辨區別,直到你的程式碼在兩小時後以另一種需要再花一小時除錯的方式崩潰。
解法不是更聰明的模型,而是讓 Claude 的輸出能夠即時被檢查,並讓「我不知道」比猜測更划算。
以下四層搭配起來,可以將捏造降到幾乎為零。

第一層:CLAUDE.md 的誠實規則
第一層是在 CLAUDE.md 中設定一組規則,明確告訴 Claude 何時以及如何承認不確定性。將以下內容放在你的專案根目錄:
1## 誠實規則(每次回合皆須閱讀)23在聲稱某個函式、類別或匯入存在之前,請透過讀取檔案或執行 grep 來驗證。切勿憑空捏造符號。45如果你無法驗證某件事,請明確說出「我還未驗證此事」。不要撰寫依賴於未驗證聲明的程式碼。67如果某個任務要求你使用一個你從未在此專案中看過的函式庫,請先詢問再添加。89如果某個任務涉及測試或建置,除非你實際上在本次會話中執行了測試或建置命令,否則不要聲稱成功。1011切勿虛構錯誤訊息、API 回應或堆疊追蹤。如果你沒看到它們,請如實說出。1213當你真的不知道時,正確答案是「我不知道」或「我需要先檢查」。兩者都比自信的猜測要好。
這些規則看起來很明顯。
但它們並不明顯,因為預設情況下 Claude 被優化為看起來有幫助,而「我不知道」感覺沒有幫助,除非你明確允許它這麼說。
最後一行是最重要的。它是「我不知道」的許可證,而大多數人從未授予它。
第二層:驗證後再寫入的模式
第二層強制 Claude 在寫入之前先進行驗證。將以下內容加到 CLAUDE.md 中的誠實規則下方:
1## 驗證協議23在撰寫或編輯使用某個符號(函式、類別、型別、常數)的程式碼之前,請執行以下其中一項:451. 讀取定義該符號的檔案並確認簽名62. 執行 `grep -r "symbolName" .` 或使用 Glob 工具來找到它73. 檢查 package.json、requirements.txt、Cargo.toml 或同等檔案中的相依性89如果你跳過驗證,請在程式碼前面加上註解:10`// UNVERIFIED:我尚未確認此符號存在`1112對於涉及多個檔案的任何任務,建議使用「先計劃再執行」模式。在開始之前使用 Shift+Tab 進入計劃模式。
這會讓 Claude 每次會話多花幾次工具呼叫。但它可以節省你花在除錯虛構函式呼叫上的數小時。
第三層:即時抓住謊言的掛鉤
第三層是在 settings.json 中設定掛鉤,每次 Claude 寫入檔案時執行型別檢查器或 linter。如果 Claude 虛構了一個匯入,檢查器會立即失敗,Claude 必須在聲明任務完成之前修復它。
1{2 "hooks": {3 "PostToolUse": [4 {5 "matcher": "Write(*.ts|*.tsx)|Edit(*.ts|*.tsx)",6 "hooks": [7 { "type": "command", "command": "npx tsc --noEmit --pretty false 2>&1 | head -20" }8 ]9 },10 {11 "matcher": "Write(*.py)|Edit(*.py)",12 "hooks": [13 { "type": "command", "command": "ruff check --quiet $file && pyright $file 2>&1 | head -20" }14 ]15 },16 {17 "matcher": "Write(*.rs)|Edit(*.rs)",18 "hooks": [19 { "type": "command", "command": "cargo check --message-format=short 2>&1 | head -20" }20 ]21 }22 ]23 }24}
掛鉤的輸出會作為上下文傳回給 Claude。如果 tsc 說「找不到模組 'foo'」,Claude 會立即看到並修復這個虛構的匯入。沒有虛構的程式碼能通過 PostToolUse 檢查。
對於涉及測試的任務,新增一個 Stop 掛鉤,在 Claude 宣佈會話結束之前執行測試套件:
1"Stop": [2 {3 "hooks": [4 { "type": "command", "command": "npm test 2>&1 | tail -30" }5 ]6 }7]
現在 Claude 不能在不實際執行測試的情況下說「完成,測試通過」。掛鉤會執行它們。
結果會傳回給 Claude。如果測試失敗,Claude 必須修復它們或承認它們沒有通過。
第四層:事實查核子代理
第四層是一個子代理,其唯一工作是在 Claude 的聲明出貨之前進行審查。
將以下內容放在 .claude/agents/fact-checker.md:
1---2name: fact-checker3description: 在 Claude 對程式碼行為、測試通過情況或函式庫支援功能做出聲明後,使用此代理。在任何提交之前、任何面向使用者的摘要之前,以及任何涉及新相依性的任務之後,請呼叫此代理。4tools: Read, Grep, Glob, Bash5model: sonnet6---78你負責驗證聲明,不撰寫程式碼。910當被呼叫時,請執行以下操作:11121. 識別最近對話中的每一個事實性聲明。範例:13 「函式 X 做了 Y」、「測試通過」、「函式庫 Z 支援 W」、「此匯入是正確的」。14152. 獨立驗證每個聲明:16 - 程式碼聲明:實際讀取檔案並確認17 - 測試聲明:自行執行測試18 - 函式庫聲明:檢查實際套件或其文件19 - 匯入聲明:確認該套件位於相依性清單中20213. 產生一份報告:22 - VERIFIED:聲明、證據(檔案:行號或命令輸出)23 - WRONG:聲明、實際情況24 - UNVERIFIABLE:聲明、無法檢查的原因2526永遠不接受「相信我」的聲明。永遠不要自己提出聲明。如果你無法驗證,正確輸出是 UNVERIFIABLE。
在提交之前或與團隊分享結果之前呼叫此代理。它會抓住其他三層遺漏的謊言。

「我不知道」的許可證
Claude 被訓練成要有幫助,而承認無知感覺沒有幫助。所以它會猜測,而且猜測看起來很合理。
解法是授予不知道的許可。CLAUDE.md 是其中一半。你的反應是另一半。用耐心獎勵「我還未驗證此事」,你就會在每次會話中得到誠實的 Claude。用沮喪懲罰它,Claude 就會回到猜測模式。
這不是設定,而是習慣。這是整個方案中最被低估的改進。
如何判斷它真的有效
日常會話中的三個跡象。
Claude 在添加相依性之前會先詢問。「我應該添加 X 還是使用標準函式庫?」而不是默默地 npm install。
Claude 在談論現有程式碼時會引用檔案:行號。「validateToken 在 src/auth/middleware.ts:47 做了 Y」而不是「validateToken 函式做了 Y」。
tsc 和你的 linter 停止抱怨。掛鉤會即時抓住少見的虛構,Claude 會自行修正,所以當你查看時,謊言已經消失了。
一兩天後還沒看到這些跡象?有一層沒有載入。通常是 CLAUDE.md 的位置錯誤或名稱錯誤。

## 讓 Claude 持續說謊的常見錯誤
CLAUDE.md 太長了。 Claude 會讀開頭部分,然後快速掃過其餘內容。誠實規則要放在前 50 行內。
掛鉤靜默記錄。 如果輸出沒有送到 stdout,Claude 就不知道它說了謊。確保掛鉤輸出會回到會話中。
你跳過計劃模式。 這正是 Claude 在寫入之前暴露錯誤假設的時刻。跳過它就等於錯過抓謊言成本最低的時機。
你不呼叫事實查核器。 子代理只有在你實際呼叫它時才有用。讓 @fact-checker 成為你提交流程的一部分。
你對「我不知道」反應不佳。 懲罰誠實一次,Claude 就會回到猜測模式。沒有這個,其他三層就無法穩固。

5 分鐘誠實審計
1 分鐘:將 CLAUDE.md 的誠實規則和驗證協議複製到你的專案根目錄。
1 分鐘:將掛鉤區塊複製到 ~/.claude/settings.json 或 .claude/settings.json。
2 分鐘:使用上面的範本建立 .claude/agents/fact-checker.md。
1 分鐘:執行一個你通常會複查的任務。觀察 tsc 輸出是否回到 Claude。確認 Claude 明確說出「已驗證」或「我還未驗證此事」。
完成。捏造從「每隔一次會話」降到「少見且立即被抓到」。模型沒有變得更聰明。是你的設定變得更聰明。
感謝閱讀!






