跳到主要內容

FDT|S1:我用五個任務,學會了怎麼跟 AI 一起把事情做「對」


多數人談「跟 AI 一起寫程式」,很容易把注意力放在 Prompt:怎麼問得更精準、怎麼讓 AI 產生更好的程式碼。

但在這個專案的第一階段走完幾個 Task 之後,我得到了一個有點不一樣的答案:

「真正影響 AI 協作品質的,不只是你怎麼問 AI,而是你替 AI 建立了什麼樣的工作環境。」

這個環境裡,有規則、有任務邊界、有測試,也有獨立的檢查與驗證。而我自己真正需要做的,反而不是一直「教 AI 寫程式」,而是在它給出一個看似合理的答案時,多問幾次:

「你確定嗎?」

以及:

「我們真的驗證過了嗎?」

這五個 Task,最後留給我的,不只是一批程式碼,而是五個我認為值得帶進下一個專案的工程習慣。
________________________________________

# 第一課:讓「能不能跑」當裁判,而不是「讀起來對不對」

專案早期,我曾經非常相信文件。一份設定檔看起來合理,一份規格也寫得完整,AI 審查過、我自己也看過,似乎就應該沒問題。

直到有一次,我們把容器真正建置起來,結果掛了。問題不是某一行設定寫錯,而是建置方式讓原始碼在開發環境中只是被「連結」進去,到了正式映像檔的階段,原始碼目錄消失,連結自然也跟著失效。

如果只看設定檔,很難發現這件事情。但只要真的建置、真的執行,問題立刻就出現。那次之後,我開始把一個很簡單的原則放進專案:

「凡是可以透過執行驗證的事情,就不要只靠閱讀來相信。」

一段寫在註解裡的限制,可能永遠沒有人注意;但如果它變成一個會失敗的測試,系統就會主動告訴你。所以後來遇到「這個東西應該可以跑」的說法,我不再把它當成結論。

實際跑一次!

讓執行結果說話。
________________________________________

# 第二課:連你手上的尺,都要先量過一次

當我開始依賴測試之後,又遇到另一個問題:

「如果測試本身就不可靠呢?」

於是我們開始用變異測試,故意把程式改壞,再看看測試能不能抓到,結果真的抓到問題了——但不是我們原本想測的問題。

有些測試單獨執行時可以正常失敗,連續執行卻偶爾會放過錯誤。一路追查後,才發現底層的快取機制會依賴檔案修改時間;在特定情況下,系統誤以為檔案沒有改變,於是繼續使用舊版本。

換句話說:「我們用來量品質的尺,本身量錯了。」

另一個例子也很有意思。獨立審查 AI 曾經判斷某個日誌工具「對這個專案是失明的」。這個說法聽起來很有道理,我們甚至一度準備把它寫進文件。但實際測試之後才發現,工具不是看不到,而是受到測試執行順序影響。

這件事最後變成我很珍惜的一條守則:

「審查者的發現,是線索,不是結論。」

AI 可以幫我找到值得調查的地方,但它的判斷仍然需要被驗證。包括——驗證 AI 的驗證結果。
________________________________________

# 第三課:承認錯誤,可以被設計成流程的一部分

這是整個階段,我覺得最有價值的一課,因為 AI 的答案有時候真的很合理,甚至合理到,你會忍不住直接採用。

有一次,AI 建議用外部掛載的方式提供設定檔。乍看之下很乾淨,也很方便。但我重新把它放回整個專案的未來規劃裡思考:如果之後系統部署到 Kubernetes,這種方式還成立嗎?

答案是 No。

於是原本「現在最好做」的方案,被退回去了。

另一個案例則更直接,AI 建議某個缺陷「留給未來任務處理」,還引用專案規則作為理由。我重新檢查那條規則後發現,AI 引用錯了。

那條規則真正限制的是「不要把未來任務的工作提前做」,而現在這兩個問題,其實是當前 Task 自己交付內容中的缺陷,所以修正它們,不是越界。

「修好自己交付的東西,本來就是自己的責任。」

這些經驗讓我開始刻意把「認錯」設計進流程。每一個重要決定,都要重新對照專案真正的目標,而不是因為上一輪已經說過,就假設它一定正確。

AI 可以推翻自己,我也可以推翻自己。

重要的不是誰先說對,而是最後留下來的決定,有沒有經過真正的求證。
________________________________________

# 第四課:突發奇想,要有一道「帶評判標準」的閘門

