我們為自主代理構建了沙盒基礎設施
NeoSigma公司構建了一套沙盒基礎設施,為自主代理提供安全、隔離且功能完整的執行環境,使其能夠像在真實開發環境中一樣工作,同時確保每一操作都受控、可重現且可丟棄。
代理的能力取決於它能夠安全行動的環境。為了讓代理自主運作,它們需要一種驗證自身工作的方法。代理可以擁有豐富的動作空間和完美的獎勵訊號,但如果沒有真實的執行環境,這些能力在很大程度上仍然是理論上的。隨著模型能力越來越強,它們被委託從事越來越重要的工作:修改資料庫、執行任意程式碼、部署基礎設施以及與生產API互動。擁有完整的執行時工作空間,代理可以驗證自己的成果並迭代直到成功。
挑戰在於構建一個與開發者本地環境無異的工作空間,同時安全隔離代理所做的一切後果。沙盒提供了一個隔離的執行環境,代理可以在此安全地執行程式碼、與服務互動並從失敗中恢復。一個設計良好的沙盒為代理提供了一個真正的樂園,同時確保每個動作都是隔離的、可重現的和可丟棄的。
一個出色的執行環境應具備以下核心特性:控制平面——以最小延遲保持執行就緒;執行平面——一臺真正的機器,而非一個Shell;安全與網路平面——隔離能力而不限制其發揮;資料平面——生產規模的確定性狀態。每個設計決策最終都是為了這些核心原則之間的帕累託前沿進行最佳化。
在本文中,我們將介紹為代理執行、探索和從經驗中學習的工作空間提供動力的核心基礎設施。我們討論如何將工作空間配備與真實環境相同的能力,包括真實的檔案系統、Docker、網路、代表性資料和生產工具,同時確保每次執行保持隔離、可重現和可丟棄。
控制平面 代理是互動式系統,花費在準備執行環境上的每一秒都是使用者等待的時間。啟動微型虛擬機器、配置儲存、克隆倉庫、初始化服務、載入工具和執行健康檢查很容易佔據請求的關鍵路徑。如果每次互動都需要從頭建立沙盒,即使是最有能力的模型也會很快感覺響應遲緩。最明顯的解決方案是避免按需建立沙盒。控制平面協調執行環境的生命週期,確保以最小延遲將正確的沙盒預配、初始化並分配給代理。它還維護一個預先預配的執行環境池,隨時可以接受工作。排程器不是為每個請求啟動新沙盒,而是嘗試將代理連線到現有的預熱沙盒。只有在預熱池耗盡或工作負載需要尚未可用的資源或配置時才會發生冷啟動。預熱沙盒遠不止是一個正在執行的虛擬機器。當它進入池中時,作業系統已啟動,Docker正在執行,倉庫已克隆,依賴項已安裝,代理執行時已初始化,支援服務(包括MCP伺服器)也已可用。從代理的角度來看,執行幾乎立即開始,因為昂貴的初始化工作已經完成。維護該池從根本上是一個排程問題,而非配置問題。持有過少的預熱沙盒會增加冷啟動延遲,而過多則浪費計算資源。排程器持續預測需求,提前配置新沙盒,並透過LRU風格的驅逐策略回收未使用的容量。最優池大小取決於工作負載模式、倉庫特徵、依賴圖、使用者行為和資源需求。最大的延遲改進並非來自加快每個配置步驟,而是來自完全避免不必要的配置工作。其中最有影響力的最佳化來自意圖預測。由於使用者互動在請求提交之前就開始了,控制平面可以在使用者仍在編寫提示時開始準備沙盒。透過將初始化與使用者思考時間重疊,許多潛在的冷啟動變成了簡單的連線,減少了感知延遲,而無需改變執行環境本身。當預熱沙盒不可用時,回退路徑仍然是確定性的。基礎映象從版本化的快照中恢復,根據工作負載分配CPU、記憶體和儲存,然後初始化、健康檢查,最後交給代理。快速路徑和回退路徑產生等效的執行環境,僅在於請求到達前已完成的工作量不同。
執行平面 沙盒的低延遲只有在其環境行為與代理最終目標環境相似時才有價值。一個省略服務、簡化檔案系統或用模擬代替生產工具的執行環境可能更快配置,但它從根本上改變了代理的行為,這是無用的。在人工環境中成功的軌跡在轉移到真實基礎設施時常常失敗。因此,我們的目標是保真而非簡約。每個沙盒都設計得儘可能接近開發者工作站。代理在一個完整的環境中操作,包括可寫檔案系統、已克隆的倉庫、專案配置、開發工具、Docker、MCP伺服器以及在生產開發中會遇到的相同支援服務。目標很簡單:如果一個任務在沙盒內成功,那麼它在針對客戶實際環境執行時也應成功。這種理念的一個後果是將容器化工作負載視為一等公民。現代軟體開發很少由主機上執行的單個程序組成。應用程式依賴資料庫、快取、訊息佇列、後臺工作執行緒和其他服務,這些通常透過Docker Compose或類似工具編排。支援這些工作流需要的不僅僅是Docker CLI,還需要沙盒內部執行一個功能正常的Docker守護程序。代理不是推理更改是否有效,而是可以直接透過構建和執行已修改的應用程式來驗證其行為。提供這種保真度不可避免地會擴大執行面。執行巢狀容器、暴露Docker守護程序和支援任意開發工具都會引入額外的安全考慮。我們沒有限制這些功能,而是透過本文後面描述的安全架構來隔離它們。目標不是降低代理的能力,而是確保這些能力保持在安全隔離的狀態。最終,執行平面的存在是為了消除評估與部署之間的差距。代理應該在與其軟體最終執行環境相同的環境中開發、測試和除錯。沙盒越接近現實,代理就越可靠。
安全與網路平面 執行平面有意賦予代理廣泛的能力。它們可以執行任意程式碼、與Docker互動、修改倉庫、訪問代表性資料以及與外部服務通訊。這些能力使代理有用,但也使沙盒安全與傳統應用安全根本不同。目標不是阻止執行,而是確保執行完全隔離。沒有任何單一的安全邊界足夠。沙盒同時執行不受信任的、模型生成的程式碼,同時與客戶基礎設施和憑據互動。防止許可權提升、秘密洩露、橫向移動和資料洩露需要多個獨立的隔離層,而非單個周界。最安全的秘密是代理永遠無法訪問的秘密。這一原則塑造了整個憑據架構。任何暴露給執行環境的憑據——無論是透過環境變數、掛載的檔案還是程序記憶體——如果攻擊者透過提示注入或模型操縱控制了代理,最終都可能被洩露。短期憑據減少了暴露,但並未消除潛在風險。如果代理可以讀取秘密,它就可以洩露它。相反,憑據必須完全位於沙盒外部。需要身份驗證的請求透過一個憑據注入代理路由,該代理在轉發請求之前立即附加適當的憑據。代理發出普通網路請求,從不觀察底層秘密,而代理成為唯一負責憑據管理的元件。秘密從未成為執行環境的一部分,從而消除了一整類洩露攻擊。此外,針對未授權主機的提示注入請求無法透過我們嚴格的出口許可列表。保護沙盒需要控制兩個方向的流量。入站流量被嚴格限制,僅允許必要的服務,而出站流量則透過許可列表控制,只允許訪問經過批准的外部端點。這種多層架構確保了即使沙盒被攻破,攻擊者也無法輕易橫向移動或洩露資料。
資料平面 每個執行都從已知狀態開始,每個動作都可恢復。相同輸入應產生相同環境,從而使失敗可除錯、評估可重複,成功軌跡可重用。資料平面負責管理沙盒的持久狀態,確保快照的一致性和環境的可重現性。透過版本化的映象和狀態快照,我們可以將沙盒回滾到任何先前的點,這對於除錯和迭代至關重要。