iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Vibe Coding

夢幻甜品師闖工程世界:Vibe Coding vs 專業開發的 0→1 冒險攻略系列 第 14

Day14|任務還沒開始,先把規則寫清楚:從 SDD 看懂 Code 前要先定義什麼

  • 分享至 

  • xImage
  •  

昨天,我們把多人協作的分支規則整理清楚了。

接下來,就開始在 Feature Branch 上做功能吧!

不過開始做功能,不是開了分支就直接往下寫。

在真正動手以前,我們需要先把「功能」定義清楚:

到底要做什麼、做到什麼程度,哪些行為才算正確?

這幾年 AI Coding 越來越熱門,只要幾句自然語言,就可以讓 Coding Agent 幫忙新增功能、修改 API,甚至一次動到好幾個模組。

也因為 Code 生得太快,「規格」這件事又重新受到重視。

這就來到今天的主題:

Spec-Driven Development(SDD,規格驅動開發)。

SDD 當然不是 AI 出現以後才突然被發明的。

但以前需求沒有講清楚,還常常是工程師自己一邊理解、一邊實作;現在如果我只跟 Agent 說:

「幫我把報名功能改成讓大家回報有空時間。」

這句話裡其實還藏著一大堆空白。

「有空時間」是一個時間點,還是一段區間?

一個人可以回報幾段?

資料要怎麼存?

原本的 API 要不要跟著改?

這些事情如果沒有先定義,Agent 還是得替我做出某種判斷。

AI Coding 讓寫 Code 變得更快,也讓「需求到底有沒有說清楚」這件事變得更重要。


我其實先會用了,才知道原來這叫 SDD

我第一次真的開始注意到 SDD,順序其實跟今天寫文章完全相反。

我不是先把理論讀完,再決定:

「好!接下來我要採用 SDD!」

在使用 Spectra 以前,我本來就會透過 Superpowers 這套 Skills,先和 AI 討論需求、整理 Plan、把工作拆成 Task,再一步一步進入實作。

Superpowers 本身不是專門的 SDD 工具;但它讓我很早就開始習慣:

不要只丟一句 Prompt,就直接叫 AI 往 Code 衝。

後來 BuJo 開發開始使用 Spectra。

當時我其實還是不知道:

「喔,原來這背後有一個叫 SDD 的概念。」

只是覺得這個工具很直覺,它會把需求,以及這份規格需要做的變動,一項一項整理成待辦事項,讓整個功能接下來要怎麼做,看起來清楚很多。

直到後期重新回頭查資料,我才發現:

原來我一直在用的這些工具,背後都在處理同一個更底層的問題——開始寫 Code 以前,先把「規格」說清楚。


SDD 到底在「驅動」什麼?

Spec-Driven Development 最核心的東西,其實就在名字裡:

讓 Specification(規格)成為後續開發的重要依據。

也就是不要從一個模糊需求,直接跳到實作。

而是先慢慢把它變成:

模糊的需求/想法
        ↓
Specification
系統應該做到什麼?
        ↓
Design / Plan
準備怎麼做到?
        ↓
Tasks
實際有哪些工作?
        ↓
Implementation
開始寫 Code

不同 SDD 工具的實際流程不一定長一樣。

目前常被拿來討論的工具,例如:

  • Kiro:Requirements → Design → Tasks
  • GitHub Spec Kit:Spec → Plan → Tasks → Implement
  • OpenSpec:強調目前系統的 Spec 和正在進行的 Change
  • Spectra:BuJo 實際使用的工具,沿用 OpenSpec 的規格資料結構,再提供自己的操作流程與介面

可以看到,不同工具會用不同的流程和文件結構來實踐 SDD。

所以這裡真正需要抓住的,不是哪一套流程才是標準答案,而是它們共同在做的事:

先把需求和預期行為整理清楚,再往設計、拆解和實作前進。


我一開始看到那些規格檔,還以為自己把專案弄壞了

第一次開始用 Spectra 的時候,我其實有點被嚇到。

因為原本只是:

「我要改一個功能。」

結果專案裡突然多出好多 Markdown、資料夾、規格檔。

我還一直問 AI:

「這是正常的嗎?為什麼只是改個東西,突然多了這麼多行?」

後來才知道,這些突然多出來的文件,其實是在把這次功能的需求、設計和修改脈絡分開整理、留下來。

像 OpenSpec/Spectra,就會把不同性質的規格資訊分開管理。

以 BuJo 實際使用的結構來看,大概可以先這樣理解:

openspec/
├─ specs/
│  └─ 現在系統應該怎麼運作
│
└─ changes/
   ├─ 這一次準備修改什麼
   │
   └─ archive/
      └─ 過去做過哪些修改

完成的 Change 會再被放進 archive/,把當時修改的脈絡留下來。

所以那些突然增加的文件,不是在替專案灌水。

原本可能只存在一句:

「我們之前好像有說過這裡要這樣改。」

現在會被拆成:

為什麼要改?
這次要改什麼?
哪些地方會受到影響?
準備怎麼實作?
有哪些 Task?
最後系統應該怎麼運作?

而這些規格檔也會跟著專案一起進版控。

這一點很重要。

因為它代表規格不是只有「我自己的 AI 看過」。

而是可以變成團隊共同留下來的專案資料。


不是每次動 Code,都需要跑一套 SDD

