AI 協作系列|第 2 篇:給 AI 看的規則系統

承接 第 0 篇 的脈絡。

問題起點:每次都要重新說

用 AI 工具寫程式,有一件事很快就會讓人煩:每次新的對話,它什麼都不記得。

你上次告訴它「commit message 用繁體中文」、「不要用 enum,改用 as const」、「寫完要先跑 typecheck」——下次開一個新的 session,全部歸零。你要嘛重新說一遍,要嘛就接受它按它自己的習慣跑。

這是一個設計問題,不是模型能力的問題。AI 工具的 session 是無狀態的,它的「記憶」只存在當前這個對話窗口裡。

解法有幾種:每次貼一段說明、在 README 裡寫規範讓它讀、或者用工具提供的 system prompt 機制。我選了一個比較結構化的做法:建立一套叫 AGENT.HQ 的集中規則系統,位於各工具配置目錄的上層,讓三個工具(Claude Code、Codex、Antigravity)在每個 session 都載入同一套設定。


它做了什麼

AGENT.HQ 本質上是一套「寫給 AI 看的規格文件」。

它不是讓人讀的文件(雖然也可以讀),而是在每次對話開始時,被載入到 AI 的 context 裡——就像 system prompt,但更結構化、更容易維護。

裡面有幾種東西:

  • 操作規範:Agent 要怎麼工作——什麼時候要先查資料再動手、什麼時候要暫停問人、怎麼判斷一件事算「完成」。
  • 按需規則:特定情境下才載入的規則——做 React 開發時讀 React 規則、做 code review 時讀 review checklist。
  • 技術偏好:我習慣用的技術棧和理由——TypeScript、React + Vite,以及選這些的背景。
  • Skills:可以被呼叫的工作流程——比如「交付檢查」、「系統性除錯」、「寫 commit message」。

設計的核心取捨:塞多少進去

這個系統最難設計的地方不是「要放什麼」,而是「要放多少」。

塞太多的問題:每次 session 的 context 有限,全部塞進去就是在浪費 token(還是想省點成本)。而且很多規則其實沒有機會被用到——「iOS 無障礙規範」對一個純後端的任務完全沒用,但如果它佔了 context 的 5%,那個空間就沒辦法用在別的地方。

塞太少的問題:如果只有「要寫 TypeScript」這種基本指令,那和沒有差不多,AI 自己都知道這件事。

我用的方案是分層載入


三層架構

第一層:全域層(AGENT.HQ)

放的是,跨工具、跨專案都適用的原則。它裡面有一個「常載核心」——每次 session 都載入,內容盡量精簡,目前大概是 200 行。另外有一個需求對照表,定義了什麼情境觸發讀哪份規則,但那些規則平常不在 context 裡。

常載核心裡放的是原則,不是規則細節:怎麼判斷要不要暫停問人、怎麼定義「完成」、多個方案時要怎麼選。這些對任何任務都適用。

第二層:工具層(~/.claude/~/.codex/~/.gemini/

每個工具有自己的設定檔,主要做兩件事:一是把全域層的規則引入、二是記錄這個工具特有的設定(比如 Claude Code 有 hooks、有 MCP server,Codex 有 reasoning_effort 設定)。

工具層的設定要維持薄——它只負責「連接」,不應該有自己的規則本體。

第三層:專案層(repo/AGENTS.mdCLAUDE.md

每個 repo 自己的規範:這個專案的架構是什麼、命名規則是什麼、哪些操作是危險的。這層優先序最高——專案中說的,比全域層說的更準確,因為它是這個專案的事實。


今天改了什麼,為什麼

用了幾個月下來,有一些地方感覺不太對。

最明顯的問題:全域層有太多技術細節。React 的 patterns、TypeScript 的規則、code review 的 checklist——這些放在全域層,意思是「對所有任務、所有工具都適用」。但實際上不是。如果今天是在查一個 bug,React 的組件設計規則根本不需要在 context 裡。

所以今天把這些東西從「全域規則」降格成「偏好模板」。

新的概念是 preferences/——這裡存的是我的技術偏好,比如「預設用 TypeScript」、「前端選 React + Vite」、「用 pnpm 管套件」。這些不是規則,而是模板——開新專案的時候,可以從這裡取用、調整成適合那個專案的版本。

平常這些不在 context 裡。只有在做技術選型的時候、或進入一個新的陌生 repo 的時候,才會載入這份偏好清單作為參考。


專案啟動前置:缺口的補完機制

調整偏好層之後,有一個新的問題出現:全域層的偏好和專案層的規範之間,有時候會有缺口。

比如,一個比較新的 repo 裡沒有定義命名規則,但全域的偏好庫裡有一份我習慣的命名規則。這時候要怎麼辦?

我想到的做法是「專案啟動前置」:每次進入一個新的或陌生的 repo,讓 Agent 做一次差異比對——掃 repo 的現有規範,對照全域偏好庫,找出缺口,把缺的部分提議移植進去。

這不是強制覆蓋,而是「提議補齊」。Repo 已有的規範不動,repo 缺少的才補,補的時候也要調整成適合那個專案的表現方式,不是照搬。


這套系統最容易壞掉的地方

設計完一套系統之後,真正的挑戰是維護。

AGENT.HQ 最容易退化的地方有兩個:

膨脹:規則越加越多,常載核心越來越大,每個 session 的 context 越來越沒空間留給真正的工作。解法是有意識地設上限,超過就要刪等量的東西才能加新的。

漂移:文件裡引用的路徑、模型名稱、工具指令,會隨著外部的更新而過期。今天路徑是對的,三個月後工具改版了,就變成一個指向不存在地方的連結。解法是有一個定期跑的 audit 腳本,自動掃描懸空引用和版本過期。

這兩個問題沒有一勞永逸的解法,只能持續注意。但把這兩個問題定義清楚,至少知道要防什麼。


本文是系列的第 2 篇。第 3 篇 說 delivery-review 框架的設計思考。