開發與維運

什麼是人工智能自動編程?它只是一個噱頭嗎?

作者 | 梧忌

image.png
毫無疑問,人工智能將改變軟件開發的方式 —— 我們已經看到了一些嘗試將人工智能應用到軟件開發所帶來的好處,例如“程序代碼自動生成”:根據圖像生成代碼、通過數據模型生成代碼……今天我感興趣的是,一個普通的開發者是否已經有了一些有用的工具,這些工具使用人工智能技術提高了他的生產力。

我將目光放到了常見的編程領域,搜索了一些稱之為「智能編程」的工具,並嘗試在它們的幫助下完成一個簡單的實驗:編寫一個具有輸入框和內容的界面,內容的會隨著輸入框的輸入而發生變化。由此來觀察這些工具提供了哪些能力,是否對我們的編程工作產生了實際性的幫助。

實驗示例代碼如下:
image.png

筆者完全認同人工智能可以幫助軟件開發的所有階段,而不僅僅是在代碼級別。

VS Code 所帶來的啟發

VS Code 是目前最受前端開發者歡迎的編輯器,它默認提供了一些智能化的功能,普通開發者可以快速上手體驗這些功能。我們從它入手來介紹編輯器領域的一些概念和專有名詞。

智能提示(IntelliSense)

IntelliSense 是 VS Code 內置的一系列功能,包含了代碼補全(Code Completion)、概況信息顯示(Quick Info)、函數簽名顯示(Parameter Info)等。

VS Code 默認為為 JavaScript/TypeScript、HTML、CSS/SCSS/Less 等語言提供了智能提示,也可以通過安裝語言插件為更多的語言添加智能提示功能。

代碼補全(Code Completion)

VS Code 智能提示功能由 VS Code 的語言服務提供支持。語言服務提供了基於語言語義和源代碼分析的代碼補全能力。具體來說,如果語言服務知道可能完成輸入,則建議的補全列表將在你鍵入後彈出:
image.png
如果繼續鍵入字符,則補全列表(變量、方法等)將被篩選,僅包含包含鍵入字符的列表:
image.png
VS Code 智能提示提供了豐富類型的補全提示,包括語言服務的建議、代碼片段(Snippet)和簡單的基於單詞的文本補全

補全列表內,它們的排序優先級(Sorting of Suggestions)如下:

  • 語言服務的建議
  • 代碼片段
  • 全局標識符
  • 簡單的基於單詞的文本

在單項內以字母順序進行排序

幾點特殊的說明:

就近原則
image.png
在上面的圖片中,你可以看到 count、context 和 colocated 是根據它們出現的範圍(loop、function、file)進行排序的。

就近原則的上下文提示默認是不開啟的,你可以通過 editor.suggest.localityBonus 設置來開啟。

代碼片段的優先級
你可以使用 editor.snippetSuggestions 設置代碼片段在代碼補全列表中是否顯示及優先級。要從代碼補全列表中刪除代碼片段,請將值設置為“none”。如果你想查看代碼片段,可以指定其在代碼補全列表上的順序:在頂部(“top”)、在底部(“bottom”)或按字母順序內聯(“inline”)。默認值為“inline”。

代碼補全列表的建議完成項
默認情況下,VS Code 在代碼補全列表中預先選擇以前使用的項目。如果你想要不同的行為,例如,總是選擇建議列表中的第一項,你可以使用 editor.suggestSelection 設置。

可用的值包括:

  • first:始終選擇頂部列表項。
  • recentlyUsed:(默認)除非前綴(要選擇的類型)選擇其他項目,否則將選擇以前使用的項目。
  • recentlyUsedByPrefix:根據以前補全的建議的前綴來選擇項目。

列表項的概況顯示(Quick Info)

在代碼補全列表上,你可以通過單擊列表項右側的圖標來查看每個補全項的概況信息,該補全項的附帶文檔將擴展到側面。展開的文檔將保持不變,並在你瀏覽列表時更新。你可以通過單擊“關閉”圖標來關閉此窗口:
640.gif

