iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
Software Development

我的 SDD 實驗之路 - 從實際使用現有工具,到設計自己的流程系列 第 12

【Day - 12】規劃過期、Bug、平行開工,Spectra 怎麼協助 apply?

  • 分享至 

  • xImage
  •  

前兩篇看過 Spectra 的基本流程,以及指引、文件檢查與歸檔的安排。這篇接著看 apply 前後:規劃文件準備好了,AI 開始實作時,還會遇到哪些問題?

例如,change 放了幾天才繼續做,原本的規劃可能已經跟不上 codebase;實作途中遇到 Bug,需要先找出原因;有好幾項工作想同時進行時,也得避免彼此影響。Spectra 為這些情況提供了一些輔助功能,我們先看看它們分別會在什麼時候用到,再逐一介紹。

這篇使用哪個版本? 以下延續前兩篇,仍以 Spectra 2.3.1 的 Skills、設定與 CLI 行為為準。

這些功能會在 apply 的哪些時候出現?

出現的時機 功能或設定 主要在處理什麼?
開始或恢復 apply 前 drift change 建立後,codebase 是否已經出現足以影響原計畫的變動。
實作途中遇到 Bug debug 問題能不能重現、發生在哪裡,以及真正原因是什麼。
apply 或 debug 真正修改 code 時 TDD 用 Red → Green → Refactor 安排測試、實作與重構的順序。
apply 執行彼此獨立的 tasks 時 parallel_tasks 透過 [P] 標記,讓支援平行執行的 Agent 環境同時處理。
多個 changes 準備同時進入 apply 時 Worktree 替每個 change 準備不同的工作目錄,避免未完成的修改直接混在一起。
每一項 task 完成時 touched files 記下這項工作碰過哪些檔案,不只留下 checkbox。

其中,前一篇的 validate、這一篇的 drift、debug 與 TDD,可以直接放回主要 workflow 的不同位置:

Spectra 2.3.1 在主要 workflow 的不同位置加入 validate、drift、debug 與 TDD:artifacts 更新後先檢查結構,apply 前確認規劃是否過期,遇到 Bug 時先找出原因,真正修改 code 時再依 TDD 順序完成

圖中的 drift、debug 與 TDD 會在不同情況下用到:change 放了一段時間,可以先用 drift 檢查;遇到 Bug 時使用 debug;TDD 則需要先從 .spectra.yaml 啟用。至於 parallel_tasks、Worktree 與 touched files,分別處理工作能不能一起做、工作目錄怎麼分開,以及完成後留下哪些紀錄,因此沒有畫成接續執行的步驟。

接下來,我們就從開始或恢復 apply 前的 drift 看起。假設這份 change 已經放了幾天,期間 codebase 又有其他修改,原本的 tasks 還能直接照著做嗎?

change 放了一段時間,原本的規劃還能直接做嗎?

規劃這份 change 時,AI 參考的是當時的程式碼。如果中間先完成了其他工作,原本打算修改的檔案可能已經搬到別的位置,或某個功能已經換了一種寫法。這時候,tasks 雖然還沒做完,裡面寫的作法卻可能已經不適用了。

drift 就是用來檢查這份規劃是否還適合繼續做。AI 使用 drift Skill 時,會先呼叫下面的 CLI 指令,取得檢查結果:

spectra drift <change-name> --json

CLI 會從【Day - 10】看過的 .openspec.yaml 讀取建立日期,確認 change 已經放了多久,也會檢查 design 提到的檔案、函式或型別是否還存在,以及其他 commit 是否改到了尚未完成的 tasks 涉及的內容,再把變動程度分成 Light、Medium 或 Heavy。接著,AI 會依照 drift Skill 的指引,先說明這個 change 是否適合直接繼續,再列出原因與建議的下一步:變動很輕時可以直接 apply;需要重新調整時,可以先透過 ingest 更新;偏離太多時,則會建議刪除舊的 change,再重新建立一份。

drift 只負責檢查與提出建議,不會自己修改 artifacts,也不會直接替我們執行下一步。最後還是由我們自行決定要繼續、先更新,還是暫停。

apply 會自己執行 drift 嗎? 會,但不是每一次。當時的 apply Skill 會在 change 建立超過 5 天,而且 change 目錄最近 3 天沒有 commit 時,先產生 drift report,再讓我們選擇直接繼續、回到 ingest 更新,或先停下來。這項檢查只是提醒,不會強制擋住 apply。

確認規劃還跟得上 codebase,或透過 ingest 更新後,就可以繼續實作了。不過,實作途中如果碰到 Bug,還是得先把真正的原因找出來!

