본문으로 건너뛰기

모래 상자

추가된 항목: @mastra/core@1.1.0

샌드박스 공급자는 Agent에 셸 명령을 실행할 수 있는 기능을 제공합니다. 작업 영역에서 샌드박스를 구성하면 Agent는 작업의 일부로 명령을 실행할 수 있습니다.

샌드박스 공급자는 통제된 환경에서 명령을 실행합니다.

  • 명령 실행: 인수를 사용하여 셸 명령 실행
  • 백그라운드 프로세스: 개발 서버 및 감시자와 같은 장기 실행 프로세스 생성
  • 작업 디렉토리: 특정 디렉터리에서 실행되는 명령
  • 환경변수: 사용 가능한 변수를 제어합니다.
  • 시간 초과: 장기 실행 명령이 중단되는 것을 방지합니다.
  • 격리: 보안을 위한 선택적 OS 수준 샌드박싱

:::tip[📹 보기]

원격 Sandbox가 Agent에 작업할 수 있는 격리된 컴퓨터를 제공하는 방식을 알아보려면 Mastra 원격 Sandbox 개요를 참조하세요. :::

지원되는 Provider
지원되는 Provider에 대한 직접 링크

  • LocalSandbox: 로컬 머신에서 명령을 실행합니다.
  • AgentCoreRuntimeSandbox: AWS Bedrock AgentCore Runtime 세션에서 명령을 실행합니다.
  • AppleContainerSandbox: Apple의 OCI Linux 컨테이너에서 명령을 실행합니다.container CLI
  • BlaxelSandbox: 격리된 Blaxel 클라우드 샌드박스에서 명령을 실행합니다.
  • DaytonaSandbox: 격리된 Daytona 클라우드 샌드박스에서 명령을 실행합니다.
  • DockerSandbox: 로컬 시스템의 수명이 긴 Docker 컨테이너에서 명령을 실행합니다.
  • E2BSandbox: 격리된 E2B 클라우드 샌드박스에서 명령을 실행합니다.
  • ModalSandbox: 격리된 Modal 클라우드 샌드박스에서 명령을 실행합니다.
  • PlatformSandbox: Mastra Platform 환경에 연결된 샌드박스에서 명령을 실행합니다.
  • RailwaySandbox: 일시적이고 격리된 철도 클라우드 샌드박스에서 명령을 실행합니다.
  • VercelSandbox: 임시 Vercel Sandbox Firecracker MicroVM에서 명령을 실행합니다.
  • VercelServerlessSandbox: 상태 비저장 Vercel 서버리스 함수로 명령을 실행합니다.

기본 사용법
기본 사용법에 대한 직접 링크

샌드박스를 사용하여 작업 영역을 만들고 Agent에 할당합니다. 그러면 Agent는 셸 명령을 실행할 수 있습니다.

src/mastra/agents/dev-agent.ts
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')

환경 격리 및 네이티브 OS Sandbox를 비롯한 구성 옵션은 LocalSandbox 레퍼런스를 참조하세요.

동적 샌드박스
동적 샌드박스에 대한 직접 링크

sandbox 옵션에는 정적 인스턴스 대신 리졸버 함수를 사용할 수 있습니다. 리졸버는 requestContext를 받아 요청별 Sandbox를 반환하므로 하나의 Workspace에서 호출자의 ID, 역할 또는 테넌트에 따라 서로 다른 Sandbox를 제공할 수 있습니다.

src/mastra/workspaces.ts
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,
})

각 요청은 Tool 실행 시 자체 샌드박스를 확인합니다.

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 지침은 일관된 자리표시자 텍스트를 사용하여 런타임 Sandbox를 설명합니다. 구체적인 요청별 세부 정보를 포함하려면 Workspace 지침을 참조하세요. 예를 들어 데이터베이스에서 테넌트 구성을 조회하기 위해 확인자는 비동기식일 수도 있습니다.

const workspace = new Workspace({
sandbox: async ({ requestContext }) => {
const tenant = await db.getTenant(requestContext.get('tenant-id'))
return new LocalSandbox({ workingDirectory: tenant.workspacePath })
},
})

수명주기 소유권
수명주기 소유권에 대한 직접 링크

Sandbox가 정적 인스턴스이면 workspace.init()이 해당 인스턴스의 start() 메서드를 호출하고 workspace.destroy()destroy() 메서드를 호출합니다. 리졸버를 사용하면 생성 시점에 Workspace가 관리할 인스턴스가 없으므로 반환된 Sandbox의 수명 주기는 호출자가 소유합니다. 확인자는 이미 시작되었거나 명시적인 시작 없이 호출을 처리할 수 있는, 사용할 준비가 된 샌드박스를 반환해야 합니다. 또한 호출자는 반환된 샌드박스에 대한 정리 타이밍을 소유합니다.

요청, 테넌트 또는 사용자별로 정리가 발생할 수 있습니다. 또한 수명이 긴 샌드박스 풀의 일부일 수도 있습니다.workspace.destroy() doesn't destroy resolver-returned sandboxes.

노트

sandbox 리졸버는 mountslsp: true와 호환되지 않습니다. 둘 다 생성 시점에 구체적인 Sandbox 인스턴스가 필요하므로 리졸버와 함께 사용하면 INVALID_CONFIG 오류가 발생하거나(mounts의 경우) 경고와 함께 LSP가 비활성화됩니다(lsp: true의 경우).

Tool 등록
Tool 등록에 대한 직접 링크

정적 Sandbox를 사용하면 Workspace가 인스턴스를 검사하여 등록할 Tool을 결정합니다. 리졸버를 사용하면 Workspace는 모든 기능을 지원한다고 간주하여 execute_command(background 지원), get_process_output, kill_process를 등록합니다. 해석된 Sandbox가 특정 기능을 구현하지 않았다면 런타임에 명확한 SandboxFeatureNotSupportedError가 발생합니다.

백그라운드 프로세스 연속성
백그라운드 프로세스 연속성에 대한 직접 링크

백그라운드 프로세스는 단일 Tool 호출보다 오래 실행될 수 있으므로 get_process_outputkill_process는 프로세스를 시작한 동일한 Sandbox에 접근해야 합니다. 기본적으로 해석된 Sandbox는 요청별로 캐시됩니다. 이후 대화 차례와 같은 후속 요청에서도 연속성을 유지하려면 sandboxCacheKey를 일관된 식별자로 설정하세요. 그러면 해석된 Sandbox가 요청 대신 해당 키를 기준으로 캐시됩니다.

const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
sandboxCacheKey: ({ requestContext }) => requestContext.get('thread-id') as string,
})

sandboxCacheKey를 사용하지 않으면 테넌트, 사용자 또는 세션이 같은 후속 호출에 리졸버가 동일한 Sandbox를 직접 반환해야 합니다. 캐시된 Sandbox가 더 이상 필요하지 않으면 자체 수명 주기 코드에서 Sandbox를 제거하고 workspace.clearSandboxCache(cacheKey)를 호출하여 Workspace 캐시 항목을 삭제하세요. 키가 지정된 모든 Sandbox 항목을 지우려면 workspace.clearSandboxCache()를 호출하세요.

작업공간 지침
작업공간 지침에 대한 직접 링크

작업 공간 지침은 Agent 시스템 메시지의 환경을 설명합니다. 샌드박스 해석기를 사용하면 작업공간은 이러한 지침을 작성하기 위해 해석기를 호출하지 않습니다. 안정적인 자리 표시자 텍스트를 내보내므로 Prompt를 구성할 때 호출자가 소유한 샌드박스를 프로비저닝하지 않으며 시스템 메시지가 요청 전체에서 일관되게 유지되므로 Prompt 캐싱이 효과적으로 유지됩니다.

구체적인 요청별 Sandbox 세부 정보를 포함하려면 instructions.dynamicSandbox'resolve'로 설정하세요.

const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
instructions: { dynamicSandbox: 'resolve' },
})

'resolve'는 모든 요청에서 리졸버를 호출하므로 Sandbox를 프로비저닝하고 요청별 시스템 메시지를 구성할 수 있습니다. Sandbox를 해석하지 않고 requestContext를 기반으로 사용자 정의 텍스트를 반환하려면 함수를 대신 전달하세요.

const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
instructions: {
dynamicSandbox: ({ requestContext }) =>
`Sandbox scoped to tenant ${requestContext.get('tenant-id')}.`,
},
})

Agent Tool
Agent Tool에 대한 직접 링크

Workspace에서 Sandbox를 구성하면 Agent에 셸 명령을 실행하는 execute_command Tool이 제공됩니다. Sandbox Provider가 백그라운드 프로세스 실행을 지원하는 경우 execute_command Tool에서 장기 실행 프로세스를 시작하기 위한 background: true도 사용할 수 있으며, 다음 두 가지 Tool이 추가로 등록됩니다.

Tool설명
execute_command셸 명령을 실행합니다. stdout, stderr 및 종료 코드를 반환합니다. background: true를 지원하므로 장기 실행 프로세스를 생성하고 PID를 반환할 수 있습니다.
get_process_outputPID를 사용하여 백그라운드 프로세스의 stdout, stderr 및 상태를 가져옵니다. 출력 줄 수를 제한하는 tail과 종료될 때까지 차단하는 wait: true를 지원합니다.
kill_processPID를 사용하여 백그라운드 프로세스를 중지합니다. 최근 출력을 반환합니다.
이러한 Tool은 자동으로 등록됩니다. 전체 Tool 이름 목록은 Workspace 클래스 레퍼런스를 참조하세요.

백그라운드 프로세스 콜백
백그라운드 프로세스 콜백에 대한 직접 링크

Agent가 execute_command Tool을 통해 백그라운드 프로세스를 시작하면 stdout, stderr 및 프로세스 종료에 대한 수명 주기 콜백을 받을 수 있습니다. execute_command Tool의 backgroundProcesses 옵션을 통해 이를 구성하세요.

src/mastra/workspaces.ts
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}`),
},
},
},
})

이러한 콜백은 Agent가 다음을 통해 시작한 모든 백그라운드 프로세스에 대해 실행됩니다.execute_command tool.

중단 신호
중단 신호에 대한 직접 링크

기본적으로 백그라운드 프로세스는 Agent의 중단 신호를 상속하며 Agent 연결이 끊어지면 종료됩니다. 다음을 사용하여 이 동작을 제어하세요.abortSignal option:

  • undefined(기본값): Agent의 중단 신호를 사용합니다.
  • AbortSignal: 맞춤 신호를 사용합니다.
  • null또는false: 중단을 비활성화합니다. Agent 종료 후에도 프로세스가 지속됩니다.
src/mastra/workspaces.ts
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 레퍼런스를 참조하세요. :::