以 C 編譯器實驗為例,理解並行 Agent 怎樣通過獨立工作區、任務鎖和 Git 協作,以及語義衝突、故障拆分、測試反饋和角色分工。
多智能體研究主要交換資料與結論。共同開發代碼時,交換的是會改變項目行為的補丁:一個 Agent 修改了接口,其他 Agent 的工作條件就可能隨之變化。
因此,並行開發需要同時組織三件事:誰正在做哪項任務、代碼變化怎樣進入共同版本、組合後的項目怎樣驗證。 工作區、任務鎖和測試分別參與其中,沒有一種機制能單獨覆蓋全部問題。
Anthropic 的 C 編譯器實驗提供了一個具體案例:16 個 Agent 共同開發 Rust 實現的 C 編譯器。這裏借它理解協作機制:
- 狀態與隔離: 各自編輯和運行,怎樣與共享倉庫保持聯繫。
- 認領與集成: 怎樣減少重複勞動,怎樣處理文本和行為衝突。
- 並行性與反饋: 怎樣把共同瓶頸拆成獨立工作,再用測試與專門角色推進項目。
一、多個 Agent 怎樣在同一項目中工作h2
先區分共享的項目狀態與各自操作的工作空間,再看任務歸屬怎樣傳播給其他參與者。
1. Shared Repository:通過代碼與任務記錄協作h3
共享倉庫協作,是讓多個 Agent 根據共同可見的項目狀態選擇工作,再通過提交交換修改。協調信息可以存在源碼、任務記錄、測試結果和進度文件中,不一定由一箇中心 Agent 逐項分派。
這個編譯器實驗沒有 Orchestrator Agent。各 Claude 會話自行選擇下一項工作;人和 Harness 負責建立總體目標、運行環境與驗證條件。
這與 Lead / Subagent 研究架構的區別,是任務安排與整合責任放在了不同位置。研究 Lead 收回材料後形成報告;共享項目則持續把修改納入同一個代碼版本。
可以把它的工作循環理解為:
讀取項目狀態 → 認領任務 → 修改與測試 → 同步共同版本 → 更新任務與進度
這裏同步的不只是源碼。其他 Agent 還需要知道哪些問題已經解決、哪些任務有人處理,以及哪些失敗已經調查過。代碼和協作記錄一起構成下一輪工作的起點。
2. Workspace Isolation:獨立操作與版本同步h3
工作區隔離解決獨立操作,版本同步解決變化傳播。
如果幾個 Agent 直接編輯同一個目錄,A 正在測試時,B 可能已經改了輸入文件;測試結果就難以對應到一份明確代碼。獨立工作區讓各 Agent 可以分別編輯、構建和運行,知道當前操作針對哪一份狀態。
實驗中,每個 Docker 容器都掛載共享裸倉庫到 /upstream,再克隆到自己的 /workspace。各 Agent 操作本地副本,通過 Git 交換提交。
本地副本不會自動等於共同版本
A 的測試可能基於版本 V,B 此時已經推送了修改。A 本地通過,只能説明自己的這份狀態通過。拉取 B 的提交以後,測試對象已經改變,需要重新檢查組合狀態。
由此可以分開兩個判斷:
- 我的修改在當前工作區是否成立?
- 我的修改與其他提交組合後,項目是否仍然成立?
這不是多跑一次同樣的測試,而是在驗證兩份不同的代碼狀態。
進度記錄補充源碼沒有表達的信息
代碼可以説明現在實現了什麼,卻未必説明為何這樣實現、已經排除了哪些假設。新會話需要藉助 README、失敗記錄和進度文件恢復工作位置。
例如,“參數傳遞失敗”還不足以接續調查;對應的目標架構、失敗用例、相關提交與已嘗試方案,才能減少重複定位。記錄也應隨項目更新,否則它會把舊判斷傳給下一輪。
3. Task Lock:認領任務與減少重複勞動h3
Task Lock 表達的是任務歸屬:當前這項工作已經有人處理。 它讓其他 Agent 在選擇任務前看到已有安排。
實驗使用 current_tasks/ 下的文本文件記錄認領。兩個 Agent 爭搶同一任務時,需要通過 Git 同步競爭認領狀態,後者轉向其他任務。工作完成後,修改與其他提交合並,再更新或移除認領標記。
理解這個機制,最重要的是區分本地意圖與共享狀態。A 只在自己的目錄裏寫下“我要修復 X”,B 未必知道;認領信息進入大家採用的同步流程以後,才具有協調作用。
任務鎖的粒度是任務,不是所有相關代碼
“修復解析條件語句”和“調整表達式表示”可以是兩個任務名,但可能同時修改一組類型。任務名不同,並不意味着涉及的文件或接口互不影響。
鎖也不能自動識別兩個失敗用例是否來自同一根因。如果大家分別認領了不同測試,最後都去改同一個基礎模塊,重複工作仍可能發生。
因此,任務認領要配合進度與失敗歸因。它減少的是無意重複,代碼能否組合還要由集成與驗證決定。
二、代碼衝突與共同故障怎樣處理h2
獨立工作不等於修改互不影響。代碼需要整合,共同失敗也需要拆成能夠分別調查的問題。
4. Git Merge:整合補丁與檢查語義衝突h3
Git Merge 整合不同提交,首先處理的是文件內容怎樣組合。並行開發還需要檢查組合之後的程序含義。
| 衝突 | 怎樣發生 | 怎樣發現與處理 |
|---|---|---|
| 文本衝突 | 兩份補丁修改相同代碼區域,Git 無法自動合併 | 對照兩項任務的意圖,手動調整補丁 |
| 語義衝突 | 文本能夠合併,但接口、假設或行為不兼容 | 編譯、集成測試和行為驗證 |
例如,A 把一個函數的返回值改成“字節數”,B 在另一個文件中仍把它當作“元素數”。兩份修改沒有碰到同一行,Git 可能順利合併,程序卻已經改變含義。
這説明“沒有衝突”有兩種完全不同的意思:沒有需要人工處理的文本衝突,不代表不存在行為衝突。
集成時需要核對的不只是自己的差異,還包括依賴條件是否變化。接口、公共類型和基礎設施修改,尤其容易影響其他任務。專門角色與任務鎖可以幫助分工,卻不能省略共同版本的驗證。
5. GCC Oracle:拆分可以獨立排查的故障h3
並行性取決於能否拆出可分別調查的子問題。
幾十個互不相關的失敗測試,容易分派給不同 Agent;一次大型構建只暴露第一個失敗點,則可能讓所有 Agent 都停在同一個位置。此時增加 Agent,往往增加的是競爭修復。
GCC Oracle:用已知可用實現縮小失敗範圍
編譯 Linux 內核時,實驗確實出現了大家圍繞同一個 bug 重複工作的情況。解決辦法是改變驗證方式:大部分文件交給 GCC 編譯,只讓剩餘部分交給待測編譯器,再檢查混合構建結果。
如果失敗,繼續把可疑集合中的一部分改用 GCC,觀察故障是否仍然出現。這樣可以逐步縮小觸發問題的範圍。
這裏的 Oracle 是提供參考行為的已知可用實現。它的作用不是讓 Agent 閲讀 GCC 源碼,而是幫助控制變量:哪些文件由待測編譯器負責,哪些變化與故障出現有關。
不同 Agent 因而可以調查不同文件集合。協作單位從“都讓整個內核編譯通過”,變成了“分別定位某個可復現故障”。
組合故障:單獨通過不代表一起通過
實驗還需要 delta debugging,尋找單獨使用正常、組合時失敗的文件對。獨立子集的測試結果,不能完全代替組合行為。
我從這個例子提取的重點是:測試不僅能驗收結果,還能改變任務的可拆分程度。能定位失敗邊界,才容易劃分責任;始終只得到同一條“大任務失敗”,就很難形成有效並行。
三、開發結果怎樣驗證與持續改進h2
測試提供修改是否成立的證據,專門角色則持續處理功能之外的質量目標。
6. Testing:局部驗證、集成驗證與迴歸檢查h3
並行 Agent 要根據測試反饋選擇下一項工作。驗證器既影響“什麼算完成”,也影響“接下來該查哪裏”。
局部驗證:確認本次修改確實解決目標問題
最小復現或專項測試,可以幫助把結果與當前補丁聯繫起來。沒有這一步,只看到整個項目偶爾成功,很難説明本次修改產生了什麼作用。
集成與迴歸:檢查共同版本和已有能力
集成檢查關注其他補丁加入後的組合;迴歸檢查關注新增功能是否破壞過去正常的行為。實驗後期出現功能反覆退化,因此增加了更嚴格的 CI 驗證。
這兩類檢查解釋了為什麼“我負責的測試通過”不等於“團隊可以繼續疊加修改”:後續 Agent 使用的是共同項目,而不是那一個孤立用例。
反饋表達:先給定位入口,再提供詳細記錄
終端可以返回失敗項目、關鍵錯誤和日誌位置,完整記錄放到外部供按需讀取。這樣下一輪能夠直接進入有關證據,而不必從海量輸出中重新搜索。
快速抽樣則縮短一次修改後的等待。實驗讓單個 Agent 內的樣本保持穩定、不同虛擬機使用不同樣本,兼顧前後比較與團隊覆蓋。抽樣適合開發反饋,最終覆蓋範圍仍應按驗收目標安排。
7. Specialized Roles:分工維護性能、結構與文檔h3
任務分解按問題劃分,角色分工則按持續職責劃分。兩者可以配合:功能 Agent 修復當前失敗,性能或質量角色處理跨模塊問題。
編譯器裏就存在兩類不同性能目標:
- 編譯器自身性能: 編譯項目需要多長時間、消耗多少資源。
- 生成代碼性能: 被編譯出來的程序運行得怎樣。
合併重複實現、審查 Rust 結構和維護文檔,又是其他職責。分別關注這些目標,能減少團隊只追逐眼前失敗測試的傾向。
不過,跨模塊工作也更容易改變其他人的條件。去重可能調整接口,結構修改可能影響正在開發的後端。因此,角色分工需要與任務認領、同步和驗證一起使用。
這項實驗在多種架構上構建了 Linux 6.9,但發佈時仍有外部工具鏈依賴、生成代碼效率與代碼質量等限制。它展示了並行協作能夠推進大型產物,也展示了測試覆蓋、並行性和工程成熟度是不同的問題。實驗報告與限制
幾個關鍵問題,串起任務認領、代碼集成與驗證h2
獨立工作區解決了什麼,又沒解決什麼?
它讓編輯和執行針對各自明確的本地狀態。提交進入共享版本以後,修改仍會互相影響,因此不能替代集成驗證。
為什麼任務認領需要同步?
沒有傳播出去的認領只是本地記錄。其他 Agent 需要在選擇工作前取得共享狀態,才能據此避開已有任務。
Task Lock 和 Git Merge 能否保證協作正確?
任務鎖協調工作歸屬,Merge 整合文本版本;行為是否兼容仍要檢查。兩者都不能單獨保證程序正確性。
沒有文本衝突,為什麼測試還會失敗?
不同補丁可能對接口含義、數據格式或執行順序作出不兼容假設。語義衝突可以發生在完全不同的文件裏。
GCC Oracle 怎樣幫助恢復並行性?
混合編譯與逐步替換文件,讓大型失敗能夠被歸因到更小集合。不同 Agent 因而有了可以分別調查的故障範圍。
為什麼快速測試與完整驗收要分開?
前者縮短反饋週期,幫助定位和比較修改;後者檢查更完整的目標與組合。通過快速樣本,説明的是這些樣本沒有暴露問題。
無中心協調 Agent,是否就等於 Handoff?
不是。這裏通過任務記錄與共享產物協調工作;Handoff指的是執行控制權從一個 Agent 轉給另一個 Agent,機制不同。