邏輯代碼自動生成相關技術概述

簡介: 如何有效地提升軟件開發的效率和質量,一直是軟件工程領域關心的問題。其中, 程序自動生成技術被認爲是提升軟件開發自動化程度和最終質量的重要方法,受到學術界和工業界的普遍關注。程序自動生成技術指利用某些技術自動地爲軟件生成源代碼,達到根據用戶的需求機器自動編程的目的。極大程度地減輕了程序員的開發負擔, 使得程序員能夠更加關注於業務價值賦能。javascript

做者 | 妙淨

image.png

做者周婷婷(花名:妙淨,微信: weekendingting)是阿里淘系技術部高級前端技術專家,視覺稿智能生成代碼 imgcook平臺負責人,阿里經濟體前端智能化方向重要成員,來自業內首個 AI 前端團隊淘系前端之 F(x) Team 。去年咱們聚焦在設計稿智能生成前端視圖代碼領域,但對於邏輯代碼的智能生成也一直在不斷嘗試,本文介紹邏輯代碼自動生成相關技術概述。

程序生成介紹

如何有效地提升軟件開發的效率和質量,一直是軟件工程領域關心的問題。其中, 程序自動生成技術被認爲是提升軟件開發自動化程度和最終質量的重要方法,受到學術界和工業界的普遍關注。程序自動生成技術指利用某些技術自動地爲軟件生成源代碼,達到根據用戶的需求機器自動編程的目的。極大程度地減輕了程序員的開發負擔, 使得程序員能夠更加關注於業務價值賦能。html

學術界上,程序生成和代碼補全是程序綜合 (program synthesis) 的重要分支, 其目的在於輔助甚至代替程序員編寫程序。回到(前)端代碼的自動生成,分爲視圖代碼和邏輯代碼,視圖代碼方面目前有相似基於設計稿自動生成 的方案(如 imgcook),本文重點講述邏輯代碼的生成技術方案,常見的生成邏輯代碼的方案包含基於可視化編排生成、基於輸入輸出樣例生成、基於代碼語料生成補全、基於功能描述生成等。前端

邏輯代碼自動生成技術方案對比

image.png

基於可視化編排生成代碼

可視化編程也發展了幾十年,其指的是藉助於一些組件化的集成代碼可視化平臺,一些不具有專業代碼技能和開發經驗的「小白」人羣也能自主組織或參與應用開發,從而把代碼開發由一項程序員專屬職能擴充到更普遍的人羣。它主要是讓程序設計人員利用軟件自己所提供的各類控件,像搭積木式地構造應用程序的各類界面,可視化編排更適合界面視圖代碼的生成;目前國外主打可視化編程、低代碼編程的平臺至少有十幾家,其中最具表明性的能夠說是 OutSystems、Mendix、Salesforce 等幾家,並且對於邏輯代碼的可視化方案也有不少,以下:
image.png
以上類 blockly 等適合比較簡單的邏輯編程,目前在少兒編程領域的應用不錯;一但邏輯複雜,搭建出來的積木也無比龐大。這樣的系統在大公司,若是給業務方直接用,太複雜須要有業務方有編程思惟,和 PRD 思惟徹底不同,門檻較高;若是給編程人員用,只是用圖形來代替了編程語言,編程人員因熟悉編程語言和相關調試等配套環境,可視化搭建的方式生成代碼反而更低效。java

其餘主流的邏輯代碼的可視化的編排(以下圖),其優點是突出「可視化流」和複用邏輯節點帶來的高效,主體是大的流程,輸入輸出、邏輯處理等細節包含在每一個節點的具體表單規則中。此方案適合複用邏輯很是多的場景,複用的邏輯可抽象成流程圖中的「節點」。節點的複用顆粒度大小是比較關鍵的,顆粒度大到一個功能服務,就是業務流程編排了,業務流程複用度比較高的場景是比較適合讓業務方直接所見所得編排使用的;顆粒度小到表達式級別能夠看作是業務邏輯編排,過小顆粒度是須要使用者有編程思惟,顆粒度過小的可視化對於有編程思惟的同窗來講,可能直接寫代碼效率更高。
image.png
小結:可視化邏輯編排生成代碼,其自己編排的成本仍是比較高的複雜狀況下甚至比手寫代碼編程還要高,但在邏輯複用度很是高的場景是比較適合的,可抽象成可複用的邏輯節點去編排,節點的複用能夠帶來部分提效。python

