這項由華為加拿大研究院、加拿大女王大學、曼尼托巴大學與康科迪亞大學聯合開展的研究,以預印本形式發布於2026年7月29日,論文編號為arXiv:2607.27167,有興趣深入了解的讀者可通過該編號查閱完整原文。
**一個真實存在的尷尬**
軟體工程師都清楚,在接手一個全新項目時,最頭疼的不是寫代碼本身,而是搞清楚"這個程序到底要幹什麼"。遇到文檔寫得含糊不清,或者某些功能根本沒有文檔,工程師就必須反覆測試、反覆確認,才能動筆。
現在,AI編程助手已經能幫我們修復代碼錯誤、補全函數、甚至處理複雜的代碼倉庫問題。但如果面對的任務是——給你一個陌生程序的簡短說明文檔,外加一個只能運行、不能看源碼的可執行文件,讓你從零開始把這個程序重新寫出來——那麼即便是目前最強大的AI模型,成功率也低得讓人咋舌:200個任務里,完整通過測試的不足1%。
這就是本篇論文所要直面的問題。研究團隊提出了一個名為SPECFIRST的框架,核心思路來自一個古老的軟體工程智慧:在動手寫任何代碼之前,先把"需求說明書"徹底搞清楚。
**一、現有AI編程助手為何在"白紙作畫"時頻頻翻車**
要理解這個問題,先設想一個場景。你被要求仿製一款陌生的廚房電器,手頭只有一張薄薄的產品介紹冊,以及一台可以通電運行、但不能打開外殼的實機。你需要把它的全部功能都復現出來——包括各種按鍵組合、各種異常情況下的報錯提示、各種邊界情形下的精確輸出。
現有的AI編程框架(比如SWE-agent、OpenHands)在這類任務里的做法,就是把"搞明白這台機器怎麼工作"和"把它造出來"這兩件事混在一起做。AI在同一個工作循環里,一邊按按鈕測試機器行為,一邊寫仿製品的設計圖,一邊動手組裝。這聽起來似乎挺高效,實際上卻造成了三個根深蒂固的問題。
第一個問題是探索不夠深入。既然要同時寫代碼,AI就不可能把測試這台機器的事做得很徹底。那些在說明書里沒提到的邊角功能——比如同時按下兩個特定按鍵會發生什麼,或者輸入超長內容時會報什麼錯——AI往往還沒來得及驗證,就已經開始動手組裝了。結果就是,仿製品的很多功能根本沒被原版驗證過。
第二個問題是記憶衰退。AI在工作過程中積累的行為知識,是以對話記錄的形式保存在"腦子"里的。但隨著對話越來越長,早期發現的重要資訊會被慢慢"擠出"有效記憶。更糟糕的是,很多框架為了節省計算資源,會壓縮歷史對話,而這個壓縮過程往往會把那些關鍵的行為發現給丟掉。研究團隊發現,在一個具體案例里,AI在第4輪就發現了程序包含十幾個功能命名空間,但在後續25輪的工作里,其中6個命名空間的名字再沒出現過,最終提交的代碼里這6個命名空間全部缺失,導致126個測試用例在代碼運行前就註定失敗。
第三個問題是早期錯誤會像滾雪球一樣越滾越大。在沒有一份穩定參考文檔的情況下,如果AI在第5輪對某個功能的理解出了偏差,它會在這個錯誤理解的基礎上繼續建造,第10輪、第50輪、第100輪的代碼都建立在這個錯誤地基上。研究團隊記錄了一個案例:AI正確讀取了某函數的參數類型定義,但在第57輪真正實現這個函數時,用了一個完全丟失了類型資訊的錯誤寫法。此後140輪里,這個函數被反覆重構了5次,但每次都復刻了那個錯誤寫法,因為AI已經沒有參照物來校正自己了。最終25個相關測試因類型錯誤而失敗。
**二、一個來自傳統軟體工程的古老答案**
傳統軟體工程早就給出了解決方案——需求分析階段必須獨立存在,而且必須先於編碼階段。在正規的軟體開發流程里,工程師會在寫第一行代碼之前,花大量時間與原型系統交互、構建場景、梳理所有功能細節,把這些發現整理成一份完整的需求說明書,然後才開始實現。
SPECFIRST就是把這個思路移植到AI編程智能體上。整個框架分成兩個階段,這兩個階段嚴格分開,互不干涉。
第一個階段叫做"規格說明提取"。一個專門的"規格智能體"(Spec Agent)接過任務,它的唯一職責就是徹底弄清楚目標程序的行為。它不寫任何代碼,只是反覆地、系統地運行那個可執行文件,觀察各種輸入下的輸出結果,把所有發現整理成一份結構化的說明文檔,也就是SPEC.md文件。
第二個階段才是"代碼合成"。一個普通的編程智能體接過任務,它手裡有三樣東西:原始說明文檔、可執行文件,以及第一階段產出的SPEC.md。這份規格文件就像一座燈塔,無論編程過程多漫長、對話記錄多繁雜,它始終在那裡,隨時可以查閱。
這個分離的設計直接瓦解了前面提到的三個問題:規格智能體可以心無旁騖地深挖行為細節;規格文件以外部文檔形式儲存,不受對話壓縮影響;編程智能體始終有一個穩固的參照物,早期的正確理解永遠不會被遺忘。
**三、規格智能體是怎麼"審訊"那個可執行文件的**
規格智能體的工作方式,就像一位偵探面對一個只能通過行為來了解的嫌疑人。它無法打開嫌疑人的大腦,只能不斷地提問、觀察反應,從蛛絲馬跡中還原全貌。
它採用的是自由形式的命令行交互,這樣它可以一次性構造複雜的測試場景——比如先創建一個特定格式的輸入文件,再運行程序處理它,然後檢查輸出結果,所有這些步驟可以鏈式執行。對於那些需要鍵盤交互的程序,環境裡預裝了終端模擬工具,讓它能夠模擬真實的按鍵操作並捕獲螢幕內容。
在探索策略上,研究團隊識別出了四類文檔最容易"說不清楚"的行為,規格智能體會專門針對這些區域展開系統性測試。首先是邊界條件——當輸入為空時會發生什麼?當輸入極長時呢?當輸入包含特殊字符時程序如何反應?這些資訊文檔通常隻字不提。其次是錯誤路徑——當參數不對、必填項缺失、參數相互衝突時,程序會在哪個輸出通道報錯?錯誤碼是多少?這些細節對於正確復現行為至關重要。再次是多參數組合效果——文檔可能分別描述了參數A和參數B各自的行為,但同時使用A和B時會發生什麼,往往沒有說明。最後是輸出格式的精確細節——欄位之間用什麼分隔符?末尾有沒有多餘空格?數字的格式化方式是什麼?這些細節在文字描述里總是模糊不清。
為了確保探索的是真實的程序行為而不是走捷徑,系統設置了明確的限制:智能體不允許通過網路搜索或代碼託管平台找到原程序的源代碼,也不允許使用反匯編工具分析程序內部結構。所有發現必須來自正常使用程序的過程。系統會自動檢測命令歷史記錄,一旦發現違規操作,當前運行立即記零分。
規格智能體的終止條件分三層:它自己判斷探索完成時會主動結束;如果遲遲不結束,1000輪操作的步驟上限會強制終止;此外還有6小時的時鐘時限作為最後保障。在實際運行中,絕大多數任務都在步驟上限遠未到來之前就自行結束了。
產出的SPEC.md文件採用六節式結構:概述、命令行參數、輸入與標準輸入、輸出格式、錯誤模式、邊界情況。這六個章節覆蓋了重新實現一個程序所需要知道的全部行為維度,結構足夠清晰讓編程智能體能直接利用,又足夠靈活不會遺漏特殊細節。
**四、用一個真實案例感受SPECFIRST的價值**
論文裡用gomplate這個程序作為貫穿始終的示例,非常值得詳細了解。gomplate是一個命令行模板渲染工具,它的說明文檔(README)只有寥寥數百字,描述了基本用法和幾個示例,末尾寫著"完整文檔請訪問官方網站"。然而這個程序實際上擴展了Go語言的模板引擎,提供了橫跨十幾個功能命名空間的大量內置函數,涵蓋數據處理、數學運算、網路操作、加密、字符串處理等方方面面。
在沒有規格提取階段的情況下,AI編程智能體面對這樣的程序時,通常只會實現文檔里明確提到的那些功能,把大量隱含功能直接忽略。而規格智能體在專門的探索階段里,會發現並記錄全部命名空間的函數列表、調用簽名、邊界行為和錯誤模式。論文展示了SPEC.md里的部分內容:完整的函數集合、各命名空間的函數別名、命令行參數的精確語義、以及若干邊界情況說明,比如"--in參數與--file參數互斥,同時使用會報錯"這類細節。有了這份文件,編程智能體在寫代碼時就知道需要實現哪些功能、每個功能的精確行為是什麼,而不是憑猜測和印象行事。
**五、實驗結果:數字背後的故事**
研究團隊在ProgramBench這個基準測試的全部200個任務上評估了SPECFIRST,這200個任務涵蓋了各種真實世界的命令行程序,包括著名的FFmpeg影片處理工具、SQLite資料庫、PHP解釋器等。這200個程序的底層實現語言主要是Rust(107個)、Go(46個)和C/C++(45個),整個測試集合包含約25萬個測試函數,平均每個任務有770個測試用例,而且這些測試對AI完全保密,AI在工作過程中無法看到測試內容。
評估使用了四個不同的AI模型:兩個來自阿里雲的開源Qwen3系列(397B參數的大模型和35B參數的中型模型),以及兩個OpenAI的模型(能力較強的GPT-5.5-high和較輕量的GPT-5.4-mini)。這四個模型橫跨兩個不同的技術路線,能力差距大約在一個數量級,用來驗證結論的普遍性。
結果非常清晰。在所有四個模型上,SPECFIRST都穩定地超越了不帶規格提取階段的直接合成方式。提升幅度從最小的6.9%(GPT-5.4-mini)到最大的21.3%(Qwen3.5-397B),最高絕對分數達到65.14%(GPT-5.5-high)。所有提升在統計檢驗下都具有顯著性,說明這不是隨機波動帶來的偶然差異。
從贏/輸/平的角度來看,在200個任務里,SPECFIRST在至少59%的任務上優於對照組,能力最強的GPT-5.5-high在75%的任務上都贏了。
不止平均分數的提升,SPECFIRST還把頂端表現拉得更高。以GPT-5.5-high為例,如果把"通過率超過90%"定義為接近完美的實現,SPECFIRST達到這個門檻的任務比例從5.5%跳升到16.5%;如果門檻提高到95%,比例從1.5%跳升到6.5%,增長了四倍多。換句話說,SPECFIRST不僅讓所有程序都做得稍微好一點,更重要的是讓一部分程序從"差強人意"直接邁入了"幾乎完美"。
在不同難度級別上,SPECFIRST的優勢同樣全面覆蓋:簡單任務、中等任務、困難任務都有提升。特別值得注意的是,對困難任務的提升往往更顯著——GPT-5.5-high在困難任務上的提升幅度達到29.9%,而簡單任務只有7.1%。這說明當任務本身的行為複雜性越高、文檔說明越不充分時,提前建立完整規格說明的價值越大。
**六、規格智能體到底多徹底地"研究"了那個程序**
研究團隊引入了一個叫做"探測覆蓋率"的指標來量化這件事。為了測量這個指標,他們給測試集裡的每個程序都裝上了代碼覆蓋率監控工具(針對不同語言分別使用對應工具),記錄每次運行時實際執行了程序里哪些代碼行。把所有探測過程中觸達過的代碼行加起來,除以程序總代碼行數,就得到了探測覆蓋率——這個數字越高,說明AI對程序行為的理解越全面。
對照組(直接合成,無規格提取)的探測覆蓋率在49%到55%之間,視模型而定。SPECFIRST將這個數字提升到了58%到60%,提升幅度在9.4%到18.5%之間,且全部具有統計顯著性。
更有意思的分析在於:SPECFIRST里有兩個智能體,規格智能體和編程智能體都會運行程序。研究團隊把兩者各自的覆蓋率單獨統計了出來。結論是,規格智能體單獨達到的覆蓋率(約55%~58%)始終高於編程智能體單獨達到的覆蓋率(31%~51%),把兩者的覆蓋合併起來,比規格智能體單獨的覆蓋只多出一點點。這說明覆蓋率的提升幾乎完全來自專門的探測階段,而不是編碼過程中順帶測試帶來的副產品。
**七、規格說明改變了編程智能體的工作方式**
研究團隊還做了一項行為分析:在整個編程過程中,每隔一個工作步驟就記錄一次代碼倉庫的規模(代碼行數),然後把時間軸歸一化,觀察代碼是如何隨時間增長的。
對照組的曲線有一個典型特徵:在工作過程的前半段,代碼幾乎沒有增長,AI一直在忙著測試和理解程序行為;到了後半段才開始快速寫代碼,但此時留給調試和完善的餘地已經不多了,經常出現"一次性傾倒"大量代碼的現象,隨後就戛然而止。
SPECFIRST的曲線則完全不同:代碼從工作開始不久就穩定增長,增長曲線更早、更平緩、持續更長,最終停止時代碼倉庫也更大——比對照組普遍大7%到29%。
研究團隊還在具體案例層面做了對比。以一個叫做"age"的程序為例,對照組的AI花了大量步驟在測試和理解行為上,最後試圖一次性寫出完整的841行代碼,不出意外地因為調試時間不夠而失敗。SPECFIRST里的編程智能體由於已經有了SPEC.md,只花了2到9步建立工作上下文,就立刻轉入了持續的代碼建設階段。
還有一個反直覺的發現值得專門說明:對照組的AI之所以表現不好,並不是因為工作步驟不夠用。研究團隊統計了對照組各任務實際用了多少步驟——結果是沒有一個任務用到了1000步的上限,所有任務都是AI自己主動停止的,中位數隻用了22到177步,只占可用預算的2%到18%。也就是說,問題不在於"給的時間不夠",而在於AI在步驟遠未用完時就已經產生了"我理解得差不多了,可以提交了"的錯誤感知,然後自行結束。單純給AI更多計算預算並不會解決這個問題,因為它們自己會停。SPECFIRST解決的是"在開始寫代碼時就掌握足夠完整的行為知識"這個本質問題。
**八、失敗案例揭示了下一步的方向**
研究團隊隨機抽取了50個失敗案例,對照著測試失敗資訊、SPEC.md內容和對應代碼片段,逐一分析失敗原因,識別出了五種失敗模式。
最常見的失敗(占52%)是"規格正確但實現出錯":SPEC.md對這個功能的描述是準確完整的,但編程智能體沒有正確實現。這類失敗的具體表現包括:某個子命令在幫助文檔里存在但程序分發邏輯里沒有處理、某個參數被解析了但效果沒有被應用、錯誤輸出的格式與SPEC.md的描述自相矛盾。這是最主要的失敗類型,意味著提升編程智能體的代碼實現能力是當前最重要的改進方向。
第二常見的是"規格描述不夠精確"(占26%):SPEC.md記錄了相關功能,但描述不夠細緻,讓編程智能體不得不猜測。比如,SPEC.md說"非法輸入會報錯",但沒有指明錯誤碼是1還是2,也沒有說錯誤資訊是輸出到標準錯誤還是標準輸出,於是編程智能體猜錯了,而測試的期望是明確的。
"規格遺漏"(占10%)表示規格智能體根本沒有發現這個功能的存在,通常是一些隱藏較深的CLI參數、子命令或錯誤路徑。"規格描述錯誤"(占4%)是SPEC.md記錄的行為與程序實際行為相反,如把應該輸出到標準錯誤的內容記成了標準輸出。最後8%是環境依賴錯誤,比如測試期望的錯誤資訊里包含了特定的DNS伺服器地址,這類問題屬於測試基礎設施的噪聲,與AI能力無關。
**九、規格文件的格式也有講究**
論文還專門測試了SPEC.md的不同格式是否會影響最終效果,在50個任務上用GPT-5.4-mini進行了對比。
測試了三種格式。第一種是完全自由格式,智能體自己決定如何組織內容,沒有任何模板約束。第二種是OpenSpec格式,這是一個來自軟體工程領域的正式規格書寫標準,要求用"必須/應當/可以"這樣的措辭標註每條需求,並為每條需求提供"給定/當/那麼"格式的場景示例,非常正式和結構化。第三種是研究團隊使用的六節式格式,介於兩者之間:有固定的章節標題提供基本結構,但章節內的書寫方式完全自由。
結果是三種格式都比沒有規格文件的直接合成更好,無規格的基準得分55.9%,自由格式60.7%,OpenSpec格式61.7%,六節式格式62.6%。六節式格式效果最好,研究團隊的解釋是:純自由格式可能導致智能體遺漏某些重要維度;而OpenSpec格式雖然更精確,但它過於正式的結構可能反而壓制了一些難以套入模板的行為細節。六節式格式的"有框架但不死板"恰好處在最有效的區間。
**十、代價:SPECFIRST要多花多少錢**
引入額外的規格提取階段意味著額外的計算成本。研究團隊統計了每個任務的平均花費,SPECFIRST的總成本比直接合成高出48%到130%。
具體來說,規格智能體本身的花費在每個任務0.25美元(GPT-5.4-mini)到3.16美元(GPT-5.5-high)之間。規格智能體增加的成本拉高了總花費,但對於GPT-5.4-mini,編程智能體的花費反而下降了17%——說明有了清晰規格後,編程過程里那些反覆試探的開銷被節省了下來。GPT-5.5-high的總成本增加了130%,主要來自其規格智能體本身的高單價。
研究團隊的觀點是,這部分額外成本是"做了更多有價值的工作"帶來的,而不是做了重複低效的工作。更寬的行為覆蓋和更大的代碼實現都是實質性產出,不是浪費。
---
說到底,SPECFIRST的核心發現可以用一句話來概括:在動手寫代碼之前,先把"這個程序到底要幹什麼"徹底搞清楚,是一件比想像中更有價值的事情。
這個道理對人類程序員來說早就是常識,但現有的AI編程框架卻在這件事上存在系統性的短板——它們總是急著開始寫代碼,在理解還很不充分的時候就倉皇上陣,結果往往是邊寫邊猜、越寫越偏。SPECFIRST通過把"弄清楚"和"寫出來"這兩個階段強制分開,讓每個階段都能全力以赴,最終得到了穩定且全面的提升。
當然,從實驗結果來看,即便加上了規格提取階段,AI程序員
的整體成功率依然有很大的提升空間——最強模型的平均通過率才65%,距離"完美復現"還很遙遠。占比52%的最主要失敗類型是"知道應該怎麼做但就是沒做對",這說明接下來的改進重點在於提升編程智能體把規格轉化為正確代碼的能力。研究團隊也指出,讓規格智能體發現那些更深層隱藏的邊界行為,是另一個值得持續探索的方向。
這項研究給我們留下一個有意思的思考:如果我們用這個框架來評估人類程序員,那些在需求分析階段花費最多精力的程序員,最終寫出的代碼是不是也更少出錯?傳統軟體工程積累的那些"最佳實踐",或許在AI編程時代同樣適用,甚至適用得更徹底。
感興趣的讀者可以通過arXiv:2607.27167查閱完整論文,參與這個在AI編程領域仍然充滿開放問題的探索。
---
Q&A
Q1:SPECFIRST框架和普通AI編程助手的本質區別是什麼?
A:普通AI編程助手會把"搞清楚程序行為"和"寫代碼"混在同一個循環里交替進行,導致理解不深入、知識容易遺忘、早期錯誤越滾越大。SPECFIRST強制把這兩件事分成獨立的兩個階段:第一階段專門由規格智能體徹底探測程序行為並寫成文檔,第二階段編程智能體拿著這份文檔再去寫代碼。就像專業軟體團隊在編碼前先做需求分析一樣,兩件事分開做,每件都能做得更徹底。
Q2:ProgramBench測試集為什麼被認為特別難?
A:ProgramBench要求AI根據一份簡短的說明文檔和一個只能運行不能看內部的可執行文件,從零開始重寫出功能完全一致的程序。難點在於文檔永遠寫不全——那些邊界情況、精確錯誤格式、參數組合效果都不會被文檔記錄,AI必須通過反覆運行程序來自己發現。測試集包含200個真實程序、近25萬個測試用例,測試對AI完全保密,目前最強的AI模型在無規格提取的情況下只能讓不足1%的程序完整通過。
Q3:SPECFIRST產出的SPEC.md文件具體包含哪些內容?
A:SPEC.md採用六個固定章節的結構:概述(程序是幹什麼的)、命令行參數(各參數的精確語義和組合效果)、輸入與標準輸入(接受什麼格式的輸入)、輸出格式(精確的欄位順序、分隔符、空白字符規則)、錯誤模式(各種錯誤情況下的錯誤碼和錯誤資訊輸出位置)、邊界情況(空輸入、極端值、參數衝突等特殊情形)。這六個章節覆蓋了重新實現一個程序所需要了解的全部行為維度。






