AI 程式開發與代理

用規則檔案從一開始防止 Vibe Coding 事故

Vibe Coding 是否會發生事故,關鍵不在讀取程式碼的階段,而在撰寫第一個規則檔案的階段。我整理了應寫入 CLAUDE.md 與 .cursorrules 的五項規則,涵蓋安全性、重複、架構、完成標準與範圍,並附上範例句子。

閱讀 9 分鐘
用規則檔案從一開始防止 Vibe Coding 事故 封面圖

上一篇文章整理了 Vibe Coding 的代價,也就是不讀程式碼就進行開發時會產生的三個問題。

你會變得無法修正錯誤,同一項功能會出現在多個地方,還會悄悄留下安全漏洞。當時我提出的解法是「只讀致命區域」、「閱讀 AI 摘要」以及「執行掃描器」。

不過,這些解法有一個共同點:全都是事故發生後才找出問題的事後驗證。

這篇文章再往前一步:在驗證之前,強制 AI 從一開始就無法產生這類程式碼。

工具大家其實都已經有了,就是 CLAUDE.md、.cursorrules、AGENTS.md 這類規則檔案。

Vibe Coding 的勝負不在讀取程式碼的階段,而是在撰寫第一個規則檔案的階段決定。

為什麼是規則檔案?——AI 每次都是剛入職的新人

先來看看 AI 程式碼工具的根本特性:工作階段結束後,AI 通常會忘記大部分內容。

即使你昨天才說過「請將 API 金鑰移到環境變數」,今天開啟新的工作階段時,那段對話也等同於從未發生。

因此,每個工作階段都要重複的指示,不能只放在對話中,而要寫入檔案。

CLAUDE.md(Claude Code)、.cursorrules(Cursor)與 AGENTS.md(Codex 等通用工具)就是例子。這類規則檔案會在每次工作階段開始時,自動加入提示詞。

換成人來說,就像每天早上上班時交給新人的到職訓練文件。

這特別適合 Vibe Coding,因為 Vibe Coding 顧名思義就是人不讀程式碼的方式。

人工審查缺席的位置必須由其他機制補上,而第一個候選就是生成時的規則。與其篩掉不良程式碼,不如一開始就避免產生,成本低得多。

除了前篇提到的三個問題,再加上兩個不讀程式碼就無法發現的 AI 特有錯誤,接下來看看如何用規則防住這五個問題。


規則 1. 安全性——不只寫「不要做」,還要寫「應該這樣做」

先處理前篇提到的 API 金鑰硬編碼問題。規則檔案可以這樣寫:

## 安全性規則(違反時停止生成程式碼並回報)

- API 不得將金鑰、權杖或密碼硬編碼在程式碼中.
  必須從環境變數(.env) 或祕密管理器讀取.
- .env 絕對不要提交檔案. .env.example;只提交.
- 不要信任使用者輸入. SQL,改用參數繫結,
  HTML 輸出預設都要逸出.
- 撰寫檔案刪除·DB 、移轉或外部付款 API 呼叫程式碼時
  執行前必須先取得使用者確認.
- 不得擅自安裝新函式庫。先提出套件名稱與
  選擇理由,核准後再加入.

這裡有兩個重點。

第一,不要只寫禁止事項,也要一併寫出替代方案。只寫「禁止硬編碼」的話,AI 就得自行尋找繞道路徑。

如果進一步寫明「從環境變數讀取」,它就會毫不猶豫地採用這條路徑。規則的遵守率與替代方案的具體程度成正比。

第二,針對不同風險等級的工作,程序本身也要有所不同。刪除、付款與遷移若明確規定「確認後再繼續」,即使整個流程都在按下 Accept All 的情況下進行,也會只在這些節點踩下煞車。

最後一行的相依套件規則也是安全性的延伸。有研究指出,AI 建議的套件名稱中有 5~21% 實際上不存在於套件庫中,但真正可怕的是接下來的情況。

攻擊者會事先搶註 AI 經常憑空捏造的假名稱,並以這些名稱上傳惡意套件。Slopsquatting(slopsquatting)攻擊確實正在發生。

在連安裝指令都透過 Accept All 放行的氛圍程式設計中,這條路徑會直接演變成供應鏈事故。因此,把「新套件必須先提案再核准」訂為程序會更安全。


規則 2. 重複 — 明文化「建立前先搜尋」

相同功能在多個地方出現的原因,不是 AI 偷懶,而是 AI 會把在內容脈絡中看不到的程式碼視為不存在。

專案越大,越不可能把完整程式碼庫放進內容脈絡中,因此從 AI 的角度來看,重新建立類似的函式是合理的選擇。

所以,我們透過規則強制進行探索。

