Kiro 把 spec 拆成三個檔,難的是它們寫完之後會腐爛
寫於 2026 年 8 月 10 日,9 月才上線(部落格的發佈額度在 8 月中用完了,稿子積壓了三週)。文中對 Kiro 的描述以 8 月 10 日的官方文件為準,你讀到時文件可能已經改版。
Kiro 產生的那三個 .md 檔,AI 到底是什麼時候讀它們的?
這個問題比它看起來重要。因為答案決定了 spec-driven 這套做法,究竟是在幫你,還是只是多產了三份沒人維護的文件。
先說清楚我的位置:Kiro 我沒有實際跑過專案,以下對它的描述都來自官方文件(kiro.dev/docs/specs)。文件沒寫的部分我不補,會直接說「文件沒提」。真正有實作經驗的那半邊,是我自己每天在用的流程。
拆開來看,它產出的是三個階段的凍結點
Kiro 的 spec 工作流會依序產生三個檔案。requirements.md 放使用者故事與驗收條件;design.md 放技術架構、時序圖與實作策略;tasks.md 把前兩者拆成一條條可追蹤的實作任務。官方稱它為三階段工作流,階段之間有審核關卡,而「已經很清楚的功能」可以用 Quick Spec 一次產出三份、跳過那些關卡。
修 bug 的話,第一個檔案換成 bugfix.md,裡面裝的是現行行為、預期行為,以及哪些行為不該被動到。
文件沒有指名它用哪一套需求書寫標準,也沒有說這些檔案最後落在 repo 的哪個位置。這兩件事我查不到,就不寫。
到這裡為止,它長得像一套文件範本。但範本不是重點。重點是這三個檔案把原本會發生在對話裡的事情,搬到了檔案裡。
決策原本住在對話裡,那是個很糟的地址
你跟 agent 講「這個欄位允許 null,因為舊資料有兩萬多筆沒填」,它照做了。這個決策現在存在哪裡?
存在那一則訊息裡。而那則訊息會被 compact 掉,換一個 session 就不存在了,你自己三週後也想不起來。下次另一個 agent 讀到這段程式碼,看見一個沒有 not-null 約束的欄位,很合理地「幫你」補上約束,然後線上炸掉。
spec-driven 真正在搬動的,就是這個地址。它把決策從「對話這種易失性儲存」搬到「檔案這種持久性儲存」。三階段、審核關卡、使用者故事的格式,這些都是手段;被搬動的東西才是目的。
想通這一層之後,很多爭論會突然變得沒意義。有人說 spec 太重、有人說直接讓 AI 寫比較快,這些爭論其實在問「要不要寫文件」。但真正該問的是:這次的決策,你打算存在哪裡?如果存在對話裡,那你等於把它扔了。
費曼講過一個判斷懂不懂的方法,大意是你能不能講給完全沒背景的人聽。spec 這件事有個類似的版本:你能不能講給三週後、已經忘記全部脈絡的自己聽。
然後就到了沒人管的那一段
好,決策搬進檔案了,程式碼也生出來了。
接下來三個月,這段程式碼會被改十幾次。有人加了快取、有人把那個欄位改成 not null 並且順手補了資料遷移、有人把整個 service 拆成兩個。
design.md 呢?
它還停在第一天的樣子。而且它看起來完全正常——格式漂亮、章節齊全、時序圖畫得很清楚,就是內容已經跟現實對不上了。這比沒有文件更糟,因為沒有文件的時候大家知道要去讀程式碼,有一份過期文件的時候,下一個人會相信它。
這是我認為 spec-driven 真正的分水嶺。產生程式碼之前那一段,各家做得大同小異,無非是拆幾個檔、卡幾道關;分野在寫完之後:當 spec 已經過期,你有沒有辦法知道?
我自己流程裡多出來的那道章
我用的是自己組的一套 CREW 流程(/plan-start、/plan、/plan-build、/plan-review、/plan-close),規格落在 .spec/{slug}/plan.md,資料庫變更另外落在 deploy.sql 當唯一事實來源。到這裡跟 Kiro 的思路沒有本質差別,都是把決策搬進檔案。
差別在最後兩步。
plan.md 裡的每個決策條目,會綁一個程式碼錨點,指向它實際落在哪個檔案的哪一段。結案時 /plan-close 會蓋一個 verified_at_commit,記下「這份規格在哪一個 commit 上被驗證過是準的」。
有了這兩樣東西,過期就從一件憑感覺的事,變成一件算得出來的事。/plan-drift 拿著錨點去比對現在的程式碼,錨點失效的就是漂移。它還把漂移分成兩類處理:機械型的(檔案搬家、函式改名)直接自動修,語意型的(這個決策的前提已經不成立了)一條條停下來問我,因為那種東西機器判不了。
說白一點,verified_at_commit 就是食品上的有效期限。沒有它,你看著一份規格只能猜它新不新鮮;有了它,過沒過期是一個比對,不是一個直覺。
我不是說 Kiro 沒處理這件事——官方文件那一頁沒提到,不代表產品裡沒有,這是兩回事(用 grep 找不到,從來不等於不存在,我在這上面栽過)。我要說的是這道題本身:任何 spec-driven 工具,你都該拿這個問題去問它。
這條原理不只管 spec
把它推廣出去會發現,這是同一個模式的很多個化身。
CLAUDE.md 裡寫著「本專案用 MySQL」,半年前搬到 PostgreSQL 了,沒人改。README 的安裝步驟停在三個版本以前。函式上方那行註解描述的是它被重構前的行為。
全部都是同一件事:一份會腐爛的東西,旁邊沒有放有效期限。
所以下次你要在 repo 裡新增任何一份「描述程式碼的檔案」時,先別急著想它要寫什麼格式。先回答一個問題就好:三個月後它跟程式碼對不上的時候,誰會先發現,怎麼發現?
答不出來,那份文件從第一天起就是負債,只是還沒到期。
來源:Kiro 官方文件 Specs。文中對 Kiro 的描述僅來自該文件,我沒有實際跑過 Kiro 專案;CREW 流程的部分是我自己每天在用的工具,錨點與 verified_at_commit 的行為描述來自實際使用。










