多 agent 並行開發:一套編排紀律
你負責定計劃、裁定、驗收;子 agent 負責寫代碼。
這不是「把任務丟出去」,而是一套有紀律的編排。下面是完整方法。
什麼時候用,什麼時候別用
用:需要多路並行推進、或要在有限時間裏把一條長計劃跑完。
別用:單個小改動、需要與人密集來回澄清的設計階段、以及你自己兩分鐘能做完的事。
派發有固定開銷——寫任務信、收編、驗證。小任務不划算,編排成本會超過它省下的時間。
一、領地劃分:約束在共享運行時狀態,不在文件路徑
最容易犯的錯,是按「文件不重疊」推理就並行派發。
這是錯的。真正決定能不能並行的,不是文件是否重疊,而是有沒有共享的獨佔資源:
- 開發服務器端口——只給需要端到端驗證的那一路,其餘任務信裏寫死「不許起也不許殺」
- 數據庫文件與遷移——同一時刻只允許一路動數據層
- 依賴安裝與 lockfile——由編排方預先建好包骨架並裝好依賴,執行方一律禁止裝包
- 版本控制的索引鎖——撞上了等幾秒重試,絕不許刪。刪掉別人正在用的鎖會毀壞倉庫狀態
- 索引本身——見下一節
另外,多個實現共用的測試夾具、根配置、公共常量,統一由編排方改,執行方各用自己的夾具。只説「只改自己的目錄」不夠,共享文件必須點名。
提交範圍要用 pathspec 收窄
某個執行方把自己的文件加進索引、還沒提交就被打斷;你隨後加入自己的文件並提交——提交動作提交的是整個索引,於是別人的半成品被裹進一條完全對不上的提交消息裏。
正確做法是用 pathspec 形式指定提交範圍,而不是「先全部加入索引再提交」。
注意 pathspec 只認已跟蹤的文件。新建文件必須先加入索引,此時索引裏可能已經有別人的東西,所以加入之後要立刻用同樣的路徑提交,把範圍重新收窄。
這一條要寫進每一封任務信。
二、每一輪的固定動作
- 收殘留——先看工作區狀態。有改動就跑測試,綠則按路徑提交,絕不整倉提交
- 驗狀態——類型檢查加測試;關鍵節點起服務端到端走一遍
- 推送——攢夠就推,不要囤
- 派下一批——按計劃順序,一次只派一條鏈的一小批。被中止時損失小
- 裁定——執行方報上來的設計缺口,能自己定的當場定並落文檔
- 更新彙報——維護一個給人看的單一入口文檔
**不要在有 agent 在飛的時候跑全量驗證。**它們的文件是半成品,類型檢查必然紅。你會把半成品誤判成迴歸,白白浪費一輪。要麼跑範圍收窄的,要麼等它們落地再跑全量。
三、任務信怎麼寫
四樣東西缺一不可:
領地——寫死只改哪個目錄,並且逐個點名列出不許碰的目錄。説「別碰其他人的」不夠,執行方不知道其他人是誰。
為什麼這麼做——給判斷依據,不只給指令。執行方拿到理由才知道邊界在哪,才能在遇到沒寫到的情況時做出合理推斷。
驗收方式——跑什麼命令、什麼算通過。
紀律塊——固定模板,每封信都帶。
兩條容易漏的
**範圍收窄的測試必須同時要求類型檢查。**測試框架不做類型檢查。只讓執行方跑收窄後的測試,等於在整個並行期間把類型這一層砍掉了——會出現測試全綠而類型檢查報一堆錯的情況。
**要求「做完一小步就提交」。**後台任務會被中止。攢着不提交的執行方一旦被殺,就是顆粒無收。
四、執行方必須停下上報、不許自行決定的
- 產品語義
- 範圍調整
- 引入新依賴
- 不可逆動作
- 兩個執行方衝突且雙方都有據
- 設計文檔本身有錯
- 實測推翻了既有結論
在任務信裏明寫:不要自己拍板,寫進報告讓編排方裁。
好的執行方會照做,而且它們對自己那一攤的診斷常常比你準。
**另外:不許為了繞過阻塞而 mock 掉生產代碼。**如果某個探針導入生產模塊失敗,正確做法是停下上報,而不是在探針裏 mock 一個假實現——那樣測出來的就不是真實系統。
最有價值的上報是「你的判斷是錯的」
這一條要在派單裏顯式寫出來:
如果實測發現我説的根因或模型不成立,如實報告並給數據,不要硬套我的模型。
不寫這句,執行方會默認你的模型正確,然後想辦法讓數據符合它。你最後拿到的是一份「成功驗證了錯誤模型」的漂亮結論。
執行方停下來説「你錯了」,比它硬湊一個好看的數字有價值得多。
五、驗收紀律:綠色不構成證據
這是整套裏最值錢的部分。
因為你不再親手跑每一步,只能讀報告,所以**「看起來對」和「真的對」輸出相同**這件事的風險被放大了。
**一、性能數字必須帶「東西真的在變」的證據。**光報速度不採信,要有獨立的、隨負載變化的佐證。而且證據不成立時,讓腳本直接拋錯,不要照常寫出結果。
**二、儀器本身要能自證。**測量要有能力區分「真實的零」和「選擇器漏報的零」。優化會改變系統結構,儀器不跟着更新就會開始安靜地説謊。
**三、端到端不可省。**單元測試在乾淨環境裏天然是綠的,測不出只在特定運行環境才暴露的問題。
**四、假通過比報錯危險得多。**報錯至少會被看見;恆真的斷言會一直綠着,直到有人偶然發現它什麼都沒驗。所以凡是斷言「某東西不存在」,先確認在當前環境裏它本來就該存在——否則你驗的是環境,不是代碼。
**五、修完必須反向驗證。**把產品代碼故意改壞,確認測試真的會紅,再改回來。不能驗證它還抓得到 bug 的測試,等於沒有。
會隨機變紅的守衞,等於沒有守衞
以牆鍾時間為閾值的斷言,在並行套件裏必然抖動。哪怕餘量給得很足,全量跑仍然會偶發失敗。
危害不在於「偶爾要重跑」,而在於它會訓練所有人忽略這盞紅燈。等哪天它因為真迴歸而變紅,沒人會當回事。如果它還擋在部署門禁上,那就是在隨機攔截部署。
修法不是調大閾值——那只是把抖動推遲到機器更忙的時候。正確做法是測工作量而不是測時間:遍歷次數、比較次數、輸出條數、請求總量。這些是確定性的,同樣能抓算法迴歸,且不受機器負載影響。
測量前先確認你測的是自己的代碼
一個指標如果被第三方服務的延遲主導,它就根本測不到你的實現,優化前後的差值只是波動。
下結論前先單獨測一次基礎設施本身的耗時,否則你優化的是別人的服務器。
加機器門禁,不要靠「記得」
比如讓構建去比對「磁盤上存在的測試文件」和「測試框架實際收集到的集合」,不一致就點名失敗。
但沒見過它正確失敗一次的門禁不算數——加完要做一次反向驗證。
六、收編時的態度
**不要只信報告。**關鍵結論自己復跑一遍。
**關於共享代碼的事實斷言必須自己查。**執行方對自身處境的描述可信,對別人代碼的斷言不一定——它看不到全局。
發現報告有誤就當場更正,並在文檔裏留痕,不要靜默改掉。
七、派發被中止時
後台通道會成批中止,有時連開發服務器一起帶走。這是常態,不是故障。
- 不要恐慌重派——先收殘留,跑測試,綠則按路徑提交
- 重試一次——這個模式通常會自己恢復,別過早轉人工
- 連續多輪失敗才轉人工——把任務寫成自包含的信投進執行方信箱,同時給出可以在自己終端直接跑的命令
- 服務被殺就立刻起回來——可能有人正在看
只要每一輪都收殘留,就不會丟工作。
八、裁定要落文檔,不要只在對話裏説
執行方報上來的設計缺口,你裁定之後要寫進設計文檔,並説明依據。
理由很直接:下一個 agent 讀不到你們的對話,只能讀文檔。
而且裁定時,寫「為什麼不那麼做」比寫「做了什麼」有用——後者讀代碼就知道,前者不寫下來,六個月後沒人記得。
收束
這套編排可以壓縮成三句:
領地劃在運行時狀態上,不劃在文件上。
執行方最有價值的輸出是「你錯了」,不是「做完了」。
綠色不構成證據。