iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
Software Development

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

【Day - 25】功能一直往上加,AI 能找出該重構的地方嗎?

  • 分享至 

  • xImage
  •  

前一篇把一份 change 的歸檔與紀錄整理好後,留下了另一個問題:功能一項項完成,原本的程式結構還適合嗎?有些重複或不好修改的地方,是累積幾次開發後才慢慢看出來的。

我自己寫 code 時也差不多:剛遇到需求,可能先用最直接的方式完成;類似需求再次出現,才會考慮把邏輯抽成共用函式。至於要不要改用物件或設計模式,還是得看當下遇到什麼問題,不會每次都照同一套順序重構。

換成 AI 寫 code 後,如果 task 只要求把功能做出來,它也不一定會主動回頭整理既有結構。【Day - 22】介紹的 Review 可以檢查這份 change 的修改,但幾份 changes 陸續完成後,還可能出現跨越不同功能的重複邏輯。那麼,我能不能隔一段時間,請 AI 找出值得整理的地方,再由我決定要不要做呢?

我在 Speclink 裡做的 improve,就是從這個問題開始。

看到 Matt Pocock 的 Improve,我也想拿 Speclink 試試看

前面介紹 grill-me 與 code review 時,已經出現過 Matt Pocock 的 Skills。其實他的技能集裡還有一份 improve-codebase-architecture,目標是從 codebase 找出「deepening opportunities」。

當時 Speclink 已經開發一段時間,卻還沒有特別停下來整理過整體架構。看到這份 Skill 時,我第一個反應就是:這個感覺很有料,剛好可以拿 Speclink 來試試看!

不過,deepening opportunities 這個詞我一開始也看不太懂。和 AI 查詢、討論後,我才慢慢理解它想找的方向:使用一個模組時,不需要先搞懂一大堆內部細節;相關的複雜邏輯,則盡量放在一起處理。

例如,理解同一個功能時,是不是得來回打開很多小檔案?呼叫一個模組以前,是不是得先知道它裡面怎麼做?這些都是它會留意的地方。

其中有一個判斷叫 deletion test:如果拿掉某一層抽象,能把原本分散的邏輯放回一起,讓後續修改更容易理解,就值得繼續研究;如果只是把相同的問題搬到另一份檔案,這次調整可能沒有什麼幫助。

當時怎麼參考? 和前面的 grill-me、code review 一樣,我當時沒有實際安裝 Matt Pocock 的 Improve Skill,而是從官方內容、影片與其他人的介紹得到啟發,再回到 Speclink 裡設計自己的流程。

Matt Pocock 的版本會先產生一份臨時 HTML report,再針對選中的候選繼續提問。這次寫鐵人賽文章時,我另外請 Codex 跑過一次,得到下面這份報告。這裡先看它怎麼整理候選就好:涉及哪些檔案、問題在哪裡,以及調整前後有什麼差別。

寫鐵人賽時請 Codex 依 Matt Pocock Improve Skill 產生的 HTML report,列出候選的涉及檔案、問題、建議與調整前後圖解

Speclink 已經有 discussion 可以保存問題、選擇與結論,我不想再多做一種只用一次的報告格式。那麼,能不能讓 AI 掃描後找到的候選,也從 discussion 接著談?

還不知道要改哪裡,就先讓 improve 找出候選

一般的 discuss,是我先提出「登入流程要怎麼調整」或「這幾個需求應該怎麼拆」,AI 再沿著題目幫我釐清。improve 的起點剛好相反:我主動要求掃描,但一開始還沒有準備好要開哪一份 change,先由 AI 從 codebase 找出幾個值得討論的重構候選。

要讓 AI 找題目,開始掃描以前還是得先決定範圍:我有指定某個模組、子系統或痛點時,它就只看那裡;沒有指定時,才從 Git 紀錄裡最近常被修改的檔案與 archived changes 裡的 evidence 推測可以先從哪裡找。這些修改紀錄只用來縮小範圍,AI 還是要回到實際 code,確認那裡是不是真的值得重新整理。

找到候選後,improve 不會直接開始改 code,而是先把掃描結果寫進 discussion 的第一個 Round。每個候選都要列出涉及的檔案、實際問題、建議作法、做完後會改善什麼,以及 AI 的推薦程度。等我選定一項,AI 才繼續一次問一題,把哪些邏輯真的適合共用、會影響哪些地方,以及是否值得再多加一層抽象談清楚。

Conclusion 完成後,確定要做的內容才會進入 propose;如果所有候選最後都不做,這場 discussion 也會寫下結論並封存,保留每個方向不採用的理由。

所以,兩個入口的差別在於題目怎麼來:discuss 從我提出的問題開始,improve 則先請 AI 找候選。討論過程都會留下 Rounds,談妥後再整理 Conclusion:

discuss 從使用者提出的問題開始;improve 先掃描並把候選記入第一個 Round,選定後繼續查證與討論,談妥後整理 Conclusion

第一次掃描,AI 提了四個我看不太懂的候選

第一次真的在 Speclink 跑 improve 時,我沒有指定模組,最後掃描範圍落在 CLI 層。AI 一口氣提出四個候選,裡面充滿了各種架構名詞。老實說,我當時每一項大致都有看,卻沒有真的看懂那些名詞在說什麼,更不知道實際會改到哪裡XD。