遇到 Bug 時,先別讓 AI 一直換答案

我們是不是很常看到這種情況:AI 一看到錯誤,就立刻猜一個原因、改一個地方,也沒有先確認這個修改會影響哪些地方。改錯了,就換另一種作法繼續試。這樣一路循環下去,原本的 Bug 不只沒有修好,修補的過程還可能再延伸出幾個新的 Bug。

debug Skill 想避免的就是這種狀況,所以它不會一開始就讓 AI 動手修改,而是先把除錯拆成四個階段:

Spectra 2.3.1 debug 的四個階段:Reproduce 穩定重現問題、Isolate 縮小問題範圍、Root Cause 驗證真正原因、Fix 用最小修改修正

它另外訂了一條限制:同一個假設最多嘗試修正三次。第三次還是失敗,就要先停下來,記錄已經試過什麼,重新檢查 root cause,而不是繼續替同一個猜測換不同寫法。

前三個階段都還在重現問題、縮小範圍與確認真正原因,直到 Fix 才會開始修正程式。不過,debug 不會讓 AI 找到原因後就直接動手,而是要求先建立能重現問題的測試,確認它真的會因為目前的 Bug 失敗。

這一步也剛好把我們帶到 TDD(Test-Driven Development,測試驅動開發):先用失敗的測試把預期行為固定下來,再完成最小實作與重構。如果 .spectra.yaml 已經啟用 TDD,debug 會再取得完整的 TDD instructions,接著依照 Red → Green → Refactor 修正。

現在有什麼不同? Spectra 3.0.0 的 debug Skill 更明確要求先執行測試、重播紀錄或可重複的實驗,讓問題真的出現,再依證據排列可能原因。Fix 後也多了 Integration:如果修正屬於某份 change,就把結果接回對應的 task;獨立的 Bug 則視需要建議建立 proposal。它新增的是修正後怎麼接回 workflow,TDD 仍然放在 Fix 裡。

那麼,Spectra 是怎麼把 TDD 接進 apply 與 debug 的呢?

.spectra.yaml 怎麼把 TDD 接進 apply 與 debug?

前面提到,debug 找到原因、準備修正時,可以依照 TDD 的順序進行。Spectra 把這個設定放在 .spectra.yaml,apply 實作功能時也能使用:

tdd: true

啟用後,AI 會依照 apply 或 debug Skill 的指引,另外呼叫 Spectra CLI,取得完整的 TDD instructions:

spectra instructions --skill tdd

這份指引會要求 AI 按照 Red → Green → Refactor,也就是先寫測試、完成實作、最後重構的順序修改程式。在 apply 裡,如果 specs 已經有具體的 Example,AI 還會被要求優先把 GIVEN/WHEN/THEN 轉成第一批測試。tasks 描述要完成什麼,TDD instructions 則補上每項工作要怎麼做。

這個設定對我來說很方便,因為在改用 Spectra 以前,我就已經要求 AI 先寫測試。搭配寫清楚的規格後,我確實覺得實作穩定不少:specs 提供輸入、操作與預期結果,AI 寫測試時就有內容可以依照。不過,規格漏寫的情境,也可能沒有對應測試,先寫測試並不會自動補齊這些缺漏。

使用 OpenSpec 的那段時間,我會把 TDD 相關要求分別放在 .claude/CLAUDE.mdopenspec/config.yaml.claude/CLAUDE.md 會先放一份整個專案共用的 TDD 提醒:

### TDD 開發

所有開發一律採用 TDD 流程,使用 `tdd-workflow` 技能引導:

- 先寫測試 → 再寫實作 → 最後重構
- 目標覆蓋率 80% 以上(unit、integration、E2E)

config.yamlrules.tasks 則負責告訴 AI,產生 tasks.md 時要怎麼拆出這個順序:

rules:
  tasks:
    - 嚴格遵循 TDD 順序:先寫測試 → 再實作 → 最後重構,禁止先實作後補測試
    - 格式範例:「1.1 撰寫 XXX 測試」→「1.2 實作 XXX 功能」→「1.3 重構 XXX」
    - 每個階段結束須包含編譯或測試驗證步驟

最後產生的 tasks.md,大概會長這樣:

## 1. TDD:撰寫紅燈測試
- [ ] 1.1 先寫測試,確認目前會失敗

## 2. 綠燈:完成實作
- [ ] 2.1 修改程式,讓前面的測試轉綠

## 3. 重構與整合驗證
- [ ] 3.1 整理程式,再執行完整測試

