Back to posts

AGENTS.md / CLAUDE.md 寫作原則

我最早是去年底先讀到這篇文章 Writing a good CLAUDE.md,我也嘗試把公司專案的 AGENTS.md / CLAUDE.md 做大整理,後續開發的體感也都變得比較順暢。

再隨著專案的規模逐漸變大、模型越來越聰明以及 Agent 的工具更新,我發現 AGENTS.md / CLAUDE.md 不是寫完就放著了,而是應該跟著 Codebase 一起迭代,於是我也開始會注意每次開發完也要更新 AGENTS.md / CLAUDE.md,這樣 AI 保持跟開發者一致的知識或是開發習慣。

最近剛好又讀到一篇 aihao.tw 的 AGENTS.md 研究與實踐,裡面有些是我之前就知道的原則,想說乾脆來整理一下我覺得不錯的原則當作紀錄。

AGENTS.md 簡介#

一般來說,開發者在第一次接觸一個 Repo 的時候,通常都會去讀根目錄的 README.md,透過這份文件可以了解這個專案是個什麼專案,有哪些指令可以用,或是特殊的知識點。

AGENTS.md / CLAUDE.md (以下都統稱 AGENTS.md)就類似給 AI 讀的 README,但這份文件是要告訴 AI 這個 Repo 的開發習慣、能做不能做的事情是什麼等等的。

用 AI Coding 不外乎有幾個工具 Claude Code / Codex / Gemini CLI,每次啟動新的對話 AI 會去讀 AGENTS.md 作為初始載入的 Context。根據工具不同讀的檔案會不一樣,例如我常用的 Claude Code 讀的是 CLAUDE.md

建立 AGENTS.md#

在講原則之前,要先知道 AGENTS.md 的建立方式以及具體檔案位置。

基本上 AGENTS.md 是手動建立的,或者是在啟動 AI 的那個目錄下 /init 這個指令來建立。

以 Claude Code 來說會放在這幾個地方:

  • 使用者層級:~/.claude/CLAUDE.md
  • 專案層級:./CLAUDE.md(在 repo 的根目錄)

像是 Codex / Gemini CLI 的話也是有分「使用者層級」跟「專案層級」,檔案位置也是差不多的邏輯,再依自己需求去找就好了。

做到這裡其實我們就已經把 AGENTS.md 建立好了,但是 AI 可能還是像個不受控的實習生一樣很難配合,接下來要講的是,讓我們的 AI 可以很好進入狀況的 AGENTS.md 寫作原則。

兩種層級:使用者 vs 專案#

前面提到 AGENTS.md 分使用者層級跟專案層級兩種,這兩層想解決的問題不一樣,寫法應該分開。

使用者層級:跨專案通用,定義跟 AI 的協作習慣(溝通語言、工作模式、shell 工具偏好等)。設定一次、所有專案都會套用。

專案層級:綁定特定 repo,描述這個專案的脈絡(技術棧版本、歷史包袱、文件位置、流程規範)。每個 repo 都要重新寫。

下面的原則按層級分組——有些只屬於使用者層級,有些只屬於專案層級,有些兩層都適用。

以下幾條部分有資料佐證,部分是我體感上有效,實際應用要看你的專案情境調整,也歡迎大家一起討論。

通用原則#

少於 200 行,最好是 100~150 行#

Anthropic 官方就有建議 CLAUDE.md 要低於 200 行,否則過長的文件會佔用更多 Context,還會降低指令遵從度。

依照我自己實際的經驗也是,超過 200 行的時候滿容易失控的,反而越少行越能遵守指令,並且也有研究指出太長的話很容易被 AI 忽略部分的指令。

但 200 行只是一個建議值,不代表控制在 200 行就不會失控,我們還是要考慮到開啟對話的當下 AI 載入了多少 Context,我體感上比較好的做法是縮短到 100~150 行。

不要直接用 /init 產生的檔案#

前面有提到可以用 /init 來建立,但大多時候自動生成內容會有專案架構、查得到的資訊、重複描述可能已經有的資訊,這些佔用 context 的廢話可能會讓 AI 浪費更多 Token。

我們可以把 /init 生成的檔案當作草稿,但具體內容再自己修正過。

不要把排版或風格檢查的規則寫進 AGENTS.md#

叫 AI 用文字規則去檢查反而又慢又浪費 Token,有時候還會做錯,我們可以用 ESLint / Prettier 這類 linter 跟 formatter 去做。

使用 Claude Code 還可以搭配 hooks 讓 AI 改完程式碼之後自動觸發。

用英文撰寫可以節省 Token#

之前有實驗過整份文件用中文寫跟用英文寫,在載入對話的時候消耗的 Token 最多可以差 30%~40%,像 AGENTS.mdSkill.md 這種給 AI 看的東西寫成英文不只是省 Token,我體感上也覺得他理解力也比中文好一些些。背後的原因應該是這些 LLM 的訓練資料大多都是英文,自然對英文的理解力會比較好。

前一陣子也有看到一篇文章AI大模型的「中文稅」:中文比英文更費Token 為什麼?,證實了用中文確實比較燒 Token。

使用者層級原則#

描述協作偏好#

我試過不管哪套工具,預設都是很雞婆、很急著把事情做完的感覺,我的習慣是在「系統層級」的 AGENTS.md 定義跟我溝通的方式。