幸好 improve 不會因為候選已經列出來,就當成我答應要做。它還是得回到 discussion,一項一項把問題問清楚。寫鐵人賽時,我回頭看了一下當時 improve 留下的內容,把四個候選和後來的處理結果整理成下面這張圖:

第一次 improve 找到四個候選:共用顯示結果、集中資料來源判斷、把同一個 command 放回一起,以及確認 CLI 與 Speclink Desktop 能否共用資料整理;前三項進入 change,第四項查證後不改

前三個候選後來都進入實作,第四個則在重新查證後決定不改。這裡先看前三項做完後,同一個 command 有哪些地方變得比較單純。

這次重構,讓 list 少了哪些重複修改?

以 Speclink 的 list command 為例,調整以前,接收指令、取得資料與顯示結果的程式碼散在不同位置。CLI 可以讀取本機檔案,也可以向遠端服務取得資料,當時這兩種模式各自維護了一份顯示邏輯。畫面想多顯示一項資訊時,得記得同時修改好幾個地方。

前面提到的「共用顯示結果」「集中資料來源判斷」與「把同一個 command 放回一起」,後來各自建立了一份 change。這三份都完成後,再回頭看 list,調整前後就會像下面這張圖:

經討論並完成三份 changes 後,list 統一判斷資料來源、集中相關程式碼,並共用顯示邏輯

這三份 changes 沒有替 CLI 增加新功能,主要是把原本散在不同地方的程式碼重新收在一起。以前同一項調整可能得在好幾個地方重複處理,AI 只改到其中一個,就可能讓不同執行方式出現差異;現在需要維持一致的顯示結果會共用同一份邏輯,改一個地方就能一起套用。下次 AI 再修改 list 時,也不用先到處找還有哪些地方要跟著調整。

前三項處理完後,還剩下 CLI 與 Speclink Desktop 能不能共用資料整理的候選。同樣是看起來相近的程式碼,這次也適合收在一起嗎?

第四個候選最後決定不改

第四個候選原本懷疑,CLI 與 Speclink Desktop 各自維護了一份相似的資料整理程式碼,或許可以抽出來共用。光看候選描述,這個方向很合理:兩邊都在整理資料,放在一起不是比較好嗎?

等前三份 changes 都完成並封存後,我才讓 improve 回頭查證第四個候選。結果才發現,兩邊需要保留的資料其實不一樣;真正重複的部分本來就已經共用了,剩下的程式碼則各自處理自己的需求。硬是搬到同一個地方,只是換了位置,並沒有真的減少重複。

最後,這項討論的 Conclusion 是 no change,沒有建立新的 change。查證後確認原本的分工已經合適,就把不改的理由留在 archived discussion 裡。這份紀錄後來也真的派上用場。

上次決定不做的方向,下一次還會再被提出嗎?

【Day - 16】提過,discussion 即使最後決定不做,也可以把理由留下來。improve 會沿用【Day - 18】介紹的舊討論搜尋,先看看相關方向以前有沒有談過。那麼,留下這些紀錄,真的能讓 AI 少提一次已經討論過的建議嗎?

寫這篇鐵人賽時,我把前面請 Codex 產生的 Matt Pocock Improve HTML report,交給 Claude Code,再跑一次 Speclink improve。報告裡有一項建議,包含了「把資料格式轉換的程式集中處理」這個作法,剛好就是前面第四個候選最後決定不做的方向。

Claude Code 找回 improve-wire-convert-seam 的 Conclusion,確認當時不改的理由仍然成立,這份報告也沒有說明現在為什麼值得改,所以沒有再把這個作法列進去。拿掉這部分後,仍然有兩個候選可以繼續討論。下面截圖中的「砍掉的子項」,說的就是這次被排除的作法:

Claude Code 找回以前決定不改的討論,確認理由仍然成立後,從報告建議中拿掉相同的作法,整理後仍有兩個候選可繼續討論

這次留下的討論紀錄,確實讓我少談了一次相同的問題。不過,如果之後需求或程式結構改變,原本不值得做的調整,也可能需要重新考慮。AI 還是得先看懂當時為什麼不改,再判斷現在的情況是否不同;工具不會只因為名稱相似,就直接排除這項建議,也不能保證 AI 每次都找得到相關紀錄。

我會在什麼時候使用 improve?

我不會每完成一份 change 就跑一次 improve。通常是隔一段時間,覺得功能已經加了不少,或某個地方開始愈來愈難改時,才請 AI 回頭看看。目前 improve 也需要我主動啟動,AI 不會在其他工作做到一半時,自行開始這套流程。

improve 這些操作步驟,可以直接寫在自己的 Skill 裡。但像專案使用的技術、命名習慣或測試要求,可能好幾個流程都會用到,又該放在哪裡?每份 Skill 都寫一次,之後不好一起修改;全部塞進 CLAUDE.md,又會愈寫愈長。

接下來,就來聊聊我怎麼整理這些規則吧!

參考資料


上一篇
【Day - 24】一份 change 做完後,Speclink 怎麼整理規格與紀錄?
下一篇
【Day - 26】AI 的專案規則,該放在 CLAUDE.md、config.yaml 還是 Skill?
系列文
我的 SDD 實驗之路 - 從實際使用現有工具,到設計自己的流程 共 26 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言