Agent Sandbox 沙箱架構: 論兩種設計模式與七種隔離方式

Source description: 最近 Agent Sandbox 這個話題蠻熱的,Simon Willison 在年初就預測「2026 會是解決 sandbox 的一年」。從他列出的名單看來這個預測蠻準: Claude Cowork 內建完整 Linux VM、Fly.io 推出 Sprites.dev、Docker 上線 Docker San…

  • 檔案同步用預簽 URL : Sandbox 要傳檔去 S3 不用拿 AWS 金鑰,而是跟控制平面要一次性的預簽 URL。

  • 強化三件套 : Docker 建置時把 Python 編譯成位元碼再刪掉 .py 原始碼;啟動入口跑起來後立刻 setuid 降權到 sandbox 使用者;讀完環境變數立刻從 os.environ 刪掉。

  • Unikraft micro-VM : 生產環境每個 agent 一個 Unikraft micro-VM,啟動時間一秒內、閒置時歸零;開發和評估環境同一個映像改跑 Docker, sandbox_mode 一個設定切換就好。

作者 Larsen 收尾一句話小編蠻喜歡: 「讓你的 agent 沒東西可偷,也沒東西要保留」 。這就是 Agent in Sandbox 配控制平面做到極致的樣子 —— sandbox 被偷走也沒差,裡面根本沒東西值得偷,被殺掉也沒差,因為狀態全在控制平面的資料庫裡。

這個案例也呼應了 Mackey 那句「agent 要的是電腦」的觀察: 後面要講的七種技術實作裡,Unikraft micro-VM 剛好踩在「MicroVM」那條線上,同時提供了「像電腦」的持久化體驗跟強隔離。

實戰案例: Listen Labs 的 Key-Swap Proxy

Browser Use 的控制平面架構固然完整,但工程量也不小。 Listen Labs 最近分享了一個輕量得多的做法,同樣是 Pattern 1 (Agent in Sandbox),但用一個巧妙的 proxy 就解決了最棘手的 API 金鑰問題。

他們的產品用 Claude Agent SDK 在 sandbox 裡跑 agent 做投影片生成,選 Pattern 1 的理由蠻直接: Claude SDK 的工具是 in-process 執行的,如果要走 Pattern 2 把 tool call proxy 出去,就得停用 SDK 內建工具自己重寫,等於跟 SDK 每次更新打架。Sub-agent 的巢狀 loop 和狀態管理更難搬出來。再加上數百次 tool call 各加 ~100ms 的延遲累積,他們判斷「為了安全而閹割 SDK」不划算。

核心手法: Key-Swap Proxy

既然 agent 要跑在 sandbox 裡,API 金鑰怎麼辦? 他們的解法是「騙 SDK」—— 給 SDK 一個假的 dummy key ( [REDACTED] ),再把 ANTHROPIC_BASE_URL 指向自己的 proxy。Agent 照常發 API 請求,proxy 收到後做一件事: 抽掉假 key、注入真正的 ANTHROPIC_API_KEY ,再轉發到 Anthropic。Agent 從頭到尾不知道真 key 的存在。

這招之所以行得通,是因為 Claude SDK 本身就支援自訂 ANTHROPIC_BASE_URL ,不用改 SDK 任何一行程式碼。跟 Browser Use 的控制平面比,這個做法薄很多 —— 不用自己維護對話歷史、不用重組上下文,proxy 純粹只做金鑰交換和轉發。

Proxy 怎麼保護自己? 一個開放的金鑰交換 proxy 等於免費提款機。他們用 session-scoped HMAC token 驗證每個請求: sandbox 啟動前後端簽一個 token,綁定 45 分鐘有效期和 sandbox IP。因為 Claude SDK 不支援注入自訂 header,他們把 token 直接嵌在 URL path 裡。Proxy 收到請求後先驗簽名、檢查過期、比對 IP,全過才做金鑰交換。

搭配 E2B 的網路隔離 ( denyOut: [ALL_TRAFFIC] ,只放行 proxy 的 hostname),sandbox 裡的 agent 就算被 prompt injection 完全掌控,也沒有 credentials 可偷、沒有外部網路可探索。