這些設定會讓產生的 tasks 帶上 TDD 順序,CLAUDE.md 則提供專案共用的提醒。換到 Spectra 後,我就不用在兩個地方重複交代這個順序,只要啟用 tdd: true,AI 進入 apply 或 debug 的修正階段時,就會依照 Skill 指引另外取得完整的 TDD 步驟。

為了確認開啟 TDD 後有什麼差別,我請 AI 準備兩個獨立的小專案,使用相同的 change、specs 與 tasks,一個開啟 TDD,另一個不開啟。需求很簡單,就是讓 sum(2, 3) 得到 5

先讓兩邊執行 spectra instructions apply --change <change-name> --json,結果拿到的工作清單、進度與操作指示都一樣。差別出現在下一步:開啟 TDD 的那組,AI 會依照 Skill 指引,再取得一份 TDD 的操作步驟。

接著讓兩組完成這個功能。開啟 TDD 的那組先寫測試,確認測試失敗後才修改程式,最後再重構;未開啟的那組則刻意安排成先寫程式、再補測試,方便比較。兩組最後都完成了 task,也通過【Day - 11】介紹的文件格式檢查。不過,未開啟那組的順序是這次對照刻意安排的,不是 Spectra 規定要這樣做的。

Spectra 2.3.1 開啟與未開啟 TDD 的比較:兩邊使用相同的 apply JSON,開啟後會額外載入 TDD instructions,將實作順序改成 Red、Green、Refactor

這個差別來自 AI 取得的指引。即使開啟 TDD,仍然要靠 AI 照著步驟執行;Spectra CLI 不會檢查測試是不是先寫的,AI 如果先改程式,也不會因此被擋下來。

現在有什麼不同? Spectra 3.0.0 在開啟 TDD 時,還會要求 AI 完成實作後,確認規格裡哪些情境已有測試、哪些還沒測到,以及哪些不需要測試,例如單一畫面的外觀細節。這仍然是要求 AI 執行的檢查,不會因為有缺漏就自動阻止 task 完成。

TDD 安排的是每一項 task 裡,測試與實作的先後順序。那如果有好幾項 tasks 彼此獨立,能不能一起做呢?

同一個 change 裡,哪些 tasks 可以一起做?

【Day - 10】提過,.spectra.yaml 有一個 parallel_tasks 開關。沒有啟用時,AI 會照著 tasks.md 的順序,一項做完再做下一項。設定成 true 後,propose 會先找出「不用等另一項工作完成,而且預計修改不同檔案」的 tasks,替它們加上 [P]

- [ ] [P] 2.1 實作登入錯誤訊息
- [ ] [P] 2.2 補上 session 過期測試

[P] 表示這些工作可以考慮一起做,但還不是確定同時開工。進入 apply 後,AI 會依照 Skill 指引,再檢查連續標記 [P] 的 tasks:有沒有哪一項必須等另一項做完?會不會改到同一份檔案的同一個地方?如果有,就仍然一項一項做。

確認可以分開做,而且目前使用的 Agent 工具也支援同時派出多個 AI Agents,才會讓它們各自處理不同的 task。例如,圖中的 Task A 和 Task B 可以同時開始,Task C 則要等兩邊都完成。如果不符合這些條件,就照原本的順序執行。

Spectra 2.3.1 啟用 parallel_tasks 後,propose 先用 P 標記可以考慮一起做的 tasks,apply 再確認工作不必互相等待、修改範圍不重疊,而且 Agent 工具支援,才交給多個 AI Agents 同時處理

如果中途透過 ingest 更新 tasks.md,原本的 [P] 會保留,新加入的工作也會依照相同條件判斷能不能一起做。

這和 TDD 可以一起使用:parallel_tasks 處理不同 tasks 能不能同時進行,每一項 task 裡仍然可以按照先寫測試、再改程式、最後重構的順序完成。

現在有什麼不同? Spectra 3.0.0 的 propose Skill 不再替工作加上 [P],而是用 [after: ...] 寫清楚「這項工作要等誰完成,才能開始」。例如 1.3 [after: 1.1, 1.2] 整合結果,就是 1.3 要等 1.1 和 1.2 都完成。到了 apply,再根據這些先後順序,找出可以一起做的工作;如果目前的 Agent 環境不支援平行執行,就依序處理。

前面處理的是同一個 change 裡的 tasks。那如果想同時進行好幾個 changes,要怎麼避免不同工作的修改混在一起呢?

多個 changes 同時開工,怎麼把工作目錄分開?

即使替每個 change 分別開啟不同的 AI Agent 對話,只要它們還是共用同一個工作目錄,一邊修改的檔案也會立刻出現在另一邊。要把這些工作分開,還需要各自的工作目錄。

