샌드박스 클라이언트
이 페이지를 사용해 샌드박스 작업을 실행할 위치를 선택하세요. 대부분의 경우 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 볼륨 스타일 전략을 지원합니다. |
| 호스티드 제공자 | 제공자별 전략은 각 제공자 구현에 포함되어 있습니다. 지원되는 마운트와 필요한 설정은 해당 제공자의 문서를 확인하세요. |
마운트 항목이 모든 백엔드에서 동작한다고 가정하지 마세요. 클라이언트가 매니페스트 메타데이터, identity(식별 정보) 또는 마운트 동작을 적용할 수 없다면, 매니페스트의 해당 부분을 조용히 무시하는 대신 초기에 실패해야 합니다.
지원되는 호스티드 플랫폼
섹션 제목: “지원되는 호스티드 플랫폼”호스티드 환경이 필요한 경우 동일한 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 bridge 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 bridge Worker와 HTTP로 통신합니다.
VercelSandboxClient는 각 PAT 자격 증명 필드를 생성별 옵션, 생성자 옵션, 그리고 VERCEL_PROJECT_ID, VERCEL_TEAM_ID, VERCEL_TOKEN 순서의 우선순위로 확인합니다. 결과 projectId, teamId, token이 모두 비어 있지 않을 때만 자격 증명을 전달합니다. 그렇지 않으면 세 필드를 모두 생략하고 플랫폼 OIDC 또는 로컬 제공자 자격 증명을 포함해 @vercel/sandbox가 인증을 확인하도록 합니다. 세션이 직렬화되고 재개될 때 완전하게 확인된 자격 증명은 보존됩니다. 직렬화된 자격 증명은 완전한 세 값의 묶음으로 취급되며 현재 옵션이나 환경 변수와 혼합되지 않습니다. 불완전한 직렬화 자격 증명은 현재 구성을 대체 수단으로 확인하기 전에 폐기됩니다. 토큰은 직렬화된 세션 상태에 계속 남아 있으므로 해당 상태를 안전하게 저장하세요.
호스티드 샌드박스 클라이언트는 제공자별 마운트 전략을 노출합니다. 스토리지 제공자에 가장 적합한 백엔드와 마운트 전략을 선택하세요.
| 백엔드 | 마운트 참고 사항 |
|---|---|
| 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 지원, 스냅샷 동작, 정리 동작은 제공자별 문서를 확인하세요.