??騰小云導(dǎo)讀
GPT 出現(xiàn)之后,很多人推測大量的軟件都會因?yàn)槠涑霈F(xiàn)而重寫。本文主要是低代碼平臺與 ChatGPT 結(jié)合的一些思考以及實(shí)踐。期望與各位讀者一起搭上 AI 這列快車,為開發(fā)提提速~
??目錄
1?背景
2 Demo 演示
3 思路
????3.1?ChatGPT+代碼生成工具結(jié)合模式
????3.2 ChatGPT 代碼生成現(xiàn)狀
????3.3?現(xiàn)階段可行的思路
? ? 3.4?案例
4 設(shè)計(jì)實(shí)現(xiàn)
? ? 4.1?架構(gòu)分層
? ? 4.2?插件化
? ? 4.3?研發(fā)調(diào)整
5 總結(jié)
01、背景
從探索模型驅(qū)動開發(fā)開始,我一直在思考一個(gè)問題:“軟件,是否可以用更簡單、更人性化的方式生成”,ChatGPT 給我了一個(gè)肯定的回答。
我們此前根據(jù)領(lǐng)域模型在生成代碼方面進(jìn)行了一些探索,希望用建模時(shí)間高倍率置換編碼時(shí)間。隨著代碼工具的不斷完善,效率提升越來越難,因?yàn)槟P褪浅橄蟮亩鴮?shí)現(xiàn)是具體的,模型所承載的信息并不足以直接生成代碼,一定需要“人”來補(bǔ)充信息,這部分工作工具無法替“人”來完成。
直到體驗(yàn)了 ChatGPT,在震驚于它強(qiáng)大的能力同時(shí),我們也就“如何將 ChatGPT 引入我們的代碼生成工具來提升研發(fā)效能”進(jìn)行了思考,并且快速搭建了一些 Demo 驗(yàn)證效果。
02、Demo 演示
“Talk is cheap. Show me the code”,先看效果:
視頻可移步到公眾號觀看
這里演示了工具基于領(lǐng)域模型生成代碼的流程,在第3到5步工具集成了一個(gè)基于 ChatGPT 接口實(shí)現(xiàn)的插件,該插件自動提取模型中的中文類名、成員變量名、成員函數(shù)中文名,然后將中文名以及翻譯用途、命名風(fēng)格輸入到 ChatGPT 得到翻譯結(jié)果,并自動填充回工具,最后生成代碼。
這里僅僅是簡單地使用了 ChatGPT 的翻譯能力,卻給我們帶來了巨大的提升,想象一下一個(gè)項(xiàng)目數(shù)十個(gè)類名、數(shù)百個(gè)成員變量名以及函數(shù)名需要根據(jù)中文翻譯為英文,有些詞還要使用翻譯軟件翻譯后再根據(jù)使用用途(類名使用名詞或者名詞短語、方法名使用動詞)轉(zhuǎn)換詞性,然后調(diào)整為大駝峰或者下劃線連接等風(fēng)格,這是多么無趣和繁瑣的工作,而現(xiàn)在只需要一鍵填充,然后做微小調(diào)整即可。
僅接入了 ChatGPT 的翻譯能力就提效如此明顯,那如果將 ChatGPT 的能力封裝為一個(gè)一個(gè)插件嵌入到整個(gè)研發(fā)過程,那會達(dá)到什么效果呢?
03、思路
3.1 ChatGPT+代碼生成工具結(jié)合模式
3.1.1 模式一:直接生成軟件
這種模式讓 ChatGPT 理解人類語言并編寫軟件,例如 ChatGPT 完全可以生成一個(gè)可運(yùn)行的貪吃蛇小游戲,當(dāng)然嚴(yán)格意義上這種模式并不是 ChatGPT 和代碼生成工具結(jié)合,因?yàn)楦静恍枰a生成工具參與,這無疑是最簡單、最自然的軟件開發(fā)方式。
遺憾的是通過測試發(fā)現(xiàn):ChatGPT 現(xiàn)階段并不能直接通過對話編寫出完整的、復(fù)雜的軟件,因?yàn)檐浖凶约旱?strong>核心域知識,而且不同的團(tuán)隊(duì)都有自己的規(guī)范、環(huán)境等要求,例如谷歌使用 gRPC 框架、部署在谷歌云,而亞馬遜的研發(fā)框架和部署環(huán)境與谷歌完全不同。我們不可能將這些信息全部輸入到 ChatGPT(這些信息太多了,通過會話描述這些信息需要大量的工作,除了考慮性能以外也擔(dān)心敏感信息泄露問題)?,F(xiàn)階段該模式無法實(shí)現(xiàn)。我想,盡管 AutoGPT 的出現(xiàn)說明 AI 確實(shí)可以從0到1完成一個(gè)項(xiàng)目,但我想沒有人敢將它生成的項(xiàng)目直接應(yīng)用于生產(chǎn)環(huán)境。
3.1.2 模式二:生成代碼片段
通過會話將代碼上下文信息輸入到 ChatGPT,它基于這些信息完善、編輯代碼,例如 Copilot 插件就是該模式。測試發(fā)現(xiàn) ChatGPT 生成代碼片段的質(zhì)量比較高且比較穩(wěn)定。
該模式和模式一的區(qū)別是代碼是“工具”將 ChatGPT 生成的“代碼片段”進(jìn)行組織,最終形成完整的軟件。
3.1.3 模式三:生成DSL
將自然語言轉(zhuǎn)換為 DSL ,然后基于 DSL 生成代碼或者軟件,這種模式和方案二的區(qū)別是 ChatGPT 不直接生成代碼,代碼是由工具根據(jù) ChatGPT 生成的 DSL 生成。ChatGPT 生成 DSL 相對穩(wěn)定,這種模式生成的代碼質(zhì)量相對前兩種模式更加可靠。
3.2 ChatGPT 代碼生成現(xiàn)狀
“知彼知己,百戰(zhàn)不殆”,我們首先要對 ChatGPT 的能力有個(gè)清晰認(rèn)識,這樣才能選擇正確的模式。我們閱讀了一些 GPT-4 能力測評論文,也做了大量的實(shí)驗(yàn)驗(yàn)證,說幾個(gè)有意思的點(diǎn):
|
在實(shí)際場景中我們寫代碼所依賴的信息非常多,除了當(dāng)前文件的上下文還可能跨文件、跨系統(tǒng)、跨倉庫……但是由于 ChatGPT 對輸入長度的限制,將所有依賴信息輸入到 ChatGPT 是不現(xiàn)實(shí)的(時(shí)間成本、敏感代碼泄露);另外一個(gè)問題是交互模式,如果代碼是離線生成還好,但如果是“和 ChatGPT 結(jié)對編程”對實(shí)時(shí)性要求是非常高的,想象一下如果 Copilot 每次生成提示都需要1分鐘你還會用嗎?
3.3 現(xiàn)階段可行的思路
結(jié)合上述信息,我們認(rèn)為盡管目前 GPT4 能力非常強(qiáng)大,但是并不能做到全自動生成應(yīng)用,尤其是針對某個(gè)行業(yè)需要匹配該行業(yè)的最佳實(shí)踐和領(lǐng)域知識,需要遵循團(tuán)隊(duì)研發(fā)規(guī)范。這些是 ChatGPT 現(xiàn)階段所無法做到的。那基于 ChatGPT 現(xiàn)有的能力,如何嵌入到代碼生成工具中呢?我作了一些粗淺的思考:
|
讀到這里也許會有疑問,這明顯就是模式二和模式三的結(jié)合,為什么要分兩次讓 ChatGPT 生成代碼呢?我下面用一個(gè)案例進(jìn)行詳細(xì)解釋。
3.4 案例
3.4.1 信息提取
如上圖所示,這是系統(tǒng)用例“接收車位狀態(tài)變化”的分析序列圖,通過分析序列圖我們可以得到如下信息:
· 控制類有一個(gè)方法為“停車收費(fèi)”; ·?控制類的“停車收費(fèi)”方法依賴實(shí)體類“泊位”; ·?分析序列圖中的實(shí)體類的成員變量可以在類圖中得到,所有指向該實(shí)體的箭頭都映射為一個(gè)方法; ·?可以根據(jù)分析序列圖得到控制類和實(shí)體類方法的偽代碼,例如“來車”的偽代碼如下: |
int?泊位::來車(){
??// 1、取值班人員
??排班(時(shí)間).取值班人員(值班人員序號);
??if(失敗){
? ??打印日志
? ??返回失敗錯(cuò)誤碼
??}
??return?0
}
3.4.2 構(gòu)建DSL生成代碼
顯然上述信息并不足以生成代碼,以“泊位::來車”這段偽代碼為例,要想映射為一段符合C++語法的代碼,至少還需要完善下面這些信息:
|
做完這些工作后,我們才能將上述偽代碼使用結(jié)構(gòu)化的語言描述以便生成代碼,例如:
{
????"return_type":"int",
????"function_name":"ArriveCar",
????"param":[],
????"impl":[
????????{
????????????"entity":"Scheduling",
????????????"function":"GetShiftPersonnel",
????????????"return_type":"int",
????????????"param":[
????????????????{
????????????????????"type":"int",
????????????????????"name":"number"
????????????????}
????????????]
????????}
????]
}
事實(shí)上需要配置的信息遠(yuǎn)遠(yuǎn)不止這些,而且完成這些工作的知識都在“人腦”中,只能人來完成,?構(gòu)建可以生成的代碼的 DSL 并不簡單。當(dāng)然我們可以通過一些方法來減少人的工作:例如將填空題修改為選擇題(大多數(shù)配置都是勾選操作而不用輸入文字)、總結(jié)最佳實(shí)踐添加默認(rèn)選擇項(xiàng)(例如成員變量默認(rèn)不生成Get函數(shù))等等,然而始終有一部分工作是繁瑣、重復(fù)、低效且需要人來完成的,例如上述步驟中的中文根據(jù)使用情景不同翻譯為不同詞性、不同格式的英文單詞。而這部分工作就需要引入 ChatGPT 來完成,由人來翻譯500個(gè)中文詞可能需要50分鐘(10個(gè)/分鐘),而讓 ChatGPT 來翻譯僅需要幾秒鐘。
3.4.3 完善代碼
經(jīng)過第一步從模型提取信息、第二步將信息轉(zhuǎn)換為生成代碼所需要的 DSL ,這時(shí)候我們就可以生成代碼了,下面是我們生成的代碼目錄的一個(gè)案例:
我們打開上述目錄中的頭文件、PROTO 文件不僅滿意的點(diǎn)了點(diǎn)頭。但當(dāng)我們點(diǎn)開泊車類的 .cpp 文件見到下面內(nèi)容不僅吐槽:生成的代碼并不能直接運(yùn)行!
// 來車
int ParkingSpace::ArriveCar() {
?? MDD-TAG-BEGIN:[flow][slot-ArriveCar][函數(shù)實(shí)現(xiàn)]
??int ret = 0;
??// 取值班人員
??Scheduling scheduling (/*請?zhí)畛鋮?shù)*/);
??ret = scheduling.GetShiftPersonnel(number);
??if (ret != 0) {
????LOG_VERR("--->>錯(cuò)誤事件名<<---", ret, "GetShiftPersonnel_ERR");
????return ret;
??}
??return ret;
?? MDD-TAG-END:[flow][slot-ArriveCar]
}
是的,到這一步大部分的方法實(shí)現(xiàn)并沒有生成。在這里分析一些原因,以上圖中的偽代碼為例,如果要生成代碼需要人補(bǔ)充什么信息呢?
|
僅僅是這么幾行偽代碼就需要補(bǔ)充如此多的信息,假如這些信息都是由人來配置,那和直接寫代碼有什么區(qū)別呢?IDE 通過友好的提示,直接寫代碼甚至比在工具配置后生成代碼效率更高!
所幸的是,無需人工配置,只要我們將偽代碼轉(zhuǎn)換為業(yè)務(wù)代碼所需要的頭文件定義等輸入到 ChatGPT,它就可以自動推導(dǎo)實(shí)現(xiàn),生成代碼。這就是為什么要“分兩次讓 ChatGPT 生成代碼”。第一次是生成 DSL 以便代碼生成工具生成質(zhì)量有保證的代碼框架、頭文件定義等,第二次是根據(jù)已經(jīng)生成的代碼繼續(xù)完善業(yè)務(wù)代碼。
思路已經(jīng)很明確,要想落實(shí)為具體方案,那就需要代碼生成工具有一個(gè)好的設(shè)計(jì),這里的好是指“模塊化、低耦合、可擴(kuò)展”,下面介紹代碼生成工具的設(shè)計(jì)實(shí)現(xiàn)。
04、設(shè)計(jì)實(shí)現(xiàn)
4.1 架構(gòu)分層
(圖源網(wǎng)絡(luò))
上圖中標(biāo)紅的部分“模型和引擎共同決定了應(yīng)用的實(shí)現(xiàn)程度和擴(kuò)展性”。本文不是講領(lǐng)域建模的內(nèi)容,因此建模知識這里不做討論,我們重點(diǎn)討論引擎的設(shè)計(jì)。補(bǔ)充一下系統(tǒng)的架構(gòu)分層如下:
協(xié)議棧:??定義代碼生成引擎輸入的格式化結(jié)構(gòu),可以的話這個(gè)結(jié)構(gòu)可以作為規(guī)范標(biāo)準(zhǔn)供各種低代碼平臺通用使用,當(dāng)然如果能夠做到這點(diǎn)就能解決掉低無代碼平臺的互聯(lián)互通問題(難而正確的事),是對整個(gè)行業(yè)有利的事情。
代碼生成引擎:對協(xié)議棧的實(shí)現(xiàn),定義了代碼生成的模版,將輸入的數(shù)據(jù)進(jìn)行處理后根據(jù)需求填入到不同的模板中,生成 C++、TS 等代碼。
引擎插件:基于引擎進(jìn)行拓展,例如使引擎更靈活,支持更多的協(xié)議。我們和 ChatGPT 結(jié)合實(shí)際上就是對 ChatGPT 的能力進(jìn)行封裝,實(shí)現(xiàn)為一個(gè)個(gè)的插件輔助人來完成工作,提高代碼生成工具的易用性。
代碼生成工具:??對引擎以及插件的封裝,是面向用戶的產(chǎn)品。
4.2 插件化
明確了架構(gòu)的分層,我們和 ChatGPT 集成的方案也就自然而然地明確了:將模型映射代碼的過程拆解為一個(gè)一個(gè)的任務(wù),分析哪些任務(wù)現(xiàn)階段是由人完成的且 ChatGPT 已經(jīng)具備相應(yīng)的能力,則基于 ChatGPT 的能力分裝為一個(gè)一個(gè)的插件,協(xié)助人完成相應(yīng)的任務(wù),提升效能。下面我們講解對幾個(gè)插件的思考。
4.2.1 代碼生成插件
讓 ChatGPT 來生成代碼,Prompt 需要包含如下三部分信息:有什么、用什么、做什么。
有什么:上文已經(jīng)解釋了我們是讓 ChatGPT 生成質(zhì)量相對穩(wěn)定的代碼片段,即某一個(gè)函數(shù)的實(shí)現(xiàn)。“有什么”實(shí)際上就是函數(shù)的入?yún)?、類的成員變量以及全局變量。入?yún)⒑皖惖某蓡T變量可以通過解析領(lǐng)域模型得到,而全局變量則定義在代碼生成的模版中,是一些固定的值(一般是全局配置)。
用什么:即實(shí)現(xiàn)該方法需要哪些實(shí)體類方法、邊界類方法、基礎(chǔ)庫。實(shí)體類方法在3.4.2展示了,DSL 生成代碼后已經(jīng)有了實(shí)體類方法的頭文件;邊界類方法即對外系統(tǒng)接口的封裝,需要進(jìn)行統(tǒng)一管理,因此也可以很方便地得到。
基礎(chǔ)庫分為官方庫和第三方庫,官方庫無需輸入,ChatGPT 可以推導(dǎo)出使用正確的方法,而第三方庫由于太多我們暫不處理,我們的目的本來也不是生成100%的代碼,無法生成的這部分就交給研發(fā)去補(bǔ)充吧(別忘了研發(fā)還有 Copilot 等利器)。
做什么:需要完善的代碼邏輯,就是偽代碼,在3.4.3有做展示,這里不再贅述。
插件將上述信息拼接為 Prompt ,剩下的就交給 ChatGPT 吧,例如上述泊位::來車方法最終由 ChatGPT 完善為:
// 來車
int ParkingSpace::ArriveCar() {
?? MDD-TAG-BEGIN:[flow][slot-ArriveCar][函數(shù)實(shí)現(xiàn)]
??int ret = 0;
??// 取值班人員
??Scheduling scheduling (time(nullptr));
??ret = scheduling.GetAttendant(number_);
??if (ret != 0) {
????LOG_VERR("GetAttendant", ret, number_);
????return ret;
??}
??return ret;
?? MDD-TAG-END:[flow][slot-ArriveCar]
}
4.2.2 翻譯插件
正如第二章所演示的效果,這個(gè)插件我們已經(jīng)實(shí)現(xiàn)完成了。目前大多數(shù)建模工具支持填寫英文名稱,但是英文名稱為非必填字段且大多數(shù)人不習(xí)慣使用英文建模,我們提取模型中未關(guān)聯(lián)英文單詞的中文,拼接為 Prompt 調(diào)用 ChatGPT 統(tǒng)一翻譯,一鍵填充。
當(dāng)然我們所需要的插件不僅僅這兩個(gè),我們也腦爆了單測生成插件、SQL 生成插件等等一系列的提效插件。
4.3 研發(fā)調(diào)整
我們評估如果按照這樣的思路,實(shí)現(xiàn)代碼生成工具可以節(jié)省90%以上的工作量,大約剩下的10%是如下工作:
代碼走查:上面已經(jīng)說了 ChatGPT 生成的代碼只是相對穩(wěn)定,因此生成的代碼默認(rèn)使用/*和*/包裹注釋掉,必須經(jīng)過研發(fā)確認(rèn)代碼正確且調(diào)整完畢后才可以刪除注釋投入使用。
代碼完善:ChatGPT 無法生成100%的代碼,例如上一個(gè)接口產(chǎn)生了一個(gè)中間結(jié)果緩存起來,該接口會使用,考慮到 ChatGPT 的性能、插件實(shí)現(xiàn)的復(fù)雜性、OPENAI 接口收費(fèi)價(jià)格等因素,我們不可能把上一個(gè)接口的信息拼接到Prompt 。這部分邏輯研發(fā)直接編寫代碼所付出的成本遠(yuǎn)遠(yuǎn)低于使用 ChatGPT 所需成本。
單元測試:ChatGPT 寫單元測試的質(zhì)量遠(yuǎn)遠(yuǎn)超出我的想象,它會考慮邊界條件等等各種因素,如果是針對基礎(chǔ)庫生成的測試用例代碼幾乎不需要修改就可以直接使用,但是如果是控制類等業(yè)務(wù)代碼的測試用例卻不能使用,例如上述接口中的 JScode 是小程序產(chǎn)生,毫無疑問 ChatGPT 無法構(gòu)造出這樣的參數(shù),是 Mock 還是調(diào)用可測試性接口獲取還需要研發(fā)根據(jù)實(shí)際情況做出調(diào)整。
無論如何,由于業(yè)務(wù)本身的復(fù)雜性,我們不可能寄希望于使用一個(gè)工具生成所有代碼,一定有一部分代碼是工具所無法完成的,依然需要人來參與。
但是這部分工作可以通過 Copilot 、IDE 插件等工具來輔助提效。
05、總結(jié)
各位仍需注意,如果直接使用 ChatGPT 有敏感信息泄露風(fēng)險(xiǎn),各團(tuán)隊(duì)可以根據(jù)需要獨(dú)立部署AI模型。對于個(gè)人開發(fā)者可以使用一些開源模型,例如 Vicuna、LLaMA 等。
迄今為止 AI 工具的出現(xiàn)主要還是為了便利人類,而不是代替人類。加以學(xué)習(xí)利用,這些工具也許能為幫助開發(fā)提速。歡迎開發(fā)者們在評論區(qū)交流。
-End-
原創(chuàng)作者|鄔俊杰
技術(shù)責(zé)編|張晉銘
各位開發(fā)者有沒有用過 GPT 輔助工作呢?GPT 能與哪些技術(shù)結(jié)合碰撞火花?還能有哪些應(yīng)用場景?歡迎在騰訊云開發(fā)者公眾號評論區(qū)中留言。我們將選取1則最有創(chuàng)意的評論,送出騰訊云開發(fā)者-靠枕1個(gè)(見下圖)。6月5日中午12點(diǎn)開獎(jiǎng)。文章來源:http://www.zghlxwxcb.cn/news/detail-599713.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-599713.html
到了這里,關(guān)于我用低代碼結(jié)合ChatGPT開發(fā),每天多出1小時(shí)摸魚的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!