函數簽名信息(Parameter Info)
當你在代碼補全列表上選擇了一個函數(方法)後,將顯示有關函數簽名的信息。當有多個參數時,突出顯示(下劃線高亮)當前正在補全的參數:
image.png

智能操作(Code Actions)

除提示外,VS Code 還內置提供了一些可由開發者主動操作的智能編碼手段。

代碼重構(Refactoring)

代碼重構提供了諸如提取函數和提取變量等功能。在 VS Code 代碼編輯中,只需選擇你要提取的源代碼,然後單擊槽中的燈泡或按(⌘)即可查看可用的重構方式:
image.png
代碼重構的能力是由語言服務提供的,因此,不同的語言所能做的代碼重構不盡相同。VS Code 通過 TypeScript 語言服務內置了對 TypeScript 和 JavaScript 的代碼重構支持。

更多關於代碼重構的功能,可參考 TypeScript 語言服務的重構章節。

快速修復(Quick Fixes)

快速修復是由語言服務提供的診斷程序,可以用來查找常見的編程問題。例如,它可以分析你的源代碼並檢測出永遠都不會執行的代碼,這些代碼在編輯器中顯示為灰色。如果你將鼠標懸停在這樣源代碼行上,你可以看到一個懸停說明,如果你將光標放在該行上,你將得到一個快速修復燈泡:
image.png
不同語言所能做的快速修復不盡相同,VS Code 對 TypeScript 和 JavaScript 內置的快速修復有:

  • 向成員訪問添加缺少的 this
  • 修復拼寫錯誤的屬性名稱
  • 刪除無法訪問的代碼或未使用的導入

開發者可以通過安裝語言插件添加更多快速修復功能。

實驗演示

在沒有安裝任何外部插件的情況下,我嘗試通過 VS Code 完成示例中的代碼,效果如下:
640 (1).gif

  • 介紹章節羅列的功能大部分都在演示中觸發了
  • 代碼補全提示類型不多,有語言關鍵字、名稱表達式和屬性表達式的類型補全
  • 代碼補全的正確率不高,多為單詞和全局變量提示
  • 我嘗試安裝了 @types/react,有了語言語義的支持後,React API 的代碼提示的效率明顯變高了

業界有哪些產品?

Visual Studio IntelliCode

Visual Studio IntelliCode(以下簡稱 VS IntelliCode)是微軟官方 2018 年 7 月 推出的智能代碼插件,在 2019 年 8 月發佈正式版本,最近一次更新是今年 6 月底。IntelliCode 支持多種編程語言(JavaScript/C++/Python),它在 VS Code 插件市場有高達六百萬的下載量。

IntelliCode for VS Code

IntelliCode 號稱能基於對代碼上下文的理解和機器學習的結合提供智能輔助開發功能。具體來說,提供了以下幾個功能。

第一個功能是更智能的代碼補全。常見的代碼補全是根據字母順序來進行排序的,VS IntelliCode 則根據上下文和「理解你的使用習慣」的來對一些方法進行了排序提取,供開發者使用的最可能正確的 API。在下面顯示的示例中,可以看到 IntelliCode 提升的預測 API 出現在列表頂部的一個新部分中,成員前綴為一個星形圖標:
image.png
這樣的功能還能運用在寫 React 組件屬性時:
image.png
第二個功能是參數的智能補全。具體來說,即當你輸入函數閉合後,將提示你以哪個變量來作為函數的參數。

例如下面的代碼:

try {
 // do something...
} catch (error) {
 // do something...
 console.error(); 
 // 當你輸入了 console.error() 後,編輯器光標會在 error 方法內
 // 並出現補全列表,第一項便是 catch 裡傳入的 error 變量。
}