基於輸入輸出樣例生成代碼

基於輸入輸出的樣例,自動推導出生成的邏輯程序,也叫 PBE(Programming by Examples),其是 2016 年微軟在論文中提到的一種程序綜合(program synthesis)的技術方案。現實中比較成功的應用案例是,Excel 中有個功能相信你們應該熟悉,那就是自動填表(FlashFill),其能夠根據幾個樣例快速的生成表格項公式,好比下圖中,根據 第一列的 2 和 4,就能夠填充偶數;第二列根據 50 和 40 自動推導出等差數列公式的結果。
image.png
以更復雜的狀況爲例:
image.png
上述的公式更復雜,現實狀況,FlashFill 的正確率只有不到 50%,後來又在 PBE 的基礎上提出了 NPBE(neural programming by example) 完成 Excel 中的 45 種字符串操做。NPBE 的意圖是讓模型從輸入輸出字符串中學習相關的特徵, 並用學到的特徵來概括正確的程序。通常 PBE 的技術實現過程以下:
image.pnggit

基於代碼語料生成補全代碼

隨着 github 的開源代碼的積累和深度學習的興起,基於源代碼理解(程序理解)應用比較多,如代碼補全推薦、還有根據代碼猜想代碼片斷的意思。程序員

代碼補全

經常使用的集成開發環境中每每整合了代碼補全工具, 通常限於關鍵字或基於語法的提示,好比在 tsx 文件中 this. 會提示出當前可用的類屬性、方法;現有的智能代碼補全工具一般基於模型性能考慮通常簡單基於靜態詞頻統計。github

好比咱們共建團隊同事基於 javascript 代碼語料庫,對比 GPT2 以後,採用 n-gram 機率模型開發的代碼補全插件。詳見這裏,其主要流程圖以下:
image.png算法

代碼意圖生成

代碼意圖生成指根據代碼內容能夠推測出代碼的功能做用,業界較知名的開源的模型和服務有 code2vec 和 code2seq,其中 code2vec 是作 code summarization(代碼功能概要);code2seq 作 code captioning (代碼功能說明)。sql

code2vec 示例說明以下:根據左側的代碼片斷,分析代碼的功能是,90.93%的機率是 contains,右側是對代碼的分析可視化過程,重點關注節點間的連線粗細,粗細用來表示決策的信息權重大小。
image.png
code2seq 示例說明以下:根據左側的代碼片斷,分析此代碼的功能說明是,save bitmap to file,右側是對代碼的分析可視化過程,一樣重點關注節點間的連線粗細,粗細用來表示決策的信息權重大小。
image.png
其內部模型詳見:其目前開源的模型數據集大小爲 billon 級,也開源了基於 typeScript 的模型。
image.png

基於功能描述生成代碼

你們一般利用天然語言來描述程序功能, 從天然語言描述到程序的自動生成是極具挑戰性的問題。天然語言文本和程序的多樣性、文本的二義性以及代碼的複雜結構, 使得創建文本和代碼的聯繫成爲一個難題。目前業內有些探索,包括 NL2SQL、NL2TFTTT、基於功能描述生成代碼。

NL2SQL

Natural Language to SQL (NL2SQL) 是CUI(Conversation User Interface)的新興研究熱點,其研究目的是將用戶輸入的天然語言轉爲可用的 SQL 語句,提升用戶查詢數據的效率,如今阻礙大數據價值變現的最大難題就是訪問數據門檻過高,依賴數據庫管理員寫複雜的SQL,並且中文的表述更加多樣複雜。此領域的國內外的研究很是多,目前 NL2SQL 領域比較有名的數據集是英文版的數據集,包括 WikiSQL、Spider、CoSQL 等。

NL2SQL 典型的三層架構以下:
image.png
NL2SQL分爲User query interface、Processing Unit、Database三部分,其中 Processing Unit 是整個架構的中心,也是語義解析的核心所在,打通了 User 與 Database 的交互通道,囊括智能分詞、實體識別、知識檢索等各個技術要點。在上述研究中,Processing Unit 的內部算法也在逐步朝着深度學習的方向進展。下面是中文 NL2SQL 大賽中冠軍團隊提出的 M-SQL 模型,在中文數據集上達到了92%的準確率。

