跳到主要內容
maxstudioNews
AI 自動化DEV Community (Claude Code)約 7 分鐘

AI 代理平行開發:五個協作者、一份合約與 25 項審查修正

作者利用五個平行的 AI 建構代理(Claude Code 和 Codex)來開發桌面應用程式 Refmade。透過一份明確定義文件所有權的 Markdown 合約,成功管理了代理之間的協作。在第一個功能版本 P0 完成前,一次審查發現了 25 項修正,凸顯了平行 AI 代理協作的複雜性與重要性。

AI 代理平行開發:五個協作者、一份合約與 25 項審查修正
圖片來源:DEV Community (Claude Code)

9 月 26 日,我讓五個建構代理(builder agents)根據一份 Markdown 合約進行開發,該合約明確規定了每個代理負責的文件。當第一個本地版本 P0 完成時,它在 127.0.0.1 上運行,通過了 224 項測試,且沒有任何請求離開本機。在此之前,一次審查發現了 25 項修正,我認為這個數字比測試數量更能說明平行代理協作的複雜性。

這篇文章是關於開發 Refmade 系列的一部分,Refmade 是一個桌面應用程式,它將你的 Claude Code 和 Codex 會話以辦公室的形式呈現:每個會話一個團隊,主代理作為團隊負責人,每個子代理作為隊友。Refmade 是一個獨立應用程式,與 Anthropic 或 OpenAI 無關。

大部分程式碼是在我的指導下由 Claude Code 和 Codex 代理編寫的。我負責規劃工作、做出決策並審查回傳的內容。目前使用者介面是韓文,這將在後續系列文章中改變。之前的文章解釋了為什麼這個「辦公室」會讀取本地日誌,而不是信任代理自行報告。這篇文章則著重於第一個實際運行的版本,即「P0」。

「合約」是一個文件所有權表。在我這裡,建構合約是一份文件,它明確定義了平行工作者之間的介面,並指定了哪個工作者可以編輯哪些文件。如果沒有這份合約,五個代理在編寫同一個應用程式時,可能會對「團隊」物件的樣貌產生五種略有不同的想法。

這份合約以 office-v2/P0-CONTRACT.md 的形式存在於儲存庫中。該文件日期為 9 月 25 日,目前約 40 KB,因為在建構過程中增加了許多區塊,其中一個用於工作流程視圖的區塊將在下文提及。其中最重要的部分是一個關於誰擁有什麼的表格:

建構者 A 擁有日誌分類、Claude 日誌讀取器,不編輯現有檔案。建構者 B 擁有 Codex 日誌讀取器,不編輯現有檔案。建構者 C 擁有辦公室模型、收集器,不編輯現有檔案。建構者 D 擁有 HTTP 伺服器、開啟指令,只編輯 CLI 進入點檔案及其翻譯鍵以新增指令。建構者 E 擁有瀏覽器頁面及其場景程式碼,不編輯現有檔案。整合者不擁有新東西,但可以編輯所有東西,僅限於整合時發現的缺陷。

每個建構者都有自己的測試,與其程式碼並列。現有的 125 項測試被凍結。不允許新增依賴項,只使用 Node 18 或更高版本,且僅限 ES 模組。~/.claude 和 ~/.codex 下的日誌對整個應用程式來說是唯讀的。我最關心的規則是最簡短的一條:「其他人的檔案是唯讀的。」

要更改介面,建構者必須先編輯合約並告知整合者,而不是直接修改別人的檔案。這與人類團隊使用的規則相同,也因此需要為代理明確寫下來。

機器上的所有程式都可以存取一個迴路埠。伺服器僅綁定到 127.0.0.1,這是比較簡單的部分。不那麼明顯的是,迴路埠對同一台電腦上的所有其他程式和使用者帳戶都是開放的,因此「本地」不等於「私有」。

建構者 D 的合約部分透過一個「每次運行金鑰」來解決這個問題。refmade open 是一個從未發布的開發者指令,它會生成一個隨機金鑰,並在 http://127.0.0.1:<port>/#k=<key> 開啟頁面。金鑰位於 # 之後,瀏覽器永遠不會將其發送到網路。

頁面會讀取它並將其附加到每個 API 呼叫。這就是目前 cli/lib/office/server.mjs 中的檢查方式:

const keyOk = ( req , params ) => { if ( ! key ) return true ; const given = req . headers [ ' x-refmade-key ' ] ?? params . get ( ' k ' ); if ( typeof given !== ' string ' || given . length !== token . length ) return false ; return timingSafeEqual ( Buffer . from ( given ), key ); };

?k= 備用方案的存在是因為 EventSource,即即時串流背後的瀏覽器 API,無法設定自訂標頭。如果請求的 Host 標頭不是伺服器自己的位址,則會收到 421 錯誤,這會阻止 DNS 重新綁定。靜態檔案不需要金鑰。如果沒有金鑰,API 將不返回任何內容。這可以保護辦公室視圖免受其他本地程式的影響。它並不能確保代理自身工作的安全,我也不聲稱它能做到。它只是在共享機器上保持視圖的私密性。

審查發現了什麼?在五個建構者完成工作且整合者將其整合後,我從四個不同角度進行了審查,然後進行了第二輪,試圖反駁每個發現。在反駁輪中倖存的發現就成了修正項目,總共有 25 項。我只有這 25 項的總數,沒有具體的清單。

當天日誌讀取的一些陷阱,例如分支的複製腳本顯示每個隊友兩次,以及一次性運行看起來像一個休息中的團隊,是前一篇文章的主題。我已知的限制清單上仍然有一個限制:已完成請求下的一行「結果」是代理最後一個回答的第一句話,代理有時會在其中寫入簡短的內部程式碼,然後這些程式碼會顯示在螢幕上。

過程中發生了兩件事,但不是程式碼本身的問題。工作流程的自我批評和修正步驟失敗了,因為我達到了每週使用限制,所以我手動檢查了這些部分。此外,執行器和檔案監控套件中的一些時間測試在負載下會不穩定,儘管單獨運行時它們會通過。這些都列在我已知的限制清單上。

我要求應用程式感覺更像一個遊戲,並希望將等待使用者回應的請求的「輪到我了」這個詞替換掉,因為它讀起來很奇怪。這成為了基於相同資料合約的三種外觀的簡要說明,只有螢幕程式碼可以改變。變體 A(舒適模擬)、B(管理模擬)和 C(復古 RPG)的頂部欄位,標籤為韓文:「代理正在工作」、「已完成請求」、「交接」、「等待回答」、「等待指令」。這些計數來自我的機器日誌,相隔數分鐘擷取,並裁剪掉了團隊名稱。

簡要說明還列出了要排除的內容:粒子雨、彩虹、升級、獎勵、代幣炫耀,以及任何與實際事件無關的裝飾性元素。效果只允許在實際發生事件時出現,例如請求結束時,一個「+1 完成」浮動在負責人上方。字體是 Galmuri,一種在 OFL 許可下的像素字體,與應用程式捆綁在一起,因此不會從 CDN 加載任何內容。我選擇了 B,即管理模擬。一旦它就位,測試數量從 224 增加到 245。

狀態詞語以簡單句子呈現。外觀簡要說明將狀態詞彙固定為五種狀態:正在工作、等待指令、需要你的回答、尚未開始、運行結束。這些詞語後來有所變化。

今天的遊戲主題在其計數器中顯示「人員正在工作」、「已完成請求」和「等待確認」,並在頂部放置更簡單的句子。今天的遊戲主題中的計數器顯示:「人員正在工作 9」、「已完成請求 0」、「等待確認 1」。這是公開的演示資料。應用程式中的狀態句子:「2 個團隊正在工作。1 個需要我的回答。」任務名稱是範例資料。

此版本的一個注意事項延續至今:已完成的請求卡片表示請求已結束,並不代表工作成功。應用程式從日誌中讀取回合邊界,即使回合結束得很糟糕,它仍然會結束。

那天晚上我必須移除的一個詞。我曾告訴代理,工作流程運行沒有正確顯示在螢幕上。他們認為這意味著結構和角色是不可見的,因此回應了一個裝配線視圖(階段橫向、分支向下)和九個角色徽章,作為新區塊添加到合約中。

大約晚上 10 點,我告訴他們,他們為分支選擇的韓文詞讀起來很奇怪,於是他們從程式碼和頁面中移除了那個詞。我保留了視圖,但那個詞必須刪除。螢幕上的術語是產品的一部分,而代理會很樂意發布一個只在合約內部有意義的詞。

結果及其限制。當 P0 完成時:通過了 224 項測試(在我選擇外觀後為 245 項),首次載入約 2 秒,並且在瀏覽器檢查中沒有向 127.0.0.1 以外的任何地方發出請求。這些數字來自我當天的測試和渲染運行筆記。

它們並不能證明任何人都可以使用這個東西。我的筆記中沒有記錄與非開發人員進行的可用性測試,245 項通過的測試也無法說明這一點。接下來是一個「朋友」功能,我將其發布到生產環境,但又在同一天決定放棄。應用程式連結將在系列文章的最後一篇中提供。

如果你將一個程式碼庫分給多個平行代理,誰擁有共享檔案?你會像我一樣使用整合者,還是讓代理互相合併工作?

Share

覺得值得一看?分享給朋友。

以上為 AI 自動翻譯導讀。原文版權歸 DEV Community (Claude Code) 所有, 建議透過「閱讀原文」前往原始網站,以取得最完整資訊並支持原作者。

Newsletter

不用每天追,AI 重點每週寄給你

43 個來源、每 2 小時更新,太多看不完。電子報每週挑最值得看的幾則,附上 Max 的看法。

每週一封。Email 只用來寄電子報,每封信都能一鍵退訂。