可惜該功能對 TypeScript 和 Javascript 不可用,官網列出了在 C+ 中的示例:
image.png
第三個功能是代碼重構建議。官網給出的示例是當我們用同樣的方法更新了多處代碼:
image.png
插件會在代碼插槽處顯示更新燈泡圖標,點擊更新燈泡圖標將告知我們還有哪些可以以同樣方式更新的代碼:
image.png
點擊列表項即可定位到可執行建議更新的代碼處,在代碼旁的插槽處可以應用建議的更改:
image.png
這個功能似乎用處不大,畢竟在我們進行代碼重構的時候可以通過使用正則表達式搜索替換的方式一次性更新所有代碼。也許其強大之處在於你是在「不自覺中」更新了兩處一樣的代碼(它會在本地跟蹤你的編輯過程和內容並檢測可重複應用的內容),然後插件給予你還可以更新更多類似代碼的提示吧。

實驗演示
640 (2).gif
IntelliCode 主要是豐富了屬性表達式的補全,在我們的實驗中,其補全效率與原生 VS Code 並無明顯差異。

Kite

Kite 是由一家硅谷的創業公司於 2017 年 3 月推出的代碼智能編輯輔助工具,支持在多個 IDE 中以插件的方式嵌入,其提供的 VS Code 插件最近一次更新是今年 7 月中。Kite 起初只適用於 Python,目前部分功能已支持 Javascript。它在 VS Code 插件市場有高達一百萬的下載量,是 Python 社區最受歡迎的 VS Code 插件之一。

Kite 母公司在 2019 年初獲得了 A 輪 1700 萬美元的融資,目前提供了免費版本和付費方案。

Kite for VS Code

Kite 官網介紹了其 智能代碼補全 功能,Kite 提供的代碼補全與典型的代碼補全方式不同的地方有:

1、為幾乎所有 JavaScript 代碼提供補全,比如語句、函數、對象等等,例如在空格後:
image.png
2、與只有單詞補全相比,Kite 提供了整行或多行的代碼補全:
image.png
3、Kite 可以猜測你當下最有可能進行的輸入,提供智能的推薦:
image.png

Using the VS Code plugin for JavaScript

除了代碼補全,Kite 還提供了智能代碼片段、智能代碼搜索、文檔搜索等功能,但這些功能目前僅支持 Python 語言。

實驗演示
640 (3).gif

  • Kite 的代碼補全類型更加豐富,補全效率也明顯比前兩者要高
  • Kite 的代碼補全列表選項不多,我猜想是為了提高正確率。從實際效果來看,觸發的補全項普遍是正確的
  • Kite 的代碼補全響應速度與 VS Code 原生功能相比,沒有感受到明顯的差異

TabNine

TabNine 的第一個版本於 2018 年底推出,支持在多個 IDE 中以插件的方式嵌入,其提供的 VS Code 插件最近一次更新今年 7 月底。TabNine 的編程語言的覆蓋度非常高,支持大多數常用的編程語言(JavaScript/Java/Python……),其在 VS Code 插件市場有高達三十萬的下載量。

TabNine 最早是社區的開源軟件,今年年初被 Codota 收購,Codata 今年四月份宣佈獲得了 1200 萬美元的融資,目前提供了免費版本和付費方案。

TabNice for VS Code

比 VS IntelliCode 提供 API 自動補全更進一步, TabNine 提供了全方位的代碼補全。只要你在編輯器中鍵入,TabNine 就會給予自動補全提醒。TabNine 官網用了三個示例來描述自己的能力。分別是:

1、基於註釋推導可能編寫的代碼,例如根據函數的註釋推導能使用的函數名、參數和返回值類型
image.png
2、基於上下文推導出可能使用的 API 和傳遞的參數:
image.png
3、瞭解常用庫的使用模式(最佳實踐),並根據上下文給出代碼補全的建議:
image.png

實驗演示
640 (4).gif

  • TabNine 實現了全類型補全,可以看到在每一次輸入 TabNine 都會出現代碼補全列表提示我們可能進行的輸入
  • 由於提示頻率高,因此正確率則不如 Kite,但 TabNine 比較討喜地在在右側面板用百分比顯示可能的匹配度,對用戶編程體驗沒有感受到有太大的干擾
  • TabNine 的代碼補全響應速度與 VS Code 原生功能相比,沒有感受到明顯的差異

aiXcoder

aiXcoder 的第一個版本於 2018 年中旬推出,2019 年底推出了 VS Code 插件,該插件最近一次更新是今年 5 月初。aiXcode 支持多種主流 IDE (IntelliJ IDEA/Eclipse/VS Code)和主流編程語言(JavaScript/Java/Python),主打 IntelliJ IDE 和 Java 語言。可能是由於推出時間不久,而且個人版本僅支持 Java ,所以它在 VS Code 插件市場下載量不高,只有 3k+ 的下載量。由於是國產軟件且功能文檔較為全面,因此也在此次調研清單裡。

aiXcoder 創始團隊來自北京大學實驗室,負責人是北大的副教授李戈老師,是一個是校企合作項目,其母公司硅心科技 18 年獲得了百萬人民幣的天使投資。aiXcoder 提供了個人版本和企業版本。

aiXcoder for VS Code

aiXCode 官網對自己提供的功能進行了較為完整體系的介紹,根據其分類,提供的功能有:

代碼智能補全

  • 單 Token 補全:即變量名、對象屬性、對象方法等輸入的補全;
  • 多 Token 補全:記得鏈式調用嗎?如果有必要,會出現多個鏈式 API 的推薦補全,例如:document.getElementById('foo').style.top
  • 整行補全:即輸入 f,補全提示 for (let i =0, j = foo.length; j >= i; i++)
  • 多行補全:一次性補全多行代碼

640 (5).gif

  • 連續多次補全:當戶確認了 aiXcoder 的推薦結果後,aiXcoder 隨即給出接下來的推薦代碼
  • 函數參數自動補全:即當用戶在調用某個函數(方法)時,提示可能輸入的參數

640 (6).gif

代碼智能搜索

  • 文檔搜索,輸入關鍵字可以搜索出相應的文檔和示例;
  • 相似代碼搜索,選中一部分代碼,在 Github 中搜索出相似的代碼,點擊進行替換;在自己倉庫中搜索出功能實現相似度高的代碼;
  • 推薦代碼搜索,輸入要實現的功能描述(中文),推薦出可供使用的代碼。

image.png
編程智能質效

通過智能分析,得出項目的質量和效率情況,幫助開發者持續進行提高。
image.png

實驗演示

由於 aiXcode 的個人版本僅支持 Java 語言,因此無法就我們的示例來進行實驗。

大公司

Facbook

Facebook 人工智能實驗室在 2019 年四月發佈了 Aroma。Aroma是一個代碼搜索和推薦工具,它使用機器學習技術使得從大型代碼庫中獲得有效的代碼進行編程輔助變得更容易和有效。通過展示與開發者正試圖編寫的代碼類似的示例(並假設這些示例對應於作為公司代碼庫一部分的高質量代碼),這個建議可以幫助開發者更快地完成功能,也可以幫助開發者儘早發現可能的錯誤或重構機會,如示例中缺少異常的處理:
image.png

Google

我沒有從公開的資料和新聞中找到 Google 關於人工智能自動編程或輔助編程的工具。但發現了 Google 對於這方面有一些研究成果。例如,Google Brain 的一個團隊層發表了一篇名為《用於建模源代碼編輯的神經網絡》的論文,他們在該論文中訓練了一個網絡,其中包含來自數千名 Python 開發人員的數百萬次細粒度編輯,用來預測未來的編輯。在這篇論文中,Google 並不關注靜態代碼,而是更關注代碼編輯作為一個隨時間演變的動態對象。

其他