把 Listen Labs 跟 Browser Use 放在一起看,可以看到 Pattern 1 的安全問題其實有一個光譜: 從最輕量的 Key-Swap Proxy (只解決金鑰外洩) 到完整的控制平面 (金鑰、對話歷史、計費、檔案同步全包),中間可以按需求逐步演進。起步階段先用 proxy 擋住最關鍵的金鑰問題,規模拉大再往控制平面走,是一條蠻務實的路徑。

技術實作的七種路線

如果從「怎麼做隔離」這層看,目前有七種主流做法,各自有各自的甜蜜點:

1. OS 層 Process 隔離 (Seatbelt / Bubblewrap)

Claude Code 2026 年加的 sandbox 就是這條路。macOS 用 Seatbelt、Linux 用 Bubblewrap ,靠作業系統原生的隔離機制限制子行程能讀寫的路徑和能連的網域。Anthropic 甚至把這個執行環境開源成 @anthropic-ai/sandbox-runtime npm 套件。

OpenAI Codex CLI 也是同一條路,macOS 一樣用 Seatbelt ( sandbox-exec 加上動態產生的 SBPL profile),Linux 則是 Bubblewrap 加 Landlock 做 LSM 層補強、再搭配命名空間隔離 ( —unshare-user/pid/net ),Windows 則用 Restricted Tokens。小編覺得蠻有意思的是,兩家主流的 CLI coding agent (Claude Code 跟 Codex) 最後都收斂到同一個技術選擇,看來 Seatbelt + Bubblewrap 已經是「本機 coding agent」的事實標準了。

優點 : 輕量、啟動快、跟本機開發無縫接軌,不用另外拉機器。 缺點 : 綁作業系統 (macOS 和 Linux 要各寫一套,Windows 原生還沒支援);隔離強度比 VM 弱,理論上還是可能被突破;在 Docker 裡跑 Linux 版還要退回弱化模式。適合單人本機用。

2. 容器 (Docker Container)

最傳統的做法,用 Docker 映像包起來。很多雲端 sandbox 服務底層其實都是容器。

優點 : 生態成熟、可重現、部署簡單、大家都會用。 缺點 : 共享主機核心,隔離強度對「真正不信任的程式碼」來說其實有點不夠;啟動稍慢 (秒級);狀態管理要另外處理。

3. MicroVM / 完整 VM

Claude Cowork 的 macOS 應用用 Apple Virtualization Framework 開一個完整 Linux VM 來跑 agent。Docker 推出的 Docker Sandboxes 每個都是 microVM,有自己的 Docker daemon、檔案系統、網路。Fly.io 的 Sprites.dev 也是這條路,主打「整個硬碟狀態的快照和還原」。

優點 : 隔離最強、硬體級別的分離;持久化狀態方便 (完美對上 Mackey 說的「他們要電腦」);快照跟還原做得好的話體驗很好。 缺點 : 資源用得多一點;設定相對複雜。這是目前「本機跑高強度 agent」的主流方向。

4. 遠端雲端沙盒服務 (Sandbox-as-a-Service)

E2B、Modal、Daytona、Runloop、Fly Sprites 這一掛。LangChain 的 Deep Agents 最近也加了 Runloop、Daytona、Modal 三家支援。

優點 : 不用自己架,直接打 API 就好;天生支援平行、擴展、長時間任務;按次計費,成本攤得開。 缺點 : 網路延遲;憑證管理要小心 (LangChain 建議用短期憑證搭配人工介入);會鎖定平台。

5. WebAssembly Runtime

Simon Willison 最看好的一條路。他自己做了實驗性的 Denobox (用 Deno 子行程跑 JS + Wasm),另外 Python 生態還有 amla-sandbox 、 eryx 、 localsandbox 三個新專案,目標都是「讓 Python 可以方便地用 Wasm 跑不信任的程式碼」。

