最近一直和一些團(tuán)隊(duì)進(jìn)行Vibe Coding相關(guān)的實(shí)踐和探索,有一些有趣的感受,今天有看到InfoQ上的一篇文章《Cursor 的 bug 太多了,他們直接買下一家代碼評(píng)審公司來(lái)修!》,覺(jué)得和我最近的思考挺契合,就分享一下。
先看一下這篇文章的幾個(gè)核心內(nèi)容:
這筆交易相當(dāng)于是把 AI 時(shí)代“創(chuàng)建、評(píng)審、合并代碼”的最佳工具組合到了一起。這三件事里,Cursor 實(shí)際上只做了其中一件——寫代碼,另兩件則是 Graphite 的強(qiáng)項(xiàng)。
根據(jù) Graphite 公司分享的數(shù)據(jù),相比 2023 年,現(xiàn)在每位工程師產(chǎn)出的代碼量大約多了 70%。主要問(wèn)題在于,代碼可以指數(shù)級(jí)增長(zhǎng),但工程師的時(shí)間仍然是人類尺度的時(shí)間。
Stacking 的核心變化在于:把變更的基本單位從 PR,變成了單個(gè) commit。在 stacking 模式下,你會(huì)把一個(gè)大的改動(dòng)拆成許多個(gè)小改動(dòng)。每一個(gè)改動(dòng)——也就是一個(gè) commit——都可以被單獨(dú)測(cè)試、評(píng)審、合并,甚至單獨(dú)回滾。
一點(diǎn)啟發(fā)
就連Cursor這個(gè)在Vibe Coding領(lǐng)域的領(lǐng)先者都遇到了代碼評(píng)審和合并的問(wèn)題,說(shuō)明在AI輔助編程的過(guò)程中,代碼質(zhì)量和協(xié)作流程依然是不可忽視的挑戰(zhàn)。當(dāng)我們還在為Copilot或者AI編碼工具能夠幫我們快速產(chǎn)出代碼,大幅提高生產(chǎn)力而興奮的時(shí)候。一些危機(jī)已經(jīng)悄然出現(xiàn):
- 生成容易,維護(hù)難,人已經(jīng)跟不上生成速度:AI可以快速生成代碼,但這些代碼往往缺乏一致性和可維護(hù)性。沒(méi)有良好的評(píng)審和合并機(jī)制,代碼庫(kù)可能會(huì)變得混亂不堪。
- 團(tuán)隊(duì)協(xié)作復(fù)雜度增加:當(dāng)多個(gè)開(kāi)發(fā)者使用AI工具生成代碼時(shí),如何確保代碼風(fēng)格一致、功能不沖突,成為一個(gè)新的挑戰(zhàn)
- 魔法打敗魔法?:考慮用AI工具來(lái)做代碼評(píng)審,魔法打敗魔法?看似合理,但實(shí)際上可能會(huì)引入新的問(wèn)題,比如AI評(píng)審工具的準(zhǔn)確性和偏見(jiàn)問(wèn)題誰(shuí)來(lái)把控?
- 業(yè)務(wù)知識(shí)的丟失:以往開(kāi)發(fā)人員編寫代碼會(huì)先理解業(yè)務(wù)需求,并在改進(jìn)功能的同時(shí)優(yōu)化代碼結(jié)構(gòu)。這個(gè)過(guò)程其實(shí)也是加深業(yè)務(wù)理解的過(guò)程,而AI生成代碼的過(guò)程,已經(jīng)不需要開(kāi)發(fā)人員理解整塊理解代碼結(jié)構(gòu),缺乏這種深度理解也讓業(yè)務(wù)知識(shí)的傳遞變得困難。
我們的實(shí)踐
我和一些團(tuán)隊(duì)進(jìn)行的Vibe Coding實(shí)踐中,也遇到了類似的問(wèn)題。所以對(duì)這篇文章提到的內(nèi)容特別有共鳴。開(kāi)發(fā)人員最開(kāi)始以為AI工具可以大幅提升生產(chǎn)力,但隨著時(shí)間推移,大量業(yè)務(wù)代碼的生成后依舊無(wú)法逃脫的一個(gè)最主要矛盾——如何避免修改一個(gè)地方不會(huì)影響其他地方好用的功能。
有些小伙伴會(huì)說(shuō),讓AI生成單元測(cè)試等自動(dòng)化測(cè)試。以前咱們?nèi)藢憣?duì)能寫單元測(cè)試的程序員要求高,現(xiàn)在AI生成測(cè)試,應(yīng)該更容易了。事實(shí)給了我們一記響亮的耳光:如果你的業(yè)務(wù)代碼已經(jīng)生成,AI生成的測(cè)試很多時(shí)候只是空殼子,他無(wú)法生成有效的測(cè)試。當(dāng)你深入探尋具體原因的時(shí)候,你會(huì)發(fā)現(xiàn)原因和沒(méi)有AI時(shí)候一樣:代碼不可測(cè)試 。
我們不得不重新回到以往的那個(gè)問(wèn)題:好的軟件工程的實(shí)踐有哪些。TDD這類傳統(tǒng)的實(shí)踐依然是解決問(wèn)題的關(guān)鍵。我們做了如下調(diào)整:
- 傳遞業(yè)務(wù)知識(shí):在Vibe Coding過(guò)程中,開(kāi)發(fā)人員通過(guò)markdown文檔描述業(yè)務(wù)上下文,讓AI理解業(yè)務(wù)需求。
- 生成思考過(guò)程:了解業(yè)務(wù)需求后,不著急生成代碼,先讓AI生成任務(wù)列表,方便人類審核是否存在理解偏差。
- 保留記憶:讓copilot這類代碼生成工具將上面的思考過(guò)程寫入記憶庫(kù)中(也是markdown文檔)。這個(gè)記憶庫(kù)就像是一個(gè)上下文活文檔庫(kù),讓AI在后續(xù)生成代碼的時(shí)候,能夠參考這些業(yè)務(wù)知識(shí)。同時(shí)確保這個(gè)記憶文檔持續(xù)更新。
- 測(cè)試驅(qū)動(dòng)開(kāi)發(fā):在生成代碼之前,先讓AI生成單元測(cè)試,再基于TDD的工作方式生成功能代碼,同時(shí)確保每個(gè)測(cè)試都是通過(guò)的。這功能實(shí)現(xiàn)的同時(shí),測(cè)試也留下來(lái),之后可以作為回歸測(cè)試集,確保后續(xù)代碼修改不會(huì)破壞已有功能。(Note:這些測(cè)試也是一個(gè)活文檔,幫助AI從另一個(gè)角度理解上下文。)
- 每次只做一點(diǎn)點(diǎn):迭代思維方式,小步快跑,這些都是好的軟件工程實(shí)踐。AI生成代碼的過(guò)程也不例外。碎片化大功能,每次只做一點(diǎn)點(diǎn),不僅方便驗(yàn)證結(jié)果,快速調(diào)整方向,也方便后續(xù)代碼的維護(hù),甚至是代碼合并時(shí)候的review以及沖突解決。其實(shí)我們?cè)跊](méi)有AI的時(shí)代,也是很反感大段代碼提交的。難道你不是看著好幾百行代碼Pull Request就頭大嗎?
小結(jié)
我們不難發(fā)現(xiàn),不管是否有AI的幫助,好的軟件工程實(shí)踐依然是解決問(wèn)題的關(guān)鍵。高效軟件工程師有了AI工具的夾持會(huì)變得更強(qiáng)大,而普通的軟件工程師有了AI工具,可能會(huì)產(chǎn)出更多的垃圾代碼。不過(guò)也從另一個(gè)角度看到,不好的軟件工程習(xí)慣會(huì)被AI快速放大,讓有觀察的程序員發(fā)現(xiàn)問(wèn)題并及時(shí)做出調(diào)整。就像我最近合作的團(tuán)隊(duì),他們之前也不喜歡做單元測(cè)試,但是使用Vibe Coding之后,他們發(fā)現(xiàn)TDD的好處,開(kāi)始學(xué)習(xí)TDD,并大范圍使用。是AI讓他們看到了更好的軟件工程實(shí)踐的價(jià)值。
讓我們借助AI的力量更好的進(jìn)化自己到下一個(gè)階段吧。