像我不喜歡 AI 直接寫程式,我希望 AI 先跟我討論確認沒問題再開工、回我中文,所以我寫了以下幾點:

- Always use zh-tw
- 除非明確要求實作,否則預設為諮詢和規劃模式
- 在執行任何程式碼修改前,必須明確確認使用者意圖
- 優先提供分析、建議和計劃,而非直接實作

慣用工具推薦(選用)#

如果有習慣的命令列工具,可以在「使用者層級」直接推薦給 AI,避免 AI 自己挑或從預設工具開始試。rg / fd 這類工具比 grep / find 速度快、輸出精簡,AI 一次命中需要的資訊、不用反覆嘗試,整體 token 消耗會降低。

像我自己會把 shell 工具跟 Python 套件管理寫進去:

## Shell Tools

Prefer these tools over traditional Unix equivalents. They are faster, respect `.gitignore` by default, and produce more parseable output.

| Task | Use | Instead of |
|------|-----|------------|
| Find files | `fd` | `find`, `ls -R` |
| Search text | `rg` | `grep`, `ag` |
| Search code structure | `ast-grep` | `grep`, `sed` |
| Interactive selection | `fzf` | manual filtering |
| Parse JSON | `jq` | ad-hoc Python |
| Parse YAML/XML | `yq` | manual parsing |

Rules:

- Use `jq` / `yq` for structured data. Do not parse JSON, YAML, or XML with regex.
- In scripts, CI, and agent workflows, avoid interactive tools like `fzf`; use non-interactive equivalents.
- If a preferred tool is missing, attempt installation when you have permission to modify the environment.
- If installation fails or is not possible, fall back to the traditional command and note it.

## Python Usage

Use `uv` for Python execution and package management.

Do **not** use `pip`, `venv`, `poetry`, or global `python` directly unless explicitly required by the environment.

| Task | Command |
|------|---------|
| Run a Python script | `uv run <script.py>` |
| Run inline Python | `uv run python -c '<code>'` |
| Run a Python module | `uv run python -m <module>` |
| Run a tool (pytest, ruff…) | `uv run <tool>` |
| Add a package | `uv add <package>` |
| Add a dev dependency | `uv add --dev <package>` |
| Remove a package | `uv remove <package>` |
| Sync environment | `uv sync` |

Rules:

- Do not install packages globally.
- Do not create virtual environments manually.
- Do not modify project dependency files (`pyproject.toml`, `uv.lock`) unless the task requires it.
- If `uv` is unavailable, install it when you have permission to modify the environment.
- If installation fails or is not possible, stop and report rather than falling back to global Python tools.

專案層級原則#

不要一次告訴 Claude 所有資訊,而是告訴他「如何找到重要資訊」#

如果 codebase 已經有 docs/README.md 之類的檔案,就不要把差不多的內容寫到 AGENTS.md,而是要告訴他去哪裡找。

有些情境需要讀指定的檔案,我會用提示路徑的方式,例如:

在撰寫任何程式碼之前,必須先讀取以下文件:

- docs/coding-style.md - TypeScript 型別宣告、Function 宣告、Component 結構
- docs/naming-conventions.md - 檔名與程式命名規範

只寫最常用的指令#

不要在 AGENTS.md 寫可能會用到的指令。

你以為你是在告訴 AI 這些指令「可以用」,但是 AI 會以為是「一定要用」,所以有時候會略過你直接執行那些指令。

像我比較常做前端開發,我就只會寫 pnpm dev 或是 pnpm build 這兩個指令。

描述 WHY 或是交接重要資訊#

交接重要資訊可以幫助 AI 在讀程式碼的時候了解「為什麼這裡這樣寫」,這樣 AI 動手之前就先有一些脈絡而不會自己腦補。

要描述在開發的時候需要知道的事情,例如:

  • 技術棧細節版本:「本專案使用 React 18 + Tailwind CSS 4 + Vite 5.x」
  • 歷史脈絡:「本專案使用 React 18,但 X 模組仍是 class component 尚未遷移,改動之前先問使用者」

不要只寫「本專案使用 React」,一來是 package.json 查得到,二來是這樣對 AI 來說不是有意義的內容。

子目錄的 AGENTS.md#

隨著專案越來越大,光是根目錄的 AGENTS.md 沒辦法涵蓋不同功能之間開發的需求,後來我發現子目錄其實是可以放 AGENTS.md,可以只描述該功能需要的 Context。

以實際經驗來說,寫 API 介面的時候我希望 AI 知道的事情有:

  • 使用 Tanstack query + Zod
  • 檔案要怎麼放
  • 命名、Hooks 拆分、query keys 等等的規範
  • 建立新的 api 介面的流程

我把這份 AGENTS.md 放在 apis/,在開發 API 的時候 AI 就能讀到這份文件。

我自己實際的經驗:子目錄放 README.mdAGENTS.md 都會有很好的效果,可能這些 AI Coding 工具的預設行為就是會去讀這些文件。

最後再提供一個小技巧#

如果覺得這篇文章不錯的話,可以把整篇文章讓 AI 讀過,再讓 AI 按照這些原則來修改你的 AGENTS.md

祝大家都有很好的開發體驗。