VS Code 中 GitHub Copilot 背後的編碼架構 (Coding Harness)
2026 年 5 月 15 日,由 Julia Kasper、Megan Rogge 與 Aaron Munger 撰寫
隨著每個新模型的發布,同樣的討論總會再次出現:哪個模型最聰明?哪個模型最快?我們該使用哪一個?這些問題固然有用,但對於像 Visual Studio Code 這樣的產品而言,模型只是「代理人編碼體驗」(agentic coding experience) 的一部分。開發者真正互動的對象是「編碼架構」(coding harness):這是一個負責組裝上下文、公開工具、執行代理人迴圈、解析工具呼叫,並將模型輸出轉換為編輯器內有用資訊的層級。在這篇文章中,我們將探討這個架構的作用、為什麼它如此重要,以及隨著模型和開發者工作流程的演進,我們如何對其進行評估。

什麼是編碼架構?
語言模型本身無法編輯檔案、執行指令或運行測試,它們只能產生文字。編碼架構就是連接程式碼編輯器與語言模型的橋樑系統。它將文字轉化為行動,並將結果反饋回去,以便模型決定下一步該做什麼。
在 VS Code 中,編碼架構承擔了三項主要責任:
-
上下文組裝 (Context assembly):在任何請求到達模型之前,架構會先建構一個提示詞 (prompt)。該提示詞包含行為指令的系統訊息、使用者的查詢、工作區結構(語言、框架、開啟的編輯器)、先前對話的歷史紀錄、工具執行結果、自訂指令以及早期會話的記憶。架構決定模型能看到什麼,而這些決定直接影響了品質。
-
工具公開 (Tool exposure):架構會宣告模型被允許呼叫的工具:讀取檔案 (
read_file)、編輯程式碼 (replace_string_in_file或apply_patch)、執行終端機指令 (run_in_terminal)、搜尋程式碼庫 (semantic_search) 等等。每個工具都有模型必須遵守的 JSON 架構,以及模型用於決定何時調用該工具的描述。可用的工具集會隨請求而異。有些工具僅針對特定模型啟用,有些在執行前需要使用者確認;使用者可以在工具選擇器中開關工具;MCP 伺服器和擴充功能可以貢獻全新的工具並插入到相同的迴圈中;而自訂代理人 (.agent.md) 則可以將其工具集限制在特定的子集。 -
工具執行 (Tool execution):當模型請求執行某個工具時(使用如
{"name": "run_in_terminal", "arguments": {"command": "npm test"}}的 JSON),架構負責驗證參數、執行工具、處理錯誤、格式化結果,並在下一次迭代中將其反饋回去。例如,如果模型要求編輯檔案,架構會寫入差異 (diff);如果模型要求執行 Shell 指令,架構則負責生成程序、捕獲輸出並進行傳遞。
上述任務都無法由語言模型直接達成。然而,這些輸入決定了模型的行為和結果,以及你在程式碼編輯器中的實際體驗。
負責協調這些任務、決定何時繼續或停止迭代,以及如何在多輪對話中保持連貫性的邏輯,即為代理人迴圈 (agent loop)。
代理人迴圈
其核心在於,當你在 VS Code 中使用代理人時,會發生一個工具呼叫迴圈:即一個「思考 → 行動 → 觀察 → 再次思考」的循環。在每次迭代中,代理人架構會建構提示詞(系統指令 + 上下文 + 歷史紀錄 + 目前為止的所有工具結果),將其發送給模型,並檢查回覆。如果回覆包含工具呼叫,架構會執行這些工具、捕獲結果並循環回到開頭。如果沒有工具呼叫,迴圈便會結束,助理的文字就會成為最終回覆。

