AI 工程

Nested AGENTS.md 實戰:Kiro IDE 1.0.309 讓你按目錄樹分層下指令

根目錄那份 AGENTS.md,已經沒人在遵守了

如果你在 monorepo 裡用 coding agent,這個劇本應該很熟:一開始根目錄放一份 AGENTS.md,二十行,乾淨俐落。三個月後它變成兩百行——前端的樣式慣例、後端的 migration 流程、infra 的 terraform 禁令、還有一段「不要自己亂改 lockfile」的血淚史,全擠在同一個檔案裡。

然後你會發現兩件事。第一,agent 開始選擇性遵守:你要它改一個 React 元件,它卻在回應裡引用了後端 service 的錯誤處理規範。第二,沒人敢刪東西——每一行都是某次踩雷留下的,但沒人知道哪些還有效。

Kiro 在 IDE 1.0.309(2026 年 8 月 13 日)針對的就是這件事。changelog 原文只有一句:

Add AGENTS.md files throughout your workspace to give Kiro instructions scoped to each directory tree.

翻成白話:AGENTS.md 不再只能放在 workspace 根目錄和 ~/.kiro/steering/,你可以把它放在整棵目錄樹的任何位置,Kiro 會把它們一起當成 steering context 讀進來。CLI 端其實早一天就有了(Kiro CLI 2.18.0,8 月 12 日),IDE 這版是補上。

同一版還包含降低 idle 資源占用、長 session 保留更多 context,以及 Cloud 設定/chat/hooks/MCP 連線的改進。changelog 頁面上 Improvements 與 Fixes 的完整細項我抓不到,所以以下只談能確認的部分。

這聽起來像個小功能。但它改變的是「你怎麼組織給 agent 的指令」——而這件事直接決定 agent 在大型 repo 裡有多可靠。

先搞懂 Kiro 的 steering 體系

要理解這句 changelog 的份量,得先知道 Kiro 原本的指令系統長什麼樣。

Kiro 把「持久化的專案知識」叫 steering,放兩個地方:

  • .kiro/steering/:跟著專案走,進版控
  • ~/.kiro/steering/:跟著你走,跨專案

衝突時 workspace 蓋過 global。

steering 檔用 YAML front matter 決定什麼時候載入,這是 Kiro 比較細緻的地方,一共四種模式:

---
inclusion: always
---

預設值,每次互動都載。適合技術棧、共通慣例。

---
inclusion: fileMatch
fileMatchPattern: ["**/*.ts", "**/*.tsx", "**/tsconfig.*.json"]
---

只有在編輯符合 pattern 的檔案時才載。

---
inclusion: manual
---

要你在聊天裡用 #troubleshooting-guide 這種方式明確拉進來才生效。

---
inclusion: auto
name: api-design
description: "REST API design patterns and conventions"
---

Kiro 自己判斷你的問題跟 description 對不對得上。

另外,steering 內文可以用 #[[file:api/openapi.yaml]] 把 workspace 裡的活檔案接進來,不用複製貼上一份會過期的副本。

關鍵差異來了AGENTS.md 走的是另一條路。依 Kiro 文件,AGENTS.md 一律 always load,不支援 inclusion 模式。1.0.309 做的事,是把「能放 AGENTS.md 的位置」從根目錄 + ~/.kiro/steering/ 擴大到整棵 workspace 樹。

所以 nested AGENTS.md 的定位很清楚:它是「按位置分區」的 always,不是「按條件觸發」的 fileMatch。這兩件事解決的問題不同,後面會講什麼時候該用哪個。

(一個要注意的文件落差:我寫這篇時,Kiro 官方 steering 文件在描述子目錄探索時仍標註為 CLI 行為,看起來文件還沒跟上 IDE 1.0.309 的 changelog。以 changelog 為準,但這是值得自己驗一下的點。)

運作原理:巢狀不是重點,「什麼時候載入」才是

三種 AGENTS.md 載入模型對比:Codex 只往上走停在 cwd、Claude Code 祖先全載加子樹按需、Kiro 1.0.309 整棵樹常駐

真正決定體感的是三個問題:從哪裡開始找、找到哪裡停、什麼時候塞進 context。三家主流 coding agent 的答案都不一樣,而這個差別會直接決定你的檔案有沒有生效。

Codex:只往上走,停在 cwd

