샌드박스 클라이언트
이 페이지를 사용하여 샌드박스 작업을 실행할 위치를 선택합니다. 대부분의 경우 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.6-sol', 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.6-sol', 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.6-sol', instructions: 'Inspect the repository before answering.',});
await run(agent, 'Inspect the repo.', { sandbox: { client: new UnixLocalSandboxClient(), concurrencyLimits: { manifestEntries: 4, localDirFiles: 16, }, },});manifestEntries는 병렬로 처리되는 최상위 항목 작업을 제한합니다. localDirFiles는 localDir() 항목 내부의 파일 복사 동시성을 제한합니다.
파일 시스템 존재 여부 확인
섹션 제목: “파일 시스템 존재 여부 확인”세션이 pathExists()를 구현한 경우 false는 백엔드에서 해당 경로가 없음을 확인했다는 의미입니다. 권한 오류, I/O 실패 및 제공업체 검사 실패는 경로가 없는 것으로 처리되지 않고 제공업체 오류와 함께 거부됩니다. 이를 통해 존재할 수 있지만 접근할 수 없는 경로를 편집기, 매니페스트 및 메모리 흐름에서 덮어쓰거나 대체하지 않도록 방지합니다.
마운트 및 원격 스토리지
섹션 제목: “마운트 및 원격 스토리지”마운트 항목은 노출할 스토리지를 설명하고, 마운트 전략은 샌드박스 백엔드가 해당 스토리지를 연결하는 방법을 설명합니다. 기본 제공 마운트 항목과 일반 전략은 @openai/agents/sandbox에서 가져옵니다.
일반적인 마운트 옵션은 다음과 같습니다.
mountPath: 샌드박스에서 스토리지가 표시되는 위치. 상대 경로는 매니페스트 루트를 기준으로 해석되며 절대 경로는 그대로 사용됩니다.readOnly: 샌드박스에서 마운트된 스토리지에 다시 쓰지 않아야 하는 경우 설정합니다.mountStrategy: 마운트 항목과 샌드박스 백엔드 모두에 맞는 전략을 사용합니다.
마운트는 임시 워크스페이스 항목으로 처리됩니다. 스냅샷 및 지속성 흐름에서는 마운트된 원격 스토리지를 저장된 워크스페이스로 복사하지 않고 마운트된 경로를 분리하거나 건너뜁니다.
일반 로컬/컨테이너 전략은 다음과 같습니다.
| 전략 또는 패턴 | 사용할 상황 | 참고 |
|---|---|---|
inContainerMountStrategy(...) | 샌드박스 이미지에서 rclone, mount-s3 또는 blobfuse2 같은 마운트 명령을 실행할 수 있는 경우 | 일반 전략으로 사용할 수 있으며 지원 여부는 백엔드에 따라 다릅니다. |
dockerVolumeMountStrategy(...) | 컨테이너가 시작되기 전에 Docker가 볼륨 드라이버 기반 마운트를 연결해야 하는 경우 | Docker 전용 |
localBindMountStrategy() | 로컬 백엔드에서 절대 로컬 경로를 워크스페이스에 바인드해야 하는 경우 | 허용되는 경우 로컬 워크스페이스 구체화에서 지원됩니다. |
백엔드 지원 범위는 의도적으로 명시되어 있습니다.
| 백엔드 | 마운트 참고 사항 |
|---|---|
UnixLocalSandboxClient | 로컬 워크스페이스 모델을 통해 로컬 바인드 방식의 마운트를 지원합니다. |
DockerSandboxClient | Docker가 스토리지를 연결할 수 있는 경우 로컬 바인드 마운트와 Docker 볼륨 방식의 전략을 지원합니다. |
| 호스티드 제공업체 | 제공업체별 전략은 각 제공업체 구현에 포함되어 있습니다. 지원되는 마운트와 필요한 설정은 해당 제공업체의 문서를 확인하세요. |
하나의 마운트 항목이 모든 백엔드에서 작동한다고 가정하지 마세요. 클라이언트가 매니페스트 메타데이터, ID 또는 마운트 동작을 적용할 수 없다면 매니페스트의 해당 부분을 조용히 무시하지 말고 조기에 실패해야 합니다.
지원되는 호스티드 플랫폼
섹션 제목: “지원되는 호스티드 플랫폼”호스티드 환경이 필요한 경우 일반적으로 동일한 SandboxAgent 정의를 그대로 사용하고 sandbox 실행 옵션에서 샌드박스 클라이언트만 변경합니다.
호스티드 제공업체 구현은 @openai/agents-extensions 제공업체 하위 경로에서 사용할 수 있습니다. 정확한 환경 변수, 실행 가능한 예제, 포트 동작, PTY 지원, 스냅샷 동작 및 정리 동작은 제공업체 문서를 확인하세요.
@openai/agents-extensions를 설치하고 패키지 수준의 피어 종속성을 충족해야 합니다. 각 제공업체에서 제공업체 SDK 패키지 또는 백엔드 설정을 추가로 요구할 수도 있습니다.
| 클라이언트 | 가져오기 경로 | 제공업체 요구 사항 |
|---|---|---|
BlaxelSandboxClient | @openai/agents-extensions/sandbox/blaxel | npm 피어: @blaxel/core |
CloudflareSandboxClient | @openai/agents-extensions/sandbox/cloudflare | Cloudflare Sandbox 브리지 Worker URL 및 Worker 인증 |
DaytonaSandboxClient | @openai/agents-extensions/sandbox/daytona | npm 피어: @daytonaio/sdk |
E2BSandboxClient | @openai/agents-extensions/sandbox/e2b | npm 피어: e2b 또는 @e2b/code-interpreter |
ModalSandboxClient | @openai/agents-extensions/sandbox/modal | npm 피어: modal |
RunloopSandboxClient | @openai/agents-extensions/sandbox/runloop | npm 피어: @runloop/api-client |
VercelSandboxClient | @openai/agents-extensions/sandbox/vercel | npm 피어: @vercel/sandbox |
CloudflareSandboxClient는 Cloudflare npm SDK를 가져오지 않습니다. 대신 배포된 Cloudflare Sandbox 브리지 Worker와 HTTP를 통해 통신합니다.
VercelSandboxClient는 생성별 옵션, 생성자 옵션, 그리고 VERCEL_PROJECT_ID, VERCEL_TEAM_ID, VERCEL_TOKEN 순서의 우선순위로 각 PAT 자격 증명 필드를 결정합니다. 결정된 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 Drive도 지원합니다. |
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 | VercelCloudBucketMountStrategy를 사용하는 생성 시점 S3 마운트를 지원합니다. 인라인 자격 증명을 사용하려면 allowS3CredentialExposure: true가 필요합니다. 직렬화된 마운트 상태는 재개할 수 없으므로 마운트된 활성 세션을 재사용하세요. |
E2B 및 Runloop의 rclone 기반 마운트에서는 사용 가능한 경우 SDK가 기존 rclone 바이너리를 사용합니다. 그렇지 않으면 SHA-256 체크섬을 검증한 후에만 SDK에 고정된 버전의 Linux 아카이브를 설치합니다. 지원되지 않는 아키텍처와 체크섬 검증 실패가 발생하면 마운트를 중단합니다.
아래 표는 각 백엔드에서 직접 마운트할 수 있는 원격 스토리지 항목을 요약합니다.
| 백엔드 | 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 지원, 스냅샷 동작 및 정리 동작은 제공업체별 문서를 확인하세요.