Sandbox
新增於: @mastra/core@1.1.0
Sandbox Provider 讓 Agent 能夠執行 shell 命令。當你在 Workspace 配置 Sandbox 後,Agent 便可在執行任務時運行命令。
Sandbox Provider 會在受控環境中執行命令:
- 命令執行:使用參數運行 shell 命令
- 背景程序:啟動開發伺服器和監察器等長時間運行的程序
- 工作目錄:從指定目錄運行命令
- 環境變數:控制可用的變數
- 逾時:防止長時間運行的命令停滯
- 隔離:可選用作保安用途的作業系統層級沙盒隔離
觀看 Mastra 遙距 Sandbox 概覽,了解遙距 Sandbox 如何為 Agent 提供隔離的電腦環境以進行工作。
支援的 Provider支援的 Provider 的直接連結
LocalSandbox:在本機執行命令AgentCoreRuntimeSandbox:在 AWS Bedrock AgentCore Runtime session 中執行命令AppleContainerSandbox:使用 Apple 的containerCLI,在本機 OCI Linux container 中執行命令BlaxelSandbox:在隔離的 Blaxel 雲端 Sandbox 中執行命令DaytonaSandbox:在隔離的 Daytona 雲端 Sandbox 中執行命令DockerSandbox:在本機長期運行的 Docker container 中執行命令E2BSandbox:在隔離的 E2B 雲端 Sandbox 中執行命令ModalSandbox:在隔離的 Modal 雲端 Sandbox 中執行命令PlatformSandbox:在綁定至 Mastra Platform 環境的 Sandbox 中執行命令RailwaySandbox:在短暫且隔離的 Railway 雲端 Sandbox 中執行命令VercelSandbox:在短暫的 Vercel Sandbox Firecracker MicroVM 中執行命令VercelServerlessSandbox:以無狀態 Vercel serverless function 的形式執行命令
基本用法基本用法 的直接連結
建立配有 Sandbox 的 Workspace,並將其指派給 Agent。Agent 之後便可執行 shell 命令:
import { Agent } from '@mastra/core/agent'
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'
const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './workspace',
}),
sandbox: new LocalSandbox({
workingDirectory: './workspace',
}),
})
const agent = new Agent({
id: 'dev-agent',
model: 'openai/gpt-5.6-sol',
instructions: 'You are a helpful development assistant.',
workspace,
})
// The agent now has the execute_command tool available
const response = await agent.generate('Run `ls -la` in the workspace directory')
有關包括環境隔離和原生作業系統沙盒隔離在內的配置選項,請參閱 LocalSandbox 參考資料。
動態 Sandbox動態 Sandbox 的直接連結
sandbox 選項除接受靜態 instance 外,也接受 resolver function。resolver 會接收 requestContext,並為每個 request 傳回一個 Sandbox,讓單一 Workspace 可根據 caller 的身分、角色或 tenant 使用不同 Sandbox。
import { Agent } from '@mastra/core/agent'
import { Workspace, LocalSandbox } from '@mastra/core/workspace'
const workspace = new Workspace({
sandbox: ({ requestContext }) => {
const userId = requestContext.get('user-id') as string
return new LocalSandbox({
workingDirectory: `/workspaces/${userId}`,
})
},
})
const agent = new Agent({
id: 'multi-tenant-agent',
model: 'your-provider/your-model',
workspace,
})
每個 request 都會在 Tool 執行時解析其專屬 Sandbox:
import { RequestContext } from '@mastra/core/request-context'
// User Alice — commands run in /workspaces/alice
const aliceCtx = new RequestContext([['user-id', 'alice']])
await agent.generate('List files in cwd', { requestContext: aliceCtx })
// User Bob — commands run in /workspaces/bob
const bobCtx = new RequestContext([['user-id', 'bob']])
await agent.generate('List files in cwd', { requestContext: bobCtx })
Workspace instruction 預設以穩定的 placeholder 文字描述 runtime Sandbox。要加入每個 request 的具體資料,請參閱 Workspace instruction。
resolver 也可以是 asynchronous,例如從數據庫查找 tenant 配置:
const workspace = new Workspace({
sandbox: async ({ requestContext }) => {
const tenant = await db.getTenant(requestContext.get('tenant-id'))
return new LocalSandbox({ workingDirectory: tenant.workspacePath })
},
})
生命週期擁有權生命週期擁有權 的直接連結
當 Sandbox 是靜態 instance 時,workspace.init() 會呼叫其 start() method,而 workspace.destroy() 則會呼叫其 destroy() method。使用 resolver 時,Workspace 在建構時沒有需要管理的 instance;caller 擁有所傳回 Sandbox 的生命週期。
resolver 必須傳回一個可供使用的 Sandbox,它可以是已經啟動,或無需明確啟動即可處理呼叫。caller 亦負責決定何時清理所傳回的 Sandbox。
清理工作可以按 request、tenant 或用戶進行,也可以是長期運行 Sandbox pool 的一部分。workspace.destroy() 不會銷毀 resolver 傳回的 Sandbox。
sandbox resolver 與 mounts 及 lsp: true 不兼容。兩者在建構時都需要具體的 Sandbox instance,因此與 resolver 一併使用時,會拋出 INVALID_CONFIG 錯誤(適用於 mounts),或停用 LSP 並顯示警告(適用於 lsp: true)。
Tool 註冊Tool 註冊 的直接連結
使用靜態 Sandbox 時,Workspace 會檢查 instance 以決定註冊哪些 Tool。使用 resolver 時,Workspace 會假設 Sandbox 具備完整功能,並註冊 execute_command(支援 background)、get_process_output 和 kill_process。如果解析所得的 Sandbox 未實作某項功能,runtime 便會拋出清晰的 SandboxFeatureNotSupportedError。
背景程序延續性背景程序延續性 的直接連結
背景程序的運行時間可能超出單次 Tool 呼叫,因此 get_process_output 和 kill_process 必須連接至啟動該程序的同一個 Sandbox。解析所得的 Sandbox 預設會按 request 快取。若要讓 Sandbox 在後續 request(例如稍後的對話回合)中延續使用,請將 sandboxCacheKey 設為穩定的識別碼。屆時,解析所得的 Sandbox 會按該 key(而非 request)快取:
const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
sandboxCacheKey: ({ requestContext }) => requestContext.get('thread-id') as string,
})
如未設定 sandboxCacheKey,resolver 本身必須為共用相同 tenant、用戶或 session 的後續呼叫傳回同一個 Sandbox。
不再需要某個已快取的 Sandbox 時,請在你自己的生命週期程式碼中銷毀該 Sandbox,並呼叫 workspace.clearSandboxCache(cacheKey) 以移除 Workspace 快取項目。呼叫 workspace.clearSandboxCache() 可清除所有具 key 的 Sandbox 快取項目。
Workspace instructionWorkspace instruction 的直接連結
Workspace instruction 會在 Agent 的 system message 中描述環境。使用 Sandbox resolver 時,Workspace 不會呼叫 resolver 來建立這些 instruction,而會輸出穩定的 placeholder 文字。這樣,建構 prompt 時便不會佈建由 caller 擁有的 Sandbox,而 system message 在不同 request 之間亦能保持一致,令 prompt caching 持續有效。
要加入每個 request 的具體 Sandbox 詳情,請將 instructions.dynamicSandbox 設為 'resolve':
const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
instructions: { dynamicSandbox: 'resolve' },
})
'resolve' 會在每個 request 呼叫 resolver,這可能會佈建 Sandbox,並令 system message 因 request 而異。你亦可傳入 function,直接根據 requestContext 傳回自訂文字,而不解析 Sandbox:
const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
instructions: {
dynamicSandbox: ({ requestContext }) =>
`Sandbox scoped to tenant ${requestContext.get('tenant-id')}.`,
},
})
Agent ToolAgent Tool 的直接連結
在 Workspace 配置 Sandbox 後,Agent 會獲得用於運行 shell 命令的 execute_command Tool。
如果你的 Sandbox Provider 支援在背景運行程序,execute_command Tool 也接受 background: true 以啟動長時間運行的程序,並會另外註冊兩個 Tool:
| Tool | 說明 |
|---|---|
execute_command | 運行 shell 命令。傳回 stdout、stderr 和 exit code。支援以 background: true 啟動長時間運行的程序並傳回 PID。 |
get_process_output | 按 PID 取得背景程序的 stdout、stderr 和狀態。支援以 tail 限制輸出行數,並以 wait: true 阻塞直至程序結束。 |
kill_process | 按 PID 停止背景程序。傳回最近的輸出。 |
這些 Tool 會自動註冊。完整 Tool 名稱列表請參閱 Workspace class 參考資料。
背景程序 callback背景程序 callback 的直接連結
當 Agent 透過 execute_command Tool 啟動背景程序時,你可以接收 stdout、stderr 和程序結束的生命週期 callback。請透過 execute_command Tool 的 backgroundProcesses 選項配置這些 callback:
import { Workspace, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'
const workspace = new Workspace({
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
tools: {
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
backgroundProcesses: {
onStdout: (data, { pid }) => console.log(`[${pid}] ${data}`),
onStderr: (data, { pid }) => console.error(`[${pid}] ${data}`),
onExit: ({ pid, exitCode }) => console.log(`Process ${pid} exited: ${exitCode}`),
},
},
},
})
這些 callback 會針對 Agent 透過 execute_command Tool 啟動的所有背景程序觸發。
Abort signalAbort signal 的直接連結
背景程序預設會繼承 Agent 的 abort signal,並在 Agent 斷線時終止。你可以使用 abortSignal 選項控制此行為:
undefined(預設):使用 Agent 的 abort signalAbortSignal:使用自訂 signalnull或false:停用 abort:程序會在 Agent 關閉後繼續運行
import { Workspace, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'
const workspace = new Workspace({
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
tools: {
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
backgroundProcesses: {
abortSignal: null, // Processes survive agent disconnection
},
},
},
})
對於程序應比 Agent 運行得更久的雲端 Sandbox(例如 E2B、Daytona 或 Modal),請使用 null 或 false。
如需完整的 SandboxProcessManager API(包括以編程方式啟動程序、讀取輸出,以及傳送 stdin),請參閱 SandboxProcessManager 參考資料。