跳到主要內容

FDT|S0:我與 AI 一起掉進的迴圈:從規格審查,到讓執行結果說話

 一開始,我以為這會是一個很單純的專案設計過程……

先把需求與架構想清楚,再把規格文件整理完整,接著按照 Task 一個一個實作。尤其在 AI 開始大量參與開發之後,我更相信前期規劃的重要性:既然 AI 可以很快幫忙整理、比對、分析,那麼先把規格打磨得完整一些,後面的實作應該會更順利。

結果,我和 AI 一起把這件事情做得太認真了。最後甚至認真到,差點忘了我們原本是要做一個可以運作的系統。
________________________________________

# 🏗 起點:我以為把規格做好,專案就會更穩

為了還有機會能夠實現「跨足半導體產業」的這個職涯發展目標,我在近期展開了一項以「半導體晶圓廠的數位孿生模擬系統建構」為主軸的技術展示專案。

在真正開始寫程式之前,我先花了大量時間整理既有設計。這些內容原本也是我在另一段長期 AI 協作過程中逐步建立起來的,涵蓋資料庫、事件定義、派工邏輯、部署方式等。

問題是,多輪討論留下來的設計,難免會有前後不一致、細節缺漏,甚至某些地方只是為了讓文件看起來完整,而被暫時補上的內容。

所以我的第一個想法很自然:

先請 AI 把文件好好審一遍。第一輪發現問題,就修正;修完,再審;再發現問題,就再修。每一輪看起來都很合理,直到後來,我開始發現,這套流程正在悄悄改變自己的目的…

原本我們想確認的是:

「這個系統到底怎麼做?」

後來卻變成:

「這份文件和另一份文件,是不是完全一致?」

# 🌀 當品質控管開始檢查自己

最麻煩的地方是,每一次審查都真的有成果。AI 找出了矛盾,我們修掉它;補上缺漏,我們又增加對應的規則與紀錄。於是文件越來越完整,審查機制也越來越細緻。

可是回頭看最後幾輪時,我發現一個很不舒服的現象:

後面的很多問題,其實不是原始設計造成的,而是前面的審查與修正自己製造出來的。
我們建立了一套自我檢查、自我糾錯的機制,最後卻開始花大量時間檢查自己昨天留下來的東西。

更尷尬的是,真正需要被實作的程式,依然沒有因此更接近可以執行。

那一刻我才意識到,文件的「完整度」和專案的「進度」其實是兩件完全不同的事情。

有些工作看起來很像品質控管,但如果它不能幫助系統更接近可驗證的狀態,就值得重新檢查它存在的理由。

________________________________________

# 😶 AI 很快,但它不會替我決定「現在到底該做什麼」

這次經驗也讓我重新思考 AI 在專案中的位置。AI 很擅長分析、整理、比對與提出修正建議。

只要我繼續提供問題,它就能非常有效率地把問題往下拆,甚至建立出比原本更完整的管理流程。但這裡有一個容易被忽略的陷阱:

「AI 可以很有效率地幫你把一件事情做得更完整,卻不代表那件事情本身值得繼續做。」

方向的判斷,仍然必須由人負責。所以我後來停止繼續增加審查規則,改問一個更直接的問題:

「這份規格,真的拿去做 Task,能不能用?」

這成為整個專案的轉折點。
________________________________________

# 🔧 轉折:不要再審規格,直接拿去消耗一次

我開始把規格真正拿去做實作,不是再多讀幾遍文件,而是直接寫 Task Card、設計執行流程、建立實際會被使用的 SQL 與程式邏輯。

這個過程很像「消耗」一份規格,因為當規格真的被拿去使用時,原本藏在文字裡的問題會很快浮現。
有些地方明明看起來寫得很完整,真正實作時才發現根本不知道下一步該怎麼走;有些地方看似有答案,仔細推演後才知道,其實只是我自己默默替它補了一個假設。
所以我給自己一個很簡單的規則:

「可以猜,但不能假裝沒有猜。」

每一次遇到規格沒有明確定義的地方,我都把自己的假設留下來:
  • 我猜了什麼?
  • 為什麼這樣猜?
  • 如果猜錯,會影響什麼?
  • 這個決定是不是會跨越目前 Task 的邊界?
這些動作很重要,因為它把「我覺得應該是這樣」和「規格明確要求這樣」分開了。而一旦兩者被分開,後面的討論就容易很多。
________________________________________

# 🔍 每一個 Task,都是一次小型驗證

後來,我和 AI 協作的方式也開始改變。AI 不再只是幫我「完成任務」,而是成為每一個 Task 裡的推演夥伴。

我會先提出自己的理解,再請 AI 找反例、想下一步、檢查依賴,然後把建議真正拿去實作。
實作之後,再回頭看執行結果。

如果結果和原本的理解不同,就重新檢查假設。

如果需要修改,就把修改原因留下來。

如果問題其實屬於另一個尚未開始的 Task,我就不急著把答案硬塞進現在的設計。

慢慢地,我發現自己真正建立起來的,不是一套更複雜的文件系統,而是一個反覆循環:
 
這個循環裡,AI 可以幫我把每一步做得更快,但每一步是否成立,都必須回到可驗證的結果。
________________________________________

# 🧠 「再往下一步」有時候比「現在看起來合理」更重要

過程中,我還養成一個自己很喜歡的習慣。

當 AI 提出一個看起來合理的方案時,我不急著接受,而是多問一句:

「如果真的照這樣做,再往下一步會發生什麼?」

這個問題曾經推翻幾個原本看起來完全合理的決定。

例如,一份索引文件少了一些內容,直覺反應是「那就補上」。