但看到 Spectra 一次多出這麼多規格文件時,我又冒出另一個疑問:

「那我之後每改一個功能,都要跑完整套 SDD 嗎?」

其實不用。

SDD 可以用在一個個功能或變更上,但如果只是非常單純、影響範圍很小的修改,跑完整套規格流程反而可能增加不必要的成本。

比較值得使用的情況,通常有這幾種:

  • 需求還有歧義:同一句需求可能有不只一種合理理解。
  • 牽動範圍比較大:會同時影響前端、API、資料模型或其他功能。
  • 行為重要、改錯成本高:像認證、權限、排程、付款這類核心流程。
  • 需要多人共同理解或之後交接:當初「為什麼這樣決定」值得被留下來。

反過來,如果只是改一個 typo、調整間距、換 icon,或非常局部又沒有改變產品行為的 UI 修改,就不一定需要特地跑一套完整的 SDD 流程。

真正要判斷的,不是「這個功能夠不夠大」,而是這次修改裡,有沒有需要先被對齊的需求、行為或決策。


BuJo 活動情境二:不是一句「改成選時間」就開始寫

這件事放回 BuJo 的活動情境二最明顯。

我們原本的報名方式,是由活動建立者先列出一個一個候選時段,再讓參與者從裡面勾選。

但這跟我們真正想表達的需求其實有落差。

參與者真正想說的比較像:

「我這一整段時間都有空。」

而不是:

「你列的 A、B、C 三個時段裡,我選 A 跟 C。」

所以後來情境二做了一次完整 redesign:

原本
建立者列出一個個候選時段
↓
參與者勾選

改成
建立者提供可報名的時間範圍
↓
參與者自由回報自己的可用區間
↓
系統計算多人重疊時間

如果只把這件事講成一句:

「把候選時段改成時間區間。」

聽起來好像只是 UI 換了一個選擇方式。

但真的把規格拆開後,連 API 傳進來的資料格式都跟著變了:

原本
{ candidateSlotIds }

改成
{ ranges: [{ start, end }] }

原本傳的是「我選了哪些既有的候選時段」,現在則變成「我有哪些時間區間有空」。

而這個差異也會一路牽動後面的資料模型、報名流程、時間重疊計算,以及最後確認活動時間的方式。

這時候的 Spec,就不再只是一句「情境二改成 Range」。

甚至後續截止時間模型再次調整時,同一份 current spec 還繼續被修改。

這一點是我現在回頭看最喜歡的地方之一:

Spec 並不是先寫完就封印起來。

需求變了,它也可以跟著變。

所以 SDD 不是要求我們在第一天就預知未來,把所有需求一次寫到完美。

它比較像是:

當共識改變時,不只改 Code,也一起更新「現在大家認為正確的是什麼」。


那麼今天的主題——Spec-Driven Development,在 Vibe Coding 和專業開發上的差異在哪呢?

假設今天我直接跟 Coding Agent 說:

「幫我把情境二改成讓大家自己回報有空時間。」

它很可能真的馬上開始動工。

但這句話裡沒講清楚的地方,還是得有人補上答案。

可能是我在下一輪 Prompt 補。

也可能是 Agent 先照自己的理解做,等畫面跑出來之後,我才發現:

「啊!不是這個意思。」

再重新修改。

問題不一定是 AI 寫 Code 寫錯。

有時候真正沒被定義的,是:

「到底怎樣才算做對?」

  • Vibe Coding:需求很容易主要存在當下對話裡,邊看結果邊補細節;當 Session、Agent 或負責的人改變,前面為什麼做出某個決定的脈絡也比較容易散掉
  • 採用 SDD 的開發方式:先把需求、預期行為、修改範圍與重要決策留下來,讓人、Agent 和後續實作有一個共同基準;需求改變時,規格也一起演進

差別不只是 AI 有沒有收到 Prompt,而是專案有沒有一份比 Prompt 更長壽的共識。


原來真正值得留下來的,不只有 Code

我現在回頭看 SDD,最有感的其實不是多了多少規格文件。

而是當自己的功能和夥伴負責的功能開始彼此交錯之後,我越來越常需要回頭確認:

「這個東西當初為什麼會變成現在這樣?」

如果答案只散落在某一次討論、某個人的記憶,或某一段和 AI 的對話裡,時間一久,很容易連自己都忘記。

但當規格跟著專案一起留下來,我至少知道可以回頭找:

為什麼當初這樣做?
後來又為什麼改掉?
現在系統正確的行為是什麼?

這也讓我慢慢覺得:

一個功能真正值得留下來的,不只有最後那份 Code,還有當初讓它長成現在這個樣子的理由。

而當需求、預期行為和要完成的 Tasks 都定清楚之後,接下來就要正式進入實作。

這時候,我又開始想:

規格都寫清楚了,要怎麼確定接下來寫出來的 Code,真的符合我們原本定義的行為?

下一篇,就來看另一種從「測試」開始推進實作的方法:

Test-Driven Development(TDD,測試驅動開發)。


參考資料


上一篇
Day 13|支線任務不能亂接回主線:從 Git Flow 看懂多人協作的分支規則
下一篇
Day15|Boss 還沒登場,先把通關條件寫好?從 TDD 看懂 Red-Green-Refactor
系列文
夢幻甜品師闖工程世界:Vibe Coding vs 專業開發的 0→1 冒險攻略19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言