業內 Google的 Analyza 採用的是語義解析和規則的方式構建的,這種方式可控性較強,可是須要人工維護一些規則進去。端到端的方案則是經過深度學習方法,採用 encoder-decoder 的方式進行 NL2SQL 的實現,整個算法系統分紅了對 SQL 幾個子句的識別,包括SELECT clause、WHERE clause,有時候還有 group by、limit 等操做符。每一個部分還會涉及到不少細節,好比表識別、屬性識別等。不一樣算法都是在這樣的框架體系下,在細節的地方作一些改動和優化,以取得一個比較好的效果。雖然端到端的 NL2SQL 方案可以減小人力維護的成本,可是隻有在 wikisql 這種簡單場景下有必定效果,針對相對複雜一點的 spider 或 cosql 場景來講,準確率很是低,達不到商業應用的要求。公司內部的數小蜜團隊實際業務落地的方案與Google的Analyza方案很類似,同時也已經對端到端 nl2sql 方案進行了研究和實現,下一步指望可以將 NL2SQL 和語義規則解析的方式融合到一塊兒,來解決複雜場景的需求。【此部分結論來源內部小蜜團隊】

NL2TFTTT

IFTTT 是什麼?意思是 if this then that;是一個新生的網絡服務平臺,經過其餘不一樣平臺的條件來決定是否執行下一條命令。例如「若是明天下雨,請今天通知我」「當有人在 Facebook 標記有你在內的相片時,就自動將那張照片備份到iPhone 的照片相冊中」,這知足了用戶把 A 服務內容串連到 B 服務的需求,而且用戶不用本身動手, IFTTT 能夠自動幫忙完成上述動做。

功能示例

以下面的應用:

  • 若是明天下雨,請發通知給我
  • 請天天 7 點給我一份天氣預報

其設置以下:
image.png
NL2IFTTT 就是經過天然語言生成如上 If-This-Then-That(IFTTT) 代碼,IFTTT 程序相對於經常使用的編程語言來講, 其結構更加簡單, 也更容易學習其結構規則。IFTTT 基於任務的條件觸發,相似極簡版編程語言,即:「若 XXX 進行 YYY 行爲,執行 ZZZ」。每個能夠觸發或者做爲任務的網站叫作一個 Channel,觸發的條件叫作 Trigger,以後執行的任務叫作 Action,綜合上面的一套流程叫作 Recipe。

NL2IFTTT 方面的實踐,2016年, Liu等人提出了一種隱注意力機制, 該機制能夠有效地學習天然語言中哪些詞對觸發器的預測更重要, 哪些詞對動做的預測更加劇要。同年,Beltagy 等人將IFTTT 程序生成問題當作語義分析問題。

數據集示例

微軟有一份開源 IFTTT 樣本集,其樣本數據相似以下,能夠方便你們更好地理解 NL2IFTTT 的問題定義:
image.png

NL2Code-TranX

相比於根據天然語言的功能描述生成 TFTTT 代碼 和 SQL,根據天然語言的需求描述直接生成 python、java、javascript 這類的編程語言邏輯代碼的難度要大的多。至今(2020.8)暫時沒有找到相關的在線可用服務,目前找到卡內基梅隆大學有相關研究產出 TranX,其能夠作到單一功能描述 生成 表達式級的代碼,相似根據單行代碼註釋生成相應代碼,見其網站 demo 以下。

TranX 功能示例

image.png
image.png
image.png
TranX 數據集示例

{
    "intent": "Sending http headers with python",
    "rewritten_intent": "sending http headers to `client`",
    "snippet": "client.send('HTTP/1.0 200 OK\\r\\n')",
    "question_id": 8315209
  },
  {
    "intent": "Python -Remove Time from Datetime String",
    "rewritten_intent": "Format a datetime string `when` to extract date only",
    "snippet": "then = datetime.datetime.strptime(when, '%Y-%m-%d').date()",
    "question_id": 26153795
  },
  {
    "intent": "How do I split a multi-line string into multiple lines?",
    "rewritten_intent": "split a multi-line string `inputString` into separate strings",
    "snippet": "inputString.split('\\n')",
    "question_id": 172439
  },
  {
    "intent": "How do I split a multi-line string into multiple lines?",
    "rewritten_intent": "Split a multi-line string ` a \\n b \\r\\n c ` by new line character `\\n`",
    "snippet": "' a \\n b \\r\\n c '.split('\\n')",
    "question_id": 172439
  },

TranX 模型示例