但再往下想,如果那份文件原本就不是完整索引,補上一部分,反而可能讓下一個接手的人誤以為它已經完整。

最後的決定反而是:保留現況,但明確標記它的用途與限制。

另一個案例則是驗收條件與實際執行結果對不上。

第一直覺可能是修改測試,讓測試配合文件;但再往下追,才發現真正錯的是文件本身。

這時候,真正正確的做法不是讓程式遷就錯誤,而是承認原本的定義有問題,直接修正源頭。
這些事情讓我越來越確定:

「工程判斷不只是找到答案,而是知道哪一個答案現在不應該被接受。」

________________________________________

# 📦 收斂:知道什麼該留下,也知道什麼不該繼續干擾

到了後期,我開始重新整理前面留下的東西。

有些審查文件仍然有價值,但它們應該被封存,而不是繼續成為實作輸入;有些資料可以保留作為歷史紀錄,但不需要每個 Task 都重新閱讀。

我也重新設計了任務的閱讀方式。真正影響整體架構的內容,成為每個 Task 都需要理解的「架構骨幹」;其他細節則依照實際任務需要再深入。

我希望做到的不是「每個人都知道全部」,而是:

「每個 Task 都知道自己應該知道什麼,也知道自己不應該決定什麼。」

這件事對我而言,比把文件寫得更加龐大更接近工程上的成熟。而當有些決策真的還不到可以決定的時候,我也開始接受一件事情:

「不硬給答案,也是一種工程上的誠實。」
________________________________________


# 🚦 最後的驗證:讓系統自己告訴我答案
最後一次讓我印象很深的是 GitHub CI。

文件收斂後,我把成果提交上去,結果 CI 很快出現失敗。以前看到這種情況,我很容易第一時間回頭翻文件,猜是不是哪裡又出現矛盾。

但這一次,我直接去看執行結果。最後發現,問題其實來自專案早期留下的 CI 設定。它假設某些工具與程式骨架已經存在,但那些內容原本就是後續階段才會建立。

也就是說,CI 失敗不代表這次修改出了問題,而是它正在檢查一個「現在本來就還不存在」的條件。

這件事讓我很有感,因為它剛好替整趟過程做了最好的示範:
  • 不要用猜的。
  • 不要再從文件推測答案。
  • 直接去執行。
  • 直接去看錯誤。
  • 直接讓系統告訴我,到底是哪一件事情真的沒有成立。
持續整合的價值,本來就包含透過自動化建置與測試儘早暴露整合問題;而這次經驗也讓我更深刻體會到,「執行結果」本身就是一種非常有價值的規格驗證。
________________________________________

# 💬 回望:AI 可以幫我走得更快,但方向仍然要由我負責

回頭看,我不能說前面的審查都是浪費。

它確實幫我找出了不少原始設計中的問題,也讓我看見很多原本沒有被清楚說明的地方。

但它真正教會我的,是另一件更重要的事情:

「任何品質控管機制,都有可能在某個時刻從『幫助專案前進』,變成『維持自己存在』」。
而 AI 的高效率,甚至可能讓這件事情發生得更快。

因為 AI 很擅長把事情繼續往下做,所以真正重要的,不只是「會不會使用 AI」,而是:
  • 我是否知道現在真正要解決的是什麼?
  • 我是否能把每個 Task 的邊界守住?
  • 我是否願意把自己的假設標記成假設,而不是把猜測包裝成規格?
  • 我是否願意在驗證結果與原本想法不一致時,承認原來的判斷需要修改?
  • 以及,我是否知道什麼時候該繼續探索,什麼時候該停止,讓專案正式收斂?
這也是這次專案讓我對 AI-assisted development 最深的一個體會:

「AI 可以幫我更快地探索、分析與實作,但人真正不可取代的價值,是定義問題、控制邊界、驗證結果,以及為最後的決策負責。」

真正好的 AI 協作,不是把更多事情交給 AI,而是讓 AI 幫我們更快碰到真實問題,再由人把每一次發現,謹慎地轉化成下一個更好的工程決策。

________________________________________

# 延伸閱讀

以下內容不是說這個專案「正式採用了」某個既定方法,而是回頭看這次實作時,可以與幾個成熟的軟體工程觀念相互對照。

1. Continuous Integration — Martin Fowler
持續整合強調頻繁整合、透過自動化建置與測試儘早得到可驗證的結果。這與本文從「文件推測」轉向「直接執行驗證」的思路有直接呼應。

2. Documenting Architecture Decisions — Michael Nygard / ADR
ADR 的核心不是記錄大量文件,而是清楚留下 Context、Decision、Consequences,使團隊能理解「為什麼做這個決定」。本文中對假設、決策與後續影響的留痕,可以從這個角度進一步理解。

3. Specification by Example — Gojko Adzic
這套方法強調以具體例子來描述需求與驗證,而不是只停留在抽象規格。本文中的「直接把規格拿去做 Task、從實作中暴露規格缺口」,可以視為與這種思維相近的實務經驗。

4. 人機協作工程日誌規範(Human-in-the-Loop AI Dev Journal)
本文並沒有把 AI 當成可以自行決定方向的代理,而是把 AI 放在分析、推演與實作的位置,由人負責問題定義、邊界與最終判斷。這也正是本文最想留下來的核心:AI 的效率越高,人反而越需要保持判斷。

# FDT 系列文章更新註記:

文章標題標記 #FDT 的文章,是我的個人專案【Fab-Digital-Twin】的一系列開發心得。
而本篇文章則是該專案的 Spring 0【Design Freeze】。

關於本專案的系列心得文章如下:
  • Spring 0【Design Freeze】:我與 AI 一起掉進的迴圈:從規格審查,到讓執行結果說話