優點 : 真·語言層沙盒、啟動毫秒級、跨平台、不需要作業系統特權。非常適合「agent 要執行一小段 LLM 生的程式碼」的場景。 缺點 : 能跑的語言或執行環境有限 (主流是 Python、JS、Rust);要用到系統工具 (docker、git CLI 等等) 就不行;生態還年輕。

6. 瀏覽器就是沙盒

Paul Kinlan 的觀點蠻有趣: 瀏覽器是一個被打磨 30 年、專門設計用來跑「來自網路的不可信程式碼」的 sandbox,幹嘛不直接用?他做的 Co-do 就是示範 —— 用 File System Access API 拿資料夾權限、CSP 管網路請求、Web Worker + Wasm 跑程式碼,整個 agent 在瀏覽器分頁裡面跑完。

優點 : 零安裝、零後端、天然跨平台、安全模型現成而且打磨多年。 缺點 : 能做的事被瀏覽器 API 限制住 (沒有 shell、沒有任意執行檔);適合輕量型應用,要碰系統工具就不行。

7. 語言層解譯器沙盒 (Capability-based)

Pydantic 最近出的 Monty 蠻有意思。他們用 Rust 從頭寫了一個 Python 位元碼虛擬機,預設「什麼都不能做」——沒檔案、沒網路、沒環境變數,要讓它做什麼就得自己審核過再開放對應的函式。

優點 : 微秒級啟動、狀態只有幾 KB 可以輕易做快照、每次執行零成本、允許清單 (allowlist) 比拒絕清單 (denylist) 安全得多。 缺點 : 只能跑 Python 子集;不適合需要整套系統工具的場景。定位比較偏「讓 LLM 寫 Python 取代一連串工具呼叫」這個用法。

Pattern 跟技術做法的對照

前面談了「兩種整合 pattern」跟「七種技術實作」,這兩個其實是不同維度 —— pattern 講 agent 和 sandbox 怎麼組合,技術實作講 sandbox 靠什麼機制做隔離。實務上會「挑一個 pattern,再挑一個技術來落地」。小編整理了一張對照表:

幾個值得注意的搭配:

  • CLI coding agent 都是 OS 層 + Pattern 2 : Claude Code 和 Codex CLI 的主循環跑在你本機,但每個 bash 指令被 Seatbelt/Bubblewrap 包住。Agent 本身其實在 sandbox 外面。

  • Pattern 1 配 MicroVM 是「大規模 agent 服務」的主流 : Browser Use 的 Unikraft、Claude Cowork 的 Apple Virtualization 都是這個組合。隔離強、啟動夠快、持久化狀態方便,適合「agent 當作可拋棄運算單元」的場景。

  • Wasm 跟 Monty 只走 Pattern 2 : 因為它們不是「完整電腦」,只是一個受限的執行引擎,主要任務是安全地跑一段程式碼。

SDK 層的整合: OpenAI Agents SDK

2026 年 4 月 OpenAI 在 Agents SDK 加上原生 sandbox 支援。小編覺得這次更新的重點不是做新的隔離技術 (底下就是用現成的 sandbox 服務),而是把「agent 工作站」的合約標準化。下面幾段試著用白話把它的設計拆開講,不用熟 SDK 的程式碼也能看懂。

走哪個 pattern、綁什麼技術? OpenAI Agents SDK 走 Pattern 2 (Sandbox as Tool) —— agent 主循環跑在你控制的 trusted 環境,要執行 shell 指令或改檔案時才遠端呼叫 sandbox,沒事不佔資源。官方用前面那兩張對照圖解釋為什麼選這個 pattern (不是說 SDK 兩種都支援,而是在說為什麼不走圖 1 那條路)。底層技術則 完全不綁定 : 同一套 agent 邏輯,本地開發可以跑 Docker 容器,生產環境換成 E2B (容器) / Vercel (MicroVM) / Cloudflare (Workers isolate) 等,換供應商只改一行設定、不用改 agent 程式碼。這也是 OpenAI 把 SDK 定位在「合約層」而不是「隔離層」的關鍵。