編程語言有嚴格的語法,它不能容忍拼寫錯誤和語法錯誤;此模型針對 AST 構建基於 Tree 的新型模型,能完整表達編程語言的全部語法;同時相應的語料標註是很是昂貴和耗時的,標記樣本的有限可用性是監督模型的瓶頸,此模型引入了 STRUCTVAE,一種用於半監督的自動編碼模型,它能夠從有限的樣本中學習,又能從現成未標記的 NL 語言中學習。論文模型詳見:
image.png

NL2Code-debuild

功能描述生成代碼的應用,還有基於 GPT3.0 的 debuild 平臺;目前演示網站關閉,從宣傳出來效果圖來看,能夠看到從功能描述生成代碼新的可能性。其能夠根據佈局語言描述生成相應的佈局代碼;也能根據簡單高階的功能描述生成相應的代碼。

debuild 功能示例
image.png
debuild 模型示例

此平臺使用的模型基於 openAI 的 GPT3.0,做者表示天然語言生成代碼基於 GPT3.0 讓以前不敢想象的的 50 年以後能生成代碼 提早到 5 年內,目前的版本仍是偏試驗,更可能是偏簡單功能描述生成高階(封裝好的組件庫、模塊庫等)的功能代碼,感興趣的能夠試試 GPT 3.0。

總結

整體來看,基於深度學習爲自動生成程序代碼是趨勢,但當前利用深度學習技術的程序生成和代碼補全還處於起步階段。利用深度學習生成程序代碼和代碼補全與傳統方法相比有了較大的提高, 而程序生成技術尚未用於工業化。其主要面臨着如下的挑戰:

1) 訓練語料的質量良莠不齊。常見工做中, 用來訓練深度學習模型的語料大體能夠分爲兩類:一類是基於 DSL 人爲構造出的程序; 另外一類是從開源社區, 如 GitHub 等網站上爬取的項目。基於 DSL 的程序每每語法較爲簡單, 程序長度較短, 易於訓練和測試, 但同時, 針對 DSL 設計的模型也難以推廣到其餘語言上使用; 而開源社區上爬取的項目雖然更接近於實際軟件開發, 可是也難以保證代碼的質量——低質量、不規範的代碼會給神經網絡帶來額外的噪聲, 而使用不一樣編程規範的代碼則會使神經網絡模型在訓練和預測時產生混淆。如何獲取統一規範的高質量程序語料庫也是一項挑戰。

2)用戶自定義邏輯生成後的泛化能力弱。程序代碼尤爲是邏輯代碼,不少都是業務閉域的邏輯代碼,須要不少業務閉域的邏輯物料,須要對現有業務的所依賴的各類服務進行高階理解,新業務須要結合本身的物料庫訓練本身的模型;但每每全新的業務依賴的服務也須要從 0 開始開發,新物料的提供比較難,除非全部依賴的服務是不可拆分的原子服務。因此邏輯模型的普適性比較難,但方法論能夠相互借鑑有普適性。

3)功能描述和程序代碼信息不對稱。若是真的作到極致,功能描述由 PRD 直接提供,可直接生成相應的程序代碼;需求描述比通常的功能描述還要高階和抽象化,需求描述->功能描述-代碼描述->程序代碼,這其中每個環節都會有不少信息損耗,這些損耗目前都是程序員經過業務經驗和編程經驗補上的。功能描述直接生成代碼解決辦法大體有 3 種,一種是端到端的從需求描述並生成 AST,若是 PD 對軟件功能的描述足夠精確,至關於創造了一個更高級的描述語言; 第二種是後面的鏈路部分(功能描述-代碼描述->程序代碼)封裝抽象成顆粒度較大的功能塊描述,目前大部分是基於這種的可行性比較高(如 NL2TFTTT 等);第三種是真正深刻到每個業務域中,上述每個環節都讓模型去一層層理解最後逐步生成代碼,語料庫的質量和最後的模型準確度效果是比較大的挑戰。

爲了減輕程序員的開發負擔, 提升軟件開發的自動化程度, 提升軟件開發的效率和質量, 學界和工業界都不斷嘗試研究程序自動生成技術。隨着深度學習技術的快速發展, 相信在未來, 愈來愈多的重複性的程序開發將由機器代替, 程序員將更關注於底層架構和上層業務價值賦能。

對於邏輯代碼的智能生成,目前阿里前端智能化團隊內部正在進行各維度的試驗,歡迎交流。

參考資料

相關文章
相關標籤/搜索