Git Worktree 可以讓同一個 repo 同時存在多個工作目錄(checkout),每個目錄各自使用不同的 branch。Spectra 把這項功能放進 Desktop,而且預設不會啟用;需要時,可以在 .spectra.yaml 打開開關並設定 Worktree 位置:

worktree: true
worktrees_dir: .spectra/worktrees

使用上面的設定後,每個 change 的 Worktree 會放在:

.spectra/worktrees/<change-name>

對應的 branch 則會使用 spx/<change-name>。透過 Desktop 建立 Worktree 後,Spectra 會把這份 change 的 artifacts 移進新的工作目錄,讓它和主要工作目錄裡的其他工作分開。

不過,artifacts 搬過去後,這份 change 並不會從主要工作目錄的畫面消失。Desktop 與 spectra list 仍然看得到它,也會顯示目前位於 Worktree;需要時,還可以透過 Desktop 把 artifacts 搬回主要工作目錄,或移除不再使用的 Worktree。

現在有什麼不同? Spectra 3.0.0 已移除自行管理 Git Worktree 的功能。前面這段是當時的操作方式;現在仍然可以透過 Git 分開工作目錄,只是不再由 Spectra Desktop 建立與搬動這些 Worktrees。

無論 change 最後在哪個工作目錄裡進行,apply 每完成一項 task,還是要更新對應的 checkbox。除了知道工作已經完成,我們還能回頭查到這項 task 改過哪些檔案嗎?

task 打勾後,Spectra 還會留下 touched files

apply 完成一項 task 時,除了把 tasks.md 裡的 checkbox 打勾,也會透過 spectra task done,把這項工作改過的檔案記進 .spectra/touched/<change>.json。例如,下面這筆簡化的紀錄表示 task 1.1 修改了 src/sync.jssrc/sync.test.js

{
  "change": "add-sync",
  "touched": [
    {
      "task_id": "1.1",
      "task_desc": "實作同步流程",
      "files": ["src/sync.js", "src/sync.test.js"]
    }
  ]
}

這樣就能查到每項 task 改過哪些檔案。不過,準備 archive 時,AI 會依照 Skill 指引先刪除這份暫存紀錄,再由 CLI 重新查看當下的 Git 變更,整理相關的程式與測試檔案,寫進【Day - 10】介紹的 @trace

因此,@trace 並不是把每項 task 的檔案紀錄原封不動留下來。同一份 change 裡,不同 requirements 可能拿到相同的檔案清單。它可以幫我們找到相關檔案,但無法精確告訴我們「這個檔案是為了哪一條 requirement 修改的」。

現在有什麼不同? Spectra 3.0.0 的 apply Skill 會要求 AI 在開始 task 前,先用 task start 記下當時的 Git 狀態。完成後,再根據這份紀錄,或由 AI 明確列出檔案,整理這項 task 改了哪些檔案。不過,如果不同 changes 都改到同一個檔案,還是需要確認各自改了哪些內容。

檔案紀錄能幫我們回查修改,但程式有沒有照著規格做好,還需要另外核對。等所有 tasks 都完成後,就可以視需要使用【Day - 9】介紹過的 verify。

從開始前檢查規劃,到實作途中處理 Bug、安排工作,再到完成後留下紀錄,這些都是 Spectra 在 apply 前後提供的協助。實際把這些功能用進開發工作後,我也開始思考哪些作法適合自己,哪些地方還想調整。

用順之後,也開始想改成自己的作法

Spectra 後來成了我主要使用的 SDD 工具,而且一直用到現在。先用過 OpenSpec,再換到 Spectra,就更能感受到這些功能帶來的方便:規劃時可以透過 propose 一次準備好文件,中途改需求有 ingest 幫忙更新,AI 有時候也會提醒我接下來可以做什麼。原本需要自己處理的事情,現在有工具幫忙,真的輕鬆不少。

用久之後,我也開始有自己的想法。有些流程用得很順,想繼續保留;有些地方則會忍不住想:「如果改成這樣,會不會更符合我的習慣?」這不就跟龍哥當時想調整 OpenSpec 一樣嗎XD。於是,我也想試著做一套自己的 SDD workflow。不過,要先做哪些東西,才能真的拿來用呢?下一篇,就來看看我怎麼開始吧!

參考資料


上一篇
【Day - 11】從指引到歸檔,Spectra 怎麼安排每一步?
下一篇
【Day - 13】Speclink 從哪裡開始?Skill、AI Agent 與 CLI 怎麼分工?
系列文
我的 SDD 實驗之路 - 從實際使用現有工具,到設計自己的流程14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言