The Focus on Architecture

對 AI 時代的軟體工程師來說,專注架構將為我們的機器夥伴帶來指數的成長。

我最近的工作都在重構,每天沒日沒夜都在重構。在重構的過程中,我發現幾件從前就很重要(我們不停得跟工程師說,也寫在團隊規則中),且跟 AI 合作之後,仍然很重要的事。

對於中大型軟體專案而言,良好的軟體架構從來都是很重要的基礎。隨著跟 AI 一起寫程式的經驗越來越多(實務上是每天都離不開各種 AI)。我覺得軟體架構的重要性不僅沒有減少,反而變得更加重要。原因也很簡單 —— 我們的機器人朋友需要清晰的結構和明確的界限來幫她發揮最大效用。

最近又讀了一次 Uncle Bob 的《Clean Code(中譯:無瑕的程式碼)》,讓我感覺比以前更重要,以下列出幾點實際操作的想法分享給大家:

Token 效率:架構即語境

使用 AI 工具時(無論是 Codex、Claude 或 Gemini CLI,我個人是最愛 Claude CLI),每一次對話都有 Token 限制(我假設你預算有限,就算預算無限,使用更多 Token 意味著效率降低,你得花更多時間喝咖啡)。雜亂無章的程式碼意味著我們需要提供更多的語境資訊,消耗更多的 Token(💸💸💸)才能讓 AI 理解我們的意圖。相反,結構清晰的程式碼本身就是最好的說明文件。

想像一個場景:我想要 AI 幫助我修改一個功能。如果我的程式碼採用了良好的分層架構,我只需要向 AI 展示相關的介面定義和少量的實作細節,AI 就能快速理解整個系統的運作邏輯。但如果程式碼結構混亂,你可能需要提供大量的上下文,甚至整個檔案的內容,才能讓 AI 明白你的需求。

好的架構設計就像是為 AI 提供了一個清晰的地圖,每個模組的職責和邊界都清楚標示。這不僅節省了 Token 跟費用,也提高了 AI 回應的準確率,降低他發生幻覺的機會。

嚴謹的命名規則

命名規則的重要性我覺得從前就很重要,現在更是重要得多!對人類來說,一個略顯模糊的函數名稱可能透過上下文或同事的解釋來理解(雖然很煩),但對 AI 而言,名稱往往是理解程式碼意圖的第一線索。

好的命名規則不單單只是讓程式碼更具人類可讀性,也可以讓 AI 更容易理解系統語意。當你的函數(function)名稱為 calculateInterestRate() 而不是 calc() 時,AI 可以更快速的理解這個函數的用途、輸入期望和可能的輸出格式。(這時候我覺得強型別語言更佔優勢)這種語意明確性讓 AI 能夠更準確地推斷相關的業務邏輯和資料結構。

更重要的是,嚴謹的命名規則能夠減少 AI 的「創造性猜測」。當名稱語意明確時,AI 不需要依賴上下文來推斷功能,這大大降低了產生錯誤理解的風險。這種精確性在大型專案中尤其重要,因為錯誤的理解可能導致連鎖反應,影響整個系統的穩定性。

我的實際狀況是 Codebase 中有比較多的命名錯誤,導致 AI 往往讀到某個函數時,會誤會函數的作用,而造成 AI 幻覺,導致錯誤調用函數。這時候只能強迫 AI 做更多研究、或者停下來先好好看看函數名稱,重新幫它取個正確的名字。

我們團隊有嚴謹的 prefix 與 suffix 命名規則(包括各種陣列、布林值得使用規範,並且避免縮寫!!),一致的命名慣例除了幫助人更快了解資料內容、還能幫助 AI 識別系統中的模式和關聯性。

例如,如果你的專案中所有處理用戶資料的類別都以 User 開頭,所有服務類別都以 Service 結尾,AI 就能自動推斷出新功能應該遵循的命名模式。這種一致性讓 AI 生成的程式碼更容易融入現有的系統架構中。

測試驅動的 AI 協作

測試對我來講就像是守門員,至少可以在當 AI 犯錯時,能夠擋下致命錯誤。另一方面,測試也可以作為規格說明,讓 AI 需要修改或擴展某個功能時,可以透過閱讀測試案例快速理解預期的輸入、輸出和邊界條件。

一個具備完整測試覆蓋率的專案,讓 AI 能夠更大膽地進行重構和優化,因為任何破壞性的改動都會被測試捕捉。就像是兩個協作的機器人,一個負責做,一個負責檢查。這種安全網的存在,讓人類工程師更願意信任 AI 的建議和實作。

噢對了!有了 AI 後,寫測試變得容易多了,儘早投資吧!

模組化設計:多 Agent 並行工作的基礎

無論是 Codex、Gemini 還是 Claude CLI,我們其實可以讓多個 AI Agent 同時處理相同 Repo(前提是你前面幾步都有做對)。一個負責前端邏輯,另一個專注於後端 API,還有一個專門處理資料庫操作。這種並行工作模式的前提是程式碼必須具備良好的模組化設計。

清晰的模組界限讓不同的 AI Agent 能夠專注於各自的領域,而不會相互干擾。每個模組都有明確的輸入和輸出接口,讓 AI 能夠獨立工作,同時確保整個系統的一致性。這種模組化的方法還有另一個優勢:它降低了溝通成本。當不同的 AI Agent 需要整合各自的工作成果時,標準化的介面和清晰的契約讓這個過程變得簡單直接。

架構也是一種 System Prompt

最後,我覺得很多人會不小心忽略的一件事——良好的程式碼架構本身也是一個天然的 System Prompt。它透過程式碼的組織方式、命名慣例和結構設計,無聲地傳達了系統的設計理念和約束條件。

你習慣用什麼風格寫作?Linter 的設定是什麼?習慣在什麼情況使用什麼設計模式?哪些功能應該被封裝在軟體的哪一層?這些你需要花大量時間說明寫 Prompt 的內容,其實都可以在日常生活中,紀律的維護架構一制性來慢慢提升。

當 AI 接觸到一個架構良好的專案時,它不需要額外的指導就能理解應該如何貢獻程式碼。程式碼的結構自然地引導 AI 採用一致的風格和方法。這種隱式的指導比明確的規則更加有效,因為它融入了程式碼的每一個細節中。

好好的跟同事(人類與機器人)討論軟體架構,我覺得會是一個值得的投資。