做專案最容易失控的時候,往往不是遇到大問題,而是突然想到:

「既然都做到這裡了,要不要順便把這個也改掉?」

這些想法很多其實都是好點子,但問題是「好點子,不代表現在就該做」。

所以我開始替這些想法設一道閘門。
  1. 要有證據,而不是只有預測。
  2. 要知道現在做與之後做,各自會付出什麼成本。
  3. 如果延後並不會讓成本明顯增加,那就留給真正負責它的 Task。
這套方式曾經讓我刻意「不做」幾件看起來值得做的事情。

例如:我發現某個資料庫目錄未來很可能造成問題。我沒有直接偷偷補掉,而是先實測重現,把錯誤留下來,再交給真正負責那一塊的任務處理。

甚至,連「把第三方套件換成自己實作的演算法」這種看起來很有技術含量的想法,也只是先完成候選方案的驗證與紀錄,而沒有趁機塞進當前 Task。

因為工程上的成熟,有時候不是「我能做什麼」,而是「我知道什麼事情現在不該做」。
________________________________________

# 第五課:把踩過的雷,變成專案的資產

如果每一次踩雷最後只剩下一句「這次學到了」,那其實很可惜。所以到了後面,我開始把那些錯誤與驗證結果留下來。不是單純記錄「發生過什麼」,而是記錄:

「當時我們相信什麼、怎麼發現它不對、最後怎麼證實,以及下一次應該注意什麼。」

例如:某種快取會讓測試結果失真、某個日誌工具其實受到執行順序影響,或者某些看似權威的測試,其實只是在比對自己寫死的常數。

這些東西慢慢變成專案自己的「地雷圖」,下一個 Task 不需要重新踩一次,而且流程本身也開始隨著這些經驗改變,任務卡不只描述「現在要做什麼」,還會再問一次:

「這個決定會不會影響很後面的任務?」

階段之間的接縫需要有人負責驗證。CI 不只是用來判斷程式有沒有壞,也成為提醒流程缺口的一道訊號。這些規則都不是一開始就設計好的。

它們是專案自己踩過幾次雷之後,慢慢長出來的。

________________________________________

# 尾聲:回頭看:AI 負責把事情做得更快,人負責確保它真的做對

這五個 Task 走完後,我對 AI 協作開發的理解,和一開始已經不太一樣。我原本以為,AI 的價值主要是提高寫程式的速度。現在我反而覺得,更重要的是:

「AI 可以把探索、推演與實作的速度拉得很快,但也因此更需要有人替它守住方向。」

人需要知道什麼時候該相信,什麼時候該驗證;什麼是規格,什麼只是自己的假設;什麼是當前 Task 的責任,什麼應該留給未來;什麼時候應該繼續探索,什麼時候應該停止,讓專案收斂。更重要的是,當結果證明自己錯了時,願不願意承認。

所以如果要用一句話總結這段經驗,我現在會這樣說:

「AI 可以幫我更快地把事情做完,但我的工作,是確保我們做的是對的事情,而且知道為什麼它是對的。」

而真正成熟的 AI 協作,也許不是讓 AI 越來越像一個「不用管的工程師」,反而是建立一個環境,讓 AI 可以快速犯錯、快速被發現、快速修正,同時讓每一次錯誤都能沉澱成下一次更好的工程決策。

這五個 Task 對我而言,最大的成果因此不是完成了多少程式碼。而是逐漸建立了一種工作方式:

「先做、再驗證;相信,但要查證;發現錯誤,就修正;有好點子,但守住邊界;踩過的雷,留下來讓下一次不用再踩。」

這可能才是我目前對「人與 AI 一起開發」最實際的理解。
________________________________________

# 延伸閱讀

以下幾個概念並不是說這個專案「照著某套方法論實施」,而是回頭整理這段實作經驗時,我發現它們與其中一些做法有很直接的對照:

1. Mutation Testing(變異測試)
對應「故意把程式改壞,確認測試真的抓得到」。

2. Executable Specification / Specification by Example
對應「把原本停留在文字裡的限制,轉成可以實際執行與驗證的條件」。

3. Determine Test確定性測試
對應『讓「能不能跑」當裁判,而不是「讀起來對不對」』。

對應容器建置與來源可追溯性的實作經驗。

對應「好點子不一定現在做」,以證據與成本判斷是否應該跨越目前任務邊界。________________________________________


# FDT 系列文章更新註記:

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

關於本專案的系列心得文章如下: