執行 AI 生成程式碼的生產應用程式需要一個沙箱,它必須強制實施程序層級隔離、支援並行工作階段、提供可程式化的生命週期 API、具備可觀測的日誌與資源指標、執行套件與網路政策,並能與應用程式後端乾淨整合。如果沒有系統性地評估每個面向就選擇沙箱,團隊最容易在產品上線後遇到問題:一個在暫存環境中看似安全的工作負載,在實際流量下卻會失效、在不同租戶之間洩漏狀態,或默默執行應用程式從未允許的程式碼。
本指南是一份需求檢查清單。它涵蓋了在每個隔離層級需要驗證的事項、生產環境的生命週期 API 必須提供哪些功能、可觀測性與資源控制應具備的樣貌,以及後端整合模式如何成就或破壞整體設計。無論你是在評估託管型沙箱還是自行建置,這些都是出貨前值得回答的問題。
沙箱隔離:程序、容器與 MicroVM
隔離是一個光譜,每個層級在效能、可攜性以及你對生成程式碼的信任程度方面,都有不同的取捨。
程序層級隔離 使用作業系統原語 — 命名空間、cgroups、seccomp 以及 AppArmor 或 SELinux 設定檔 — 來限制程序可以存取的資源。它速度很快,不需要單獨的 VM 核心,但所有程序共享主機核心。核心漏洞或一個通過 seccomp 過濾器的特權系統呼叫,可能會影響同一台主機上的其他工作負載。程序隔離對於低風險、短生命週期、受信任的程式碼路徑來說是一個合理的起點,但對於可能嘗試系統呼叫、建立子程序或安裝套件的不可信 AI 生成程式碼而言,這層邊界過於薄弱。
在此層級需要驗證的事項:
- 哪些系統呼叫被阻擋?當遇到未知系統呼叫時,預設政策是什麼?
- 命名空間是按照每個任務、每個租戶還是跨工作共用?
- cgroup 限制是在任務層級還是僅在主機層級執行?
- 沙箱在結束時是否會清理所有程序、暫存檔案、socket 與共享記憶體?
容器層級隔離 增加了檔案系統與網路命名空間的邊界,並使映像管理可重複。容器啟動速度比完整 VM 快,且更容易組合,並廣泛受到編排層的支援。其取捨在於容器仍然共享主機核心,而容器的邊界強度完全取決於底層的執行階段設定。特權容器、寬泛的能力集合、掛載的主機 socket 以及主機網路模式,都會將有效邊界削弱到幾乎為零。
在此層級需要驗證的事項:
- 容器映像是否精簡,只包含工作負載實際需要的執行階段與工具?
- 能力是否被降至所需的最小集合?
- 容器是否以無 root 方式執行?還是需要 root 權限?對此有哪些控制?
- 主機 PID 命名空間、主機網路與 Docker socket 是否被明確排除?
- 掛載的磁碟區是否僅限於明確定義的路徑?根檔案系統在可能的情況下是否設為唯讀?
MicroVM 隔離 將每個工作負載置於一個輕量級虛擬機器中 — 擁有自己的客戶核心、虛擬裝置以及一個由 KVM 支援的客戶與主機邊界。像 Firecracker 這樣的技術使用極簡的裝置模型來減少攻擊面,同時保持足夠快的啟動速度以支援互動式使用。MicroVM 邊界意味著客戶核心中的漏洞不會自動影響主機或其他客戶。
在此層級需要驗證的事項:
- 每個代理執行、每個租戶或每個並行工作階段是否都獲得一個獨立的 MicroVM?
- 從 API 呼叫到可執行狀態的啟動延遲是多少?這個延遲是從暖池、快照還是冷啟動測量的?
- 客戶映像是否進行版本控制、是否稽核其中包含的執行階段與工具,並定期更新?
- 如果客戶核心發生 panic 或變得無回應,主機層級會發生什麼事?
實際的決策取決於你的威脅模型。對於不可信的 AI 生成程式碼,MicroVM 隔離是最強的普遍可用邊界,但它無法取代檔案系統政策、出口控制、套件治理或機密處理。這些控制措施必須建立在你所選擇的隔離層之上。
管理並行沙箱工作階段
一個同時為多位使用者生成程式碼的生產應用程式,需要一個將並行性視為首要考量而非事後補救的沙箱。
關鍵問題如下:
每個工作階段的隔離:當 50 個工作階段同時執行時,每個工作階段是否都有自己獨立的檔案系統、程序樹、網路命名空間與憑證範圍?工作階段之間的狀態洩漏是多租戶沙箱應用程式中最具破壞性的失敗模式之一,而且在測試中(工作階段是順序執行的)通常難以察覺。
工作階段限制與反壓:沙箱是否將並行限制作為一個明確的 API 契約來呈現?如果 500 個請求到達,而平台支援 100 個並行工作階段,API 是回傳結構化的錯誤、排入佇列,還是默默降級?生產應用程式需要這個訊號來實現反壓、佇列管理以及面對使用者的回饋機制。
負載下的資源公平性:當一個工作階段消耗異常高的 CPU 或記憶體時,其他工作階段是否受到每個工作階段資源限制的保護?還是單一嘈雜的工作負載會拖垮整個池?
暖池與工作階段啟動延遲:互動式編碼功能需要次秒級的工作階段啟動時間。這通常需要一個預先初始化的環境池,可以立即被宣告使用,而不是按需啟動。請確認平台是否記錄了暖池的可用性,以及在不同並行層級下預期的啟動延遲。
工作階段重複使用 vs. 全新環境:有些應用程式會受益於跨多個代理回合重複使用一個長生命週期的工作階段,而其他應用程式則需要每個請求都有一個乾淨的環境。請確認這兩種模式都受到支援,並且工作階段重複使用不會攜帶先前對話中的過時狀態。
生命週期 API:建立、執行、終止
生命週期 API 是你的應用程式與沙箱執行階段之間的介面。一個生產等級的 API 至少必須提供:
建立:初始化一個新的沙箱工作階段,可選擇從範本或快照建立,並指定資源限制、環境變數與掛載的磁碟區。回應應包含工作階段 ID 與一個「就緒」訊號,而不僅僅是確認收到。
執行:提交程式碼或命令以執行。這應是一個非同步呼叫,並回傳一個執行 ID。API 必須支援指定工作目錄、該次呼叫的環境覆蓋,以及一個逾時設定。
串流輸出:將標準輸出與標準錯誤作為串流擷取,而不僅是在執行完成後提供最終結果。對於長時間執行的任務、需要耗費數秒的代理步驟,以及任何向使用者顯示漸進式進度的 UX 來說,串流輸出至關重要。
終止:在執行完成前結束一個正在進行的執行。沙箱應保證程序樹被清理,而不僅僅是父程序。
清理:銷毀工作階段並釋放所有相關資源 — 檔案系統、記憶體、程序槽、網路狀態以及任何持有的憑證。此呼叫應具有冪等性,以便在網路錯誤後重試時不會產生錯誤。
上傳與下載檔案:在執行前將輸入檔案傳入沙箱,並在執行後擷取輸出產物。檔案傳輸應受到大小限制,並透過政策控制哪些路徑可以寫入。
值得為生產使用驗證的額外功能:
- 暫停與恢復:能否在不遺失狀態的情況下暫停一個長時間執行的工作階段,並在稍後恢復?這對於速率限制、成本控制以及代理回合之間的工作階段交接非常有用。
- 快照:能否擷取當前工作階段狀態,並將其作為未來工作階段的起點?這是暖池與可重複使用環境的關鍵機制。
- 逾時強制執行:如果執行的程式碼超過了牆上時鐘逾時時間,平台是否會乾淨地終止它,並回報正確的結束狀態?
可觀測性:日誌、指標與追蹤
你無法偵錯或稽核你看不到的東西。生產環境的沙箱需要內建的可觀測性,而不是事後附加。
標準輸出與標準錯誤擷取:每次執行都應產生一個與工作階段 ID 和執行 ID 相關聯的擷取輸出記錄。這應在執行完成後可透過 API 存取,而不僅是作為即時串流提供。
執行日誌:平台應記錄哪些程式碼被執行、何時開始、何時結束、結束碼為何、哪個使用者或租戶擁有該工作階段,以及使用了哪個範本或快照。這些記錄是重建事發經過所需的最低資訊。
資源指標:生產應用程式需要每個工作階段的 CPU 使用率、記憶體峰值、牆上時鐘時間以及檔案系統寫入量的指標。這有助於容量規劃、異常偵測以及每個工作階段的成本歸屬。
錯誤追蹤:當沙箱無法啟動、執行或清理時,錯誤資訊應是結構化的:包含錯誤碼、訊息、工作階段 ID,以及足夠的上下文來區分使用者錯誤(錯誤的程式碼、缺少套件)與平台錯誤(配額已滿、內部失敗)。
稽核軌跡:對於多租戶應用程式,稽核軌跡應使代理行為可被重建:包含工作階段 ID、租戶、執行順序、套件安裝、聯絡的外部網域、寫入的檔案,以及清理結果。原始客戶程式碼與完整的命令輸出可能不應預設包含在稽核日誌中 — 請根據你的保留與存取政策實際能支援的內容來設計。
應避免的情況:一個只顯示「執行失敗」卻沒有結構化錯誤、沒有工作階段層級日誌,也無法區分逾時、記憶體不足或程序逃逸嘗試的沙箱。這會迫使你在應用程式層對所有內容進行檢測,導致重複工作,並錯過沙箱可以直接觀察到的事件。
CPU、記憶體與逾時限制
無限制的資源消耗是沙箱化工作負載在生產環境中造成問題的最簡單方式之一 — 無論是降低其他工作階段的效能,還是造成意外的基礎設施成本。
一個生產環境的沙箱必須在工作階段層級強制執行限制,而不僅僅是在主機層級:
CPU:限制單一工作階段可以消耗的 CPU 時間。一個產生無限迴圈的工作階段不應降低同一台主機上其他工作階段的效能。請確認此限制是硬性上限(程序被限流或終止)還是軟性限制(與其他程序競爭可用的 CPU)。
記憶體:設定一個記憶體上限,當達到時觸發清理或終止,而不是允許工作階段耗盡主機記憶體。請確認達到限制時會發生什麼事:OOM 終止、結構化錯誤回應,還是無回應的掛起。
牆上時鐘逾時:每次執行呼叫都應有最大持續時間。逾時應在平台層級強制執行,而不僅是在客戶端層級 — 如果客戶端斷開連線,沙箱仍應在設定的限制時間終止執行。
磁碟使用量:生成的程式碼可能會寫入大型輸出檔案、安裝大型套件或填滿工作目錄。對工作階段工作目錄設定磁碟配額可以防止失控的寫入。
程序數量:AI 生成的程式碼可能會衍生子程序、背景工作者或 shell 命令,而這些命令本身又會衍生更多程序。對工作階段命名空間中的程序總數設下限制,可以防止 fork 炸彈與失控的子程序樹。
在評估沙箱平台時,請檢查這些限制是否可針對每個工作階段進行設定(以便不同的使用者層級或任務類型可以有不同的限制)、是否在沙箱層級強制執行,以及達到限制時是產生結構化的 API 錯誤還是默默失敗。
套件安裝政策
AI 生成的程式碼經常要求安裝套件 — pip install、npm install、apt-get、Git 克隆、直接 URL 抓取。每一個操作都會在執行階段將外部程式碼拉入沙箱,這是沙箱需要管理的最危險操作之一。
一個生產環境的套件政策應涵蓋:
註冊表允許清單:哪些套件註冊表是允許的?PyPI 和 npm 是預設選項,但許多團隊希望能夠限制為內部鏡像、精選的註冊表或明確核准的來源。
安裝快取:當許多工作階段安裝相同的熱門套件時,層級快取或拉取通過代理可以避免重複下載、減少啟動延遲,並為你提供一個檢查點來審視正在擷取的內容。
離線模式:某些工作負載應完全不允許套件安裝 — 環境已預先烘焙到映像或範本中,安裝嘗試應以明確錯誤訊息失敗。這對於重視可重現性而非靈活性的評估執行來說是合適的模式。
雜湊驗證與鎖定檔案:當允許安裝套件時,鎖定版本與雜湊驗證可以降低註冊表被入侵而改變沙箱內執行程式碼的風險。
大小限制:套件及其傳遞依賴可能很大。對每個工作階段下載的總大小設定上限,可以防止意外或蓄意的儲存空間耗盡。
套件記錄:每次安裝嘗試都應記錄在執行稽核日誌中:套件名稱、請求的版本、註冊表來源以及成功或失敗。這是你需要在事件發生時重建進入沙箱內容的資料。
向沙箱供應商提出的問題不應該是「使用者可以安裝套件嗎?」,而是「每次安裝如何進行稽核?預設允許哪些註冊表?我能否為敏感工作負載設定更嚴格的限制?」,以及「我能否為敏感工作負載設定更嚴格的限制?」
網路與出口控制
網路存取是沙箱接觸非預期目的地的第二大主要途徑。預設開放出口在開發時很方便,但對於執行 AI 生成程式碼的生產應用程式來說,這是一個糟糕的預設值。
預設拒絕出口:最強的生產姿態是預設封鎖所有對外連線,並明確允許清單化工作階段合法需要的目標。這需要更多設定,但使存取模型可被稽核。
允許清單化的目標:對於編碼代理,典型的允許目標可能包括套件註冊表、代理被設計成呼叫的一組特定公開 API,以及沒有其他東西。對於資料分析代理,清單可能包括特定的資料來源。請確認平台支援每個工作階段或每個租戶的目標允許清單。
DNS 政策:DNS 應與出口政策一致處理。一個無法連線到任意 HTTP 目的地的工作階段,也應無法解析任意 DNS 名稱,並利用該資訊推斷網路拓撲或透過基於 DNS 的通道繞過控制。
內部服務存取:AI 生成的程式碼不應能夠存取雲端元資料端點(例如 AWS 執行個體元資料服務)、內部 API、私有資料庫或管理面板,除非這些是明確設定的。請確認沙箱的預設網路政策是否封鎖了已知的內部位址範圍。
套件下載出口:套件安裝是網路操作。如果出口受到限制,請確保套件註冊表允許清單與出口政策一致,或者使用受信任網路內部的拉取通過代理。
記錄對外連線:即使允許出口,記錄工作階段聯絡了哪些網域和 IP 對於事件調查仍然有用。並非所有沙箱平台都原生提供此功能;請確認你將獲得什麼資訊。
機密與憑證注入
AI 代理經常需要憑證 — API 金鑰、資料庫連線、OAuth 權杖、短期的雲端憑證。沙箱如何處理機密,對於安全性和營運可靠性都至關重要。
狹窄的範圍:每個工作階段應只接收它執行特定任務所需的機密。將包含所有憑證的廣泛環境檔案掛載到每個工作階段,在營運上很方便,但這意味著任何工作階段中被入侵或行為異常的程式碼都可以存取所有這些憑證。
短期憑證:如果後端支援,偏好使用生命週期與工作階段持續時間相關的短期權杖。這限制了洩漏憑證的有效窗口。
注入機制:請確認機密是透過環境變數、掛載的檔案還是透過機密 API 注入的。環境變數預設可供工作階段中的所有程序存取;掛載的檔案可以限定在特定路徑和權限設定。對於最敏感的憑證,請考慮使用機密 API,它只向明確授權的程序提供值。
遮罩:沙箱不應透過標準輸出、標準錯誤、執行日誌、錯誤訊息或模型可見的工具回應來回顯機密。遮罩是應用程式層的責任,但一個支援可設定日誌清理功能的沙箱可以減少意外暴露的影響範圍。
清理:在工作階段結束後,請確認環境變數、掛載的機密檔案以及任何快取的憑證資料都已作為工作階段拆卸的一部分被清理,而不是留給下一個工作階段繼承。
暫時性 vs. 持久性檔案儲存
不同的工作負載有不同的持久性需求,一個生產環境的沙箱應清楚支援這兩種模式。
暫時性工作階段:對於短生命週期的程式碼執行,預設模式是建立一個乾淨的工作目錄、執行程式碼、產生輸出,然後銷毀。暫時性工作階段易於理解:每次執行都從已知的基準線開始,不會累積狀態,清理也很直接。它們是評估任務、一次性程式碼完成以及任何重視可重現性而非連續性的工作的正確選擇。
持久性工作區:長時間運行的編碼代理、迭代開發工作流程以及多輪代理工作階段,通常需要一個能跨多次執行呼叫存活的空間。在某一輪中安裝的檔案、快取的依賴項、寫入的程式碼以及累積的歷史,應在下一輪中可用。持久性工作區操作起來更複雜:它們會累積狀態、可能偏離範本,並且需要一個明確的生命週期 — 工作區何時清理?誰擁有它?在兩次工作階段之間有哪些存取控制來保護它?
快照與範本:範本讓你定義一個已知良好的基準環境 — 執行階段、工具、依賴項 — 並一致地從中啟動工作階段。快照會擷取正在執行的工作階段的當前狀態,並將其作為未來工作階段的起點。兩者對於需要可重複環境和低啟動延遲的團隊都很有用。請確認範本有版本控制、誰可以建立和更新它們受到控制,以及快照是按租戶隔離的。
輸出產物匯出:執行完成後,哪些內容可以離開沙箱?一個生產環境的政策應定義哪些檔案路徑是可匯出的、適用的大小限制為何,以及產物在應用程式接收之前是否經過審查或過濾。
跨工作階段狀態:請明確你的應用程式設計是否打算讓工作階段共享狀態。意外共享 — 透過共享的套件快取、共享的磁碟區或錯誤路由的工作區 — 是一種常見的多租戶隔離失敗。
後端整合:REST、WebSocket、SDK
一個沙箱只有當它能夠乾淨地整合到應用程式後端時才有用。三種主要的整合模式是 REST、WebSocket 和 SDK。
REST:對於提交離散執行請求並輪詢結果的應用程式來說,REST API 是最低摩擦的整合方式。它適用於短生命週期的任務,使用標準的 HTTP 工具易於偵錯,並且能自然地融入現有的服務架構。其取捨在於與推送通知相比,輪詢結果會增加延遲,而串流長時間執行的輸出則需要 SSE 或輪詢日誌端點。
WebSocket:WebSocket 連線支援應用程式與沙箱之間的雙向、低延遲通訊。這是互動式使用案例的正確選擇:一個在程式碼執行時串流輸出結果的編碼助理、一個需要即時發送命令和接收回應的瀏覽器代理,或是一個持續監控執行的評估框架。其取捨在於營運複雜性:WebSocket 連線需要持久狀態、重新連線處理,並且在客戶端和伺服器端都需要更複雜的基礎設施。
SDK:語言原生 SDK 隱藏了傳輸細節、處理認證、為工作階段管理和執行提供型別化介面,並且通常包含用於串流輸出、上傳檔案和管理範本的輔助功能。對於大多數應用程式開發者來說,SDK 是最快的整合路徑。請確認 SDK 正在積極維護、涵蓋完整的 API 表面,並以你的應用程式可以處理的結構化方式處理錯誤。
你的應用程式需要擁有的整合點:無論傳輸方式為何,你的應用程式負責授權(哪些使用者可以建立工作階段以及使用哪些資源限制)、核准關卡(哪些工具呼叫或程式碼執行在執行前需要人工審查)、結果處理(沙箱輸出如何被代理呈現或處理),以及清理(當使用者流程完成或代理回合結束時觸發工作階段拆卸)。
一個設計良好的沙箱 API 不應試圖擁有你的應用程式的業務邏輯。它應該公開基本原語 — 建立、執行、串流、終止、清理 — 並讓你的應用程式層在其之上建立正確的產品行為。
故障復原與清理
生產系統會失敗。一個能夠優雅處理失敗的沙箱可以防止資源洩漏、過時狀態以及難以偵錯的事件。
執行逾時處理:當正在進行的執行超過其逾時時間時,平台應乾淨地終止程序樹,並回傳一個結構化的錯誤回應 — 而不是留下一個消耗資源的殭屍工作階段。請確認工作階段在逾時後會發生什麼事:是自動清理,還是需要明確的清理呼叫?
工作階段崩潰復原:如果沙箱主機當機或工作階段 VM 意外退出,平台應偵測到失敗、將工作階段標記為已終止,並透過 API 公開該狀態,以便應用程式可以做出反應。工作階段不應在沒有任何 API 訊號的情況下默默消失。
清理保證:cleanup 或 terminate API 呼叫應可靠地釋放所有資源:CPU 和記憶體分配、檔案系統配額、程序槽、網路狀態和憑證。清理應具有冪等性 — 對同一個工作階段 ID 多次呼叫不應回傳錯誤。這在實際應用中很重要:在網路錯誤後重試清理的應用程式程式碼不應出現問題。
部分執行失敗:當程式碼在執行中途失敗時 — 未處理的例外狀況、程序被終止、缺少套件 — 沙箱應回傳一個結構化的結果,用以區分部分成功(在失敗前產生了一些輸出)與完全失敗。建立在部分結果之上的應用程式需要此資訊,以避免向使用者呈現不完整或誤導性的輸出。
失控程序處理:如果生成的程式碼建立了一個在主要執行完成後仍存活的背景程序,沙箱應將其作為工作階段清理的一部分終止,而不是允許它無限期運行。請確認平台的清理是否涵蓋完整的程序樹,而不僅僅是執行呼叫的直接子程序。
容量與配額錯誤:當平台達到工作階段容量上限,或租戶已達到其配額時,API 應回傳一個特定的錯誤碼,讓應用程式可以明確處理 — 而不是一個通用的 500 錯誤或默默掛起。這允許應用程式進行佇列、退避,或向使用者提供有用的訊息。
Novita Agent Sandbox
Novita Agent Sandbox 是一個專為代理工作負載打造的託管沙箱平台。它針對編碼代理、資料分析代理、瀏覽器導向的工作流程以及較長時間運行的代理工作階段,其中生成的程式碼需要在隔離、可觀測的環境中執行,而不會落地到應用程式伺服器或共享基礎設施上。
對於已經在使用 Novita AI 模型 API 的團隊來說,Agent Sandbox 可以成為更廣泛代理架構的一部分:模型規劃並生成程式碼,沙箱提供具有可程式化生命週期的隔離執行環境,而應用程式層則負責授權、核准關卡和結果處理。
Novita 描述的功能包括 MicroVM 隔離、並行工作階段支援、涵蓋建立、執行、串流、終止和清理的生命週期 API、用於管理工作階段狀態的暫停與自動恢復功能、用於快速且可重複環境啟動的範本和快照,以及與 Novita 模型 API 的整合。在做出架構決策之前,請在 Novita Agent Sandbox 文件 和產品頁面上驗證當前功能可用性、資源設定選項和定價。關於特定隔離邊界、並行限制、啟動延遲和網路政策的聲明,應根據當前的產品文件進行確認。
在根據本指南中的需求評估 Novita Agent Sandbox 時,請套用與其他供應商相同的檢查清單:每個工作階段的隔離邊界、生命週期 API 完整性、可觀測性表面、可設定的資源限制、套件政策選項、出口控制、機密處理、持久性模型以及後端整合支援。
常見問題
我應該為 AI 生成的程式碼選擇哪種隔離模型?
對於不可信的 AI 生成程式碼,MicroVM 隔離提供了最強的邊界,但它增加了營運複雜性。對於風險較低的工作負載,當容器正確強化時 — 沒有特權模式、最小能力、在可能的情況下將根檔案系統設為唯讀、以及沒有主機 socket 掛載 — 容器隔離是足夠的。對於可能嘗試系統呼叫、衍生子程序或安裝套件的不可信程式碼,僅靠程序隔離的邊界過於薄弱。請將隔離層級與你的實際威脅模型相匹配。
如何在生產沙箱中處理套件安裝?
使用註冊表允許清單,而不是預設開放存取。加入拉取通過快取以減少冗餘下載,並為你提供一個檢查點。記錄每次安裝嘗試,包含套件名稱、版本、來源和結果。對於重視可重現性而非靈活性的工作負載 — 評估執行、自動化流程 — 請考慮使用離線模式,其中環境已預先烘焙,且完全禁止安裝。
生命週期 API 至少應提供哪些功能?
建立、執行(含串流輸出)、終止和清理。串流輸出是最簡實作中最常缺失的功能,而它正是對互動式代理 UI 最重要的功能。清理必須具有冪等性,且必須涵蓋完整的程序樹,而不僅僅是入口程序。
如何防止機密透過沙箱洩漏?
將憑證範圍狹窄地限定在任務所需 — 不要使用廣泛的環境檔案。偏好使用短期權杖。如果機密可能出現在標準輸出中,請不要預設記錄完整的標準輸出。請確認沙箱在工作階段拆卸時會清理環境變數和掛載的機密檔案。將遮罩視為應用程式的責任,而非沙箱的保證。
