宅中地 - 每日更新
宅中地 - 每日更新

贊助商廣告

X

上交大等機構研究:AI寫代碼前先「問明白」,修復成功率提升4.4個百分點

2026年07月23日 首頁 » 熱門科技

這項由上海交通大學、匹茲堡大學與廣東以色列理工學院聯合開展的研究,於2026年7月以預印本形式發布(arXiv編號:2607.11111),有興趣深入了解的讀者可以通過該編號查閱完整論文。

軟體開發這件事,說白了就是在一大堆相互纏繞的代碼中找到那根出問題的線,然後把它修好,還不能把旁邊好好的線弄斷。對于越來越多被用來自動修復代碼的AI系統來說,這件事遠比表面看起來要難。研究團隊觀察到一個令人頭疼的現象:這些AI就算擁有堪稱頂級的推理能力,依然會在修代碼時頻繁犯錯。問題的根源不是它們不夠聰明,而是它們對要修的那個代碼庫根本不夠了解。

換個更貼近生活的說法——你能想像一個外科醫生在完全不了解病人身體狀況的情況下直接開刀嗎?現有的AI修復系統做的事情,基本上就是這樣:拿到一份"病情描述"(也就是bug報告),然後直接在代碼里翻找、下刀。結果可想而知,不是找錯了地方,就是修了表面、留著病根,甚至越修越亂。

這篇論文提出了一個叫做**ACQUIRE**(全稱Agent Collaboration for Question-Answer-driven Issue REsolution,可以理解為"通過問答驅動的智能體協作來解決代碼問題")的新框架。它的核心邏輯只有一句話:先搞清楚,再動手。在真正開始修代碼之前,系統會主動向代碼庫"提問",把不懂的東西弄清楚,然後再拿著這些知識去修復問題。實驗結果顯示,在一個包含500個真實GitHub問題的標準測試集上,這套方法將AI的修復成功率提升了最多4.4個百分點,同時花費的時間和金錢代價依然保持在合理範圍內。

一、為什麼AI修代碼總是"看不懂地圖就出發"

要理解這項研究解決的是什麼問題,先得明白現有AI修代碼系統的通病是什麼。

當一個開發者在GitHub上提交了一個bug報告,比如說"程序在處理帶括號的參數類型時會崩潰",AI系統拿到的就是這樣一段文字描述,加上整個代碼庫。代碼庫可能有數萬個文件、數十個模組,裡面充斥著各種相互調用、相互依賴的函數和類。AI需要從這片叢林裡找到出問題的那棵樹,再精準地修剪它。

問題在於,光憑bug描述里的幾個關鍵詞,AI往往只會做"關鍵詞匹配"——哪個文件名、函數名和描述里的詞最像,就去改哪裡。這就好比你告訴一個剛來的維修工"家裡水管漏水了",他不去檢查管道走向、不了解房子的結構,直接根據你說的"漏水"兩個字去找所有和水有關的東西,結果把好好的熱水器給拆了,真正漏水的地方卻沒碰到。

研究團隊從多項實證研究中總結出,AI修代碼失敗的最主要原因包括這樣幾類:停留在表面的關鍵詞定位,找不到真正出錯的源頭;跨模組追蹤失敗,搞不清楚一個錯誤是怎麼從A傳導到B再傳導到C的;違反隱含的接口約定,不知道某個函數有特定的調用規則;以及缺乏對外部庫或協議規範的了解。更糟糕的是,那些失敗的修復嘗試消耗的計算資源是成功修復的四倍以上、執行步驟是成功修復的將近兩倍。這意味著,越是搞不清楚狀況的AI,越會在錯誤的路上越走越遠、成本越燒越高。

已有一些研究嘗試在修復之前先做一些"探索"。比如有的系統會先構建代碼庫的結構圖,標記出哪些地方可能有問題;有的會生成一份摘要,告訴AI大概在哪裡找。但這些方法本質上依然是"修復導向"的探索——它們輸出的是"可能出問題的地點列表",而不是"你真正需要理解的知識"。把一張地圖交給一個不知道目的地在哪裡的人,並不能幫他找到路。

二、靈感來自經驗豐富的程序員的工作方式

研究團隊的靈感來自一個樸素的觀察:有經驗的開發者在面對一個陌生代碼庫里的bug時,並不會立刻開始翻代碼找位置。他們會先問問題。"這個函數究竟是怎麼工作的?""這個API的調用有什麼約束?""這個模組和那個模組之間是怎麼傳數據的?"把這些問題搞清楚之後,他們才會動手修復。這種先理解、後行動的模式,在軟體工程的調試研究中早有記錄——有經驗的程序員投入更多時間在程序理解上,結果反而修得更快、更准。

受此啟發,研究團隊設計了一個驗證實驗,想看看"提前把關鍵問題問清楚"到底能帶來多大幫助。他們構造了一個"理想條件"場景:給AI一個bug報告,同時偷偷告訴它正確答案在哪些文件里,並且為它生成一個和這個bug最相關的問題以及基於正確文件的準確答案。然後把這對問答注入到AI修復系統里,看看成功率會怎麼變。

結果相當鼓舞人心。在原本失敗的116個案例中,有26個因為獲得了這組"提前知道答案的問答"而成功修復。這意味著,大約22%的失敗案例,其實不是因為AI推理能力不夠,而是因為它缺少了某些關鍵知識。更值得注意的是,這個實驗條件還相當保守——只提供了一個問題,而且答案只基於正確文件,而不是整個代碼庫。真實系統能挖掘的資訊遠不止於此。

這個實驗確立了一個核心信念:如果能在修復之前為AI提供精準的、有根據的代碼庫知識,就能顯著提升修復成功率。接下來的問題是,在沒有"提前知道正確答案"這種作弊條件的情況下,怎麼自動生成這樣的知識?

三、ACQUIRE的工作方式:三個角色、兩個階段

ACQUIRE的設計圍繞三個專門的AI角色展開,它們分別承擔不同的職責,通過兩個階段的協作完成整個修復任務。

第一個角色叫做"提問者"(Questioner)。它的工作是拿到bug報告之後,不急著找代碼,而是先生成幾個有針對性的問題。這些問題不是隨意發問,而是按照一套經過仔細設計的分類框架來提的。研究團隊在分析了大量真實失敗案例之後,歸納出四類最常見的知識缺口,也就是AI最容易因為不了解而修錯的知識類型。

第一類是"機制與行為",占了所有問題的約70%。這類問題關注的是"某個功能到底是怎麼運作的"——比如數據在函數之間是怎麼流轉的,某個狀態是在哪裡被更新的,某種異常是在哪個環節被觸發的。第二類是"設計與用法",占約18%,關注的是"某個接口或API有什麼使用約定"——哪些參數是必須的,調用順序有沒有要求,出錯時會拋出什麼類型的異常。第三類是"定位與結構",占約8%,關注的是"某個功能在代碼庫的什麼地方實現"——這類問題直接幫助AI縮小搜索範圍。第四類是"生態與標準",占約3%,關注的是代碼庫依賴的外部知識——比如某個第三方庫的行為規範,或者某種協議的技術標準。

提問者會根據當前bug的具體內容,從這四類框架中挑選最合適的角度生成問題,而不是機械地每類出一題。某些bug可能需要兩個都是"機制與行為"類的問題,某些則需要跨類別組合。默認設置下,每個bug生成兩個問題。

第二個角色叫做"回答者"(Answerer)。每生成一個問題,就會啟動一個獨立的回答者實例來處理它。回答者的工作方式和一個有經驗的開發者查閱代碼庫非常相似:它可以瀏覽目錄結構、打開文件、搜索關鍵詞、查看函數定義——但它只能讀,不能改,整個代碼庫在這個階段保持原樣。

回答者有三條嚴格的行為準則。首先,答案必須有依據,必須引用具體的文件路徑、函數名、代碼行為,而不能憑空猜測。其次,一旦收集到足夠的證據就要主動提交答案,不要無限漫遊。第三,如果實在找不到充分的證據,必須明確說"找不到",而不是編造一個聽起來合理的答案。多個回答者實例並行工作,互相不共享探索過程,這樣既保證了每個答案的獨立性和專注度,也大幅壓縮了等待時間——整個提問回答階段的耗時取決於最慢的那個實例,而不是所有實例的時間之和。

第三個角色叫做"修復者"(Resolver)。它拿到的不只是原始的bug報告,還有前兩個角色生成的完整問答知識集合。這些問答內容在修復開始之前就已經被整合進修復者的上下文,讓它在第一步操作之前就已經掌握了關鍵的代碼庫背景知識。

有一點設計細節值得特別說明:這些問答知識是作為"參考資訊"提供給修復者的,而不是強制指令。修復者可以根據自己在探索過程中觀察到的實際代碼,來驗證、調整甚至推翻問答中的某些說法。這種"建議而非命令"的注入方式,保證了系統的魯棒性——即使某個答案有小的偏差,修復者依然有機會通過直接查看代碼來糾正。

四、實驗怎麼做的,結果怎麼樣

研究團隊選用了SWE-bench Verified作為測試平台。這是一個由500個真實GitHub問題組成的測試集,每個問題對應一個真實的代碼庫,修復結果的好壞用開發者事先寫好的單元測試來判定——通過了測試才算真正修好了。這種評測方式非常嚴格,無法靠"看起來像修好了"來矇混過關。

為了驗證ACQUIRE的效果不依賴於特定的AI模型,研究團隊選用了兩個來自不同技術路線的大語言模型。一個是DeepSeek-V3.2,這是一個開源的"混合專家"架構模型,參數量達到6710億,每次推理時激活約370億參數,在代碼理解和生成任務上表現出色。另一個是GPT-5-mini,來自OpenAI,是一個面向高效部署優化的閉源模型,速度快、成本低。

對比的基準方法涵蓋了當前主流的"修復前探索"策略。Mini-SWE-Agent是一個最基礎的修復系統,不做任何預處理,直接疊代地執行shell命令來找bug和改代碼。LocAgent通過構建代碼庫的異構圖(包含導入關係、調用關係、繼承關係),用AI引導的多跳遍歷來生成"可疑位置列表"。CoSIL通過逐步擴展本地調用圖來精煉搜索範圍,輸出緊湊的高相關性代碼片段。LingmaAgent構建代碼庫級別的知識圖,結合蒙特卡洛樹搜索來引導探索,生成修復導向的倉庫摘要。SWE-Debate則引入多智能體辯論機制,讓多個AI獨立提出修復假設,互相質疑,最終達成共識。

結果顯示,ACQUIRE在兩個模型上都取得了所有方法中最高的修復成功率:在GPT-5-mini上提升了3.8個百分點(從58.4%到62.2%),在DeepSeek-V3.2上提升了4.4個百分點(從66.4%到70.8%)。更關鍵的是,ACQUIRE的成本和時間開銷都相當合理——每個實例的平均花費在兩個模型上分別是0.054美元和0.073美元,平均耗時分別是302秒和1042秒。相比之下,LingmaAgent的成本是ACQUIRE的2到4倍,SWE-Debate的成本是ACQUIRE的7到14倍,而它們的修復成功率提升遠不及ACQUIRE。

那些定位導向的方法(LocAgent和CoSIL)在GPT-5-mini上不僅沒有提升,反而出現了下降,這揭示了一個深層問題:把一張"可疑位置清單"交給推理能力有限的模型,不但幫不上忙,還可能誤導它走向錯誤的路徑。ACQUIRE的問答知識則不同,它傳遞的是"為什麼這個地方值得關注、它的行為邏輯是什麼",而不只是"去那裡看看"。

五、生成的知識到底有多可靠

一套系統的知識獲取機制再精妙,如果產生的知識本身錯漏百出,那注入再多也只會幫倒忙。為此研究團隊對生成的問答質量做了嚴格的人工審核。

四位電腦科學專業的碩士研究生(各有四年開發經驗)對232對問答進行了獨立雙盲評審,分歧通過討論解決。這232對問答來自四個不同的結果分組:原本失敗、有了ACQUIRE變成功的44個案例;原本成功、有了ACQUIRE反而失敗的22個案例;以及從另外兩個分組(一直失敗、一直成功)中各隨機抽取的25個案例。

評審結果顯示,232對問答中有230對(99.1%)被標記為"有依據"——其中98對(42.2%)完全準確,所有說法都能在代碼庫中找到明確支撐;另外132對(56.9%)存在輕微偏差,比如行號不精確、函數歸屬稍有錯誤,但核心結論不受影響。只有2對(0.9%)包含了真正無依據的核心聲明,被判定為"有誤導性的無根據斷言"。

這種高可靠性並非偶然。ACQUIRE的問答設計有一個內在的優勢:把一個複雜的bug報告拆解成幾個範圍明確的小問題,每個回答者只需要聚焦在一個具體問題上,搜索和推理的範圍大幅縮小,犯錯的機會自然也少得多。這就像一個人被問"請介紹一下中國近代史"會說很多錯的,但被問"1919年五四運動發生在哪個城市"幾乎不會答錯。

研究團隊還仔細分析了那22個"原本成功、引入ACQUIRE後反而失敗"的案例。其中只有5個是真正由於問答內容的誤導造成的——比如問答強調了一個相關但並非關鍵的位置,修復者就一直在那裡打轉,偏離了正確修復路徑。有趣的是,這5個案例里的10對問答中,只有1對被判定為無根據的錯誤聲明,其餘9對在內容上是正確的,只是提供了"正確但不是關鍵"的資訊,誤導了修復者的注意力方向。

剩餘17個失敗案例則與問答質量關係不大,主要是修復者自身的行為問題:把一個正確的線索過度泛化、只實現了修復的一部分、引入了額外的不必要改動等等。這說明,改進修復者對問答知識的"批判性使用能力",是未來進一步提升系統表現的重要方向。

六、是什麼讓系統真正有效:兩個設計選擇的驗證

為了確認ACQUIRE的性能提升究竟來自哪裡,研究團隊構造了兩個"削減版"變體進行對比實驗。

第一個變體叫做ACQUIRE-Proposal,把提問者和回答者的整個問答流程替換成一個單步"提案生成":系統讀取bug報告,直接生成一份包含根因分析和修復建議的提案,然後把這份提案注入修復者。這個變體的成績跌到了66.0%,比完整的ACQUIRE(70.8%)低了4.8個百分點,甚至比什麼都不做的基礎系統(66.4%)還要低。

這個結果揭示了一個重要道理:讓AI一次性完成"讀懂bug、分析原因、給出建議"這三件事,會產生一種"什麼都沾點兒、什麼都不深入"的分析,既不夠聚焦,又容易自相糾纏。相反,把這個複雜任務拆解成若干個範圍明確的小問題,每次只讓AI回答一個具體問題,不僅答案更準確,對修復者的幫助也更直接。這就像讓一個助手幫你準備一場演講,"幫我把這場演講準備好"這個指令下去,出來的東西往往不對路;但"幫我找三個關於氣候變化的具體數據"這樣的分解指令,往往更容易得到有用的結果。

第二個變體叫做ACQUIRE-FreeQ,保留了完整的問答流程,但去掉了提問者用來指導生成的四類框架。提問者可以自由地提任何它覺得相關的問題,沒有任何分類約束。這個變體的成績是67.0%,比完整版低了3.8個百分點。

為了弄清楚為什麼加了分類框架的問題更好,研究團隊用AI評審系統對兩組問題進行了多維度評分。結果顯示,有分類框架指導的問題在"診斷實用性"(即答案對於縮小debug範圍的幫助程度)上高出0.38分,在"推理深度"(即需要多少跨文件、跨模組的分析)上高出0.38分,在"覆蓋度"(即一組問題覆蓋了多少不同的診斷角度)上高出0.78分。自由生成的問題最大的問題是"同質化"——兩個問題往往從相似的角度切入,浪費了寶貴的提問機會。分類框架的作用就像一個提醒,確保提問者從多個不同維度去審視同一個問題,而不是把兩個問題都用在同一件事上。

在500個實例的兩兩對比投票中,有分類框架的ACQUIRE在294次中被評為更優,ACQUIRE-FreeQ只有111次,另有95次平局。不失率達到77.8%。

七、問多少個問題最合適

ACQUIRE默認生成兩個問答對,但研究團隊也系統地測試了不同數量的效果。

生成零個問答的時候,系統退化為純粹的基礎修復系統,成功率是66.4%,每個實例花費0.055美元。加入一個問答對之後,成功率立刻跳升到69.0%,而額外花費僅有0.005美元。這意味著,哪怕只給AI補充一條有根據的知識,也能帶來實質性的改善。

兩個問答對的時候,成功率達到了峰值70.8%,每個實例花費0.073美元。這是整個測試範圍內效果最好的配置,也是研究團隊採用的默認設置。到了三個問答對,成功率回落到69.0%,而花費繼續上升到0.082美元。這種"先升後降"的曲線背後有兩個原因:兩個來自不同類別的問題能夠有效覆蓋互補的知識缺口;而第三個問題往往和前兩個有知識重疊,注入更多內容反而會稀釋修復者的注意力,讓它在已知資訊和新資訊之間來回權衡,造成認知上的負擔。

這個發現和語言模型處理長文本的一般規律吻合——上下文過長時,模型對關鍵資訊的響應能力會下降,甚至"迷失在資訊的中間"。兩個精準的問答對,恰好在資訊豐富度和認知負荷之間取得了最佳平衡。

八、一個具體案例:58步找到一個關鍵字母也沒提到的文件

研究團隊挑選了一個具體的真實案例來展示ACQUIRE和普通修復系統的差距。這個問題來自Python文檔生成工具Sphinx:當開發者用 `:param dict(str, str) opc_meta:` 這樣的格式描述一個參數時,Sphinx會把類型"dict(str, str)"解析成"dict(str",把參數名解析成"str) opc_meta"——也就是說,碰到括號里的逗號和空格就斷掉了。

普通修復系統拿到這個報告,看到的關鍵詞是"渲染錯誤",就去找和渲染、輸出相關的代碼。它先去改了typehints.py,發現不對;再去改writers/html.py,還是不對;然後又跑到autodoc/__init__.py里試圖打一個補丁,依然失敗;最後做了回滾。整個過程走了117步,從未碰到真正出問題的文件。這就像一個人因為"燈泡不亮了"去換整個電路板,卻完全沒有檢查過燈泡本身。

ACQUIRE的提問者生成了一個問題,大意是:"這個代碼庫里的文檔字符串解析器目前是怎麼從`:param`指令中提取類型資訊的,尤其是當類型裡面有嵌套括號時?"

這個問題的角度完全不同——它不是從"渲染"入手,而是從"解析機制"入手。回答者按照這個方向探索,先查看了autodoc/和napoleon/這兩個看起來最相關的模組,沒找到實際的解析邏輯;然後擴大搜索範圍,進入了sphinx/util/目錄,在那裡發現了docfields.py文件,裡面的TypedField類里有一行代碼:`parts = fieldarg.split(None, 1)`——這行代碼用的是按空格分割,碰到"dict(str, str) opc_meta"時,第一個空格在括號裡面,所以分割出了"dict(str,"和"str) opc_meta",把類型名切錯了。回答者的答案精確地給出了文件路徑、類名、行號和根本原因。

