前面六天的案例,都是崩潰、鎖死、撞號、效能異常——AI 犯錯,或者人跟 AI 一起被現實打臉。今天要講一個完全不同性質的案例:一次單純的需求規格討論,從頭到尾沒有 bug、沒有事故。 但正因為沒有戲劇性的翻車,反而更適合拿來問一個平常被忽略的問題——當協作很順利的時候,AI 到底在幫你做什麼?
這次的任務,是既有的稽查 APP 的 API(甲縣市已經上線在用),現在要擴充給另一個縣市(乙縣市)使用。
一開始我只丟了一句話:「請先讀取這支程式,我想要針對該程式進行規格調整。」AI 讀完 910 行程式碼後,沒有反問我「作業流程是什麼」,而是從路由參數、swagger 描述、彼此的引用關係(例如某支 API 的註解寫著「步驟 2 或步驟 4 取得之 guid」)反推出一整套作業流程,附上一張 API 一覽表,然後才說:「以下是我的理解,請確認。」
這個順序很值得注意:先用手上的證據建構一個可驗證的假設,再拿去對答案,而不是先問一輪需求。 我確認了大方向,但也糾正了兩個細節——某支查詢 API 其實是刻意取「歷次申報的聯集」、某個回存動作寫入的其實是第三張表,跟場所、申報並列,不是掛在申報底下。AI 收到糾正後,立刻回頭把資料模型的層級關係重新講一次,還順手推導出一個我沒明講的隱含事實:這次稽查存進去的內容,會在下次稽查時出現在歷史紀錄欄位裡,整個流程其實是閉環的。
甲縣市的流程確認完,我丟出乙縣市要擴充的四項新需求(排班機制、多張照片、新增稽查類別、簡圖標註)。AI 沒有照單全收去逐項설計,而是先停下來問了一個貫穿全局的問題:
「甲縣市與乙縣市是同一套部署、同一個資料庫嗎?」
這個問題問得很準——因為答案會決定接下來每一項需求是「加參數」「加欄位」還是「開一支全新的端點」,順序反了,後面的設計會全部推倒重來。AI 還一併問了「乙縣市是新做一支 APP,還是沿用同一支」,因為如果是沿用,所有既有回傳結構的異動都得向後相容。這兩個問題都不是需求細節,是先把地基問清楚,才不會蓋到一半發現方向錯了。
討論到「改既有端點」還是「開一支平行端點」時,我提出一個判斷依據:「這支專案有完整的單元測試,似乎可以把改既有端點的風險降到最低。」
AI 沒有直接順著這個前提往下走,而是先做了一次測試覆蓋盤點,逐一對照每支端點有沒有測試。結果:其中一支查代碼用的端點完全沒有測試,另一支查書圖的端點邏輯寫在路由層、根本無從測試。
「先做測試覆蓋盤點,再談選型——因為盤點結果會直接推翻『有完整單元測試所以敢改』這個前提。」
這跟系列裡大部分「AI 犯錯、人糾正」的案例方向正好相反:這次是 AI 的查證習慣,戳破了我自己過度樂觀的假設。 我以為的「有測試保護」,實際上是「一半有、一半沒有」。
還有一段類似的糾正:我提到早期團隊只測 module、不測 router,是因為測 router 常常跳出 timeout 或 slow 的雜訊,很惱人。AI 沒有接受「router 測試本身有問題」這個歸因,而是指出實際發 HTTP 請求的測試工具是行程內呼叫、路由分派是微秒級的,真正拖慢測試的是後面那段資料庫查詢——這段耗時測 module 一樣要付,不會因為換成測 module 就消失。真正的雜訊來源,其實是告警門檻設得太低,導致幾乎每一筆都被標黃、久了黃色就失去意義。AI 建議的是回頭校準門檻,而不是接受「router 測試不可靠」這個結論。
討論到一半,我明講了一條規則:
「如果是程式或邏輯錯誤可以順手修正,但是業務動作要先問過我才可以修改。」
這句話很短,但很重要——它把「AI 可以自主判斷的範圍」跟「必須先問過人」的範圍畫成兩塊,不是憑感覺,是明說。這正是 Day 07 講過的「human-in-the-loop 是分工設計」的另一個實例,只是這次分工邊界是在需求討論階段就先講清楚,而不是等出事之後才補。
乙縣市的稽查允許多人負責同一個場所(雖然承辦人「發誓」不會同時處理同一個場所,但「人類誓言不可信」,所以設計上要假設真的會衝突)。討論到後來,規則定案為:檢查紀錄以「場所編號+日期」為唯一鍵,先上傳者生效,後上傳者撞鍵作廢,作廢內容不保留,由承辦人自己到後台調整。
AI 在這個規則定案之後,追出了一個沒人提過的漏洞:
「乙花了一天做檢查,回辦公室補傳,後端收下照片、丟掉文字、回一個成功——若 APP 收到成功就把本機佇列清掉,乙那份檢查結果就真的消失了,他到後台要調整檢查結果時已經無從參照,只能憑記憶重打。」
問題出在「作廢」跟「失敗」在 APP 端看起來是同一種「成功」回應,APP 會照樣清空手機上的暫存資料。承辦人辛苦一整天蒐集的檢查內容,會在完全沒有察覺的情況下憑空消失。AI 的建議是:回傳要區分「正常轉入」跟「撞鍵作廢」兩種成功,後者要讓 APP 保留本機資料、提示使用者自行到後台補登。這個洞不是靠測試踩出來的,是靠把整條資料流程在腦中重新跑一遍、想到「APP 端拿到成功會做什麼」才浮現的。
這篇沒有真相大白的高潮,因為根本沒有謎題要破——但正因為如此,才看得清楚 AI 在一次順暢協作裡實際貢獻了什麼:
先讀程式碼、用證據建構理解再邀請確認,而不是被動等指令;遇到「這應該沒問題吧」的樂觀假設,先去查證再回答,而不是順著語氣附和;把「這樣做會不會有雜訊」的抱怨,往回推到真正的機制上,而不是照單全收使用者的歸因;在規則定案之後,繼續把資料流程在腦中跑一遍,抓出設計者自己都還沒想到的邊界情況。
這些都不是「解決一個已知的錯誤」,是在事情發生之前,先把地基檢查一遍。跟系列前面幾天比起來,這種價值很不顯眼——沒有崩潰畫面、沒有戲劇性的「AI 你錯了」時刻,但少了這層查證習慣,「乙的檢查結果無聲消失」這種問題,往往是等到真正出事、有人來投訴,才會被發現。
明天要離開需求討論的世界,回到生產環境的另一個事故——一個所有連線設定都對、程式碼也沒有改過的即時通訊功能,本機測試一切正常,一換到正式環境卻整個斷線,而且連一行有意義的錯誤訊息都沒留下。