是時候停止程式碼審查了
作者曾構建最好的AI輔助程式碼審查工具,但如今認為傳統的人工程式碼審查已不再必要:知識傳遞、培訓和大部分技術債務管理都已被AI改變,缺陷檢測也應交給自動化工具和AI分類。工程師應把時間花在理解架構和意圖上,而不是手動逐行閱讀diff。
看到這個標題,也許有人會皺眉。我理解,因為就在不久之前我也持同樣看法。今年年初,我花了一個月構建了當時——甚至可能現在依然是——世界上最好的AI輔助程式碼審查工具。但如今,我已經完全不再做傳統意義上的程式碼審查了。
在人類主導的軟體開發中,程式碼審查主要有三個目的。第一是知識傳播,避免只有一位工程師知道如何安全地修改某段程式碼;第二是培訓,資深工程師透過審查初級工程師的程式碼來幫助對方成長;第三是缺陷檢測和避免技術債務。作者認為,前兩個目的已經不再需要依賴程式碼審查來實現。藉助AI,我們可以極快地理解任意程式碼,按需獲取上下文,不再需要為每個PR花費幾小時甚至幾天來通讀。至於培訓,AI寫程式碼之後,再向初級工程師反饋程式碼質量問題,價效比已經不高。模型目前還不能跨會話學習,雖然各大實驗室都在嘗試解決這個問題,預計幾年內會有突破。
技術債務也不再像過去那樣可怕。如果方向錯了,直接修改程式碼去糾正方向就好。這是更高層次的YAGNI原則:如果未來再做的成本並不比今天更高,那就不必現在花昂貴的時間去做可能不必要的事情。實際上,隨著模型逐月變強,未來做的成本往往會更低。新模型Fable 5,以及程度稍低的Sol 5.6和K3,在改進程式碼方面的能力遠超前代,雖然仍會犯錯,但每次釋出都在減少。
剩下的是缺陷檢測。我們得先承認,人工程式碼審查從來就不擅長找缺陷。它總比沒有好,但最好的研究顯示檢出率約為35%,在安全等專業領域往往更低。工程師應該把這件事自動化。軟體領域幾十年來積累了大量關於如何讓程式碼更健壯的研究,甚至包括很難推理的分散式系統程式碼,但在過去,由於需要為結構化和插樁做出巨大改變,這些方法幾乎無法落地。現在有了按需智慧,這個問題不存在了。所以作者覺得奇怪:幾乎還沒有人開始引入這些技術。
靜態分析就是其中一個例子。Coverity從2002年就存在了,但人們更願意使用Ruff和Clippy這樣更簡單的工具,因為更復雜的檢查在真實程式碼庫中噪聲太大。而現在,AI可以直接在噪聲中判斷哪些真正值得關注。作者為Bifrost寫了兩條自定義分析流水線,都輸入GPT,由它分類哪些應該忽略、哪些應該自動修復、哪些應該上報給人類。
那麼,應該把“審查預算”花在哪裡?作者並不認為人類不該接觸細節。架構、不變數和意圖仍然需要人來理解,但手動閱讀diff,即使是精簡後的diff,也不再是獲得或維持這種理解的最佳方式。/plan 是作者的推薦工具。它可以讓你在動手前發現指令中的歧義,除非是最機械、最直接的改動,否則都不應跳過。你可能會驚訝於模型覺得哪些地方有歧義,也會慶幸沒有讓它獨自猜測。這也是檢查難以變更的外部承諾的最佳時機,比如持久化資料格式、公開API、協議等。
作者舉了今天早上的例子。他正在構建Hel——一個“harness of harnesses”。當會話增長到數十萬事件時,worker-controller協議變得臃腫而緩慢,重新連線需要幾分鐘。這種事在過去的人工審查中百分百會被發現,但這意味著每次提交都要做那種級別的審查。如果那樣做,四天之後大概連1.0的邊都摸不到,而不是幾乎完成。發現問題後,他進入 /plan 說:根據儀表盤目標,我們需要worker提供哪些事件,應該如何表示?原始事件流、每100毫秒彙總,還是其他方式?模型給出了合理設計,但作者發現有些地方對不上,於是要求把提議的結構對映到它驅動的功能上,結果又發現了幾個需要清理的問題。
作者的結論是:直到大約2024年,程式碼審查都是傳播知識、指導團隊、防止技術債務和儘早修復bug的寶貴工具。但如今,變更變得太容易,工作方式也變了,手動例行閱讀diff已是對資深工程時間的浪費。如果他現在作為獨立貢獻者找工作,會避開那些仍然把這種審查當作變相派活兒的組織,那種文化幾乎和毫無意義的會議一樣令人反感。在大多數科技公司,人力工程時間是最昂貴的資源。與其花在手動閱讀diff上,不如用來構建能比人眼更好地捕捉迴歸的新系統。