智能編碼在前端研發的創新應用
一、前端開發實例
今天主要想分享一些關于大模型如何協助我們進行前端編碼的實踐。首先,讓我們以一個前端開發的實例開始。通常,當需要實現一個新的前端功能時,我們會收到相關的背景和需求描述。我的期望是,大模型能夠直接使用這些描述來實現需求。例如,如果我們需要在人員信息中添加增刪改查的方法,我希望只需提供需求描述,大模型就能細化需求并檢索相關的代碼。這正是大模型的強項,即能夠規劃和執行任務。

最終生成這個需求實現可能涉及到多個文件的修改或工程級別的修改,這就需要進行 repo level 的代碼生成。在進行問答時,我們用戶實際上就是在做“提示詞工程”。
設計提示詞工程其實非常簡單。我們對生成的代碼有技術棧的要求,需采用 React 或 Vue 架構,并明確組件庫是采用 AntD 組件庫或其他。從 PRD 中復制需求后,即可開始生成業務代碼。由于需求內容較多,字段繁多,形成了一個長表單,因此生成的代碼也較長,可以清楚地看到效果,這個需求的表單項很多。如果是程序員手動編寫代碼,需要逐個敲入 form item 并確認類型。

在前端開發中,重復性勞動是普遍存在的,需要反復確認并一行行地敲代碼。盡管現在有低代碼或組件化的方法來提高開發效率,但編寫一段簡單的代碼仍需花費幾分鐘。這樣繁瑣的過程無疑讓人厭煩,而 AI 代碼助手的出現則能幫助我們快速完成這些任務,從而有更多時間和精力專注于那些真正需要創造力和深度思考的問題。讓編程更有效率,讓我們能夠更快地得到想要的結果。
二、提升開發效率:自然語言生成代碼實踐
目前,通過通義靈碼,我們可以簡單描述并快速生成一個復雜的代碼實現,從而顯著提高開發效率。它最終會生成多個文件的代碼,和它們之間的調用關系。例如,第二步是創建一個名為 Personal form 的組件,生成了一個代碼文件。接下來肯定是要去調用附件,怎么在主應用中引入這個組件,每個文件需要修改什么都會呈現出來。這其實是一個非常端到端的從描述生成代碼的過程。更復雜的增刪改查操作需要具備 repo level 的代碼生成能力,即庫級別的生成能力,這要求更高。
我們仔細查看生成的結果,我本希望可以直接復制粘貼使用這段結果。然而,遺憾的是,生成的代碼在很多情況下無法一次性滿足我們的需求。原因在于,這段代碼過于冗長,模型認為一次性生成全部內容過于繁瑣,因此對返回的內容進行了必要的省略,未能一次性提供我們期望的答案。盡管如此,生成的代碼已經非常接近最終版本,接下來,我們將分析為何它未能給出正確的答案。

那么我們該如何應對呢?最重要的是要明確問題。接下來的步驟是將問題轉化為模型可以理解的形式,或者以更詳細的方式傳遞給模型,或者糾正和補充信息以幫助回答。因此,我們可以在前一個問題的基礎上繼續追問:“能否將省略或補充的字段補充完整?”并使用 AntD5 組件庫這種更細化的版本要求,在追問中提出細節要求。
這就是問答提示詞,大家能夠理解如何去提問,這是我們能做的一個事情。理解了問答提示詞,實際上就很好地理解了代碼補全的基本原理。我們再來看代碼補全的提示詞,想一想應該是什么呢?可能就是代碼的大模型。

它不是通過網絡搜索資料,而是基于已學習的參數,根據上下文的提示詞來生成內容。例如,假設提示詞為“補全這段 time script 代碼,上文是什么,下文是什么”,這是一個最簡單的代碼補全提示詞示例。通過這樣的提示詞,可以與任何模型服務進行交互,進而生成一個代碼編輯助手。
三、代碼生成模型的質量影響因素與上下文作用
那么,模型生成代碼的效果或質量受到哪些因素的影響呢?當前開發文件的內容質量是關鍵,它能同時感受到編碼風格、語言框架以及代碼中的自然語言,如注釋、偽代碼等的影響。如果代碼需求表述清晰,上下文完整,生成的代碼將更符合預期。反之,如果缺乏上下文或表述模糊,生成的代碼可能不夠準確,需要人工進一步調試。這意味著在業務邏輯實現過程中,人工智能無法完全理解我們所需的清晰業務邏輯。代碼生成推薦以后,人與 AI 協同編程的過程中,良好的代碼風格和規范可以提供更好的上下文,有助于生成更精準的代碼,也離不開程序員自身對完整需求的理解。
通過一個簡單的例子,我們可以看到上下文是如何影響生成代碼的。

