샌드박스 클라이언트
이 페이지를 사용해 샌드박스 작업을 어디에서 실행할지 선택하세요. 대부분의 경우 SandboxAgent 정의는 동일하게 유지되고, 샌드박스 클라이언트와 클라이언트별 옵션만 sandbox 실행 옵션에서 변경됩니다.
결정 가이드
섹션 제목: “결정 가이드”| 목표 | 시작점 | 이유 |
|---|---|---|
| macOS 또는 Linux에서 가장 빠른 로컬 반복 개발 | UnixLocalSandboxClient | 추가 서비스 의존성이 없고 간단한 로컬 파일 시스템 워크플로를 사용할 수 있습니다. |
| 기본 컨테이너 격리 | DockerSandboxClient | 특정 이미지로 Docker 내부에서 작업을 실행합니다. |
| 호스티드 실행 또는 프로덕션 스타일 격리 | 호스티드 샌드박스 클라이언트 | 워크스페이스 경계를 공급자 관리 환경으로 이동합니다. |
로컬 클라이언트
섹션 제목: “로컬 클라이언트”대부분의 사용자는 다음 두 샌드박스 클라이언트 중 하나로 시작합니다:
| 클라이언트 | 설치 | 선택 시점 |
|---|---|---|
UnixLocalSandboxClient | 없음 | macOS 또는 Linux에서 가장 빠른 로컬 반복 개발. 로컬 개발의 좋은 기본값입니다. |
DockerSandboxClient | 로컬에서 Docker CLI 사용 가능 | 컨테이너 격리 또는 로컬 일관성을 위한 특정 이미지가 필요할 때 |
Unix-local은 로컬 파일 시스템을 대상으로 개발을 시작하는 가장 쉬운 방법입니다. 더 강한 환경 격리나 프로덕션 스타일 일관성이 필요하면 Docker 또는 호스티드 공급자로 이동하세요.
Unix-local에서 Docker로 전환하려면 에이전트 정의는 그대로 유지하고 클라이언트만 변경하세요:
import { run } from '@openai/agents';import { SandboxAgent } from '@openai/agents/sandbox';import { DockerSandboxClient } from '@openai/agents/sandbox/local';
const agent = new SandboxAgent({ name: 'Workspace reviewer', model: 'gpt-5.5', instructions: 'Inspect the sandbox workspace before answering.',});
const result = await run(agent, 'Inspect the workspace.', { sandbox: { client: new DockerSandboxClient({ image: 'node:22-bookworm-slim' }), },});
console.log(result.finalOutput);동일한 에이전트는 일반적으로 어느 로컬 클라이언트로도 실행할 수 있습니다:
import { DockerSandboxClient, UnixLocalSandboxClient,} from '@openai/agents/sandbox/local';
const client = process.env.USE_DOCKER ? new DockerSandboxClient({ image: 'node:22-bookworm-slim' }) : new UnixLocalSandboxClient();세션 소유권
섹션 제목: “세션 소유권”수명 주기 스타일은 두 가지입니다.
| 스타일 | 전달하는 것 | 세션을 닫는 주체 | 사용 시점 |
|---|---|---|---|
| SDK 소유 | sandbox: { client } | 러너 | 샌드박스가 한 번의 실행 동안만 유지되면 될 때 |
| 개발자 소유 | sandbox: { session } | 개발자 코드 | 나중에 파일을 검사하거나, 동일한 라이브 세션을 재사용하거나, 여러 실행을 조율해야 할 때 |
세션을 직접 만들었다면 직접 닫으세요:
import { run } from '@openai/agents';import { Manifest, SandboxAgent } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();const agent = new SandboxAgent({ name: 'Workspace reviewer', model: 'gpt-5.5', instructions: 'Inspect the sandbox workspace before answering.',});
const client = new UnixLocalSandboxClient();const session = await client.create({ manifest });
try { await run(agent, 'First pass.', { sandbox: { session } }); await run(agent, 'Follow-up pass.', { sandbox: { session } });} finally { await session.close?.();}재개 및 스냅샷
섹션 제목: “재개 및 스냅샷”샌드박스 상태와 대화 상태는 별개입니다:
- SDK 대화 상태는
result.history, SDKSession,conversationId또는previousResponseId에 있습니다. - 샌드박스 상태는 라이브 샌드박스 세션, 직렬화된
sessionState,RunState샌드박스 페이로드 또는 스냅샷에 있습니다.
sessionState는 샌드박스 클라이언트를 통해 동일한 백엔드 세션에 다시 연결하려는 경우 사용하세요. 저장된 워크스페이스 콘텐츠로 초기화된 새 세션이 필요하면 스냅샷을 사용하세요.
import { Manifest } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const manifest = new Manifest();const client = new UnixLocalSandboxClient({ snapshot: { type: 'local', baseDir: '/tmp/my-sandbox-snapshots' },});
const session = await client.create({ manifest });const state = await client.serializeSessionState?.(session.state);await session.close?.();
if (state) { const restored = await client.resume?.( await client.deserializeSessionState!(state), ); await restored?.close?.();}RunState는 더 큰 워크플로를 일시 중지하거나 재개할 때 러너가 관리하는 샌드박스 상태도 보존할 수 있습니다. 샌드박스 수명 주기가 직렬화된 실행 외부에서 관리되는 경우 명시적인 sessionState를 사용하세요.
매니페스트 구체화
섹션 제목: “매니페스트 구체화”매니페스트 항목은 에이전트가 실행되기 전에 준비됩니다. 실행별 또는 클라이언트 생성 호출별로 구체화 동시성을 조정할 수 있습니다:
import { run } from '@openai/agents';import { SandboxAgent } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } from '@openai/agents/sandbox/local';
const agent = new SandboxAgent({ name: 'Repository inspector', model: 'gpt-5.5', instructions: 'Inspect the repository before answering.',});
await run(agent, 'Inspect the repo.', { sandbox: { client: new UnixLocalSandboxClient(), concurrencyLimits: { manifestEntries: 4, localDirFiles: 16, }, },});manifestEntries는 최상위 항목 작업의 병렬성을 제한합니다. localDirFiles는 localDir() 항목 내부의 파일 복사 동시성을 제한합니다.
마운트 및 원격 스토리지
섹션 제목: “마운트 및 원격 스토리지”마운트 항목은 노출할 스토리지를 설명하고, 마운트 전략은 샌드박스 백엔드가 해당 스토리지를 연결하는 방식을 설명합니다. 기본 제공 마운트 항목과 일반 전략은 @openai/agents/sandbox에서 가져오세요.
일반적인 마운트 옵션:
mountPath: 샌드박스에서 스토리지가 나타나는 위치입니다. 상대 경로는 매니페스트 루트 아래에서 해석되고, 절대 경로는 그대로 사용됩니다.readOnly: 샌드박스가 마운트된 스토리지에 다시 쓰면 안 될 때 설정합니다.mountStrategy: 마운트 항목과 샌드박스 백엔드 모두에 맞는 전략을 사용합니다.
마운트는 임시 워크스페이스 항목으로 처리됩니다. 스냅샷 및 지속성 흐름은 마운트된 원격 스토리지를 저장된 워크스페이스로 복사하는 대신 마운트된 경로를 분리하거나 건너뜁니다.
일반 로컬/컨테이너 전략:
| 전략 또는 패턴 | 사용 시점 | 참고 |
|---|---|---|
inContainerMountStrategy(...) | 샌드박스 이미지가 rclone, mount-s3 또는 blobfuse2와 같은 마운트 명령을 실행할 수 있을 때 | 일반 전략으로 사용할 수 있으며, 지원 여부는 백엔드에 따라 다릅니다. |
dockerVolumeMountStrategy(...) | 컨테이너가 시작되기 전에 Docker가 볼륨 드라이버 기반 마운트를 연결해야 할 때 | Docker 전용입니다. |
localBindMountStrategy() | 로컬 백엔드가 절대 로컬 경로를 워크스페이스에 바인드해야 할 때 | 허용되는 경우 로컬 워크스페이스 구체화에서 지원됩니다. |
백엔드 지원은 의도적으로 명시적입니다:
| 백엔드 | 마운트 참고 사항 |
|---|---|
UnixLocalSandboxClient | 로컬 워크스페이스 모델을 통해 로컬 바인드 스타일 마운트를 지원합니다. |
DockerSandboxClient | Docker가 스토리지를 연결할 수 있는 경우 로컬 바인드 마운트와 Docker 볼륨 스타일 전략을 지원합니다. |
| 호스티드 공급자 | 공급자별 전략은 각 공급자 구현에 포함되어 있습니다. 지원되는 마운트와 필요한 설정은 해당 공급자 문서를 확인하세요. |
마운트 항목이 모든 백엔드에서 작동한다고 가정하지 마세요. 클라이언트가 매니페스트 메타데이터, 아이덴티티 또는 마운트 동작을 강제할 수 없다면 매니페스트의 해당 부분을 조용히 무시하지 않고 조기에 실패해야 합니다.
지원되는 호스티드 플랫폼
섹션 제목: “지원되는 호스티드 플랫폼”호스티드 환경이 필요할 때도 일반적으로 동일한 SandboxAgent 정의를 그대로 사용할 수 있으며, sandbox 실행 옵션의 샌드박스 클라이언트만 변경됩니다.
호스티드 공급자 구현은 @openai/agents-extensions 공급자 하위 경로에서 사용할 수 있습니다. 정확한 환경 변수, 실행 가능한 코드 예제, 포트 동작, PTY 지원, 스냅샷 동작 및 정리 동작은 공급자 문서를 확인하세요.
@openai/agents-extensions를 설치하고 패키지 수준의 peer 요구 사항을 충족하세요. 각 공급자는 공급자 SDK 패키지 또는 백엔드 설정도 필요할 수 있습니다:
| 클라이언트 | 가져오기 경로 | 공급자 요구 사항 |
|---|---|---|
BlaxelSandboxClient | @openai/agents-extensions/sandbox/blaxel | npm peer: @blaxel/core |
CloudflareSandboxClient | @openai/agents-extensions/sandbox/cloudflare | Cloudflare Sandbox 브리지 Worker URL 및 Worker 인증 |
DaytonaSandboxClient | @openai/agents-extensions/sandbox/daytona | npm peer: @daytonaio/sdk |
E2BSandboxClient | @openai/agents-extensions/sandbox/e2b | npm peer: e2b 또는 @e2b/code-interpreter |
ModalSandboxClient | @openai/agents-extensions/sandbox/modal | npm peer: modal |
RunloopSandboxClient | @openai/agents-extensions/sandbox/runloop | npm peer: @runloop/api-client |
VercelSandboxClient | @openai/agents-extensions/sandbox/vercel | npm peer: @vercel/sandbox |
CloudflareSandboxClient는 Cloudflare npm SDK를 가져오지 않습니다. 대신 배포된 Cloudflare Sandbox 브리지 Worker와 HTTP로 통신합니다.
호스티드 샌드박스 클라이언트는 공급자별 마운트 전략을 노출합니다. 스토리지 공급자에 가장 적합한 백엔드와 마운트 전략을 선택하세요:
| 백엔드 | 마운트 참고 사항 |
|---|---|
| Docker | 로컬 전략인 inContainerMountStrategy() 및 dockerVolumeMountStrategy()와 함께 s3Mount(), gcsMount(), r2Mount(), azureBlobMount(), boxMount(), s3FilesMount()를 지원합니다. |
ModalSandboxClient | S3, R2 및 HMAC 인증 GCS 마운트 항목에서 ModalCloudBucketMountStrategy로 클라우드 버킷 마운트를 지원합니다. |
CloudflareSandboxClient | S3, R2 및 HMAC 인증 GCS 마운트 항목에서 CloudflareBucketMountStrategy로 Cloudflare 버킷 마운트를 지원합니다. |
BlaxelSandboxClient | S3, R2 및 GCS 마운트 항목에서 BlaxelCloudBucketMountStrategy로 클라우드 버킷 마운트를 지원합니다. 또한 BlaxelDriveMount 및 BlaxelDriveMountStrategy를 사용한 영구 Blaxel Drives를 지원합니다. |
DaytonaSandboxClient | S3, GCS, R2, Azure Blob 및 Box 마운트 항목에서 DaytonaCloudBucketMountStrategy로 rclone 기반 마운트를 지원합니다. |
E2BSandboxClient | S3, GCS, R2, Azure Blob 및 Box 마운트 항목에서 E2BCloudBucketMountStrategy로 rclone 기반 마운트를 지원합니다. |
RunloopSandboxClient | S3, GCS, R2, Azure Blob 및 Box 마운트 항목에서 RunloopCloudBucketMountStrategy로 rclone 기반 마운트를 지원합니다. |
VercelSandboxClient | 현재 호스티드 전용 마운트 전략은 노출되어 있지 않습니다. 대신 매니페스트 파일, 리포지토리, 스냅샷 또는 기타 워크스페이스 입력을 사용하세요. |
아래 표는 각 백엔드가 직접 마운트할 수 있는 원격 스토리지 항목을 요약합니다:
| 백엔드 | AWS S3 | Cloudflare R2 | GCS | Azure Blob Storage | Box | S3 Files |
|---|---|---|---|---|---|---|
| Docker | 예 | 예 | 예 | 예 | 예 | 예 |
ModalSandboxClient | 예 | 예 | 예 | 아니요 | 아니요 | 아니요 |
CloudflareSandboxClient | 예 | 예 | 예 | 아니요 | 아니요 | 아니요 |
BlaxelSandboxClient | 예 | 예 | 예 | 아니요 | 아니요 | 아니요 |
DaytonaSandboxClient | 예 | 예 | 예 | 예 | 예 | 아니요 |
E2BSandboxClient | 예 | 예 | 예 | 예 | 예 | 아니요 |
RunloopSandboxClient | 예 | 예 | 예 | 예 | 예 | 아니요 |
VercelSandboxClient | 아니요 | 아니요 | 아니요 | 아니요 | 아니요 | 아니요 |
노출된 포트
섹션 제목: “노출된 포트”백엔드가 지원하는 경우 샌드박스 클라이언트는 resolveExposedPort(port)를 통해 엔드포인트를 노출할 수 있습니다.
| 클라이언트 | 동작 |
|---|---|
UnixLocalSandboxClient | 구성된 포트를 127.0.0.1로 확인합니다. |
DockerSandboxClient | 구성된 컨테이너 포트를 게시하고 해당 호스트 엔드포인트를 확인합니다. |
백엔드가 허용 목록을 강제해야 하는 경우 클라이언트 옵션에서 포트를 선언하세요:
import { DockerSandboxClient } from '@openai/agents/sandbox/local';
const client = new DockerSandboxClient({ image: 'node:22-bookworm-slim', exposedPorts: [3000],});기능 지원 매트릭스
섹션 제목: “기능 지원 매트릭스”| 기능 | Unix-local | Docker |
|---|---|---|
exec_command | 지원됨 | 지원됨 |
PTY write_stdin | 지원됨 | 지원됨 |
apply_patch | 지원됨 | 워크스페이스 파일 API를 통해 지원됨 |
view_image | 지원됨 | 워크스페이스 파일 API를 통해 지원됨 |
명령용 runAs | 호스트가 사용자를 확인하고 해당 사용자로 전환할 수 있을 때 지원됨 | 컨테이너/사용자 설정에 따라 제한됨 |
| 로컬 스냅샷 | 지원됨 | 지원됨 |
| 로컬/Docker 마운트 | 로컬 바인드 스타일 지원 | 바인드 및 Docker 볼륨 스타일 지원 |
로컬 PTY 지원은 SDK 프로세스의 작은 Python 3 브리지를 사용합니다. 이 브리지는 tty: true 세션에만 사용됩니다. 이 경우 Node.js가 기본 제공 PTY API를 제공하지 않으며, SDK에는 대화형 stdin, 신호 처리 및 종료 상태 보고를 위한 표준 POSIX PTY 동작이 필요합니다. SDK 코드를 실행하는 환경에 python3를 설치하거나, OPENAI_AGENTS_PYTHON을 Python 3 실행 파일로 설정하세요. 이는 Docker 샌드박스 이미지 내부에 설치된 Python 버전이 있는 경우에도 그 버전과는 별개입니다.
호스티드 공급자 지원은 공급자마다 다릅니다. 정확한 옵션, 환경 변수, 포트 동작, PTY 지원, 스냅샷 동작 및 정리 동작은 공급자별 문서를 확인하세요.