AI友好架構:AI程式設計最佳正規化,構建10x效率提升的程式碼庫(萬字長文)

AI 友好架構是一種將成熟的軟體架構原則與生成式 AI 的能力相結合並進行調整的軟體構建方法。其核心目標是建立一個既便於人類協作,又能被 AI 高效理解、分析、生成和持續演進的程式碼資產與系統環境,從而顯著提升開發效率。
生成式 AI 在你的程式碼庫上工作不好存在諸多原因,其中一個就是:你的程式碼庫不夠 AI 友好。而除了 AI 不友好之外,它存在的另外一個問題就是:對於人類來說也不友好。工作於程式碼庫的團隊沒有保持一致的規範與最佳實踐,導致了程式碼庫的可讀性差、可維護性差、可擴充套件性差等問題。
文章太長,詳細見:https://ide.unitmesh.cc/ai-friendly

引子 1:軟體工程 – 團隊實踐優於最佳實踐

軟體工程並沒有所謂的真正最佳實踐,只有適合於團隊的實踐。在使用 AI 之前,我們有必要對團隊現有的軟體工程實踐進行一個簡單的梳理。

程式碼命名規範的產生:構建統一的語言

舉我們最簡單的金融場景作為示例,你有一個產品名稱: 穩享靈動慧利,那麼你的程式碼應該怎麼寫:
  • 直接翻譯:SteadilyEnjoyAgileWisdomAndBenefits
  • 挑選重點:AgileBenefitController
  • 拼音全稱:WenXiangLingDongHuiLi
  • 拼音首字母:WXLDHL
  • ……
通常來說,方案 1 和方案 2 肯定不是你的首選,因為你的 Tech Lead/架構師會告訴你:其他人看不懂 —— 並不止是考慮到外包或者新手程式設計師,還要考慮其他 人查詢程式碼時也會一臉懵逼。方案 3 和方案 4 是最常見的選擇,所以只要團隊達成一致即可。

程式碼檢視在檢視什麼:維護團隊最佳實踐

當拼音達到了某種默契之後,會達到另外一種氾濫:使用者會被翻譯為 YongHu,或者作為福建人經常遇到的梗:YongFu。那麼,如何去避免這個問題呢?一種 簡單的方法是:程式碼檢視。在這種場景下,你使用 Sonarlint 之類的工具,並不能很好地幫助你解決這個問題,所以我們會依靠於程式碼檢視在一定程度上解決 這個問題。
我們預期程式碼檢視的目的是:
  • 規範一致性:命名規範、程式碼風格、註釋規範等
  • 保持最佳實踐:通用邏輯模式採用、程式碼重用等
  • 業務邏輯正確:程式碼修改是否符合業務邏輯
  • 潛在的 bug:邏輯錯誤、效能問題等
通常來說,你很難透過程式碼檢視來發現潛在的 bug:
  • 多數人很難深入瞭解業務邏輯,難以考慮到所有的邊界條件
  • 程式碼檢視的時間有限,無法覆蓋所有的程式碼
所以,多數情況下,程式碼檢視的目的並不是為了發現 bug,而是為了讓團隊達成一致的規範與團隊最佳實踐。

遏制麵條式程式碼:分層築結構,內聚定邊界

我們常常在微觀細節上追求程式碼質量,卻可能忽視了宏觀架構的持續“腐化”,導致可維護性下降,最終陷入“麵條式程式碼”的困境。這往往是因為我們未能 從結構層面思考:新程式碼應置於何處?相關邏輯應如何組織? 錯誤的放置和無序的增長,不僅使程式碼超出人類的認知極限,也讓 AI 難以有效理解和介入。
應對之道在於構建清晰的結構,這主要依賴於兩個相輔相成的策略:
  1. 架構分層 (Layering):在宏觀上,透過分層(如表現層、業務邏輯層、資料訪問層)來劃分系統的主要職責區域 。這強制性地隔離了不同型別的關注點(例如,介面邏輯不應與資料儲存邏輯混合),為程式碼庫提供了高層級的秩序和導航圖。
  2. 邏輯內聚 (Cohesion/Aggregation):在微觀上,即在各層內部,強調內聚性。這意味著功能上緊密相關的程式碼單元(類、函式、模組)應該聚合在一起。例如,所有處理“使用者認證”的邏輯應集中管理,而不是散落在各處。這確保了模組功能的單一性和明確性。