在這里,通常新建文件開始,其實大模型都已經開始理解我們,就開始做推測了。我們的文件名是 User.tsx,那這里就有一些暗示了,文件的擴展名其實代表了我們代碼語言類型是什么?TSX 這種類型的文件其實都是通常用在 React 框架里面。
文件名通常與組件名相同,代碼模型據此進行識別。在輸出和輸入的 type 中,當需要聲明一個類型時,它會推薦使用 UserProps。這是因為模型能夠感知文件名與組件名的一致性,這是一種它所學習到的模式,即類型命名與組件名相同。因此,生成代碼后,我們只需按 tab 鍵進行采納即可。
定義好類型后按 tab 鍵,然后它會開始補充組件的函數問題。我們按回車鍵多次,它會繼續生成代碼。當我引入了 Table 組件后,它自動補全了 Table 符合數據源要求的數據結構。再按 tab 鍵,它執行采納操作,從而自然而然地形成了我們整個 return 一個 DOM 元素的邏輯。
四、代碼補全技術的局限與優化方法
代碼補全的結果并非每次都準確,這可能與上下文的精確度有關,也與代碼生成模型的能力相關。在當前上下文信息不足的情況下,可能會有多種生成結果。特別是在前端開發中,由于交互的性質,用戶行為難以準確預測。

讓我們以一個三方 API 為例,演示在生成代碼過程中模型是如何補充相關庫的。看起來還是很有道理的。它實際上學到了一種普遍的模式:大駝峰式 API 通常通過小寫中劃線的包名零引入。然而,在 NBA 官網中并未找到該包,正確的依賴包應為“utrie”。有時,API 的命名比程序員更規范、標準,但并不意味著這些 API 在客觀上確實存在。
另一個問題是,通常在 TS 中,代碼塊始于 import。我很難確定我引入的這個依賴的 former 里面究竟是什么函數。如果僅從模型中看到函數定義,很容易隨意生成這個 formatter,甚至函數的 API 參數的定義,這些在編碼時都是不確定的。這會導致所謂的“幻覺”,即模型可能編造出不存在的包,這就需要開發者介入識別并干預。
五、大模型代碼生成中的幻覺問題及解決策略
在自定義組件庫時,許多開發者會基于公共組件庫,并針對特定業務需求進行修改。例如,在篩選組件中,我們可能不需要清除按鈕。因此,在自定義組件庫時,我們會刪除這一屬性。然而,當大模型學習公共數據時,它通常會學習到“clear”這一屬性,并可能推薦出業務組件庫中未定義的選項。這是一個普遍現象。后續我們將探討如何調優,以及如何干擾模型生成結果以優化其輸出。

首先,我們需要提供更多信息以幫助模型生成更準確的內容,避免或減少生成的幻覺。這是每個大模型都需要解決的問題。當用戶向模型輸入內容時,他們應該提供更多信息,使模型能夠感知到更多的內部細節,從而避免在生成代碼時產生幻覺,導致開發者無法接受結果或影響開發效率。因此,我們會進行更多的調整。
其實我們靈碼團隊為了避免這個問題,做了很多相關的工作。包括代碼的語義分析,代碼的引用鏈、調用鏈這些跟蹤,以及各種推導和相似代碼的分析。我們在補全當前上下文這個代碼的時候,我們會獲取已解析的依賴關系或跨文件簽名。將更多的信息融入到代碼補全里。這樣,在生成當前代碼片段時,能夠忠實于語言和數據,從而避免亂生成代碼。

當然如果你說完全避免,這個也不是完全確定的。因為靈碼不會存儲用戶代碼,也不會使用用戶的代碼。它所有的索引代碼、索引內容或檢索召回都是在用戶的本地完成的,然后再結合大模型的內容進行生成。我們會持續迭代這一部分,包括支持語言的擴展和生成格式。那么,究竟生成的內容是推薦一行代碼、一個容器外部,還是一個完整的函數或類,對于我們開發者來說是至關重要的。
六、探討人工智能大模型生成前端代碼的挑戰
我們非常關注自動生成代碼的質量。如果生成的代碼力度過大,可能會導致每次只生成單行代碼,這不僅冗余,而且需要多次點擊才能完成函數補全。因此,我們會通過自適應的方式生成相關的例子,例如,它可能會生成整個 for 循環或 if 語句。在編寫工具函數時,當遇到注釋,會更傾向于將整個函數解析出來,以滿足開發者習慣并確保生成的代碼符合實際需求。在這方面,我們已經進行了大量的優化工作,效果顯著,得到了明顯的提升。