回合 (Turn) 是使用者可見的聊天交換:你傳送一則訊息,代理人最終產生一個回覆。在該回合中,代理人迴圈可能會執行多次輪次 (Rounds)。一輪是指迴圈的一次完整執行:建構提示詞、呼叫模型、接收文字及/或工具呼叫、執行任何工具、記錄結果,並決定是否繼續。所有這些輪次的完整執行即為迴圈的運行 (Run)。單一使用者回合可能會觸發多次輪次,因為模型需要搜尋檔案、讀取程式碼、編輯檔案、執行測試、讀取輸出,並針對失敗進行修正。
工具呼叫迴圈受限於迴圈控制檢查。我們強制執行工具呼叫限制、在輪次之間檢查取消請求,並執行停止掛鉤 (stop hooks)。停止掛鉤是擴充點,可以檢查代理人狀態並決定允許其結束或推動其繼續工作。在迴圈內,提示詞會在每次迭代時重新建構。這意味著模型總是能看到工作區的最新狀態:如果它在三輪前編輯了檔案,目前的提示詞會反映該編輯結果。架構還會管理對話摘要。當累積的歷史紀錄過大時,它會將早期的輪次壓縮成摘要,以便模型在不觸及上下文視窗上限的情況下繼續工作。
注意:想看看架構如何運作嗎?你可以探索 VS Code 原始碼,使用聊天介面中的「工具 UI」來檢視請求可用的工具,並開啟 聊天除錯視圖 (Chat Debug View) 來檢查提示詞、工具呼叫及結果。
架構即產品
當新模型發布時,它必須適配現有的架構。系統提示詞、工具定義、迴圈邏輯、上下文組裝,這一切都是經過數月實際使用而不斷建構與微調的成果。模型在填補空白的能力上會有所提升,但「架構」本身定義了哪些部分是空白。
這點尤為重要,因為 GitHub Copilot 允許你使用來自多個供應商的模型。此外,VS Code 中的 GitHub Copilot 支援一個不斷成長的模型生態系統。開發者可以在模型之間切換、使用自動選擇、引入自己的 API 金鑰,或透過擴充功能安裝額外的供應商。這意味著 VS Code 必須處理一個廣泛且持續演進的生態系統,而非單一穩定的 API。
正是這個架構讓 VS Code 能夠在不強迫開發者每次重新學習產品的前提下,處理這種模型靈活性。你應該能夠切換模型或嘗試新的供應商,同時保持熟悉的核心體驗:聊天、會話、工具、終端機輸出、除錯和版本控制。
但整合新模型絕不僅僅是在模型選擇器中增加一個選項而已。供應商在公開工具呼叫、結構化輸出、推理控制、提示詞快取、上下文限制和錯誤行為方面各有不同。有些模型擅長長期規劃,有些擅長簡潔的編輯。每個模型都有不同的強項,我們會在每次發布前與模型供應商密切合作,相應地調整系統提示詞、工具描述和迴圈行為。供應商通常會提早提供新模型檢查點(即即將發布模型發布前的快照),讓我們能在模型公開之前就開始調整架構。

不同的模型需要不同的架構行為。Claude 模型使用 replace_string_in_file 進行編輯;GPT 模型則使用 apply_patch。Gemini 需要提醒它使用工具呼叫而不是進行敘述,並且在歷史紀錄中遇到孤立的工具呼叫時會中斷。有些模型支援擴展思考並需要推理努力控制。有些在簡潔的系統提示詞下運作最佳;而另一些則需要詳細且結構化的指令才能保持進度。架構會為不同模型選擇不同的系統提示詞——Claude Sonnet 4 與 Claude 4.5 的提示詞不同,而這兩者又與 Opus 的提示詞不同。
所有這些針對不同模型的差異絕非微不足道。它們轉化為針對個別模型的系統提示詞、工具集和對話管理。這意味著當新模型發布時,我們不能僅僅切換一個開關,而是需要驗證其行為。在任何東西發布之前,我們都會驗證工具架構、重新調整預設值並重新運行完整的代理人會話。除了模型功能是否正常運作外,更困難的問題是:我們如何驗證新模型是否真的提供了更好的結果?
評估使架構保持誠實
就像你在發布新功能前需要測試一樣,模型也需要測試。這就是模型評估 (model evaluation) 的切入點。在模型於 VS Code 中發布之前,我們會從多個角度進行評估。我們運行離線基準測試 (benchmarks)、進行內部測試,並將其與產品中現有的模型進行比較。模型上線後,我們持續進行衡量:A/B 測試、聚合使用訊號以及每週報告,幫助我們了解模型在真實開發者工作流程中的行為。