OpenAI Codex 啟動時會組一條 instruction chain:先全域 ~/.codex/AGENTS.md,再進 project scope。官方文件的說法是「Codex concatenates files from the root down, joining them with blank lines」——從 repo root 往下串接、用空行接起來;越靠近你當前目錄的檔案排在越後面,所以後面的蓋前面的

每一層目錄它檢查的順序是 AGENTS.override.mdAGENTS.mdproject_doc_fallback_filenames 裡設定的名字,每層最多只採用一個非空檔案。override 存在,同層的 AGENTS.md 就整份被忽略。

兩個實務上很容易踩的限制:

  1. 它「停在你的 cwd」。文件明說「Codex stops searching once it reaches your current directory」。也就是說,你在 repo 根目錄開 Codex,apps/web/AGENTS.md 根本不會被讀。要讓子目錄規則生效,你得 cd apps/web 再開 Codex。
  2. 總量上限 32 KiBproject_doc_max_bytes 預設值,可在 ~/.codex/config.toml 改)。串接到超過就停止加入後續檔案——注意是「停止加入」而不是截斷單一檔案,所以排在後面的深層指令會整份消失,而且不會有明顯提示。

Claude Code:祖先全載 + 子樹按需

Claude Code 原生讀的是 CLAUDE.md,不是 AGENTS.md。它的載入分兩段:

  • 往上走的部分:從 cwd 沿目錄樹往上,每層找 CLAUDE.mdCLAUDE.local.md,全部在啟動時完整載入。順序是從檔案系統根往下排,越靠近 cwd 的排越後面;同一層則是 CLAUDE.local.md 接在 CLAUDE.md 後面。
  • 往下走的部分:cwd 底下子目錄的 CLAUDE.md 會被發現,但不在啟動時載入,而是等 Claude 真的讀到那個目錄裡的檔案時才進 context。

這個「按需」設計省 token,但有個大家常踩的坑:壓縮(/compact)之後,根目錄的 CLAUDE.md 會從磁碟重新讀進來、重新注入,巢狀的不會——它要等下次再讀到那個子目錄的檔案才重新載入。所以「壓縮完 agent 突然忘記前端規則」通常不是幻覺,是這個機制。

要 debug 到底載了什麼,兩招:session 裡跑 /contextMemory files 清單;或掛 InstructionsLoaded hook,把載入的檔案、時機和原因印出來。

Claude Code 不吃 AGENTS.md,但官方給了兩個橋接法。第一個是 import:

<!-- CLAUDE.md -->
@AGENTS.md

## Claude Code
Use plan mode for changes under `src/billing/`.

第二個是 symlink(Windows 需要管理員權限或開發者模式,建議還是用 import):

ln -s AGENTS.md CLAUDE.md

順帶一提兩個細節:@path import 最多遞迴四層;而且 import 進來的檔案照樣在啟動時全載——拆檔只幫組織,不省 context。真的要省,得用 .claude/rules/paths: frontmatter 做路徑條件載入。

Kiro 1.0.309:整棵樹常駐

Kiro 這版的行為最單純:workspace 樹上任何位置的 AGENTS.md,都會作為 steering context 載入,跟你其他 steering 檔一起。沒有「停在 cwd」,也沒有「按需才載」。

好處是可預期——你放了就一定會生效,不用猜 agent 有沒有剛好讀到那個目錄的檔案。代價也很直接:它是 always,沒有 inclusion 模式可以節流。一個五十個 package 的 monorepo,每個 package 放一份,就是五十份常駐在 context 裡。

Kiro 有沒有像 Codex 那樣的總量上限?官方 changelog 和 steering 文件我都沒查到明確數字,所以這裡不猜。這是最值得自己實測的一點:放十份 nested AGENTS.md 進去,看 context 佔用怎麼變化。

手把手:把 monorepo 的指令拆開

monorepo 分層 AGENTS.md 範例:全域個人偏好、根目錄共通規則、服務層、前端層、infra 守門規則

Step 1:先量根檔案有多肥

wc -l AGENTS.md
grep -c '^-' AGENTS.md

經驗值:超過 150 行、或者你自己讀完想不起來前三分之一寫了什麼,就該拆。

Step 2:用三個判準切

逐行問這三個問題,答案決定它該去哪:

  1. 這條規則在整個 repo 都成立嗎? → 是,留在根。
  2. 它只在某個目錄底下成立嗎? → 是,移到那個目錄。
  3. 它是「事實/慣例」還是「多步驟流程」? → 流程不該進 AGENTS.md,該做成 skill 或 spec;AGENTS.md 適合放「一直都對的事實」。