SDK 新加了兩層合約 : 一層叫「環境合約」,描述 sandbox 開起來是什麼樣 —— 要掛哪些檔案、哪些目錄、要從哪個 git repo clone、要掛載哪些 S3 / R2 / GCS / Azure Blob 儲存 (SDK 裡這叫 Manifest )。另一層叫「操作合約」,把 agent 在 sandbox 裡能做的事拆成可組合的能力: 執行指令、編輯檔案/檢視圖片、載入技能包、跨次執行累積經驗、長對話壓縮 (SDK 裡這叫 Capabilities ,對應的能力名稱是 Shell / Filesystem / Skills / Memory / Compaction )。環境合約定義「agent 進到什麼環境」,操作合約定義「agent 在環境裡能做什麼」,兩個合起來就是 OpenAI 想標準化的「agent 跟 sandbox 之間的介面」。

內建九家供應商 : Blaxel 、Cloudflare、Daytona、E2B、Modal、Runloop、Vercel 七家雲端,加上本地的 Docker 跟 Unix 行程共九家,全部共用同一組合約介面。

題外話 — OpenAI 自己的 Hosted Containers 竟然不在清單裡 : OpenAI 其實有自家的 sandbox 即服務,叫 Hosted Containers (走 Responses API 的 container_auto 旗標),OpenAI 預先幫你開好 Debian 12 容器、裝好 Python / Node / Ruby / Go 等環境,可以跨 request 存活 20 分鐘閒置時間。但這個服務 目前不在 Agents SDK 的 9 家內建供應商清單裡,兩條路是分開的。Hosted Containers 目前的定位看起來是「只用 OpenAI 模型、只需要跑段程式碼或簡單 shell、不想管 sandbox 基礎設施」的輕量場景 —— 一個 flag 就能用。至於會不會被收進 Agents SDK 當第十家?小編猜應該會啦,畢竟 OpenAI 把 SDK 定位成合約層、自家又有現成供應商,兩邊打通是自然的事,就看時機。

Host 跟 sandbox 的分工 : 這裡有個容易誤會的點 —— SDK 裡有個類別叫 SandboxAgent ,聽起來像「住在 sandbox 裡的 agent」(Pattern 1),但它 不是 。官方 Cookbook 白紙黑字寫「 harness outside the sandbox 」。實際分工:

  • Host 端跑的 : Agent 主循環、LLM 呼叫、操作合約的 handler、MCP server、憑證

  • Sandbox 裡跑的 : 只有「操作合約被呼叫時觸發的實際動作」—— 執行中的 shell 指令 (例如 pytest )、正在被編輯的檔案、agent 啟動的子行程 (test runner、dev server 之類)

操作合約底層就是註冊給 LLM 的 function calling 工具。LLM 吐出「執行 pytest 」這樣的 tool call,host 上的 handler 攔下來、把指令送進 sandbox 跑、結果再回到 host 塞進對話。所以「Sandbox as Tool」這個名字剛好兩層意思都對上: 架構上 sandbox 是 agent 從外部呼叫的能力,技術上就是 function call 工具。

狀態切成三類分別管 : Host 跟 sandbox 分離之後,狀態也自然分開。SDK 把 run 的狀態切三類:

  • 執行狀態 : 模型訊息 (也就是對話訊息)、工具狀態、核准流程 —— 存在 host

  • Sandbox session 狀態 : 可序列化的連線描述,拿來重連同一個 sandbox —— 存在 host

  • 工作區快照 : Sandbox 裡檔案的備份,拿來初始化一個新 sandbox —— 存在 host 或外部儲存

好處有三個: 憑證不會暴露在 LLM 生成程式碼跑的環境裡;sandbox 容器死掉不等於整個 run 掛掉,三類狀態可以分別還原;容易平行跑多個 sandbox 或把子 agent 路由到獨立環境。前面 Browser Use 手工打造的那條控制平面路線,這裡直接變成 SDK 的預設。

對話紀錄放在哪? 三類狀態裡的「執行狀態」就包含對話訊息 —— 預設跑在 host。但這只是其中一種做法,對話歷史其實有三個可能的存放位置:

不管選哪個,原則不變: sandbox 一律不碰對話紀錄 ,對話收束在哪一層是上游的選擇題。用 OpenAI 伺服器端 conversation 時,host 只握一個對話 ID 當指標、LLM 狀態由 OpenAI 後端管,host 本身可以薄到幾乎只剩轉發層 —— 這對做 SaaS agent 服務特別有吸引力。

一個具體案例 : OpenAI Cookbook 有一份 legacy codebase 遷移 agent 教學 ,做的是把程式碼從 Chat Completions 搬到 Responses API。做法是把大遷移拆成「一個服務一個 task」,每個 task 開一個獨立 sandbox、agent 跑完產出一個 patch 就把 sandbox 拆掉,天然對應到一個獨立 PR 的 review 流程。Agent 只拿 Shell 跟 ApplyPatch 兩個 Capabilities,其他東西全部留在 host 端。這個例子還順便示範一個蠻漂亮的延伸: MCP server 也掛在 host 端 —— agent 要查 OpenAI 官方文件時,透過 host 的 MCP 代查,sandbox 自己根本不用拿 MCP 憑證、也不用開對外網權限。憑證、工具、文件通通留在 host,sandbox 真的就乾淨只有當下這個 task 的檔案跟指令。

2026 的 agent 基礎設施不只在卷 sandbox 本身,也在卷「agent 跟 sandbox 之間的合約」長什麼樣,OpenAI 這步就是在定義那個合約。

每條路線都有各自的甜蜜點,小編簡單收斂一下選擇建議:

  • 本機單人用 Claude Code 這類 coding agent → OS 層 sandbox 最無痛

  • 要讓 agent 自己建環境、裝套件、長期工作 → MicroVM (Docker Sandboxes、Fly Sprites、Claude Cowork 這類)

  • 產品要讓使用者帶自己的 agent 跑程式碼 → 遠端雲端 sandbox (E2B、Modal、Daytona、Runloop)

  • 只需要安全地跑一小段 LLM 生的程式碼 → Wasm sandbox 或 Pydantic Monty

  • 做純前端/客戶端 agent → 瀏覽器 sandbox

Agent 這件事最後還是會收斂到「信任邊界」的工程問題。Anthropic 把 sandbox-runtime 開源、OpenAI 在 Agents SDK 裡把 Manifest 跟工作區標準化、Pydantic 用 Monty 做能力制 (capability-based) 解譯器、Luis Cardoso 寫了 Field Guide…這個方向確實是 2026 年 agent 基礎設施最值得盯的區塊之一。

過去一兩年大家在 agent 層堆各種 prompt 技巧、規劃器、記憶、工具,這些都很重要。但真的要讓 agent「放手去做」,底下這層隔離才是那個決定「膽子能放多大」的前提 —— 沒有 sandbox 撐著,再好的工具你也不敢給它自動核准。這兩件事是互補的: 工具決定 agent 能做什麼,sandbox 決定我們敢讓它做到哪。

  • The two patterns by which agents connect sandboxes (LangChain)

  • Execute code with sandboxes for Deep Agents (LangChain)

  • Field guide to sandboxes for AI (Luis Cardoso)

  • Claude Code Sandboxing 設計 (Anthropic)

  • Claude Code Sandboxing 官方文件

  • Pydantic Monty

  • The browser is the sandbox (Paul Kinlan)

  • Simon Willison 對 Sprites.dev 的看法

  • Docker Sandboxes 文件

  • How We Built Secure, Scalable Agent Sandbox Infrastructure (Larsen Cundric / Browser Use)

  • How We Built Our Sandboxed Claude Agent without Leaking Its API Keys (Listen Labs)

  • The next evolution of the Agents SDK (OpenAI)

  • Sandbox Agents 官方文件 (OpenAI)

  • Migrate a Legacy Codebase with Sandbox Agents (OpenAI Cookbook)

  • Shell Tool 跟 Hosted Containers 文件 (OpenAI)

  • Sandbox Agents PR (openai/openai-agents-python #2889)