目前有多個公開的模型基準測試,作為共享參考點非常有用。我們利用這些基準測試與廣泛的模型生態系統進行比較,並找出明顯的效能退步。但在前沿 (frontier) 水平上,它們作為品質指標已不再足夠。OpenAI 在發現前沿模型有時能憑記憶重現「黃金修補程式」(gold patches) 後,停止報告 SWE-bench Verified 的結果,因為這使得基準測試受污染的問題變得難以忽視。
覆蓋範圍是另一個限制。SWE-bench 很有價值,但它仍然集中在公開的錯誤修復任務上。Terminal-Bench 對於衡量命令列能力很有用,但許多任務看起來更像是孤立的終端機謎題,而非開發者在編輯器中實際會遇到的工作流程。真實世界的編碼代理人需要的不仅仅是修補已知錯誤或解決 Shell 挑戰,它們還需要建構專案、遷移程式碼庫、跨檔案重構、遵循指令以及處理終端機與瀏覽器。
我們仍然會執行這些基準測試,但它們僅僅是一個起點。為了決定哪些模型適合在 VS Code 中發布,我們需要更貼近我們實際構建的產品的東西。
建構 VSC-Bench
這就是為什麼我們建構了 VSC-Bench,這是我們針對 VS Code 代理人行為的離線評估套件。VSC-Bench 專注於公開基準測試未良好涵蓋的 VS Code 特有開發者任務:自訂代理人模式、擴充功能工作流程、MCP 與工具使用、終端機與瀏覽器互動、多輪對話,以及涵蓋 TypeScript、Python、C++ 等多語言的編碼任務。
我們使用 VSC-Bench 來衡量模型在解決方案準確性、代理人努力程度、Token 效率和延遲方面的表現。下圖重點說明了解決率和 Token 使用量,但在模型成為 VS Code 體驗的一部分之前,我們會評估全方位的維度。在模型或推理設定成為編輯器預設值之前,這種權衡至關重要。
此圖表總結了 40 次 VSC-Bench 運行,涵蓋了 8 種模型努力程度配置。每個點代表一種模型配置;點的位置越高,表示解決的任務越多;位置越往右,表示使用的 Token 越多。對於這組 VSC-Bench 任務而言,xhigh 配置使用的 Token 比 high 多,但解決的任務反而略少,這可能表示它已經過了「有益努力」的甜蜜點,額外的思考並不能轉化為更好的結果。
每個 VSC-Bench 任務都在可重現的容器化工作區中運行。架構會啟動 VS Code、開啟工作區、將一個或多個使用者提示詞發送給代理人、讓代理人以文字和工具呼叫回應,然後評估結果。這讓我們能更真實地檢視完整的代理人迴圈:不僅僅是最終程式碼看起來是否正確,而是代理人使用編輯器、終端機、語言服務、瀏覽器和工具的方式,是否符合 VS Code 的體驗。
結合公開基準測試,VSC-Bench 為我們提供了更平衡的訊號:公開評估告訴我們模型與業界水準的比較,而產品專屬評估則告訴我們它是否已準備好提供開發者在 VS Code 中期待的體驗。
我們如何在合併前對代理人變更進行基準測試
基準測試不僅僅是用於發布模型。它們也是我們在架構變更合入前進行審核的方式。如果 PR 涉及核心工具、系統提示詞或任何可能影響代理人行為的變更,我們會在合併前要求基準測試數據。
對於這些 PR,VS Code 團隊使用自動化評估評估流程。為 PR 新增 ~requires-eval-assessment 標籤即可啟動此流程:PR 會被建構、封裝為評估代理人、進行基準測試,結果會回傳至 PR 中。
-
建構 PR。 Webhook 會將標籤事件路由到
vscode-engineering中的工作流程,啟動針對 PR 合併參考的 Azure DevOps 建構。失敗時會自動重試一次;PR 會收到「queued 1 of 2」(已排入佇列 1/2)的評論,以便審核人員追蹤進度。 -
發布評估代理人。 建構成功後,發布管線會將版本化代理人 (
0.0.0-dev.) 發布到dev標籤下的vscode-evalsnpm 饋送中。PR 評論會變更為「queued 2 of 2」。 -
建立評估議題。 發布管線會向
vscode-engineering發送一個repository_dispatch,在github/evald上開啟一個針對該已發布代理人的模型評估議題。 -
回報結果。 evald 運行基準測試、進行監控並產生分析評論。Azure Logic App 會將評論網址(非分析主體內容,該部分在 evald 上保持隱私)透過另一個
repository_dispatch回傳,並將連結張貼在原始的 VS Code PR 上。

模型是引擎,架構是車輛。
我們從開發者每幾個月就會問的問題開始:哪個模型最好?但對於編碼代理人來說,這個問題有點像是在問:哪顆引擎最好?引擎固然重要,但它本身是不夠的。模型所看到的上下文、它能接觸的工具、維持運作的迴圈,以及確保一切正常運作的評估,這一切才是編碼架構,也是我們投入最多工程時間的地方。
隨著模型獲得更長的上下文、更好的規劃與原生工具使用等新功能,架構也會隨之演進以充分利用這些特性。而隨著開發者將代理人模式應用於新的工作流程,我們也會將學到的知識反饋到迴圈、工具和評估中。每一個 VS Code 的版本發布,都會在模型更新的同時帶來架構上的改進。
如果你好奇架構是如何運作的,今天就可以親自動手體驗。探索 VS Code 原始碼,使用聊天介面中的工具 UI 查看請求可用的工具,並開啟 聊天除錯視圖 (Chat Debug View) 來檢查代理人運行背後的提示詞、工具呼叫及結果。嘗試切換模型、添加自己的工具,讓我們知道哪些方式有效——歡迎在我們的 GitHub 儲存庫分享你的回饋。
祝開發愉快! 💙