譯者 | 布加迪
審校 | 重樓
大語(yǔ)言模型(LLM)正在改變軟件開(kāi)發(fā)生命周期,其在代碼理解、代碼生成、調(diào)試等方面發(fā)揮著功效。本文深入探討如何利用LLM調(diào)試代碼庫(kù),詳述了其核心功能、用于訓(xùn)練的方法以及應(yīng)用未來(lái)進(jìn)一步發(fā)展的方向。盡管LLM存在幻覺(jué)等一些問(wèn)題,但事實(shí)證明,通過(guò)復(fù)雜的智能體調(diào)試框架將LLM集成到開(kāi)發(fā)環(huán)境中可以提高開(kāi)發(fā)人員的效率。
引言
LLM在編碼領(lǐng)域不斷演變的角色
LLM已證明不僅可以應(yīng)用于自然語(yǔ)言處理領(lǐng)域,在各種與代碼相關(guān)的任務(wù)(包括代碼生成和翻譯)中也取得了卓越的性能。它們?yōu)镚itHub Copilot和Cursor等AI編碼助手提供支持,并在HumanEval和MBPP等標(biāo)準(zhǔn)基準(zhǔn)測(cè)試中展現(xiàn)出媲美人類的性能。
LLM可以根據(jù)文本描述生成完整的代碼片段、完成函數(shù)并提供實(shí)時(shí)語(yǔ)法建議,從而簡(jiǎn)化代碼創(chuàng)建的初始階段。然而,其應(yīng)用顯然可以擴(kuò)大到軟件開(kāi)發(fā)生命周期中更復(fù)雜、更迭代的過(guò)程。
代碼調(diào)試的重要性
調(diào)試是軟件開(kāi)發(fā)中一個(gè)耗時(shí)卻又至關(guān)重要的部分,涉及錯(cuò)誤識(shí)別、定位和修復(fù)。這些錯(cuò)誤涵蓋從簡(jiǎn)單的語(yǔ)法錯(cuò)誤到復(fù)雜的邏輯缺陷等各類錯(cuò)誤。傳統(tǒng)的調(diào)試方法通常具有挑戰(zhàn)性,尤其是對(duì)于初級(jí)程序員來(lái)說(shuō),他們可能難以應(yīng)對(duì)晦澀難懂的編譯器消息和復(fù)雜的代碼庫(kù)。調(diào)試過(guò)程的效率直接影響開(kāi)發(fā)進(jìn)度和軟件質(zhì)量,因此需要更先進(jìn)、更直觀的工具。
LLM的核心功能
代碼理解與分析
除了針對(duì)海量代碼語(yǔ)料庫(kù)進(jìn)行廣泛的預(yù)訓(xùn)練以理解自然語(yǔ)言外,LLM 還專門(mén)使用大型編碼數(shù)據(jù)庫(kù)進(jìn)行訓(xùn)練,以識(shí)別常見(jiàn)的編程模式并推斷代碼段的預(yù)期含義。這項(xiàng)基礎(chǔ)功能使它們能夠分析代碼中的語(yǔ)法錯(cuò)誤和邏輯不一致之處。
錯(cuò)誤定位與識(shí)別
LLM在調(diào)試中的一項(xiàng)主要應(yīng)用是能夠協(xié)助識(shí)別和定位錯(cuò)誤。基于LLM的調(diào)試迎來(lái)了最新進(jìn)展,不僅限于行級(jí)錯(cuò)誤識(shí)別。較新的方法可以更精細(xì)地預(yù)測(cè)錯(cuò)誤位置,其精細(xì)度從行級(jí)延伸到token級(jí)。我們可以采用各種技術(shù)來(lái)識(shí)別錯(cuò)誤并修復(fù)錯(cuò)誤。這可以通過(guò)利用CodeT5等編碼器LLM來(lái)實(shí)現(xiàn),它們可以更精確地定位有問(wèn)題的代碼段。
代碼修復(fù)
最近,LLM智能體還可以直接提出代碼修改建議。它們可以采用迭代過(guò)程來(lái)改進(jìn)和修復(fù)源代碼。
人們對(duì)自我修復(fù)技術(shù)的興趣也日益濃厚:LLM運(yùn)行其生成的代碼,觀察結(jié)果,然后根據(jù)錯(cuò)誤原因進(jìn)行調(diào)整。這整個(gè)過(guò)程有助于提高最終代碼的可靠性和質(zhì)量。這種自我修正機(jī)制模仿了人工調(diào)試的某些方面,即開(kāi)發(fā)人員測(cè)試、觀察錯(cuò)誤,然后修改代碼。
比如說(shuō),開(kāi)發(fā)人員可能會(huì)這樣提示LLM修復(fù)錯(cuò)誤:
Python
# User Prompt:
# "The following Python function should calculate the factorial of a number,
# but it's returning an incorrect result for inputs greater than 0.
# Can you identify the bug and fix it?"
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n) # Bug is here - infinite recursion!
# --- LLM's Suggested Fix ---
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)針對(duì)代碼庫(kù)和問(wèn)答論壇的檢索增強(qiáng)生成(RAG)
LLM可以對(duì)內(nèi)部代碼庫(kù)和問(wèn)答論壇(內(nèi)部和外部)執(zhí)行高效的檢索增強(qiáng)生成(RAG),并提供相關(guān)且簡(jiǎn)潔的摘要,這對(duì)調(diào)試過(guò)程大有幫助。這需要理解本地更改的構(gòu)建或運(yùn)行時(shí)錯(cuò)誤、設(shè)計(jì)和訪問(wèn)模式方面的問(wèn)題,或即時(shí)執(zhí)行RAG以了解并提供概述和相關(guān)提示。LLM可以將其與對(duì)代碼庫(kù)的理解相結(jié)合,從而為進(jìn)一步調(diào)試和可能的修復(fù)提供提示。
這預(yù)示著未來(lái)調(diào)試技術(shù)的進(jìn)步將不僅依賴更出色的面向代碼的模型,還依賴將自然語(yǔ)言理解與代碼推理相結(jié)合的創(chuàng)新方法,使LLM能夠以一種更概念化、更類似人的方式解釋和解決編碼問(wèn)題。
用于調(diào)試的測(cè)試用例生成
LLM可以通過(guò)強(qiáng)大的測(cè)試用例生成功能為高效的調(diào)試機(jī)制提供支持。它們可以創(chuàng)建具有多樣化測(cè)試輸入的單元測(cè)試用例,這對(duì)于有效檢測(cè)錯(cuò)誤至關(guān)重要。一些AI編程工具體現(xiàn)了這種能力,允許開(kāi)發(fā)人員通過(guò)提供自然語(yǔ)言提示來(lái)生成結(jié)構(gòu)良好的測(cè)試用例。
Python
// User Prompt:
// "Generate a JUnit test case for the following 'Calculator.add' method.
// Include a test for positive numbers, negative numbers, and zero."
class Calculator:
def add(self, a, b):
return a + b
// LLM-Generated Test Case:
import unittest
class TestCalculator(unittest.TestCase):
def test_add_positive_numbers(self):
calculator = Calculator()
self.assertEqual(5, calculator.add(2, 3), "Adding two positive numbers")
def test_add_negative_numbers(self):
calculator = Calculator()
self.assertEqual(-5, calculator.add(-2, -3), "Adding two negative numbers")
def test_add_with_zero(self):
calculator = Calculator()
self.assertEqual(2, calculator.add(2, 0), "Adding a number to zero")
if __name__ == '__main__':
unittest.main()構(gòu)建調(diào)試能力的方法
數(shù)據(jù)完善和監(jiān)督式微調(diào)
使用所需語(yǔ)言的高質(zhì)量調(diào)試數(shù)據(jù)集進(jìn)行領(lǐng)域特定訓(xùn)練,對(duì)于增強(qiáng)LLM,使其能夠有效調(diào)試并實(shí)現(xiàn)最佳性能是一個(gè)非常重要的環(huán)節(jié)。
監(jiān)督式微調(diào)(SFT) 需要在公共和內(nèi)部代碼庫(kù)上運(yùn)行,以了解設(shè)計(jì)、構(gòu)建和測(cè)試模式。研究表明,與較小的模型(比如70億參數(shù)的模型)相比,較大的LLM、尤其是參數(shù)超過(guò)700億的模型表現(xiàn)出非凡的調(diào)試能力和卓越的錯(cuò)誤修復(fù)準(zhǔn)確性。
自然語(yǔ)言作為中間表示(NL-DEBUGGING)
NL-DEBUGGING框架通過(guò)引入自然語(yǔ)言作為代碼調(diào)試的中間表示,儼然是一大進(jìn)步。這種方法將代碼轉(zhuǎn)換成自然語(yǔ)言理解,便于更深層次的語(yǔ)義推理并指導(dǎo)調(diào)試過(guò)程。這使得LLM能夠提出多種調(diào)試策略和解決方案。常用的自然語(yǔ)言表示包括草圖、偽代碼和關(guān)鍵思維點(diǎn)。
高級(jí)提示工程策略
提示設(shè)計(jì)是有效調(diào)整LLM以執(zhí)行錯(cuò)誤修復(fù)任務(wù)的關(guān)鍵因素。提供全面的上下文(比如原始源代碼)可以顯著提高LLM生成的錯(cuò)誤解釋的質(zhì)量和準(zhǔn)確性。
可以采用各種提示工程策略來(lái)優(yōu)化性能,包括一次性提示、為L(zhǎng)LM分配特定角色(比如指示其“像一位非常資深的Python開(kāi)發(fā)人員一樣行事”)以及將復(fù)雜任務(wù)分解成更小、更易于管理的子任務(wù)。進(jìn)行負(fù)面提示也可能有效,明確表述期望輸出不應(yīng)包含的內(nèi)容。
多 LLM 和智能體調(diào)試流程
為了克服單一LLM的固有局限性,并超越通常無(wú)法應(yīng)對(duì)復(fù)雜調(diào)試場(chǎng)景的簡(jiǎn)單的“提示輸入,代碼輸出”模型,研究人員正在開(kāi)發(fā)多LLM和智能體調(diào)試框架。不同的LLM有不同的角色,比如“代碼學(xué)習(xí)者”和“代碼教師”,它們集成編譯器反饋,以提高錯(cuò)誤識(shí)別和修復(fù)的準(zhǔn)確性。
比如說(shuō),使用Claude進(jìn)行代碼檢索,使用GPT-4進(jìn)行深度分析。此外,當(dāng)LLM旨在校正或調(diào)試自身輸出時(shí),可以采用迭代式改進(jìn)。

局限與挑戰(zhàn)
淺層代碼理解和語(yǔ)義敏感性
當(dāng)今大語(yǔ)言模型在調(diào)試方面的一個(gè)關(guān)鍵局限性是,它們通常缺乏對(duì)代碼實(shí)際工作方式的深入理解。其理解能力嚴(yán)重依賴詞匯和句法特征,而非對(duì)程序邏輯的語(yǔ)義理解。
研究表明,進(jìn)行一些細(xì)小的非語(yǔ)義更改(比如刪除死代碼、更新注釋/變量命名等)時(shí),LLM可能會(huì)失去在相當(dāng)一部分(比如78%)的錯(cuò)誤程序中調(diào)試相同錯(cuò)誤的能力。LLM還可能難以丟棄不相關(guān)的信息,將死代碼視為對(duì)程序的語(yǔ)義有積極貢獻(xiàn)的代碼,這可能導(dǎo)致在錯(cuò)誤定位過(guò)程中出現(xiàn)誤診斷。
復(fù)雜和邏輯錯(cuò)誤方面的性能
雖然LLM大有前景,但整體調(diào)試性能仍然不如人類。分析表明,某些類別的錯(cuò)誤對(duì)于LLM來(lái)說(shuō)仍然極具挑戰(zhàn)性——具體來(lái)說(shuō),與更簡(jiǎn)單的語(yǔ)法和引用錯(cuò)誤相比,邏輯錯(cuò)誤和涉及多個(gè)相互關(guān)聯(lián)問(wèn)題的錯(cuò)誤對(duì)于LLM理解/調(diào)試起來(lái)要困難得多。
上下文窗口約束和可擴(kuò)展性問(wèn)題
現(xiàn)代軟件存儲(chǔ)庫(kù)通常很龐大,涵蓋成千上萬(wàn)個(gè)token。在這樣的環(huán)境中進(jìn)行有效的調(diào)試需要LLM全面處理和理解整個(gè)代碼庫(kù)。盡管最近的技術(shù)進(jìn)步使得傳遞大型上下文成為可能,但LLM仍難以在極端上下文規(guī)模下保持可靠的性能。據(jù)觀察,隨著上下文長(zhǎng)度的增加,性能會(huì)下降,這限制了它們完全理解和調(diào)試大型多文件項(xiàng)目的能力。
幻覺(jué)和輸出不一致的問(wèn)題
LLM的一個(gè)關(guān)鍵漏洞是很容易產(chǎn)生“幻覺(jué)”——聽(tīng)起來(lái)似乎合理但實(shí)際上不正確或完全捏造的內(nèi)容。這通常意味著開(kāi)發(fā)人員需要反復(fù)檢查,有時(shí)甚至需要花另外的時(shí)間去調(diào)試AI建議的代碼或修復(fù)方案。幻覺(jué)可能源于多個(gè)途徑,包括編寫(xiě)不當(dāng)?shù)奶崾?、饋送給模型的上下文信息不清晰,或使用過(guò)時(shí)的模型版本。
測(cè)試覆蓋問(wèn)題
雖然開(kāi)發(fā)人員可以生成可執(zhí)行且多樣化的測(cè)試用例,但他們常常難以掌握測(cè)試中更具戰(zhàn)略性和邏輯性的方面:識(shí)別需要覆蓋哪些特定的語(yǔ)句、分支或執(zhí)行路徑。這種限制對(duì)于調(diào)試至關(guān)重要,因?yàn)橛行У恼{(diào)試通常依賴精心設(shè)計(jì)的測(cè)試用例,這些測(cè)試用例可以隔離并暴露特定的問(wèn)題代碼路徑。
“調(diào)試衰減”現(xiàn)象
研究表明,AI調(diào)試的有效性遵循指數(shù)衰減模式。經(jīng)過(guò)幾次迭代后,LLM發(fā)現(xiàn)錯(cuò)誤的能力會(huì)顯著下降(下降60%-80%),這使得連續(xù)的、無(wú)指導(dǎo)的迭代計(jì)算開(kāi)銷大、效率低。這表明,需要人工干預(yù)來(lái)重置和指導(dǎo)調(diào)試過(guò)程,而不是依賴長(zhǎng)時(shí)間的獨(dú)立AI迭代。
結(jié)論
LLM 將通過(guò)提高效率和開(kāi)發(fā)人員生產(chǎn)力來(lái)徹底改變代碼調(diào)試。它們能夠理解代碼、定位錯(cuò)誤、提出修復(fù)建議并生成測(cè)試用例,這標(biāo)志著相對(duì)傳統(tǒng)方法有了重大進(jìn)步。
未來(lái)在于這樣一種協(xié)作模式:AI協(xié)助人類開(kāi)發(fā)人員,增強(qiáng)他們的技能,而不是取代他們。通過(guò)持續(xù)學(xué)習(xí)、戰(zhàn)略整合以及關(guān)注人機(jī)合作,LLM將成為軟件開(kāi)發(fā)生命周期中不可或缺的工具,有望將調(diào)試轉(zhuǎn)變成更主動(dòng)、更智能的過(guò)程。
原文標(biāo)題:LLMs for Debugging Code,作者:Surya Teja Appini





