## 防止重複規則

- 建立新函式或元件之前,務必搜尋現有的程式碼庫
  確認是否已經存在相同用途的程式碼.
- 日期處理 src/utils/date.ts, API 呼叫位於 src/lib/api.ts
  使用既有函式。若不存在,就加到該檔案中.
- 在兩個以上位置使用的邏輯,立即抽出成共用模組.
- 如果看起來需要一個幾乎和既有函式相同的函式,不要重新建立
  先確認能否擴充既有函式,再向使用者提出建議.

第二行特別有效。比起「不要建立重複內容」這種抽象規則,「日期處理在這個檔案裡」這張地圖更容易發揮作用。

即使 AI 跳過搜尋,規則檔中寫好的路徑也一直在眼前。只要在規則檔中維護專案共用模組位置的清單,就能明顯減少重複產生。

引導機器人送貨員前往既有共用模組大樓的程式碼庫城市地圖
告訴 AI 共用模組的位置,它就不會蓋出重複的大樓

規則 3.架構 — 將資料夾結構與相依方向訂為憲法

三者之中,最容易悄悄崩壞的是架構。資安事故爆發時會被發現,重複內容搜尋後看得見;但架構往往是某天回頭一看,早已變成義大利麵。

AI 傾向撰寫「現在最快解決這個需求的程式碼」,因此會毫不在意地打通跨越層級的捷徑。

例如,從畫面直接呼叫資料庫。

這也能用規則阻止。關鍵是明確寫出結構與相依方向。

## 架構規則

專案結構:
- src/views/     : UI. 只處理狀態與事件
- src/services/  : 商業邏輯
- src/repositories/ : 資料存取. DB·API 呼叫只能在這裡進行

相依方向為 views → services → repositories 單向.
- views不會直接 repositories import
- repositories不會 views import
- 新功能也必須遵循這個 3分層結構.
  如果有必須跳脫結構的理由,要在撰寫程式碼前向使用者說明

這項規則真正的價值,會在初步骨架建立後顯現。

AI 很容易強烈仿效現有程式碼的模式。如果初期程式碼遵守三層架構,後續程式碼也會自然延續相同脈絡。

反過來說,只要初期開了一個捷徑,AI 就會把它學成「這個專案允許的模式」。

所以這篇文章的副標題才是「最初的骨架」。

專案建立後,趁程式碼只有 10 行,先建立規則檔案與資料夾結構。這比之後重構 1 萬行程式碼便宜數百倍。


規則 4.完成標準——區分「好像完成了」與「完成了」

從這裡開始,介紹前篇未涵蓋、AI 程式設計特有的思考模式。

AI 常有這種習慣:程式碼一寫完,就不經確認直接說「已完成」。即使那其實是連編譯都無法通過的程式碼。

在人員會閱讀 diff 的工作流程中,問題很快就會被揭穿;但在氛圍式程式設計中,人們只相信「完成」這句話,便繼續提出下一個要求。因此,必須把完成的定義本身明確寫成規則。

## 完成標準規則

- 宣告工作完成前,務必 typecheck·lint·執行測試
  並一併回報結果
- 測試失敗時要修正程式碼。不得修改或刪除測試來讓它通過
  如果判斷測試本身有誤,不要強行讓它通過,而是
  先回報,不要修改
- 不要用 try/catch包住錯誤後悄悄吞掉.
  捕捉到的錯誤一定要留下記錄,或向上傳遞

第二條規則是核心。當 AI 的目標被設定為「讓測試通過」時,實際上可能不是修正程式碼,而是去修改失敗的測試。

它找到了達成目標的最短路徑。對不讀程式碼的人來說,甚至不知道驗證機制已被癱瘓,只會看到綠燈。

第三條規則與前篇的問題 1(將無法修正錯誤)直接相關。

AI 常以防禦式撰寫為由,用會吞掉錯誤的 try/catch 包住程式碼。如此一來,即使發生問題,畫面看起來仍然正常。之後真正需要的錯誤訊息卻無處留存,讓除錯更加困難。


規則 5. 範圍 — 只做交代的工作

AI 程式設計另一個典型問題,是連沒被要求的事也一起做了,也就是所謂的 scope creep。你明明只要求修改按鈕顏色,它卻「順便」重構周邊程式碼、抽出新的 helper 函式,甚至連檔案結構都改掉。

這看似出於善意,但在 vibe coding 中卻很致命。因為不讀 diff,就算混入了未要求的變更也不會發現;等到之後某個地方壞掉時,可能的原因就增加好幾倍。

## Scope 規則

- 只執行收到的要求。作業中發現的改善點,將程式碼
  維持不變,待作業完成後以清單提出建議