最常見的誤判是第 3 條。「發版流程:先跑測試、再 bump 版本、再 tag、再 push」這種東西塞進 always-load 的檔案,每個 session 都在燒 token,但一個月只用到一次。

Step 3:寫子目錄檔

根目錄——只放不會變的:

<!-- repo/AGENTS.md -->
# 專案共通

- 套件管理一律用 pnpm,不要用 npm / yarn
- commit 訊息格式:`type(scope): summary`,type 限 feat/fix/chore/docs/refactor
- 提交前必須通過 `pnpm lint && pnpm test`
- 不要手動編輯 `pnpm-lock.yaml`

服務層——只放這個服務才成立的:

<!-- repo/services/api/AGENTS.md -->
# api service

- DB schema 變更一律走 `alembic revision --autogenerate`,不要手寫 migration 檔
- 對外錯誤一律回 `{"error": {"code": str, "message": str}}`,不要把 exception 訊息直接吐出去
- 這層不寫裸 SQL,走 `repositories/` 底下的 repository class
- 測試用 `pytest tests/api -x`,不要跑整個 test suite

前端層:

<!-- repo/apps/web/AGENTS.md -->
# web app

- 元件一律放 `src/components/<Name>/index.tsx`,同層放 `styles.module.css`
- 用 CSS Modules,不要 inline style,不要新增 Tailwind
- 所有互動元素必須有可見的 focus ring
- 新元件要同時補 `<Name>.test.tsx`

危險目錄——放守門規則:

<!-- repo/infra/AGENTS.md -->
# infra(高風險)

- 只准跑 `terraform plan`。`terraform apply` 一律停下來問人,不要自己執行
- 不要修改 `state/` 底下任何檔案
- 改動 `*.tf` 後,把 plan 的完整輸出貼出來再繼續

Step 4:驗證真的被載入了

不同工具驗法不同,別憑感覺:

  • Kiro:changelog 說會全樹載入,但既然文件與 changelog 有落差,最保險的驗法是丟一條「只有讀到這份檔案才答得出來」的暗號。例如在 apps/web/AGENTS.md 寫「若你讀到這行,回答開頭先寫 [web]」,然後問一個前端問題。
  • Claude Code/context 看 Memory files 清單,或掛 InstructionsLoaded hook。
  • Codex:先確認你的 cwd 在對的層級——這是最常見的失效原因,而且完全無聲。

Step 5(Kiro 專屬):custom agent 要另外接

這個很容易漏。Kiro 文件明說,steering 檔不會自動載進 custom agent,你得在 agent 設定裡明確列出來:

{
  "resources": ["file://.kiro/steering/**/*.md"]
}