使用人工智能大模型生成前端代碼相較于后端的 Java 或 Python 代碼會面臨更多的挑戰。盡管 Python 和 Java 在后端開發中表現出色,但在前端應用中,其表現并不盡如人意。我們可以通過以下維度來分析原因。編寫一個 VUE 文件時,該文件實際上融合了三種不同類型的語言:JS 或 TS 腳本(腳本語言),TS(強類型語言),以及 HTML+TS 等標簽(標簽語言)。

像 CSS 這類語言,嚴格來說并不算編程語言。它們更接近于規則級的配置。在前端開發的學習過程中,我們會發現規范的多樣性和非標準化。尤其在前端技術的歷史演進過程中,出現了許多大版本、小版本和技術分支。前端開發涉及的進展更為多樣,如 JavaScript 的動態特性、TypeScript 的強類型系統以及 HTML 和 CSS 的混合使用。實際上,沒有一個統一的領域模型存在。而且,HTML 和 CSS 在很多方面并沒有統一的標準,各個組件庫標簽的定義也各不相同。
即便在同一企業內部,也可能存在不同的前端開發團隊或個人開發者,他們可能會采用不同的技術棧或編碼風格。在前端框架的選擇上,我們有 React、Vue 和 Angular 等。在國內,Vue 可能是主流選擇,同時也有其他遵循不同最佳實踐的團隊。相比之下,Java 作為后端語言,盡管有多種框架如 Spring、Hibernate 等,但其核心語法和面向對象的編程原則相對統一。
此外,前端在接收到需求后,前端代碼直接影響用戶界面呈現和交互體驗。需求的變化越接近用戶,變化頻率越高。這要求前端代碼不僅需要保證功能正確性,還需要考慮代碼生成的復雜度、美觀以及響應式的頻繁迭代和變更。而后端更關注業務邏輯和數據處理,抽象程度相對較高。
前端代碼還需具備實時性和動態性以處理用戶輸入并及時給予反饋,這涉及到復雜的事件監聽和狀態操作。相比之下,后端執行環境通常更加穩定,對外部變化的響應不如前端頻繁。此外,還有一些兼容性問題以及提升用戶體驗的問題。因此,前端代碼生成面臨的挑戰不僅包括交互和交互邏輯,還包括用戶體驗和兼容性方面,這些都需要 AI 模型具備更高級的理解能力和對細節的精準把握,從而使得前端代碼生成成為一個更為復雜的任務。
七、優化前端開發者工作環境與企業級服務的大模型應用
針對前端開發者的優化工作環境,我們進行了深入思考和改進。我們考慮過模型是否存在知識盲點?即使我們優化了提示詞并輸入了大量上下文,開發者已經完成了所有能做的事情,但模型仍存在不足,無法提供相關知識,從而無法給予開發者必要的幫助。遇到這種情況,正確的做法是清晰地闡述問題,最好能圍繞問題展開,全面介紹業務技術、團隊編碼等相關背景信息,至少要讓模型理解問題的背景、場景以及待解決的問題。

在企業級服務方面,我們深入考慮了與企業核心需求相關的方面。主要是將企業的自有代碼、第三方庫以及特定的內部 API,還有其他問答服務整合到當前大模型服務中。這還包括企業內部文檔處理,這些都是對企業至關重要的需求。我們可以通過構建與企業相關的代碼和文檔的知識庫,結合大模型的發展,提供更強大的數據處理和檢索召回功能。這是我們的優化重點方向,旨在讓生成的代碼更貼近開發者自己編寫代碼和知識。
八、企業知識庫與大模型融合的實踐策略
在學習大量優質公開數據時,我們的大模型無法直接獲取企業的私有知識。這就是 RAG 方案的由來,該方案類似于為企業量身定制增強效果,以滿足獨特需求。對于大模型的落地應用來說,對我們的企業而言,成本最低且門檻最低的方法就是 RAG 技術。它不僅是一個技術,而且是知識庫管理的一種方式。通過 RAG 技術,我們可以將企業的知識和私有化知識庫與大模型融合,從而更有效地解決用戶和開發者的問題。
在實施過程中,有兩個關鍵角色不可或缺。一個是知識庫管理員,負責上傳高質量的代碼倉庫和文檔。另一個是我們的企業開發者,他們提出問題并參與編碼現場。
其實,核心是一個詞庫,因此我們需要知識庫管理員準備一些文本。這些文本構成了我們的知識庫。簡而言之,我們將這些文本存儲在一個類似數據庫的系統中,該系統被稱為“向量”。我們針對特定項目進行檢索,即在獲取一個文本后,希望從庫中找到與該文本相似的其他文本,以加速檢索過程。
我們將使用一種新型的向量數據庫系統。在將文本或代碼片段存入數據庫之前,需要先進行切分。如何將文章分割成各個段落?我們需要合理地分割不同類型的前端語言代碼。例如,標簽應從開始標簽到結束標簽進行分割,而 Java、JavaScript 等語言則需按代碼塊進行分割。這一過程涉及多種算法,這里不再詳細說明。接下來,我們將切分后的每個段落或片段,即窗口,存入向量數據庫。在存儲之前,需要將它們轉化為向量的向量化形式,這一過程稱為“Embedding 向量化”。一旦知識庫被上傳,我們就已經完成了知識的 Embedding 向量化,并將其存放于向量數據庫中。
接下來討論什么呢?用戶開始編碼,那么我們該如何自動補全代碼或者用戶開始使用的場景。我們首先將用戶的問題轉化為一個向量,這個過程我們仍需要使用 Embedding。有了這個問題的向量后,我們還需要在向量數據庫中檢索包含該問題的答案或段落,或者是相似的代碼片段。這個搜索過程實際上是在數據庫中檢索的過程。檢索完成后,我們讓數據庫返回可能包含問題的幾個段落。我們將這些段落放在一起,這個過程我們稱之為檢索,檢索出來的結果也被稱為 Context 上下文。這個上下文可以與我們之前提到的所有上下文結合,并整合成一個 Prompt。
因此,讓大模型回答這個問題構成了整個流程的核心。如何有效地裁剪代碼或加速檢索過程呢?在優化過程中,存在多種策略可選。如果用戶能夠構建一個高質量的代碼倉庫或知識庫,那么召回與用戶需求高度相關的代碼片段的概率將會顯著提升。這意味著,當我編寫某段代碼時,系統已經在向量數據庫中存儲了相似或高度相似的代碼,從而實現高效的檢索。

九、前端組件庫文檔的重要性及實踐案例
以前端組件文檔為例,它實際上是一種高質量的文檔。當你使用開源組件庫時,通常會在官網找到以 markdown 格式呈現的網頁。這種網頁格式是為了方便開發者的閱讀和查詢,幫助我們快速了解組件庫的 API 及其應用場景。因此,這些文檔通常會單獨發布為網頁形式。
該文檔的質量之所以高,是因為它首先用自然語言介紹了組件的功能和應用場景,然后提供了具體的代碼實現。因此,它實際上架起了一座橋梁,連接了自然語言與代碼。通過專業工具將這些網頁轉換為markdown 格式后,我們便可以開始進行問答。

前端代碼是基于腳本和標簽語言的特性生成的,我們來看一下具體效果。我們團隊有一個名為 Teamix UI 組件庫的資源,它包含了基礎和業務組件。當這些組件被上傳到知識庫后,靈碼在生成答案時會自動輸出 import 語句,引入 UI 私有庫。這一特性帶來的好處是生成的代碼可以直接復制并粘貼,省去了進一步修改的步驟,極大提高了效率。
十、前端團隊代碼倉庫管理實踐
那么,企業如何在前端團隊中實現代碼倉庫的落地呢?在與客戶的交流中,我發現他們往往將此事視為門檻很高的事情。因為建立一個高質量的知識庫需要投入大量精力,這可能包括文檔和代碼倉庫的管理,或者建立一個模板工程。在此,我想澄清一下,以我們前端團隊是如何實施這個過程為例,其實這是一個很簡單的過程,不需要過于復雜。我們直接在靈碼的后臺建立一個名為“云原生前端團隊”的私有知識庫,并上傳代碼倉庫的壓縮包,將其設置為私有知識庫成員。

為什么要設置為私有呢?這是因為我們的前端團隊負責的產品線多樣,各產品間差異較大,技術棧的差異也較大。此外,每個開發人員所管理的倉庫各不相同。鑒于此,我們沒有按照團隊來劃分知識庫,而是細化到個人層面,以避免不同組件庫或 API 之間的混淆,以及潛在的版本沖突問題。例如,由于 VUE2 和 VUE3 的技術棧不同,我們為它們設置了獨立的存儲空間。那么,如何形成這個獨立的知識空間呢?答案是通過設置為私有,并選擇私有時,通過成員權限來實現。