除了上面這些提供整體性智能化解決方案的工具,我還發現了一些專注於對某一單項的能力進行智能化的工具,它們或不成規模,但探索的方向依然有趣:

  • DeepCode:幫助發現項目中的代碼缺陷、安全漏洞、性能和 API 使用問題的插件。下圖演示了 DeepCode 使用“問題”選項卡和語法突出顯示檢查所有問題時的表現:
    image.png
  • Intelli Refactor:該插件是對 VS Code 內置代碼重構功能的增強。

能力和體驗對比

最後,讓我們用表格的形式橫向對比這些工具的能力覆蓋和體驗,其中能力部分以工具官網介紹為依據,體驗部分以我的實驗的個人感受為依據。

由於實驗使用的是前端代碼,且受限於代碼的設計、我個人的機器情況和編程習慣,因此不能作為科學的依據,僅供參考。

主要能力對比

image.png

  • 離線使用:不依賴於網絡即可使用。部分軟件使用深度學習技術,因此需要較大的計算資源,因此使用雲端資源,依賴網絡環境。
  • 領域定製:使用企業或團隊的私有代碼訓練「專用的智能化引擎」,提供更符合企業或團隊編程習慣的建議。

智能提示對比

image.png

  • 補全類型:即能觸發補全提示的情況
  • 屬性表達式:object.${api}
    image.png
  • 名稱表達式:
    image.png
  • 多 Token 補全:如下圖所示,encode是單 Token 補全,encode('utf8') 即是多Token 補全
    image.png
  • 整行補全:如下圖所示,post 是單 Token 補全,post(my_url, data=my_data)是整行補全
    image.png
  • 多行補全:如下圖所示,一次性補全了多行的代碼
    640 (7).gif

使用體驗對比

image.png

  • 補全效率:即對於同一段代碼,需要多少次鍵入才能完成輸入,鍵入越少,補全效率越高;
  • 準確率:即對於同一段代碼,補全提醒首選項的正確的次數與補全提示出現的總次數的比例,比例越高說明準確率越高;
  • 相應速度:即在用戶輸入後多久出現補全提示列表,可通過同一段代碼來測試補全提示的出現平均值;
  • 硬盤資源:離線使用需依賴機器學習模型,因此模型會佔用硬盤資源;

只是噱頭嗎?

通過這個簡單的實驗,可以說,到目前為止,人工智能「自動編程」更多的是市場營銷。我相信這些工具在未來幾年會有很大的進步,並可能成為開發者真正的虛擬助手,但我們離這一步還有些距離。同時不可否認的是,當下使用這些工具讓開發者在編程效率上得到了一定的提升。

  • 對於初級開發者來說,智能編程工具對於編程效率和體驗的提升是明顯的,它能提供有效的建議,幫助初級開發者更快地寫出更好的代碼;
  • 對於高級開發者來說,智能編程工具對於效率的提升則較小,但依然能帶給我們一些愉悅的編程體驗。高級開發者熟練其領域的技能和知識,編程的主觀性較強,且有自己的代碼品味,代碼提示有時候會是一種干擾,所以智能編程工具應該需要具備個性化設置的能力;
  • 與任何使用機器學習方法一樣,智能編程工具的效果取決於訓練數據的質量。如果不使用 GitHub 數據來訓練系統,而是使用內部/私有存儲庫對其進行訓練,則會獲得更好的效果;

另外起初,我只關注到了自動編程對於提高生產效率的效益,但在調研的過程中我發現,人工智能自動編程對於生產質量和編程教育也會有廣闊的前景。

在將來,我想我們還會看到一些編程機器人,我們可以與他們進行一些配對編程,並討論特定方法的目標是什麼,讓機器人為我們找到最好的解決方案。

參考資料

作者是 Iceworks 核心開發者,Iceworks 是面向多端應用開發的研發套件,幫助開發者和研發團隊更快更好地構建多端應用,歡迎使用。


image.png
關注「Alibaba F2E」
把握阿里巴巴前端新動向

Leave a Reply

Your email address will not be published. Required fields are marked *