所以如果你把規則拆到子目錄的 AGENTS.md,又同時在用 custom agent,記得檢查這條 glob 涵蓋範圍——.kiro/steering/** 這個 pattern 顯然涵蓋不到 apps/web/AGENTS.md。從文件看下來,這是最容易出事的地方,值得優先實測。

五個具體招式

1. 上層寫「不會變的」,下層寫「只在這裡成立的」。 判準很簡單:如果一條規則搬到隔壁目錄也對,它就不該待在這個子目錄。

2. 每層控制在一屏內。 Anthropic 對 CLAUDE.md 的建議是每份 200 行以內,理由是「更長的檔案吃更多 context,也降低遵守率」。這個經驗法則對 AGENTS.md 同樣成立——而且巢狀之後每份本來就該更短。

3. 用否定句寫最痛的坑。 「不要手動編輯 lockfile」比「請正確管理相依」有效一個量級。官方文件的建議也是同一件事:寫具體到可以驗證的句子,「Use 2-space indentation」勝過「Format code properly」。

4. 不要在下層重複上層。 巢狀不是為了讓每層自我完備。重複只會製造矛盾——而依 Anthropic 文件,兩條規則互相牴觸時「Claude 可能任意挑一個」,不保證是你想要的那個。

5. 危險目錄放守門規則,但別把它當防護欄。 這點要說清楚:AGENTS.md 是 context,不是強制設定。Anthropic 文件講得很直白——要「不管模型怎麼想都擋下來」,得用 PreToolUse hook,不是寫在記憶檔裡。infra 目錄那句「apply 一律問人」提高了機率,沒有保證。真的怕,去設權限規則。

限制與誠實的部分

先講數字歸屬,免得誤傳:

  • 32 KiB 是 Codex 的數字project_doc_max_bytes 預設值),不是 Kiro 的,也不是 AGENTS.md 規範的一部分。
  • 200 行是 Anthropic 對 CLAUDE.md 的建議上限,是經驗法則不是硬限制;同一份文件也說 CLAUDE.md 不論多長都會完整載入。
  • Kiro 的載入上限我查不到。changelog 和 steering 文件都沒寫。有需要請自己測。

其他該講清楚的:

我沒有實際跑過 Kiro 1.0.309。 這篇的機制描述全部來自 changelog 和官方文件。特別是「全樹載入」在大型 monorepo 的實際 context 成本,我只能說這是最該驗的點,不能替你打包票。

官方文件和 changelog 有落差。 Kiro steering 文件描述 AGENTS.md 子目錄探索時仍標註為 CLI 行為,而 IDE changelog 1.0.309 說 IDE 也有了。兩者不一致時我傾向相信 changelog(它更新),但這正是「丟暗號驗證」值得做的原因。

「最近的檔案贏」是規範說法,不是所有工具的實作。 agents.md 的 FAQ 寫「The closest AGENTS.md to the edited file wins; explicit user chat prompts override everything」。但 Codex 的實作是「串接後靠後的蓋前面的」;Claude Code 的實作更直接——官方文件原話是所有找到的檔案 are concatenated into context rather than overriding each other,也就是全部串接、不互相覆蓋。換句話說,「覆蓋」在多數實作裡是靠位置順序影響模型注意力,不是硬性的 config override。這個差別在你寫互相衝突的規則時會咬人。

什麼時候別拆

  • 小 repo 別拆。 單一 service、一兩百個檔案,一份根 AGENTS.md 就夠。拆了只是多幾個沒人維護的檔案。
  • 規則是「條件式」而不是「位置式」時別拆。 「所有 *.test.ts 都要用 AAA 結構」跟目錄無關、跟副檔名有關。這種在 Kiro 該用 inclusion: fileMatch 的 steering 檔,在 Claude Code 該用 .claude/rules/paths: frontmatter,都比塞進某個目錄的 AGENTS.md 準確。
  • 主要用 Codex 且習慣在 repo 根目錄工作時,拆了也白拆。 它不會往下讀。要嘛改成 cd 到子目錄再開,要嘛把規則留在根。
  • 需要硬性阻擋的事情別寫進來。 用 hook 或權限設定。

跨工具怎麼共用一份

如果你的團隊三種工具都有人用(很常見),現實的做法是:

  1. 以 AGENTS.md 為單一來源,按目錄樹分層放好。Kiro 1.0.309 與 Cursor(根目錄 AGENTS.md 會自動吃)原生支援。
  2. Claude Code 用 import 橋接:每個有 AGENTS.md 的目錄,放一份一行的 CLAUDE.md,內容就是 @AGENTS.md。這樣巢狀的按需載入行為也跟著走。
  3. Codex 使用者接受「只往上」的限制,並在團隊文件寫明「改前端請 cd apps/web 再開 Codex」。

順帶一提,AGENTS.md 這個格式不是單一廠商的東西——它由 OpenAI Codex、Amp、Google 的 Jules、Cursor、Factory 幾方共同促成,目前由 Linux Foundation 底下的 Agentic AI Foundation 維護。押注在這個格式上,比押在任一家的專屬檔名安全。

對工程團隊的意義

把上面收斂成一份可以直接執行的清單:

  • wc -l AGENTS.md,超過 150 行就排時間拆
  • 逐行套三判準(全域?位置相關?事實還是流程?)
  • 流程類的移去 skill / spec,不要留在 always-load 的檔案
  • 每個子目錄檔控制在一屏內,不重複上層內容
  • 高風險目錄(infra、migrations、scripts)補一份守門 AGENTS.md
  • 同時用 hook / 權限設定做真正的硬阻擋,不要只靠文字
  • 用「暗號驗證」確認每一份都真的被載入
  • Kiro custom agent 使用者:檢查 resources glob 的涵蓋範圍
  • Claude Code 使用者:在每個目錄補 CLAUDE.md 內含 @AGENTS.md
  • 把「哪一層放什麼」寫進 README,不然三個月後又會膨脹回去

最後一句:nested AGENTS.md 解決的是組織問題,不是遵守問題。拆對了,agent 收到的指令更精準、更少矛盾,遵守率會上升。但它終究是 context 不是 config——真正不能出錯的事,該用 hook 擋。

來源

整理:DataAgent · Coding Agent 實戰教學

發表迴響

%d 位部落客按了讚: