Github2.5k星,Karpathy轉(zhuǎn)贊,「流程工程」讓LLM代碼能力瞬間翻倍,直接淘汰提示工程
代碼生成可以說是大模型應用中效果最好,使用人群最廣的一項任務了。
但是由于編程語言眾多,要應對各種不同的邊緣場景,代碼生成任務又是對模型能力要求最高的任務,一般的自然語言提示,甚至是CoT等方法,對于代碼生成任務來說,效果也不是很好。
但是最近在GitHub上有一個項目大火,它通過一系列針對大模型代碼生成任務的優(yōu)化,將提示詞工程升級為一個更加復雜的「流程工程」,能夠大幅提升模型輸出的代碼質(zhì)量。
項目地址:https://github.com/Codium-ai/AlphaCodium
就連AK看了,都很興奮地轉(zhuǎn)發(fā),認為如果代碼生成任務能夠以更科學的流程,而不是簡單的問答方式來和大語言模型互動的話,性能確實還有不少提升的空間。
作者把這個項目稱為AlphaCodium ,一種基于測試的、多階段、面向代碼的迭代流程。
他們在由谷歌DeepMind提出的一個非常有難度的代碼測試集CodeContests上進行測試,將GPT-4的成績從19%提高到了44%。
由于CodeContests代碼生成問題的復雜性,簡單的提示優(yōu)化,甚至CoT提示,無法獲得有意義的性能提高。
最主要是因為就算強如GPT-4,也難以理解和「消化」問題,會不斷產(chǎn)生錯誤的代碼。
適用于自然語言任務的通用流程可能不適用于像CodeContests上這種有難度代碼生成任務。
CodeContests數(shù)據(jù)集
CodeContests是Google Deepmind推出的一個具有挑戰(zhàn)性的代碼生成數(shù)據(jù)集,其中包括了很多像Codeforces等競賽性編程平臺編寫的問題。
這個數(shù)據(jù)集包含約一萬個可用于訓練LLM的問題,以及用于評估LLM解決具有挑戰(zhàn)性的代碼生成問題的能力的驗證和測試集。
作者沒有訓練專用模型,而是開發(fā)了一個面向代碼的流程,這個流程可以應用于任何能夠用于編碼任務的預訓練的LLM,例如GPT或DeepSeek。
下圖展示了一個 CodeContests 數(shù)據(jù)集中的典型問題示例:
為什么CodeContests是一個評估代碼生成任務的LLM的優(yōu)秀數(shù)據(jù)集?
主要原因是:
1)CodeContests與許多其他競爭性編程數(shù)據(jù)集不同,它利用一套全面的不公開的測試來避免錯誤檢測——每個問題包含約200個生成的代碼解決方案,輸出和輸入都要通過這個測試。
2)LLM通常不擅長關注小細節(jié),因為他們通常會將問題描述轉(zhuǎn)換為某種「平均」描述,接近于模型接受訓練時的常見案例。
另一方面,現(xiàn)實世界的問題經(jīng)常包含正確解決問題內(nèi)容中至關重要的小細節(jié)。
CodeContests 數(shù)據(jù)集的一個關鍵特征是,問題描述在設計上是復雜而冗長的,并且存在一些小細節(jié)和細微差別(參見上圖中的典型問題描述)。
作者認為增加這種問題理解的自由度是有益的,因為它能真實模擬現(xiàn)實生活中的問題,這些問題通常很復雜,涉及多種因素和考慮因素。
這與更常見的代碼數(shù)據(jù)集(例如 HumanEval)形成對比。
作者認為適當?shù)淖晕曳此紩箚栴}更加清晰、更加連貫。這說明了問題理解作為流程的一部分的重要性,它很可能導致正確的代碼解決方案。
為了應對這種和現(xiàn)實問題很接近的測試集,作者提出了這樣一個流程:
該流程主要是一個迭代過程,作者根據(jù)輸入輸出測試反復運行和修正生成的代碼。
這種以代碼為導向的流程有兩個關鍵要素:
- 預處理階段是一個線性流程,用自然語言對問題進行推理。在預處理階段生成額外的數(shù)據(jù),如自我反省和公共測試推理,以幫助迭代過程;
- 代碼迭代階段包括根據(jù)特定測試生成、運行和修復代碼的迭代階段。這個階段使用人工智能生成的額外測試來豐富公共測試。
面向代碼的設計理念
AlphaCodium 流程廣泛使用了以下設計概念:
YAML 結構化輸出
結構化輸出的使用——要求模型生成 YAML 格式的輸出,相當于給定的 Pydantic 類——是我們提出的流程中的關鍵組件。此類指令的示例:
...
Your goal is to present possible solutions to the problem.
Make sure that each solution fully addresses the problem goals, rules, and constraints.
The output must be a YAML object equivalent to type $PossibleSolutions, according to the following Pydantic definitions:
class Solution(BaseModel):
name: str = Field(descriptinotallow="The name of the solution")
content: str = Field(descriptinotallow="A description of the solution")
why_it_works: str = Field(descriptinotallow="Why this solution is correct. Be specific and detailed regarding the problem rules and goals")
complexity: str = Field(descriptinotallow="The complexity of the solution")
class PossibleSolutions(BaseModel):
possible_solutions: List[Solution] = Field(max_items=3, descriptinotallow="A list of possible solutions to the problem. Make sure each solution fully addresses the problem rules and goals, and has a reasonable runtime - less than three seconds on a modern computer, given the problem constraints for large inputs.")
結構化輸出消除了「提示工程」所需的大部分麻煩和黑暗知識,而是允許以簡單的、類似代碼的方式呈現(xiàn)復雜的任務。它還使得獲得涉及多個階段的復雜答案成為可能,代表邏輯和有條理的思維過程。
要點分析
當要求 LLM 推理問題時,要求輸出采用要點格式通常會獲得更好的結果。
要點鼓勵對問題的深入理解,并迫使模型將輸出劃分為邏輯語義部分,從而改進結果。
例如,通過對問題的要點進行自我反思(見上圖),每個要點代表對問題不同部分的語義理解——一般描述、目標和規(guī)則、輸入結構和輸出結構。
LLM在生成模塊化代碼時做得更好
當要求 LLM生成單個冗長函數(shù)時,結果往往很差 - 代碼通常包含錯誤或邏輯錯誤。
更糟糕的是,單個整體代碼損害了執(zhí)行迭代修復的能力——即使給出了錯誤消息,模型也難以查明和修復問題。
具有雙重驗證的軟決策
LLM往往會在需要思考、推理并做出嚴格、重要決策的代碼任務中遇到困難。
以針對問題生成附加測試的任務為例。很多時候,模型生成的一些測試是完全錯誤的。
通過雙重驗證過程,作者添加了一個額外的步驟,在給定生成的輸出的情況下,要求模型重新生成相同的輸出,但在需要時進行更正。
例如,將生成的 AI 測試作為輸入,要求模型重新生成相同的測試,同時糾正錯誤的輸出(如果存在)。我們發(fā)現(xiàn),雙重驗證的這一步驟在鼓勵模型批判性和推理性的同時,比直接問「是/否」問題更有效:「這個測試正確嗎?」
推遲決策,盡量避免直接提問,并留出探索的空間
向模型提出有關復雜問題的直接問題時,我們總是會看到幻覺和錯誤答案。
采用逐步數(shù)據(jù)積累的流程,從簡單的任務到困難的任務:
從最簡單的任務開始 – 對問題的自我反思,并對公共測試進行推理。
開始生成額外的人工智能測試以及問題的可能解決方案。
只有在獲得模型對上述任務的答案后,我們才會開始實際的代碼生成和運行修復迭代。
測試錨點
即使經(jīng)過雙重驗證,一些人工智能生成的測試也會是錯誤的。
這使得迭代變得具有挑戰(zhàn)性——當測試失敗時,我們?nèi)绾沃朗且驗榇a錯誤,還是因為測試錯誤?
當我們直接詢問模型「誰錯了」時,經(jīng)常會看到幻覺,并可能最終得到錯誤修復的代碼。
為了解決這個問題,作者使用了「測試錨點」技術:
– 首先迭代公共測試,我們知道這是正確的。完成后,將所有通過的測試設置為錨定測試。
– 然后,一項一項地迭代人工智能生成的測試。如果測試通過,則將其添加到測試錨點列表中
-如果測試失敗,假設是因為代碼不正確,并嘗試修復代碼。
然而,要求固定代碼也通過已經(jīng)獲得的所有測試錨點。因此,測試錨點將保護輸出免受錯誤固定代碼的影響。
測試錨點的另一個優(yōu)化是將人工智能生成的測試從易到難進行排序。這樣,迭代過程就有更多機會在過程開始時獲得錨點,這可以在以后迭代更復雜的人工智能測試時用作保護,因為錯誤測試輸出的可能性更高。
結果
直接使用提示詞 Vs AlphaCodium
將 AlphaCodium 結果與通過單個精心設計的直接提示獲得的結果進行了比較。
可以看出,AlphaCodium流程一致且顯著提高了LLM在CodeContests問題上的性能。
對于開源 (DeepSeek) 和閉源 (GPT) 模型以及驗證集和測試集都是如此。