當現有的設計不夠時,重構變成了我們改進的手段,以將不同職責的程式碼,按照邏輯關係,清晰地劃分到不同的“層”或者“模組”中去。

引子 2:嘗試並理解 AI 程式碼生成的限制要素

通常來說,在我們使用 AI 進行程式設計時,會分為多種方式:
  • 網頁聊天式生成:即 ChatGPT 之類的網頁聊天式生成,其特點是需要手動輸入上下文
  • IDE 外掛式生成:即在 IDE 中直接生成程式碼,可以選擇上下文,或者自動選擇上下文
兩種模式的核心差異在於是否帶有使用者的上下文資訊。

理解基於上下文的 AI 程式碼生成:龍生龍,鳳生鳳

在使用 AI 外掛的程式碼補全時,你會明顯發現:生成的程式碼質量優於 ChatGPT 之類的網頁聊天式生成。以 AutoDev 示例專案 假設我們希望生成一個新的 API 介面:delete blog 介面,那麼我們會在 getBlog 的結束處新增一個註釋:Untitled 工程中的 BlogController 為例。
  1. @RestController
  2. @RequestMapping("/blog")
  3. publicclassBlogController{
  4. BlogService blogService;
  5. publicBlogController(BlogService blogService){
  6. this.blogService = blogService;
  7. }
  8. @ApiOperation(value ="Get Blog by id")
  9. @GetMapping("/{id}")
  10. publicBlogPost getBlog(@PathVariableLong id){
  11. return blogService.getBlogById(id);
  12. }
  13. // delete blog by id
隨後,觸發 AI 模型的補全或者模型生成,生成的程式碼如下:
  1. @ApiOperation(value ="Delete Blog by id")
  2. @DeleteMapping("/{id}")
  3. publicvoid deleteBlog(@PathVariableLong id){
  4. blogService.deleteBlogById(id);
  5. }
其中的 @ApiOperation 便是根據我們前面的程式碼規範而生成的附加程式碼,在 deleteBlog 這個方法名同樣會受到我們前面程式碼命名規範的影響。也因此,當你基於別人的程式碼修改時,會發現 AI 的質量可能不如你預期的那麼好。好的程式碼會讓 AI 生成更好的程式碼,而屎山則更容易讓 AI 生成屎山。當兩種型別(規範好和差)的程式碼非常好的混合在一起時,你就只能靠運氣了。
如果你預期 AI 生成一大段程式碼(多個方法)時,當缺乏足夠的上下文時,補全式模型的效果會大打折扣,諸如於生成不存在的方法。而現在的補全式模型往往為了效果更好 ,所以會過度擬合,進而導致難以生成大段程式碼。

理解好的問題表達的重要性:欲速則不達

在生成式 AI 時代,問題表達的質量直接影響生成程式碼的質量。我們在使用 AI 進行程式設計時,通常會面臨兩種情況:
  • 模糊的需求描述:如 “實現一個使用者管理功能”,AI 可能生成不完整或不符合預期的程式碼。
  • 問題過於急迫或簡單:希望透過簡短的指令迅速得到程式碼,這種做法往往會導致生成的程式碼存在許多潛在問題。
在 AI 幫你實現使用者管理功能時,他需要先能通過當前的程式碼庫理解什麼是使用者,什麼是管理,才能有限地根據你的需求生成程式碼。否則,AI 會根據自己的理解 隨機生成程式碼,導致質量不高。
因此,首先我們需要定義:在生成式 AI 時代,什麼是好的問題?(這個可以交給 AI 來研究,諸如 Google DeepResearch)。
核心要素初步識別
透過初步搜尋,我發現了一些構成有效 AI 提示的關鍵要素,例如清晰的任務指令、充分的背景資訊、具體的細節描述、明確的角色設定、 期望的輸出格式以及所需的語氣和風格。此外,提供範例和設定約束條件也是很重要的技巧。
簡單來說就是好的提示詞技巧。有效的提示詞需要清晰和具體,諸如於:
  • 明確任務指令: 清晰地說明希望 AI 完成的具體任務(如“編寫一個 Python 函式”、“重構這段 Java 程式碼”、“生成 SQL 查詢”)。避免使用模糊或歧義的語言。
  • 提供充分背景資訊 (Context): AI 需要上下文來理解任務所處的環境。這包括:
    • 專案背景: 告知 AI 專案的目標、使用的技術棧(語言、框架、庫版本)、架構模式等。
    • 現有程式碼: 提供相關的現有程式碼片段、介面定義、類結構或函式簽名,讓 AI 瞭解當前的實現方式和約束。
    • 領域知識: 如果任務涉及特定業務領域,提供相關的領域術語、規則或概念(如 DDD 中的通用語言)。
  • 具體細節描述: 詳細說明需求,包括輸入、輸出、預期行為、需要處理的邊界條件或錯誤情況。例如,不僅僅是“計算階乘”,而是“編寫一個 Python 函式 factorial,接受一個整數 n 作為輸入,返回 n 的階乘。確保處理 n 小於 0 的情況,返回 None”。
結合這些提示詞工程技術,特別是充分利用現有程式碼庫的上下文和領域知識,可以顯著提高 AI 生成程式碼的準確性、相關性和質量,使其更好地融入專案。

理解受限的小引數理解能力:巧婦難為無米之炊

PS:如這裡的子標題,我們藉助於 ChatGPT 生成了歇後語。
在現今的 AI 輔助程式設計工具裡,通常會帶有大量的不同模型,諸如於:補全、FastApply、聊天、推理等。不同模型引數不一,有的模型引數高達 175B,甚至更高,而有的模型則只有 6B。通常來說,引數越大,模型的理解能力越強。諸如於網傳的早期的 Copilot 應用中:補全採用的是 ~ 12B 的模型 Codex,而補全採用的是 ~175B 的模型 GPT-3.5。當你的引數量變小以後,比如採用的是 3B 的補全,模型很難理解複雜的需求,又或者是對於中文的理解能力變得非常有限。在這種時候,可能會出現類似於,你 使用簡單的中文描述,模型卻無法理解的情況。
當你想實施複雜的需求時,你就需要藉助於引數大的模型來構建。因此,模型越大,生成質量越好,但是速度越慢;針對不同場景,需要不同生成策略

構建 AI 友好程式設計:從實踐到模式

透過一篇文章來介紹 AI 友好型架構是一種困難的事,我將盡可能使用模式來抽象,以便於你在不同的場景下進行使用。這些模式的目標是建立一個既便於人類協作,又能被 AI 高效理解、分析、生成和持續演進的程式碼資產與系統環境。

模式:領域知識豐富上下文與問題定義

問題:使用者的需求描述往往模糊不清,AI 難以理解其意圖,導致生成的程式碼質量不高。

實踐方式:領域語言與提示詞工程最佳化使用者輸入

解決方案:透過應用領域驅動設計(DDD)的原則,將複雜的業務領域知識顯式化、結構化,為 AI 提供更豐富、更精確的上下文資訊, 從而提升其對需求的理解和生成程式碼的質量。
實現示例:在 AutoDev 中,我們透過 AI 生成領域術語表,使用者在輸入內容後,可以選擇最佳化提示詞來豐富上下文資訊。
  1. 構建術語表。透過靜態程式碼分析拿到所有的類名、函式名資訊,交給模式來分析理解和生成,生成 domain.csv,包含中英文和描述資訊。
  2. (可選)使用者介入編輯術語表。
  3. 最佳化提示詞。使用者在 AutoDev 的輸入框內,點選最佳化提示詞後,即可以將上下文資訊帶入需求中。
舉例:使用者的需求是:“實現一個使用者管理功能”,那麼可以結合領域知識,利用 DDD 的通用語言(Ubiquitous Language),將其重新定義為:實現一個“使用者賬戶管理”的功能,包含“使用者註冊 (Customer Registration)”、“使用者啟用 (Account Activation)”、“使用者資料更新 (Profile Update)”等。即透過領域術語來豐富需求描述,提供更清晰的上下文資訊。
詳細定義示例:“(角色:資深 Java 工程師)使用 Spring Boot 框架,實現一個‘客戶賬戶管理’限界上下文的核心功能,包括:(1)處理 POST 請求 /customers/register 用於客戶註冊 (Customer Registration),接收包含'name', 'email', 'password' 的 JSON,驗證 email 格式和密碼強度,成功後儲存至資料庫併發布‘CustomerRegistered’領域事件。(2)處理 POST 請求 /accounts/activate/{token} 用於賬戶啟用 (Account Activation)……” 這種方式提供了更清晰的業務術語、技術約束和具體行為描述。

實踐方式:將需求工程應用於 AI 互動

解決方案:在 IDE 連線線上的需求相關的工具(如 Jira、Confluence、Notion 等),將使用者的輸入/需求轉換為檢索條件(如關鍵詞),呼叫線上的工具 進行檢索,獲取相關的需求資訊,再將使用者的輸入轉換為帶完整需求上下文資訊的提示詞,交給 AI 進行處理。
實現示例:在 Cursor、Copilot、AutoDev 等工具中,可以透過自定義 Agent、MCP 等工具,讓使用者可以接入自己的需求工具、智慧體,以讓使用者 按照自己的需求進行檢索。
  1. 使用者構建自己的 Jira MCP 伺服器
  2. 將 MCP 伺服器配置到專案中使用
  3. 將檢索到的 Jira Issue 的摘要、驗收標準(Acceptance Criteria)、附件設計文件等內容,按照“領域術語表 + 需求模版”格式彙總,交由模型來處理。
舉例:使用者輸入:“新增支付提醒功能”,可以由工具來提示:在 Jira 中找到 2 條相關 Issue:PAY-102、INVOICE-58,是否將它們的描述和驗收標準作為上下文?[是/否]?由使用者來進行確認是不否進行關聯,並進一步最佳化提示詞。

模式:基於專案知識與規範的智慧生成

問題:AI 程式設計助手通常缺乏對特定專案的深入理解,包括其編碼規範、技術棧選型、架構設計、領域術語、歷史決策以及團隊約定等。當開發者與 AI 互動時, 若不手動提供這些上下文,AI 生成的程式碼或建議往往是通用的,可能不符合專案標準、引入不相容的技術、或與現有架構衝突。反覆手動提供完整上下文效率低下且易遺漏關鍵資訊。
解決方案:構建一個系統性的框架,使 AI 助手能夠自動、持續地獲取並利用專案特定的知識和規則,從而將其響應“錨定”在專案的實際環境中。

實踐方式:藉助 Project Rule 預先定義專案上下文

問題:在每次與 AI 互動時手動提供完整的專案特定上下文(編碼規範、技術棧、架構模式、API 約定等)效率低下且容易遺漏,導致 AI 生成的程式碼不符合專案要求或團隊標準。
解決方案:利用現代 AI 編碼助手提供的“專案規則”或“自定義指令”功能,預先定義專案上下文資訊,使 AI 能夠自動載入並遵循這些規則。這需要結合有效的知識捕獲和管理策略, 並透過檢索增強生成(RAG)技術將知識提供給 AI。
實現示例:利用現代 AI 編碼助手提供的“專案規則”、“自定義指令”或類似配置功能。
舉例:在專案特定位置(如 .cursorrules.github/copilot-instructions.md, IDE 設定)建立配置檔案。其可能包含以下內容:
  • 規則內容: 使用自然語言(常為 Markdown)描述:
    • 編碼規範與風格指南: 如命名約定、程式碼格式化標準。
    • 技術棧與庫約束: 指定使用的框架、庫版本,停用或推薦特定庫/API。
    • 架構模式與設計原則: 如微服務、事件驅動,DDD 限界上下文劃分,SOLID 原則的特定應用。
    • API 使用約定: 內部/外部 API 的呼叫方式、認證要求、資料格式。
    • 錯誤處理策略: 標準的異常處理流程、日誌記錄級別與格式。
    • 領域術語: (可連結到第一個模式中的術語表)專案的核心業務術語及其含義。
  • 作用域管理: 支援全域性、專案級、特定檔案型別/路徑的規則設定,甚至動態啟用規則(如 Cursor)。
透過有效利用這些 AI 程式碼助手內建的規則配置功能,團隊可以顯著提升 AI 程式碼助手的實用性和可靠性,使其更好地融入特定專案的開發流程。

實踐方式:持續的專案知識捕獲與注入

解決方案:讓 AI Agent 能夠利用專案中不斷積累和演變的動態知識,以及使用者偏好,理解更深層次的背景、決策邏輯和隱性經驗。
實現機制:利用 AI Agent 的 "Memories" 功能,將關於工作區和使用者偏好的關鍵資訊持久化儲存在本地(例如,可能儲存在專案下的 .augment 資料夾內的 augment.memories 檔案中)。系統會自動學習並更新這些記憶,同時使用者也可以透過直接編輯記憶檔案、點選互動介面中的 按鈕或向 Agent 發出明確指令來手動管理記憶內容。這些儲存的記憶隨後作為檢索增強生成(RAG)的關鍵知識源:系統在處理請求時會檢索相關的記憶, 並將其與當前上下文(如程式碼庫資訊)一同注入給大語言模型,從而生成更符合使用者需求和專案背景的響應。
舉例:諸如 Augment 的 Memories 會記錄使用者在對話中的關鍵細節,以 augment.memories 儲存在專案中,以供後續對話時使用。以下是之前記錄的一些具體使用者偏好示例,這些都可能被儲存在 augment-memories.md 中:
  • The user wants to use jetBrains jewel repository as a reference for fixing project errors.
  • Use JetBrains JewelUI components exclusively instead of Material components.
  • The user wants to use a send button icon from JetBrains jewel instead of a restart icon.
潛在的挑戰:記憶汙染/損壞:自動學習可能出錯,手動編輯也可能引入錯誤;透明度不足:難以完全理解記憶內容及其影響;管理開銷:需要使用者主動監控和清理,增加負擔;安全風險:本地檔案可能成為提示注入的目標。

小結:手動的知識獲取

需要強調的是,“專案知識驅動的上下文注入”模式的成功實施,高度依賴於團隊持續進行有效的知識管理。這包括對顯式知識 資源(如專案文件、知識庫、程式碼註釋、設計規範)的系統性維護,以及對隱式知識 (蘊含在團隊經驗、歷史決策、溝通討論、開發實踐中)的挖掘與沉澱。只有當這些專案知識被有效捕獲並變得可訪問時,“專案規則”和“Agent Memories”等上下文注入機制才能發揮最大效用,(通常透過 RAG 技術)為 AI 提供準確、豐富的上下文資訊。

模式:自文件化程式碼增強語義化表達

問題:傳統的軟體文件(如外部規格說明書、設計文件、註釋檔案)往往與程式碼實現不同步,維護成本高,資訊滯後 。程式碼作為開發者溝通的核心媒介,如果本身不夠清晰,會導致其他開發者(或 AI 工具)難以理解其功能、意圖和互動方式,增加了認知負荷和維護難度 。

實踐方式:語義化命名與結構化設計

解決方案:讓程式碼本身成為其最主要、最準確的“文件” 。透過系統性地應用一系列編碼實踐(如清晰命名、良好結構、明確型別、策略性註釋等),使程式碼的結構、命名和表達方式儘可能清晰、直觀,從而讓閱讀者能夠直接透過閱讀程式碼來理解,減少對外部解釋的依賴 。
實現示例:
  • 命名規範:使用描述性強的變數、函式和類名,如 calculateInvoiceTotal() 而非 calc()。
  • 結構化設計:遵循設計模式(如 MVC、MVVM)和編碼規範,確保程式碼模組化、可重用。

實踐方式:適應於 AI 理解的程式設計正規化

問題:傳統程式設計往往隱含許多假設:函式輸入引數的有效範圍、返回值關係等沒有明確定義。呼叫者或開發者難以預知這些假設,一旦違背前提就可能引發錯誤。AI 輔助生成的程式碼也無法知道這些潛在契約,可能產生行為不可預測的實現。
解決方案:在程式碼中顯式定義前置條件(Precondition)、後置條件(Postcondition)和不變數(Invariant)。例如,在函式簽名或註釋中宣告引數要求, 在關鍵位置加入斷言(assert)或使用契約庫。這樣函式的期望行為清晰可見,任何呼叫都必須滿足前置條件,保證後置結果符合預期。明確的契約既約束了程式碼正確性,也為 AI 提供了語義線索。
實現示例:
  • 利用型別系統 (Type Systems):在靜態強型別語言(Java, C#, TypeScript)中,明確的型別註解提供了關於資料結構、函式簽名和預期資料流的強形式化資訊,AI 可利用這些資訊生成型別安全且符合介面的程式碼。
  • 採用契約式設計 (Design by Contract, DbC):透過嵌入形式化的前置條件 ( requires)、後置條件 ( ensures) 和不變數 ( invariant),精確描述元件的責任和期望行為。
  • 擁抱函數語言程式設計 (Functional Programming, FP) 原則:
    • 純函式: 無副作用,輸入相同則輸出相同,簡化 AI 的推理過程。
    • 不可變性: 避免狀態修改,使程式碼狀態更易預測和跟蹤。
    • 高階函式與組合: 模組化和宣告式風格可能更易於 AI 理解結構和意圖。
語義豐富性與實用性的權衡:像高階型別系統和 DbC 這樣的技術為 AI 提供了顯著更豐富的語義資訊,但與基本的命名約定或註釋相比,它們的採用成本和複雜性更高。AI
的理解能力隨著更明確的語義資訊的增加而提高。

模式:驗證優先開發(Validation-First Development)

驗證優先開發(Validation-First Development,簡稱 VFD)是一種針對 AI 生成程式碼固有不確定性與幻覺現象而設計的軟體開發模式。它以“生成-審查-測試-最佳化”為核心迴圈,強調* 先快速生成,再嚴格驗證與最佳化*,透過多輪迭代保障最終軟體產出的正確性、可靠性與可維護性。
在程式碼生成語境下,幻覺指的是 AI 生成了看似合理但實際上是錯誤的、不存在的、無意義的或者與事實不符的程式碼、API 呼叫、庫引用、配置項或邏輯片段。例如,AI 可能自信地使用一個虛構的庫函式,或者實現一個聽起來合理但演算法邏輯完全錯誤的排序方法。這種現象源於大型語言模型基於模式匹配和機率預測的本質,而非真正的理解或推理。
背景問題:傳統開發方法論(如 TDD、BDD)強調精確的預先定義和確定性實現,難以適應 AI 程式碼生成固有的機率性及其可能產生的“幻覺”(即看似合理但實際上錯誤的程式碼)。

直接將未經充分驗證的 AI 生成程式碼整合到系統中,存在質量、安全性和合規性風險,容易快速積累技術債務。

實踐方式:生成-審查-測試-最佳化迴圈

解決方案:採用以“驗證”為核心的快速迭代迴圈,充分利用 AI 的生成效率,同時確保產出符合質量標準。

核心原則

是承認 AI 輸出的機率性,將開發焦點從“規範驅動實現”轉向“生成後驗證”,並透過嚴格、多維度的檢驗管理潛在風險。
實現示例:
  • 生成 (Generate)。使用 AI 程式碼生成工具(如 GitHub Copilot、Cursor、Windsurf 等)根據提示快速產出程式碼、測試用例、文件等內容。
  • 審查 (Review)

     。結合人工審查(程式碼走查、邏輯檢查、幻覺識別)與自動化工具(靜態分析、風格檢查、複雜度分析、安全掃描)評估生成產物。

    可輔助使用工具,如 Windsurf 的 Lint 自動修復功能或 CodeRabbit 的智慧審查模組。
  • 測試 (Test) 。採用全面、自動化的驗證策略,超越傳統單元測試,涵蓋功能正確性(如屬性基測試)、效能效率、安全漏洞掃描(SAST/DAST)、魯棒性(模糊測試)及語義正確性(業務規則驗證、架構約束檢查)。
  • 最佳化 (Optimize)。根據審查與測試結果,透過人工修改或最佳化提示詞(Prompt Engineering)進行改進,形成持續閉環迭代,直至達到質量標準。

檢查策略

由於幻覺檢測是一個活躍且未完全解決的研究領域,目前最佳實踐通常是結合多種手段進行:
  • 事實核查與交叉引用。將 AI 生成的程式碼(尤其是 API 呼叫、庫使用、配置項等)與官方文件、可靠程式碼庫或 API 規範進行比對驗證。理論上,也可以藉助專門訓練的 AI 輔助進行交叉驗證。
  • 一致性檢查。核查生成內容是否與專案現有程式碼約定、架構模式、設計風格保持一致。例如,若 AI 生成了與專案其他部分截然不同的資料處理邏輯,應引起警覺。
  • 靜態分析與型別檢查。利用強型別語言特性和先進靜態分析工具,捕捉明顯幻覺,如呼叫未定義變數、錯誤函式、錯誤型別等問題。
  • 依賴關係驗證。檢查生成內容中引用的外部庫、模組或 API 是否實際存在,並確認版本相容性。
  • 置信度評分(謹慎使用)。部分 AI 工具提供置信度分數。低置信度可能提示存在幻覺風險,但高置信度也不能完全排除錯誤,因此需輔助使用。
  • 人工審查的重要性。當前階段,經驗豐富的開發者透過人工走查仍是識別複雜幻覺和微妙邏輯錯誤最有效的方式。
  • 針對性測試。針對懷疑存在幻覺的部分,設計特定測試用例驗證其功能正確性、邊界條件與隱含假設。

模式:面向 AI 理解的程式碼重構

程式碼重構是改進現有程式碼結構和質量而不改變其外在行為的過程。
問題:程式碼太長時,AI 可能會無法理解,或者超出上下文,或者是生成的程式碼質量不高,可以透過重構來解決這個問題。許多重構技術天然地有助於提升程式碼對 AI 的友好度,因為它們的目標通常是降低複雜性、提高可讀性和增強模組化。
  • 上下文超載:當單個函式或檔案過長時,AI 模型容易因 token 限制或困惑於多重責任而無法有效理解全域性邏輯
  • 可讀性差:缺乏清晰的方法劃分與命名,令 AI 難以提取關鍵業務意圖,生成的補全或重寫質量不高

實踐方式:應用經典重構技術最佳化程式碼結構與可讀性

定義:程式碼重構是改進現有程式碼結構和質量而不改變其外在行為的過程,透過消除程式碼異味、提高模組化和可讀性,降低複雜度,從而更易於 AI 工具進行分析和生成高質量程式碼
解決方案:系統化採用諸如提煉函式(Extract Method)、提煉類(Extract Class)、重新命名(Rename Variable/Method)、等經典重構手法,消除程式碼異味, 降低每個模組的認知複雜度,從而使 AI 模型更易聚焦於單一職責和業務邏輯
實現示例:
  • 識別“上帝類”或“神物件”:透過靜態分析工具定位檔案或類中責任過多的區域。
  • 提煉函式:將長方法中邏輯塊拆分為獨立、具名的小方法,如將“資料校驗”、“業務處理”、“日誌記錄”分別提煉出來。
  • 提煉類:將相近職責或狀態資料抽離到新的類中,減少主類耦合度。
  • 重新命名:統一變數、方法、類的命名規範,使其業務意圖對 AI 更直觀。
  • 移除死程式碼與臨時程式碼:剔除無用方法和註釋,降低上下文噪聲。

實現方式:藉助 AI 輔助分析進行結構性重構

AI 直接重構的問題:
  • 模組依賴不透明:多層呼叫鏈與高耦合使得開發者和 AI 難以把握整體結構,重構風險高。
  • 重構決策憑印象:缺乏資料支撐,易遺漏高價值改動點或誤傷核心功能。
解決方案:引入自動化的呼叫關係分析(Usage Analysis)與依賴追蹤(Dependency Tracking)技術,結合 AI 輔助解釋或總結, 形成資料驅動的重構策略。透過理解某個類、模組、方法的使用情況,量化其改動影響範圍、頻次、耦合度,科學規劃重構順序與粒度。
解決方案:
  1. 利用靜態分析或 LSP(Language Server Protocol)工具,生成目標類/方法的呼叫點列表、呼叫頻次及呼叫層級圖;
  2. 用 AI 對這些結果進行自然語言摘要,幫助快速理解各呼叫方的上下文;
  3. 基於呼叫熱度和耦合度,制定分階段重構策略,先從高頻、深層呼叫處入手,後續再最佳化低頻、可替換模組。
實現示例:諸如 AutoDev 提供的 /usage 命令,可以幫助你分析程式碼的呼叫情況。
  1. 分析程式碼呼叫情況:使用 AutoDev 提供的 /usage 命令(例如 /usage:com.example.service.OrderService)來分析指定程式碼(如 OrderService)的呼叫情況。目的是通過了解程式碼的具體使用場景(例如:“OrderService.processOrder 在 CheckoutController 中被呼叫 8 次用於提交訂單;在 BatchProcessor 中被非同步排程 3 次用於批次結算。”)為後續重構提供依據。
  2. 確定重構策略:基於第一步的分析結果,由 AI 評估並決定最適合的重構策略。
  3. 執行重構與修正:AI 呼叫其 AI IDE 能力來執行具體的重構操作,並負責修正過程中可能出現的錯誤或遺漏。
與 AI 純修改相比,藉助於 Intellij IDEA 的重構功能才能更好地進行重構。

注意事項

進行這些重構時,應採用小步快跑、持續整合和自動化測試(如遵循 Red-Green-Refactor 模式)來確保不破壞現有功能。透過有針對性的重構,可以系統性地改善程式碼庫結構,使其更易於 AI 理解、導航和生成高質量程式碼。

定義 AI 友好架構

AI 友好架構是一種將成熟的軟體架構原則與生成式 AI 的能力相結合並進行調整的軟體構建方法。其核心目標是建立一個既便於人類協作,又能被 AI 高效理解、分析、生成和持續演進的程式碼資產與系統環境,從而顯著提升開發效率。
將上述的模式總結為表格:
上述模式的幾個關鍵點是:
  1. 人類友好是基礎:AI 友好的程式碼庫首先必須是人類友好的,遵循一致的團隊規範(如命名約定)、清晰的程式碼結構(分層與內聚),具備良好的可讀性、可維護性和可擴充套件性。
  2. 顯式化的上下文與意圖:透過領域驅動設計(DDD)的通用語言、豐富的領域術語表、最佳化的提示詞工程以及與需求工具的整合,為 AI 提供清晰、準確的任務背景和業務意圖(對應模式 1)。同時,利用專案規則(Project Rules)、Agent 記憶(Memories)和 RAG 技術,注入專案特定的規範、技術棧和歷史決策(對應模式 2)。
  3. 程式碼本身的語義表達:強調程式碼的自文件化能力,透過語義化命名、結構化設計、明確的型別系統、契約式設計(DbC)或函數語言程式設計原則,讓程式碼本身就能清晰地傳達其功能、約束和意圖,減少 AI 理解的障礙(對應模式 3)。
  4. 適應 AI 生成特性的流程:採用“驗證優先開發”(Validation-First Development, VFD)模式,建立“生成-審查-測試-最佳化”的迭代迴圈,承認並管理 AI 生成程式碼的不確定性和潛在“幻覺”,透過嚴格的多維度驗證(包括幻覺檢測)確保最終產出的質量和可靠性(對應模式 4)。
  5. 持續最佳化的結構:透過面向 AI 理解的程式碼重構,應用提煉函式/類、重新命名等經典技術,並藉助 AI 輔助分析(如呼叫關係分析),持續改進程式碼結構,降低複雜度,使其更易於 AI 處理和理解(對應模式 5)。
而基於以上模式,AI 友好的架構可以被視為一個多層次的系統,涵蓋了從基礎知識到互動情境化、生成與驗證、以及持續改進反饋的各個方面。
  1. 第一層:基礎知識與結構層 (Foundational Knowledge & Structure):強調清晰的領域知識定義、結構良好且語義豐富的程式碼庫,為 AI 理解和操作奠定基礎。
  2. 第二層:互動情境化層 (Contextualized Interaction):關注在人機互動的關鍵節點,透過精確的需求資訊和專案特定知識(利用 RAG、Agent Memory 等技術注入)為 AI 提供必要的上下文。
  3. 第三層:引導生成與驗證層 (Guided Generation & Validation):AI 在此層根據第一層的基礎知識和第二層的即時上下文進行程式碼生成,並透過嚴格的驗證優先開發(VFD)流程確保產出質量。
  4. 第四層:持續改進反饋層 (Continuous Improvement Feedback Loop):利用第三層的驗證結果反饋最佳化提示詞、更新知識庫、觸發程式碼重構或語義增強,並透過持續的知識管理確保持續改進。
當然,AI 友好的架構並不是一成不變的,它需要隨著技術的發展、團隊的需求和專案的演變而不斷調整和最佳化。透過這種方式,團隊可以在快速發展的 AI 技術環境中,保持高效的開發流程和高質量的程式碼產出。

總結

AI 程式設計並不是銀彈,而是一個需要團隊共同努力的過程。透過結合領域知識、專案規範、程式碼結構和驗證流程,團隊可以有效地利用 AI 程式設計助手的能力,提升開發效率和程式碼質量。


相關文章