碼農狂喜!微軟提出CodePlan,跨168個代碼庫編碼任務,LLM自動化完成
對于大模型來說,擅長的是本地化編碼任務。
但如果任務跨越了多個相互依賴的文件,LLM卻無法解決。
對此,微軟研究人員設計了一個任務無關的神經網絡框架,名為CodePlan。
圖片
論文地址:https://arxiv.org/pdf/2309.12499.pdf
論文中,CodePlan綜合了多步驟編輯鏈(chain-of-edits),是一種將程序分析、規劃和LLM結合在一起的新方法。
一起來具體看看,CodePlan是如何設計的?
CodePlan:大模型+規劃
軟件工程活動中,例如軟件包遷移、修復靜態分析或測試的錯誤報告,以及向代碼庫添加類型提示或其他規范,涉及到對整個代碼存儲庫的普遍編輯。
研究人員將這些活動規劃,為「存儲庫級別的編碼任務」。
隨著編碼工具如GitHub Copilot、Code Whisperer得到了大模型能力加持,已經為碼農在本地化編碼問題提供了解決方案。
然而,現實是,「存儲庫級別的編碼任務」更加復雜,不能直接通過LLM解決,因為存儲庫中的代碼是相互依賴的,整個存儲庫可能太大而無法納入提示。
這項研究中,微軟團隊將庫級編碼框架作為一個規劃問題,并提出了一個任務不可知的框架,稱為CodePlan。
CodePlan綜合了一個多步驟的編輯鏈(計劃) ,其中每一步都會調用代碼位置上的LLM。該代碼位置上的上下文來自整個存儲庫、以前的代碼更改和特定于任務的指令。
CodePlan是基于增量依賴分析、變更可能影響分析和自適應規劃算法的新型組合。
圖片
如下圖,展示了復數庫API的變化,微軟研究人員的任務是根據這一變化遷移代碼庫。
圖片
圖3左側顯示了代碼庫中使用復數庫的相關部分。
具體來說,Create.cs文件中的方法func,調用了庫中的create_complex方法,Process.cs文件中的方法Process.cs調用了func。
圖片
研究人員將圖1中的任務描述和func主體傳遞給LLM,以生成修改后的func代碼,如圖3右側所示。
可以看到,LLM已經正確地編輯了對create_complex API的調用,以便它返回一個Complex類型的對象,而不是兩個浮點值的元組。
注意,這個編輯導致了方法func的簽名發生了變化——它現在返回了一個Complex類型的對象。
這就需要修改方法func的調用者,比如Process.cs中的process方法,如圖3左下角所示。如果不對process方法的主體進行適當的修改,代碼就不能構建!
圖3右下方顯示了對process方法的適當修改,它能使版本庫達到一致的狀態,從而在編譯時不會出錯。
對于研究人員來說,最主要的是構建一個「存儲庫級別的編碼系統」,能自動生成編輯所需的派生規范。
LLM驅動的庫級編碼任務定義如下:
圖片
CodePlan整體框架中,輸入是一個存儲庫、一個通過自然語言指令或一組初始代碼編輯表達種子規范的任務,一個正確性oracle和一個 LLM。
CodePlan構建了一個計劃圖,圖中的每個節點都標識 LLM需要履行的代碼編輯義務,而邊則表示目標節點需要在源節點之后履行。
CodePlan監控代碼編輯,并自適應地擴展計劃圖。
一旦計劃中的所有步驟都已完成,存儲庫將由oracle進行分析。如果oracle驗證了資源庫,則任務完成。如果發現錯誤,錯誤報告將作為下一輪計劃生成和執行的種子規范。
圖片
此外,CodePlan算法還維護了一個依賴關系圖,圖4說明了依賴關系圖的結構。
圖片
刷新SOTA
研究人員評估了CodePlan在兩個存儲庫級任務上的有效性: 包遷移 (C#)和時態代碼編輯(Python)。
每個任務在多個代碼庫上進行評估,每個代碼庫都需要對多個文件(2-97個文件)進行相互依賴的更改。
圖片
這種復雜程度的編碼任務,以前從未使用過LLM自動完成。
研究結果表明,與基線相比,CodePlan更符合基本事實,能夠讓5/6個存儲庫通過有效性檢查,比如,無差錯構建和正確的代碼編輯。
總之,CodePlan為自動化復雜的庫級編碼任務提供了一種有前途的方法,既提高了生產率,又提高了準確性。
它成功應對了許多挑戰,為高效可靠的軟件工程實踐開辟了新的可能性。
參考資料:https://twitter.com/adityakanade0/status/1706291449674039711