昨天聊到,AI 在資訊還不完整時,可能先根據假設往下做;而需求改變之後,舊的假設也可能繼續影響後面的結果。
放回軟體開發的情境,我覺得這有點像小時候疊積木蓋房子。如果下面已經歪了,還一直往上加,房子可能就會越蓋越不穩。這時候得回頭檢查,看看哪些地方需要調整,才能繼續往上蓋。

開發時也是如此。隨著需求逐步釐清,我們得重新檢查原本的假設與結構是否還適用。但很難要求自己在第一個 prompt 就把所有事情想清楚吧?這些調整,本來就是持續開發的一部分。
那昨天留下的問題就來了:軟體工程可以怎麼幫助我們與 AI,一起面對這些變動?
軟體工程兩大重點:
當問題規模很小、需求固定,而且幾乎沒有後續維護成本時,很多軟體工程方法的價值確實不容易體現。
但如果這個東西要一直用下去,我們就得考慮:下次需求改變時,還看得懂原本怎麼做的嗎?知道要改哪裡嗎?改完之後,又怎麼確認沒有影響其他功能?
軟體工程的各種方法,就是在處理這些問題。至於需要做到什麼程度,仍然得看專案的情境,沒有一套永遠適用的最優解。
回到昨天的 Context。AI 在修改程式時,需要知道目前的規則、相關程式的行為,以及這次修改要達成什麼目標。
如果這些資訊只存在我們腦中,或者散落在前後矛盾的對話裡,AI 就可能根據不完整或過期的資訊往下做。
而平常的工程習慣,可以幫助我們把這些資訊留下來、整理清楚。
例如,程式的命名與結構能表達各部分的用途;文件可以記錄需求與設計理由;測試則能把部分預期行為變成可執行的檢查。當 AI 讀取這些內容時,就有更具體的依據理解專案。
當然,前提是這些內容仍然反映現況。需求改了,文件與測試卻沒更新,反而可能成為另一個誤導來源。所以重點也包括:修改功能時,一起確認哪些既有資訊與決定需要調整。
另一方面,如果程式各部分的責任與合作方式比較清楚,我們也比較容易找出這次任務相關的內容,向 AI 說明修改範圍,以及需要注意的影響。
這不代表 AI 從此不會犯錯,但當結果不符合預期時,我們有依據可以回頭檢查,並把檢查結果交給 AI 繼續修正。合作就能形成「理解、修改、檢查、調整」的過程。
而整理文件、探索不同拆法、補上測試與執行檢查,AI 本身也能協助完成。這也是我覺得兩者能相輔相成的地方:工程方法讓合作有依據,AI 則有機會降低實踐這些方法的成本。
你可能會覺得,現在 AI 能力那麼強,在 prompt 裡提醒它「保持乾淨的架構、遵守軟體工程原則」,不就好了?
首先 Know how 絕對是人類最基本的必備條件,有足夠知識你才能更有效率地使用 AI agent 並且與其討論。
一直很喜歡李宏毅老師提過的一個例子,人類之於AI,就像是坐在大象上的象伏,大象是有能力,但若無法好好下指令駕馭 也無法得到你想要的結果。
而且就如同recap提到的重點,軟體開發不存在最佳解。在各個設計架構之間是存在不同 tradeoff 的。
所以相比於只要求「請保持良好的架構」,若有相關的背景知識,能更容易的與其進行討論:目前有哪些需求?哪些地方可能改變?這次的拆法能幫上什麼忙,又增加了哪些成本?
並透過與AI在對話中的次次的摩擦,不僅讓能加深自己的作品的理解,也提高對其能力的掌握度。 可喜可賀。
但,AI又已經這麼發達了,這過程中,部分老舊的軟工概念有機會淡出,也有新的維度需要帶入。
這也是我想透過這個系列挑戰的事情:並且如何系統化的介紹AI時代下的軟體工程。
接下來會開始介紹軟體工程的相關概念,大致分成三個方向。
順序會從比較具體、結果容易檢查的方法,逐步走向需要根據情境判斷的設計與取捨。
1. 規則與紀錄:讓 code 容易接手,讓修改有依據
先從閱讀 code 所需的精力開始,聊命名、function 長度、參數量,再介紹 formatter、linter、Git、測試,以及設計文件與決策紀錄。
目標是讓我們更容易理解 AI 寫了什麼、追蹤改了什麼,以及確認修改後的結果。
2. 程式組織與模組化:把想法變成程式
腦中有一個 workflow,要怎麼拆成可以分段執行的程式?資料與行為要放在哪裡?各部分又要怎麼合作?
這裡會搭配例子,介紹程序導向、物件導向、class,以及物件之間的持有/組合與繼承關係,練習把想法表達成具體的程式結構。
3. 設計原則與取捨:為什麼要這樣拆?
再往下會聊抽象與實作,以及 SOLID 等設計原則,可能搭配 design pattern 或 DB 的實際例子。
除了理解原則本身,也會討論它能處理什麼問題、增加什麼成本,以及什麼時候值得採用。
每個主題都會包含概念介紹、例子,以及如何與 AI 一起合作。具體篇幅再邊寫邊調整。
明天就開始進入正文吧