
用 SDD 開發大功能,我學到的幾件事
這篇整理自 2026 年 8 月在前端讀書會的分享,記錄用 SDD(spec-driven development,規格驅動開發)開發一個大功能時,遇到的問題和學到的事。
我所在的產品前端團隊,從今年四月左右開始用 OpenSpec 嘗試 SDD。OpenSpec 是一套給 AI coding agent 用的 SDD 工具,先寫規格,再照規格實作。我們搭配 agent skills,省下過去跑 Scrum 時寫技術文件、拆卡、開估點會議的時間。
七月左右來了一個新的大功能,由我負責這個功能的前端交付。規格非常龐大,我開始想怎麼開發才比較有效率。
起點:一份四千行的 PRD
這次的 PRD 有 4,045 行、178 條 acceptance criteria,要全部讀完才開始規劃,太花時間了。
先讓 agent 幫忙拆
我寫了一個拆解功能的 feature-breakdown skill,把 PRD 和後端的技術文件交給它,先拆出幾個子 change。這樣不用讀完四千行,就能開始有條理地規劃。
實驗:跨 change 共用 context
拆成多支 change 之後,每支 change 跑 propose 時,都要重新讓 agent 讀一次 PRD、後端文件這些相同的背景資料,佔掉不少 context window。我想試試看不同的 change 之間能不能共用 context,於是做了一個 context pack,記錄跨 change 依賴的 contract,再加上一個同步 context 的機制。它需要花心力維護,但上游一改,就能很快同步到各支 change 的規格,是值得投資的成本。
上游一動,下游全部跟著變
前端拿到的上游文件有兩份:PRD,以及一份 1,333 行、還在草稿狀態的後端技術文件。開發期間 PRD 改了 14 版,每改一次,下游都要跟著調整。
什麼時候開始跑 SDD?
OpenSpec 的流程是先跑 propose,產出 proposal、design、tasks 這幾份文件。如果上游還在變動就開始跑,上游一改,這些文件就要重來,而每份規格裡都藏著很多微決策。
這次跟以前最大的差別在於 context 的量。以前一支 change 對應一份小 PRD,上游改了,就改那一支。現在一份 PRD 拆成了 13 支 change,上游每改一次,我都要先判斷這次改動會影響到哪幾支。
這個判斷可以交給前面那個同步 context 的 skill,但改一次可能就要更新 13 支。skill 幫我省下找出受影響範圍的時間,可是要改的東西還是一樣多。
規格一直在改,實作卻是零
13 支 change、3,266 行規格、改了 14 版,實作是 0 行。
這是整個過程中最讓我卡住的地方。規格來回改了很多版,卻一行程式碼都還沒寫。我只希望這些規格能趕快落地。
零實作也讓 PM 不安
我們原本設計的估點 skill,參考的是 propose 產出的文件,所以要估點,得先把 propose 跑完。但跑 propose 的同時,需要做出許多技術上的微決策,要讓 PM 拿到全部的估點,會花上不少時間。
PM 其實已經用過去的點數粗估過,也排好時程了,只是規劃階段還是需要確切的數字。現在回頭想,他想知道的可能是事情有沒有在推進,點數只是剛好能拿來看的東西。偏偏實作是零,什麼進度都看不到。
我開始懷疑自己用 SDD 的方式是不是錯了。規格改了很多版卻沒有任何實作,聽起來根本就是瀑布式開發(waterfall)。
Learning 1:SDD 和 waterfall 的爭論
開發社群早就討論過這個問題。
認為 SDD 走回 waterfall 老路的人,談的多半是實際用起來的狀況。Marmelab 的〈The Waterfall Strikes Back〉列了七種 SDD 的問題,其中一種叫「Double Code Review」:技術規格裡已經寫了程式碼,要先 review 規格、再 review 實作,review 的時間變成兩倍。INNOQ 的〈The Right Kind of Hard〉寫的是作者自己的經驗,一個簡單的 user story 膨脹成上千行的規格,原本該動手做的時間,都拿去寫文件了。
另一邊則是在講 SDD 本來該怎麼用。AWS 的 Marc Brooker 在〈Spec Driven Development isn’t Waterfall〉裡寫道:
Specifications aren’t up-front designs because you don’t need to, and probably shouldn’t, develop the entire specification upfront.
他的意思是,規格不用一開始就全部訂好。規格是一份有版本控管、持續更新的文件,實作跟著它一起往前走。
兩邊說的都有道理,一邊描述實際發生的事,一邊描述理想的用法。
Learning 2:SDD 是為 flow 設計的
對我啟發最大的,是 Yuval Yeret 的〈Spec-Driven Development Isn’t Waterfall〉。他是敏捷顧問,有自己的商業立場,不過這句話我很認同:
Spec-driven development is designed for flow, not waterfall.
flow 指的是規格寫完就趕快變成程式碼,不要放著。
為了下週要做而寫的規格,寫完很快就會用到;為了其他理由寫的,常常一放就是好幾週
所以開始寫規格之前,可以先問自己為什麼現在要寫。
Learning 3:規格不該用來凍結需求
Yeret 在同一篇文章裡也提醒:
The danger is when we treat the spec as a way to remove the need for adaptation, especially when we combine it with larger batch sizes.
換個說法,就是有人想改需求的時候,搬出規格說「這裡已經定了」。
一次寫多少規格,也會影響這件事。只寫一支 change 的規格,就算真的拿來擋改動,影響的也只有那一支。但如果 13 支一次全部寫好,等於 13 份假設同時定了下來,花在上面的心力越多,就越捨不得改。
現在每次要搬出規格時,我會先想一下,自己是要用它釐清該做什麼,還是想用它擋下需求的變動。如果是後者,那就是不知不覺用 waterfall 的思維在做 SDD 了。
回頭看:我是為了估點而寫規格
因為估點 skill 要讀 propose 產出的文件,為了讓 PM 拿到估點,我把 13 支 change 全部展開到 tasks,但其中下週真的要開工的只有一兩支。
說穿了,我寫這些規格是為了估點,不是為了馬上要做。其他規格寫好之後就一直放著,等上游改了再重寫,這就是那「0 行實作」的由來。
估點和寫規格其實可以分開。在拆任務的階段,可以先用別的方式粗估,例如根據 feature-breakdown 拆出來的子 change,對照過去類似功能的點數,先給 PM 一個範圍。等某支 change 真的要開工了,再跑 propose,把那一支的點數估準。
Learning 4:兩套工作思維的矛盾
改用 SDD 之後,團隊討論過還要不要估點。工程師覺得沒必要,但 PM 規劃時程還是需要點數。最後的折衷是寫一個估點 skill,讓 agent 自動估,工程師不用再開估點會議。
| 傳統流程 | 現在的流程 | |
|---|---|---|
| 估點的輸入 | 技術文件,再拆成卡片 | OpenSpec 產出的文件 |
| 估點的方式 | 人工估點 | 和過去的紀錄比對 |
| 對輸入精確度的要求 | 低,讀的是人,會自己判斷 | 高,它同時是實作的上游 |
在傳統流程裡,估點用的技術文件寫個大概就夠了。看文件的是人,不清楚的地方大家會自己判斷,估完點,這份文件的任務也差不多結束了。
估點 skill 讀的則是 OpenSpec 的文件,而這些文件就是之後實作要照著走的規格。agent 會照著它寫程式,它也要放進 codebase 長期維護,沒辦法只寫個大概。也就是說,想要估點,就得先把規格寫到能拿來實作的程度。
估點這件事是從舊流程帶過來的,在新流程裡,它的成本卻變了。用 SDD 的工作方式,規格應該寫完就做;PM 的規劃卻需要一次拿到全部的點數。兩邊一碰在一起,就變成為了估點先把全部的規格寫完,又回到 waterfall 的做法。
自動化估點的好處也是真的,工程師不用另外寫技術文件,也不用開估點會議。只是在這次這種大功能上,它的代價特別明顯。
Learning 5:不用再等全部規劃好才開始實作
我以前習慣先把所有東西規劃好,再一次進到開發階段。
在有 agent 之前,這樣做很合理。切換上下文的成本很高,寫錯了也要自己重寫。現在有了 agent,實作的成本降低,前端可以更快地迭代,邊做邊調整也不再那麼昂貴,但先規劃好全部的習慣還留著。
一直停在規劃階段,就用不到這個好處。規劃階段沒有 build、沒有測試,也沒有 PR,得不到任何回饋,只能憑判斷一個一個做微決策。這些決策花掉不少心力,上游一改,又可能要重來。如果早點做出一支 change,很多問題在實作時就會浮現,比在規格裡反覆推敲快得多。
這次把 13 支全部展開、遲遲沒有開始實作、規格越堆越多,回頭看都是這個習慣造成的。
後端規格還沒確定,前端可以怎麼先跑 SDD
回到前面那個問題:上游還在變的時候,什麼時候開始跑 SDD?前端常常要等後端的 API 規格確定才能動工,但規格不會有完全固定下來的一天,一直等下去,前端就會排在 waterfall 的最下游。
一種做法是由前端先寫 GraphQL 的 schema(SDL)。前端拿到型別就能先跑 SDD,把畫面和流程做出來;等後端的規格確定,再更新底層串接的部分。之前有個功能這樣做過,效果不錯,而且那份 SDL 只是前端開發用的,不需要合進後端。
延伸思考:成本轉移到了哪裡
以前實作的成本很高,重工的成本更高,所以先把規劃做足、減少重工是合理的做法。估點、拆任務、寫技術文件,都是在這個前提下發展出來的。
有了 agent,寫程式和重寫程式的成本都降低了,瓶頸移到了其他地方。與其沿用舊流程裡為了降低實作成本而設計的做法,不如重新看看現在卡在哪裡,再想辦法解決。
換了新的工具,也要回頭看看這個工具是為了什麼樣的工作方式設計的,再檢查自己的工作流程和想法有沒有跟著調整,這是我這次最大的收穫。
參考資料
以下都是實踐者的意見和案例,不是嚴謹的實驗結果。