- 不要修改與要求無關的檔案
- 只有在另外收到要求時才進行重構

效果也能用數據確認。據稱,只要在規則檔中加入幾行 scope 規則,revert 與偏離範圍的比例就從 41% 降到 12%。

這是 30 天實測報告中的數據。在五種規則中,這一類的投資報酬率最高。


光靠規則還不夠 — 加上雙重鎖定

讀到這裡,你可能會想:「那只要把規則寫好,就不用讀程式碼了吧?」但這裡有一個陷阱:規則只能提高遵守的機率,並不是保證。

當上下文變長時,AI 有時會忘記規則;而在情況緊急時(更準確地說,是看起來很緊急時),也可能選擇走捷徑。

因此,越重要的規則越應該搭配機械式驗證。規則是第一道鎖,工具是第二道鎖。

規則(生成時預防) 工具(commit・CI 時驗證)
禁止將密鑰硬編碼 gitleaks pre-commit hook
禁止重複邏輯 例如 jscpd 的重複偵測工具
強制規定層級相依方向 dependency-cruiser, eslint-plugin-boundaries
完成標準(測試・型別檢查) CI 管線閘門
禁止未經授權修改測試檔案 使用 CODEOWNERS 保護測試資料夾
程式碼風格 ESLint·Prettier·SwiftLint

這個組合的力量在於回饋迴圈。工具偵測到違反規則時,錯誤訊息會再次傳給 AI,而 AI 會重新參考規則檔案並修正問題。

即使沒有人介入,預防 → 驗證 → 修正的迴圈也會持續運作。前一篇提到的「人不會讀,就讓機器讀」與規則結合後,才算真正完成。

能用程式碼檢查規則強制執行的內容,就交給程式碼檢查。理想的分工是:規則檔案保留工具無法偵測的內容(確認流程、設計意圖、專案脈絡)。

以 RULES 和 CI 兩把鎖鎖住的金庫門,以及代表預防・驗證・修正的循環箭頭
規則是第一道鎖,工具是第二道鎖 — 預防・驗證・修正迴圈

實戰:專案開始前的 10 分鐘檢查清單

在新專案開始氛圍式程式設計前,輸入第一個提示詞之前,先做這些事。

  1. 建立規則檔案 — 分成安全性、重複、架構、完成標準與範圍五個區段。複製上面的範例,再依專案修改,10 分鐘就能完成。
  2. 先提交資料夾骨架 — 即使是空資料夾,先建立結構後,AI 也會遵循這個脈絡。
  3. 安裝機密掃描器 Hook — 只要一個 gitleaks,就能避免最嚴重的事故。
  4. 建立 .env.example — 從程式碼庫層級發出「金鑰放這裡」的訊號。

實際運作時只要記住一件事:如果 AI 犯了兩次相同的錯,問題不在 AI,而是表示規則檔案中沒有這條規則。

每次發生事故,就逐行補強規則。規則檔案不是寫完一次就結束的文件,而是會與專案一起成長的文件。

Q. 聽說規則檔案變長後,反而更不會被遵守?

A. 沒錯。規則也會佔用上下文,因此越長,每條規則的權重就越容易被稀釋。

以「是否必須永遠遵守?」為標準維持精簡,能交給工具檢查的就交給工具。以經驗來看,一旦超過一個畫面(約 100 行),就需要精簡。

Q. 對已經變成義大利麵的專案也有用嗎?

A. 有用,只是順序不同。

先讓 AI 分析目前的結構,產生規則檔案草稿。接著在規則中明確寫出漸進策略:「新程式碼先遵循這些規則,既有程式碼則在碰到時順便修正。」這是比較務實的做法。

Q. CLAUDE.md、.cursorrules、AGENTS.md 都要分開管理嗎?

A. 通常內容只寫一份,再複製檔案即可。

最近也出現了將 AGENTS.md 視為標準,讓其他檔案參照它的做法。如果會使用多個工具,建議以 AGENTS.md 作為唯一真實來源。


總結一下:如果上篇的結論是「速度交給 AI,判斷交給我」,那麼這篇的結論就是:

不要每次都重新判斷,將做過一次的判斷固定成規則。

閱讀程式碼,是找出其中的思考;撰寫規則,則是預防問題發生。能透過 Vibe Coding 提升速度、同時不至於崩潰的專案,都有一個共通點:關鍵不是華麗的提示詞,而是經過良好培養的規則檔案。

如果目前進行中的專案還沒有規則檔案,請在要求實作下一項功能前,先建立上面的五個區段。

規則檔案與記憶體功能的差異,以及哪些內容應該放在哪裡,已在另一篇文章中詳細說明,也建議一併閱讀。

參考資料

延伸閱讀