修復者拿到這個答案,直接打開docfields.py,確認了那行有問題的split調用,然後實現了一個能識別括號嵌套的分割函數來替代它。整個修復過程只用了52步,比基礎系統的117步減少了55%。

這個案例體現了ACQUIRE最本質的優勢:通過把問題轉化成對"底層機制"的追問,而不是對"表面症狀"的搜索,系統能夠抵達那些與bug報告在字面上沒有任何關聯的正確位置。

說到底,這項研究做的事情其實很樸實——它只是把人類程序員面對陌生代碼庫時的本能反應,系統化地賦予了AI:先問,再修。這不是什麼革命性的顛覆,而是一種對現有AI修複流程的有效補充。通過把一個完整的bug理解任務拆解成若干個小問題,並讓AI在真實代碼庫里尋找有根據的答案,整個修復過程變得更有方向感、更少走彎路。

從實際效果來看,4.4個百分點的提升在這個領域並不是一個可以隨意忽略的數字。當前最先進系統的成功率已經在七成左右,每提高一個百分點都需要付出相當的努力。ACQUIRE以相對輕量的代價實現了這樣的提升,且在兩種不同架構的模型上都保持了一致性,說明它補充的是一種普遍存在的能力缺口,而非針對某個模型的特殊優化。

當然,這套方法也有它的局限。目前的提示設計和測試主要針對Python代碼庫,是否同樣適用於其他編程語言還有待驗證。四個問題類別的框架也是基於對過往失敗案例的人工分析歸納出來的,未來或許可以通過更大規模的數據自動學習出更精細的分類體系。此外,現在的問答知識是在修復開始前一次性生成的,不會隨著修復進程的推進而動態更新——如果AI在修復過程中產生了新的疑惑,它沒有辦法再回頭追問。如何在修復過程中實時獲取知識、同時控制好額外的成本,是這個方向上一個值得探索的開放問題。

對於普通用戶來說,這項研究的意義在於:未來你在GitHub上提交的bug,或者你請AI幫你修的代碼錯誤,有更大的概率能被一次修對、修全、修得不留後遺症。而背後的原因,只是一個簡單的習慣的改變——先弄清楚,再動手。

有興趣深入研究這套框架的讀者,可以通過arXiv編號2607.11111查閱完整論文,相關代碼和數據也已公開發布。

Q&A

Q1:ACQUIRE框架在修復代碼前具體會問什麼類型的問題?

A:ACQUIRE的提問者會從四類框架中生成問題:第一類是"機制與行為",約占70%,問的是某個功能內部如何運作;第二類是"設計與用法",約占18%,問的是API接口有哪些調用約束;第三類是"定位與結構",約占8%,問的是某個功能在代碼庫哪裡實現;第四類是"生態與標準",約占3%,問的是依賴的外部庫或協議規範。系統默認每個bug生成兩個問題,從不同角度覆蓋知識缺口。

Q2:ACQUIRE生成的問答知識準確率有多高?

A:研究團隊對232對問答進行了人工雙盲評審,結果顯示99.1%的問答被標記為"有依據",其中42.2%完全準確,56.9%存在輕微偏差(如行號不精確)但核心結論正確,只有0.9%即2對包含了真正無依據的核心斷言。高準確率來自於問題拆解設計——每次只問一個小問題,讓回答者的任務範圍大幅縮小,減少了出錯機會。

Q3:SWE-bench Verified測試集是怎麼評判代碼修復是否成功的?

A:SWE-bench Verified包含500個來自真實GitHub倉庫的代碼問題,每個問題配有開發者預先編寫的單元測試。AI生成修復補丁後,系統會自動運行這些單元測試,只有測試全部通過才算修復成功,計入Pass@1指標。這種評測方式無法靠"看起來修對了"矇混過關,必須真正解決了bug才能得分。

宅中地 - Facebook 分享 宅中地 - Twitter 分享 宅中地 - Whatsapp 分享 宅中地 - Line 分享
相關內容
Copyright ©2026 | 服務條款 | DMCA | 聯絡我們
宅中地 - 每日更新