通過讓團隊成員僅接觸與其工作直接相關的代碼倉庫,可以減少干擾,提高專注度。這就是整個操作過程。有人認為準備倉庫很麻煩,需要準備許多模板工程,還要做很多集合,以及搞清楚團隊的業務分工。其實,有一種非常簡單的方法可以立即啟動外的能力,即首先將團隊當前編碼的倉庫上傳,建立一個知識庫即可。或者,你也可以選擇團隊中那些代碼質量高的幾個人的代碼倉庫,上傳這些倉庫也能立即發揮作用。如果我上傳的代碼倉庫與實際開發的相似度越高,那么效果就會越好。啟用企業知識庫能力后,我們團隊的 AI 生成占比提升了 5% 到 10% 左右。
為什么數據會有所波動呢?這是因為我們團隊的編碼活動在不斷變化。例如,某個月我們專注于國際化開發,這包含自動化工具與文案的改寫,導致 AI 生成內容的占比相對較低。因此,需要根據具體的實際開發活動來分析數據。另外,團隊在編碼風格上也有一致性的要求,比如前端編碼規范,eslint 等,通常我們在配置里面會有清晰的 case 和約定。

十一、探討 AI 在提升編碼工作效率中的應用
那么我們推薦通過知識庫上傳符合編碼規范的文檔以校正。例如,我們可以在代碼倉庫中進行校正。在開發過程中,我們推薦使用最下面這種寫法,以確保代碼既清晰又高效。通過在靈碼知識庫中上傳符合編碼規范的代碼,團隊成員可以輕松訪問并效仿最佳實踐。他推薦出來的就是最好的代碼,這樣就確保了項目代碼的一致性和高質量。
另外,我們還提供一鍵修復報錯的功能,當我們在編寫代碼過程中遇到紅色標注的錯誤時,可以利用這個功能讓靈碼進行修復并跟進修改結果。這個提示非常好,我們經常用你,這是一個高頻的使用場景。

另一個非常推薦大家使用的是 commit message,即提交信息的生成。在進行代碼提交時,團隊成員經常隨意填寫提交信息,Code Review 也無法有效管理和驗證這些信息。雖然我們可以結合 husky等工具對 commit 做卡點,但這也會降低工作效率,而且開發很容易繞過。靈碼能自動生成變更信息,從而直接提交,有效幫助我們提高了工作效率。

通義靈碼最近針對開發者進行了一項調研,收集了超過一千份問卷。調研結果顯示,72% 的受訪者認為編碼工作效率得到了顯著提升,這是一項相對不錯的評估結果。我們之前討論過人與機器協作的主題,也談及了前端開發過程中的相關經驗。

十二、未來展望
軟件如何賦能?從 AI 開始,我們更加依賴于 AI 作為軟件工程主力進行代碼的整合和開發。隨著 AI 智能占比的不斷提升,我們不斷探索更強大的模型來解決問題,例如 GPT 等更先進的模型,以及克服更前沿的智能體技術。此外,還需要處理多模型間的配合和接口協作。因此,采用先進的軟件開發理念是必要的,開發人員需學習如何更好地利用 AI 提升開發效率,拓展自身能力的極限。這其實是一個更先進的軟件開發理念,并且它已經發生,甚至將 AI 融入整個軟件工程團隊的合作中。

沒有這些因素,我相信未來將會發生一些質變。例如,四十年前人類開始步入神話時代,意味著我們對團隊協作的依賴達到了新的高度,無論是現在還是未來。這包括項目如何劃分、人與人之間的協作方式,以及是否可以擴展等都提出了許多問題,并且我們也在尋找解決方案。接下來,人與智能體的交互將變得更為緊密,比如 N 年以后是否可以逐漸過渡。這個逐漸過渡的過程實際上是溫和的,從依賴人類到依賴超大規模算力的轉變,可能會取代我們的一些職責。這不僅僅是簡單的疊加關系。對于AI和超大規模算力,這是否意味著我們可以大幅度提升軟件質量,是否可以縮短研發周期并提高效率,還有創造出更優質的軟件并持續發展,這無疑是肯定的。
在這一過程中,我們不可避免地會遇到一些挑戰。我們希望借助這項技術,提升軟件工程的質量或縮短交付周期。這是我們的未來展望。

浙公網安備 33010602011771號