## AI coding agent 不會記得你為什麼這樣寫:用 ADR 為專案守住決策脈絡
O'Reilly Radar 於近日刊出一篇由軟件架構師 Duncan Davidson 撰寫、經作者本人同意轉載自其個人 blog 的文章,提出的觀點看似老派、卻切中要害:架構決策紀錄(Architectural Decision Records,簡稱 ADR)——這項早在 2011 年由 Michael Nygard 正式定型的實務慣例——迎來了一個意想不到的新讀者:AI coding agent。
「為什麼現在需要談這個?」原因有二。第一,coding agent 在 session 之間沒有記憶,每次對話都要從倉庫「重新認識」專案。第二,「vibe coding」式的工作模式會產生大量沒有解釋的程式碼:結果是,團隊的 repo 顯示了程式碼「做了什麼」,卻完全沒有留下「為什麼這樣做」的脈絡。
### Agent 看不到的那一層
程式碼本身可以告訴 agent 一個函數怎麼運作,但無法告訴它:某個架構邊界是有意為之,還是歷史偶然;某個依賴為什麼被刻意移除;某條規範(例如不引入某類第三方庫)背後是合規還是維運考量。結果往往是 agent 在重構時「好心」把早已被拒絕的方案重新引進來,或者忽略跨系統整合時的既定資料契約。
ADR 補的正是這一層:決策本身、被拒絕的替代方案、以及施加的約束。
### 可以直接 copy 的 ADR 模板
ADR-0004: 決策標題(一句話)
狀態:已接受 / 已過時(取代 ADR-00xx)/已拒絕 日期:YYYY-MM-DD
背景
兩三句話說明當時面對的問題與約束(合規、效能、成本、供應商限制)。
決策
清楚寫出「我們選擇了什麼」,而非討論過程。
被拒絕的方案
- 方案 A:為何拒絕(一句話即可)
- 方案 B:為何拒絕
後果
接受這個決策後,哪些事情變得更容易或更難? ```
重點只有四條:
- 記錄「決策」而非「開會活動」;
- 寫給未來的讀者(包括 agent);
- 像程式碼一樣納入版本控制(放進
docs/adr/,走 PR 審核); - 不可就地修改——一旦某份紀錄被推翻,就把舊的狀態標為「已過時」,再寫一份新的取代它。
最後一條尤其值得留意:若採用「取代而非修改」的規則,ADR 的歷史會自動變成一條可追溯的決策鏈,agent 沿著「Superseded/已過時」的狀態一路讀回去,就能重構出決策曾經反轉的理由;反之,就地編輯恰好抹掉這套做法存在的目的——脈絡本身。
接線到 agent:讓 agent 真的讀得到
- 在 repo 根目錄的 agent 指令檔(如
AGENTS.md、CLAUDE.md或專屬 prompt 檔)中寫明:「變更任何架構層面的東西之前,先讀取docs/adr/並遵循狀態為『已接受』的決策。」 - 在實作程式碼附近放一行註解指過去,例如
// 參考 ADR-0004:此處不可引入 X 類依賴(原因見 ADR)。這是整套做法中最實用的一行——agent 在上下文窗口裡最容易讀到程式碼本身。 - 讓 ADR 進入 CI:可選做法是在 pull request 模板中加入「是否需要新 ADR?」的勾選欄,成本極低。
警惕過度文件化
原文最值得咀嚼的警告是:不要把每個微決策都寫成「法庭審訊筆錄」。當 ADR 變成冗長的會議紀錄,真正有用的訊號就會被淹沒——對人類和 agent 一樣。過短沒問題,冗長才是問題。短、準、講決策,才是讓 records 長期有效的形狀。
三步驟落地
- 盤點:找出現存最常被 agent「誤解重構」的三個架構選擇,各補一份短 ADR。
- 接線:把
docs/adr/寫進 agent 指令檔,並在程式碼加指標註解。 - 養成習慣:在 pull request 流程加一個勾選問題,一個月後回顧並刪除寫得太長的紀錄。
這套做法沒有工具鏈依賴,也不需要新採購——只需要一個目錄和幾行規則。
給團隊的一句提醒
對於正在把 AI 導入 legacy 與 greenfield 並存專案的團隊來說,這是一項值得趁 repo 還小、還來得及整理時就制度化的紀律。脈絡一旦流失,補回來的成本遠高於當初寫下三段文字。
(本文觀點引述自 O'Reilly Radar 於 2026 年 10 月 2 日刊出的轉載文章,原文出自 Duncan Davidson 的 blog;ADR 格式可追溯至 Michael Nygard 於 2011 年提出的架構決策紀錄實務。)
## AI coding agent 不會記得你為什麼這樣寫:用 ADR 為專案守住決策脈絡
O'Reilly Radar 於近日刊出一篇由軟件架構師 Duncan Davidson 撰寫、經作者本人同意轉載自其個人 blog 的文章,提出的觀點看似老派、卻切中要害:架構決策紀錄(Architectural Decision Records,簡稱 ADR)——這項早在 2011 年由 Michael Nygard 正式定型的實務慣例——迎來了一個意想不到的新讀者:AI coding agent。
「為什麼現在需要談這個?」原因有二。第一,coding agent 在 session 之間沒有記憶,每次對話都要從 repo「重新認識」專案。第二,「vibe coding」式的工作模式會產生大量沒有解釋的程式碼:結果是,團隊的 repo 顯示了程式碼「做了什麼」,卻完全沒有留下「為什麼這樣做」的脈絡。
### Agent 看不到的那一層
程式碼本身可以告訴 agent 一個函數怎麼運作,但無法告訴它:某個架構邊界是有意為之,還是歷史偶然;某個依賴為什麼被刻意移除;某條規範(例如不引入某類第三方庫)背後是合規還是維運考量。結果往往是 agent 在重構時「好心」把早已被拒絕的方案重新引進來,或者忽略跨系統整合時的既定資料契約。
ADR 補的正是這一層:決策本身、被拒絕的替代方案、以及施加的約束。
### 可以直接 copy 的 ADR 模板
ADR-0004: 決策標題(一句話)
狀態:已接受 / 已過時(取代 ADR-00xx)/已拒絕 日期:YYYY-MM-DD
背景
兩三句話說明當時面對的問題與約束(合規、效能、成本、供應商限制)。
決策
清楚寫出「我們選擇了什麼」,而非討論過程。
被拒絕的方案
- 方案 A:為何拒絕(一句話即可)
- 方案 B:為何拒絕
後果
接受這個決策後,哪些事情變得更容易或更難? ```
重點只有四條:
- 記錄「決策」而非「開會活動」;
- 寫給未來的讀者(包括 agent);
- 像程式碼一樣納入版本控制(放進
docs/adr/,走 PR 審核); - 不可就地修改——一旦某份紀錄被推翻,就把舊的狀態標為「已過時」,再寫一份新的取代它。
最後一條尤其值得留意:若採用「取代而非修改」的規則,ADR 的歷史會自動變成一條可追溯的決策鏈,agent 沿著「Superseded/已過時」的狀態一路讀回去,就能重構出決策曾經反轉的理由;反之,就地編輯恰好抹掉這套做法存在的目的——脈絡本身。
接線到 agent:讓 agent 真的讀得到
- 在 repo 根目錄的 agent 指令檔(如
AGENTS.md、CLAUDE.md或專屬 prompt 檔)中寫明:「變更任何架構層面的東西之前,先讀取docs/adr/並遵循狀態為『已接受』的決策。」 - 在實作程式碼附近放一行註解指過去,例如
// 參考 ADR-0004:此處不可引入 X 類依賴(原因見 ADR)。這是整套做法中最實用的一行——agent 在上下文窗口裡最容易讀到程式碼本身。 - 讓 ADR 進入 CI:可選做法是在 pull request 模板中加入「是否需要新 ADR?」的勾選欄,成本極低。
警惕過度文件化
原文最值得咀嚼的警告是:不要把每個微決策都寫成「法庭審訊筆錄」。當 ADR 變成冗長的會議紀錄,真正有用的訊號就會被淹沒——對人類和 agent 一樣。過短沒問題,冗長才是問題。短、準、講決策,才是讓 records 長期有效的形狀。
三步驟落地
- 盤點:找出現存最常被 agent「誤解重構」的三個架構選擇,各補一份短 ADR。
- 接線:把
docs/adr/寫進 agent 指令檔,並在程式碼加指標註解。 - 養成習慣:在 pull request 流程加一個勾選問題,一個月後回顧並刪除寫得太長的紀錄。
這套做法沒有工具鏈依賴,也不需要新採購——只需要一個目錄和幾行規則。
給團隊的一句提醒
對於正在把 AI 導入 legacy 與 greenfield 並存專案的團隊來說,這是一項值得趁 repo 還小、還來得及整理時就制度化的紀律。脈絡一旦流失,補回來的成本遠高於當初寫下三段文字。
(本文觀點引述自 O'Reilly Radar 於 2026 年 10 月 2 日刊出的轉載文章,原文出自 Duncan Davidson 的 blog;ADR 格式可追溯至 Michael Nygard 於 2011 年提出的架構決策紀錄實務。)
