개념
최신 에이전트는 파일 시스템의 실제 파일을 다룰 수 있을 때 가장 효과적으로 작동합니다. 샌드박스 에이전트는 특화된 도구와 셸 명령을 사용해 대규모 문서 모음을 검색하고 조작하며, 파일을 편집하고, 결과물을 생성하고, 명령을 실행할 수 있습니다. 샌드박스는 에이전트가 사용자를 대신해 작업할 수 있도록 모델에 지속적인 워크스페이스를 제공합니다. Agents SDK의 샌드박스 에이전트를 사용하면 샌드박스 환경과 연결된 에이전트를 실행할 수 있습니다. 이를 통해 필요한 파일을 파일 시스템에 쉽게 배치하고, 샌드박스를 오케스트레이션하여 대규모로 작업을 시작, 중지, 재개할 수 있습니다.
에이전트에 필요한 데이터를 중심으로 워크스페이스를 정의합니다. 새 워크스페이스는 GitHub 저장소, 로컬 파일과 디렉터리, 작업용으로 생성한 파일, S3나 Azure Blob Storage 같은 원격 파일 시스템, 그 밖에 제공하는 샌드박스 입력으로 채울 수 있습니다.

SandboxAgent는 Agent를 확장하므로 여전히 Agent입니다. instructions, tools, handoffs, mcpServers, modelSettings, 출력 타입, 가드레일, 훅 등 일반적인 에이전트 인터페이스를 유지하며, 기존 run() 및 Runner API를 통해 실행됩니다. 달라지는 것은 실행 경계입니다.
SandboxAgent는 에이전트 자체를 정의합니다. 일반적인 에이전트 설정에 더해defaultManifest,baseInstructions,runAs같은 샌드박스 전용 기본값과 파일 시스템 도구, 셸 액세스, 스킬, 메모리, 압축 등의 기능을 포함합니다.Manifest는 파일, 저장소, 마운트, 환경을 포함하여 새 샌드박스 워크스페이스의 초기 콘텐츠와 구조를 선언합니다.- 샌드박스 세션은 명령이 실행되고 파일이 변경되는 실행 환경입니다.
sandbox실행 옵션은 실행에 사용할 샌드박스 세션을 확보하는 방법을 결정합니다. 예를 들어 세션을 직접 주입하거나, 직렬화된 샌드박스 세션 상태에서 다시 연결하거나, 샌드박스 클라이언트를 통해 새 샌드박스 세션을 생성할 수 있습니다.- 저장된 샌드박스 상태와 스냅샷을 사용하면 후속 실행에서 이전 작업에 다시 연결하거나 저장된 콘텐츠로 새 샌드박스 세션을 초기화할 수 있습니다.
Manifest는 새 샌드박스 워크스페이스의 초기 콘텐츠를 정의합니다. 재사용된 세션, 직렬화된 세션 상태, 스냅샷 모두 실행 시점에 워크스페이스를 제공하거나 변경할 수 있으므로, 모든 실행 중인 샌드박스의 현재 파일을 나타내지는 않습니다.
이 페이지에서 “샌드박스 세션”은 샌드박스 클라이언트가 관리하는 실행 환경을 의미합니다. 정확한 경계는 클라이언트와 설정에 따라 달라집니다. Unix-local 세션은 macOS나 Linux에서 OS 수준의 격리를 추가하지 않고 호스트 프로세스를 실행하는 반면, Docker와 호스티드 클라이언트는 컨테이너 또는 제공업체가 관리하는 실행 환경을 사용합니다. 이는 세션에서 설명하는 SDK의 대화형 Session 인터페이스와는 다릅니다.
외부 런타임은 여전히 승인, 트레이싱, 핸드오프, 재개에 필요한 상태 관리를 담당합니다. 샌드박스 세션은 명령과 파일 변경을 관리합니다. 실행 환경이 제공하는 격리 수준은 백엔드와 설정에 따라 결정됩니다.
구성 요소의 연동 방식
섹션 제목: “구성 요소의 연동 방식”샌드박스 실행은 에이전트 정의와 실행별 샌드박스 설정을 결합합니다. 러너는 에이전트를 준비하고 실행 중인 샌드박스 세션에 연결하며, 후속 실행을 위해 상태를 저장할 수 있습니다.
샌드박스 전용 기본값은 SandboxAgent에 둡니다. 실행별 샌드박스 세션 선택 사항은 sandbox 실행 옵션에 둡니다.
수명 주기는 다음 세 단계로 나눌 수 있습니다.
SandboxAgent,Manifest, 기능을 사용해 에이전트와 워크스페이스 초기 콘텐츠를 정의합니다.- 샌드박스 세션을 주입, 재개 또는 생성하는
sandbox실행 옵션을run()이나Runner에 전달하여 실행합니다. - 나중에 러너가 관리하는
RunState, 명시적인 샌드박스sessionState, 저장된 워크스페이스 스냅샷에서 작업을 이어갑니다.
셸 액세스가 가끔 사용하는 도구 중 하나에 불과하다면 도구의 호스티드 셸부터 시작하세요. 워크스페이스 관리, 샌드박스 클라이언트 선택, 샌드박스 세션 재개 동작이 설계의 일부라면 샌드박스 에이전트를 사용하세요.
사용 시점
섹션 제목: “사용 시점”샌드박스 에이전트는 다음과 같은 워크스페이스 중심 워크플로에 적합합니다.
- 코딩 및 디버깅: GitHub 저장소에 보고된 이슈의 자동 수정을 오케스트레이션하고 관련 테스트를 실행합니다.
- 문서 처리 및 편집: 사용자의 금융 문서에서 정보를 추출하고 세금 신고 양식의 초안을 작성합니다.
- 파일 기반 검토 또는 분석: 답변하기 전에 온보딩 자료, 생성된 보고서, 결과물 묶음을 확인합니다.
- 격리된 멀티 에이전트 패턴: 각 검토 또는 코딩 하위 에이전트에 자체 워크스페이스를 제공합니다.
- 다단계 워크스페이스 작업: 한 실행에서 버그를 수정하고 나중에 회귀 테스트를 추가하거나, 스냅샷 또는 샌드박스 세션 상태에서 재개합니다.
파일이나 지속적으로 유지되는 파일 시스템에 접근할 필요가 없다면 계속 Agent를 사용하세요. 셸 액세스가 가끔 필요한 기능 중 하나에 불과하다면 호스티드 셸을 추가하세요. 워크스페이스 경계 자체가 기능의 일부라면 샌드박스 에이전트를 사용하세요.
샌드박스 클라이언트 선택
섹션 제목: “샌드박스 클라이언트 선택”macOS나 Linux에서 신뢰할 수 있는 로컬 개발을 하거나 외부에서 격리된 환경을 사용하는 경우 UnixLocalSandboxClient를 사용하세요. Unix-local 워크스페이스, 작업 디렉터리, HOME 환경 변수는 OS 수준의 격리를 제공하지 않습니다. 신뢰할 수 없는 입력의 영향을 받은 명령을 포함하여 신뢰할 수 없는 명령에는 적절히 설정된 DockerSandboxClient나 호스티드 제공업체를 선택하거나, 외부 격리를 제공하세요. Windows에서는 Docker나 호스티드 제공업체를 사용하세요. Unix-local 실행 제한을 참고하세요.
대부분의 경우 SandboxAgent 정의는 그대로 유지하고 sandbox 실행 옵션에서 샌드박스 클라이언트와 그 옵션만 변경합니다. 로컬, Docker, 호스티드, 원격 마운트 옵션은 샌드박스 클라이언트를 참고하세요.
핵심 구성 요소
섹션 제목: “핵심 구성 요소”| 계층 | 주요 SDK 구성 요소 | 다루는 질문 |
|---|---|---|
| 에이전트 정의 | SandboxAgent, Manifest, 기능 | 어떤 에이전트를 실행하며, 새 세션은 어떤 워크스페이스 규약에 따라 시작해야 하나요? |
| 샌드박스 실행 | sandbox 실행 옵션, 샌드박스 클라이언트, 실행 중인 샌드박스 세션 | 이 실행은 실행 중인 샌드박스 세션을 어떻게 확보하며, 작업은 어디에서 실행되나요? |
| 저장된 샌드박스 상태 | RunState 샌드박스 페이로드, sessionState, 스냅샷 | 이 워크플로는 이전 샌드박스 작업에 어떻게 다시 연결하거나 저장된 콘텐츠로 새 샌드박스 세션을 어떻게 초기화하나요? |
주요 SDK 구성 요소는 다음과 같이 각 계층에 대응합니다.
| 구성 요소 | 담당 영역 | 고려할 질문 |
|---|---|---|
SandboxAgent | 에이전트 정의 | 이 에이전트는 무엇을 해야 하며, 어떤 기본값을 함께 유지해야 하나요? |
Manifest | 새 세션의 워크스페이스 파일과 폴더 | 실행이 시작될 때 파일 시스템에 어떤 파일과 폴더가 있어야 하나요? |
Capability | 샌드박스 네이티브 동작 | 이 에이전트에 어떤 도구, 지침 조각, 런타임 동작을 연결해야 하나요? |
sandbox 실행 옵션 | 실행별 샌드박스 클라이언트 및 샌드박스 세션 소스 | 이 실행은 샌드박스 세션을 주입, 재개 또는 생성해야 하나요? |
RunState | 러너가 관리하는 저장된 샌드박스 상태 | 이전에 러너가 관리하던 워크플로를 재개하면서 샌드박스 상태를 자동으로 이어받고 있나요? |
sandbox.sessionState | 명시적으로 직렬화된 샌드박스 세션 상태 | RunState 외부에서 이미 직렬화한 샌드박스 상태로부터 재개하려고 하나요? |
sandbox.snapshot | 새 샌드박스 세션에 사용할 저장된 워크스페이스 콘텐츠 | 새 샌드박스 세션을 저장된 파일과 결과물로 시작해야 하나요? |
실용적인 설계 순서는 다음과 같습니다.
Manifest또는 매니페스트 초기화 객체로 새 세션의 워크스페이스 규약을 정의합니다.SandboxAgent로 에이전트를 정의합니다.- 내장 기능이나 사용자 정의 기능을 추가합니다.
run(agent, input, { sandbox: ... })또는new Runner({ sandbox: ... })에서 각 실행이 샌드박스 세션을 확보하는 방법을 결정합니다.
샌드박스 실행 준비 과정
섹션 제목: “샌드박스 실행 준비 과정”실행 시 러너는 이 정의를 샌드박스 기반의 구체적인 실행으로 변환합니다.
sandbox실행 옵션에서 샌드박스 세션을 결정합니다.- 실행에 실제로 적용할 워크스페이스 입력을 결정합니다.
- 기능이 그 결과로 생성된 매니페스트를 처리하도록 합니다.
- 고정된 순서로 최종 지침을 구성합니다. 먼저 SDK의 기본 샌드박스 프롬프트 또는 명시적으로 재정의한 경우
baseInstructions를 사용하고, 이어서instructions, 기능의 지침 조각, 원격 마운트 정책 텍스트, 렌더링된 파일 시스템 트리를 추가합니다. - 기능 도구를 실행 중인 샌드박스 세션에 연결하고, 준비된 에이전트를 기존
run()및RunnerAPI로 실행합니다.
샌드박스를 사용해도 턴의 의미는 바뀌지 않습니다. 턴은 여전히 모델의 한 단계이며, 단일 셸 명령이나 샌드박스 작업이 아닙니다. 샌드박스 측 작업과 턴 사이에는 고정된 1:1 관계가 없습니다. 실제로는 샌드박스 작업 후 에이전트 런타임에 모델 응답이 추가로 필요할 때만 턴을 하나 더 소비합니다.
SandboxAgent 옵션
섹션 제목: “SandboxAgent 옵션”일반적인 Agent 필드에 추가되는 샌드박스 전용 옵션은 다음과 같습니다.
| 옵션 | 주요 용도 |
|---|---|
defaultManifest | 러너가 생성하는 새 샌드박스 세션의 기본 워크스페이스 |
instructions | SDK 샌드박스 프롬프트 뒤에 추가할 역할, 워크플로, 성공 기준 |
baseInstructions | SDK 샌드박스 프롬프트를 대체하는 고급 재정의 옵션 |
capabilities | 이 에이전트와 함께 유지할 샌드박스 네이티브 도구 및 동작 |
runAs | 셸 명령, 파일 읽기, 패치처럼 모델이 사용하는 샌드박스 도구의 실행 사용자 |
샌드박스 클라이언트 선택, 샌드박스 세션 재사용, 매니페스트 재정의, 스냅샷 선택은 에이전트가 아닌 sandbox 실행 옵션에 둡니다.
defaultManifest
섹션 제목: “defaultManifest”defaultManifest는 러너가 이 에이전트에 대해 새 샌드박스 세션을 생성할 때 사용하는 기본 워크스페이스입니다. Manifest 인스턴스 또는 new Manifest(...)에 전달하는 것과 동일한 초기화 객체를 전달하세요. 에이전트가 일반적으로 시작할 때 필요한 파일, 저장소, 보조 자료, 출력 디렉터리, 마운트를 정의하는 데 사용합니다.
defaultManifest는 기본 워크스페이스만 제공합니다. 실행에서 sandbox.manifest로 defaultManifest를 재정의할 수 있으며, 재사용하거나 재개한 샌드박스 세션은 기존 워크스페이스 상태를 유지합니다.
import { file, gitRepo, Manifest } from '@openai/agents/sandbox';
const manifest = new Manifest({ root: '/workspace', entries: { 'task.md': file({ content: 'Fix the failing test and summarize the change.', }), repo: gitRepo({ repo: 'openai/openai-agents-js', ref: 'main', }), }, environment: { NODE_ENV: 'test', },});instructions와 baseInstructions
섹션 제목: “instructions와 baseInstructions”프롬프트가 달라져도 유지되어야 하는 간결한 규칙에는 instructions를 사용하세요. SandboxAgent에서는 이 지침이 SDK의 샌드박스 기본 프롬프트 뒤에 추가되므로, 내장 샌드박스 안내를 유지하면서 자체 역할, 워크플로, 성공 기준을 추가할 수 있습니다.
SDK 샌드박스 기본 프롬프트를 대체하려는 경우에만 baseInstructions를 사용하세요. 대부분의 에이전트에서는 설정하지 않는 것이 좋습니다.
| 설정 위치 | 용도 | 예시 |
|---|---|---|
instructions | 에이전트의 일관된 역할, 워크플로 규칙, 성공 기준 | ”온보딩 문서를 검토한 다음 핸드오프하세요.”, “최종 파일을 output/에 저장하세요.” |
baseInstructions | SDK 샌드박스 기본 프롬프트의 완전한 대체 | 사용자 정의 저수준 샌드박스 래퍼 프롬프트 |
| 사용자 프롬프트 | 이번 실행에 대한 일회성 요청 | ”이 워크스페이스를 요약하세요.” |
| 매니페스트의 워크스페이스 파일 | 긴 작업 명세, 저장소별 지침, 범위가 제한된 참조 자료 | repo/task.md, 문서 묶음, 샘플 자료 모음 |
사용자의 일회성 작업을 instructions에 복사하거나, 매니페스트에 두어야 할 긴 참조 자료를 포함하거나, 내장 기능이 이미 주입하는 도구 문서를 반복하거나, 실행 시 모델에 필요하지 않은 로컬 설치 메모를 섞지 마세요.
capabilities
섹션 제목: “capabilities”기능은 SandboxAgent에 샌드박스 네이티브 동작을 연결합니다. 실행 전에 워크스페이스를 구성하고, 샌드박스 전용 지침을 추가하고, 실행 중인 샌드박스 세션에 연결되는 도구를 노출하고, 해당 에이전트의 모델 동작이나 입력 처리를 조정할 수 있습니다.
내장 기능은 다음과 같습니다.
| 기능 | 추가 시점 | 참고 사항 |
|---|---|---|
shell() | 에이전트에 셸 액세스가 필요한 경우 | exec_command를 추가하고, 샌드박스 클라이언트가 PTY 상호작용을 지원하면 write_stdin도 추가합니다. |
filesystem() | 에이전트가 파일을 편집하거나 로컬 이미지를 확인해야 하는 경우 | apply_patch와 view_image를 추가합니다. 상대 경로는 기본적으로 워크스페이스 루트를 기준으로 하며, sandbox.cwd를 설정하면 해당 디렉터리를 기준으로 합니다. |
skills() | 샌드박스에서 스킬 탐색과 구체화가 필요한 경우 | 샌드박스 로컬의 SKILL.md 스킬에는 .agents나 .agents/skills를 수동으로 마운트하기보다 이 기능을 사용하세요. |
memory() | 후속 실행에서 메모리 결과물을 읽거나 생성해야 하는 경우 | shell()이 필요하며, 실행 중 업데이트에는 filesystem()도 필요합니다. |
compaction() | 장기 실행 흐름에서 압축 항목 이후 컨텍스트 정리가 필요한 경우 | 모델 샘플링과 입력 처리를 조정합니다. |
기본적으로 SandboxAgent.capabilities는 Capabilities.default()를 사용하며, 여기에는 filesystem(), shell(), compaction()이 포함됩니다. capabilities: [...]를 전달하면 이 목록이 기본값을 대체하므로, 계속 사용할 기본 기능도 포함해야 합니다.
view_image는 최대 10 MB의 PNG, JPEG, GIF, WebP, BMP, TIFF, SVG 이미지를 허용합니다. SDK는 래스터 파일 이름 확장자를 신뢰하는 대신 파일 시그니처로 래스터 형식을 감지하므로, 래스터 확장자만 붙인다고 지원하지 않는 바이트가 유효해지는 것은 아닙니다. SDK는 콘텐츠 또는 .svg나 .svgz 파일 이름으로 SVG를 인식합니다.
compaction()은 기본적으로 DynamicCompactionPolicy를 사용합니다. 인식된 모델의 경우, 이 정책은 렌더링된 컨텍스트가 해당 모델의 컨텍스트 윈도우의 90%에 도달하면 Responses API에 압축을 요청합니다. 모델이 없거나 알 수 없는 경우에는 대체 임계값으로 240,000토큰을 사용합니다. 다른 비율과 대체 임계값을 사용하려면 new DynamicCompactionPolicy(thresholdRatio, fallbackThreshold)에 전달하세요. 지원하는 모든 모델에 하나의 고정된 토큰 임계값을 적용하려면 new StaticCompactionPolicy(threshold)를 사용하세요. 동적 비율은 0부터 1 사이의 유한한 숫자여야 합니다.
서버 측 압축으로 압축 항목이 생성되면, 이 기능은 해당 항목과 이후 입력을 유지하고 이전에 다시 전달된 항목은 제거합니다. 압축 항목은 사람이 읽을 수 있는 요약이 아니라 내부를 해석할 수 없는 모델 상태이므로, 수정하지 않고 그대로 전달하세요. 이러한 제어는 Responses 압축을 지원하는 모델 전송 방식에만 적용됩니다.
매니페스트
섹션 제목: “매니페스트”Manifest는 새 샌드박스 세션의 워크스페이스를 설명합니다. 워크스페이스 root를 설정하고, 파일과 디렉터리를 선언하고, 로컬 파일을 복사하고, Git 저장소를 복제하고, 원격 스토리지 마운트를 연결하고, 환경 변수를 설정하고, 사용자나 그룹을 정의하고, 워크스페이스 외부의 특정 절대 경로에 대한 접근 권한을 부여할 수 있습니다.
매니페스트의 환경 값은 기본적으로 영구 저장됩니다. API 키, 액세스 토큰, 그 밖에 샌드박스 상태와 함께 저장하면 안 되는 단기 자격 증명에는 { value: "...", ephemeral: true } 같은 임시 항목을 사용하세요.
매니페스트를 구체화하거나 재개할 때 다시 조회해야 하는 비밀 정보에는 EnvValueReference를 상속하고 registerEnvValueReference()로 등록하세요. 참조는 비밀이 아닌 조회 메타데이터만 영구 저장하고, resolve()를 통해 현재 런타임 값을 가져옵니다. 각 하위 클래스는 자체적으로 안정적이고 비어 있지 않은 정적 type을 선언해야 하며, serialize()에는 예약된 value 필드를 포함하면 안 됩니다. 매니페스트를 재구성하기 전에 모든 프로세스에서 파서를 등록하고, 파서가 조회 키를 검증하여 허용 목록에 있는 키만 허용하도록 하세요. 영구 저장된 RunState 환경 참조를 재개하려면 해당 참조 항목이 포함된 현재의 신뢰할 수 있는 매니페스트가 필요합니다. 그렇지 않으면 SDK는 세션을 복원하기 전에 재개를 거부합니다.
매니페스트 항목 경로는 워크스페이스 기준 상대 경로입니다. 절대 경로이거나 ..로 워크스페이스를 벗어날 수 없으므로, 로컬, Docker, 호스티드 클라이언트 간에 워크스페이스 규약을 이식할 수 있습니다.
작업을 시작하기 전에 에이전트에 필요한 자료는 매니페스트 항목으로 정의하세요.
| 매니페스트 항목 | 용도 |
|---|---|
file(), dir() | 소규모로 생성한 입력, 보조 파일, 출력 디렉터리 |
localFile(), localDir() | 샌드박스에 구체화할 호스트 파일이나 디렉터리 |
gitRepo() | 워크스페이스로 가져올 저장소 |
s3Mount(), gcsMount(), r2Mount(), azureBlobMount(), s3FilesMount() 같은 마운트 | 샌드박스 내부에 표시할 외부 스토리지 |
로컬에서 구체화할 때 localFile()과 localDir()의 소스 경로는 로컬 소스 기준 디렉터리 내부에 있어야 합니다. 기본 기준 디렉터리는 Node 프로세스의 현재 작업 디렉터리이며, 로컬 샌드박스 클라이언트는 항목을 구체화할 때 클라이언트별 기준 디렉터리를 제공할 수 있습니다. 다른 호스트 절대 경로 디렉터리에서 소스를 가져와야 한다면, 필요한 최소 범위의 Manifest.extraPathGrants 항목을 추가하세요.
extraPathGrants는 로컬 지연 스킬 탐색에도 사용됩니다. 소스 기준 디렉터리 외부를 가리키는 localDirLazySkillSource()는 매니페스트에서 해당 디렉터리에 대한 권한을 부여하지 않으면 무시됩니다. 공유 스킬, 데이터셋, 참조 저장소 같은 입력 묶음에는 readOnly: true를 사용하는 것이 좋습니다.
각 경로 권한 항목에는 샌드박스 경로가 있으며, 필요한 경우 별도의 호스트 경로도 있습니다.
path는 샌드박스 내부에서 보이는 절대 POSIX 경로입니다.hostPath는 호스트와 샌드박스 경로가 다를 때 사용하는 선택적 호스트 네이티브 절대 경로입니다. Windows에서는 드라이브가 명시되어야 하며, UNC 경로와 장치 경로는 지원하지 않습니다.
UnixLocalSandboxClient에서는 호스트와 샌드박스 경로가 같아야 하므로 hostPath를 생략하세요. DockerSandboxClient는 컨테이너 생성에 사용하는 매니페스트에 해당 권한 항목이 있으면 별도의 hostPath를 지원합니다. 이미 실행 중인 컨테이너에서는 이 매핑을 추가하거나 변경할 수 없습니다. Docker 명령은 생성 시 권한이 부여된 샌드박스 경로를 workdir로 사용할 수 있습니다. 워크스페이스와 설정된 권한 범위 밖의 경로는 계속 거부됩니다.
Unix-local 세션에서 이러한 권한은 SDK를 통한 로컬 소스 접근과 SDK 파일 API가 접근하는 경로를 제어합니다. readOnly: true 권한은 SDK 파일 API가 해당 경로에 쓰는 것을 방지합니다. 이 권한은 macOS나 Linux의 임의 셸 명령을 제한하지 않습니다. 명령은 경로 권한이 부여되지 않은 경우에도 프로세스 권한과 외부 격리가 허용하는 호스트 경로에 접근할 수 있습니다.
import { Manifest, localDir, skills } from '@openai/agents/sandbox';import { localDirLazySkillSource } from '@openai/agents/sandbox/local';import { dirname, join } from 'node:path';import { fileURLToPath } from 'node:url';
const appRoot = dirname(fileURLToPath(import.meta.url));const repoDir = join(appRoot, 'repo');const sharedSkillsDir = '/opt/company/agent-skills';
const manifest = new Manifest({ extraPathGrants: [ { path: sharedSkillsDir, readOnly: true, description: 'Shared skill bundle.', }, ], entries: { repo: localDir({ src: repoDir }), },});
const skillCapability = skills({ lazyFrom: localDirLazySkillSource({ src: sharedSkillsDir, }),});마운트 항목은 노출할 스토리지를 설명하고, 마운트 전략은 샌드박스 백엔드가 해당 스토리지를 연결하는 방법을 설명합니다. 마운트 옵션과 제공업체 지원은 샌드박스 클라이언트를 참고하세요.
Permissions는 매니페스트 항목의 파일 시스템 권한을 제어합니다. 이는 샌드박스가 구체화하는 파일에 관한 것이며, 모델 권한, 승인 정책, API 자격 증명에 관한 것이 아닙니다.
사용자는 작업을 실행할 수 있는 샌드박스 내의 사용자 계정입니다. 해당 계정이 샌드박스에 존재하도록 하려면 매니페스트에 사용자를 추가하세요. 그런 다음 셸 명령, 파일 읽기, 패치처럼 모델이 사용하는 샌드박스 도구를 해당 사용자로 실행하려면 SandboxAgent.runAs를 설정하세요.
파일 수준의 공유 규칙도 필요하다면 사용자를 매니페스트 그룹 및 항목의 group 메타데이터와 함께 사용하세요. runAs 사용자는 샌드박스 네이티브 작업을 실행하는 주체를 제어하고, Permissions는 샌드박스가 워크스페이스를 구체화한 후 해당 사용자가 읽고, 쓰고, 실행할 수 있는 파일을 제어합니다.
SnapshotSpec
섹션 제목: “SnapshotSpec”SnapshotSpec은 새 샌드박스 세션에서 저장된 워크스페이스 콘텐츠를 어디에서 복원하고 어디에 다시 영구 저장할지 지정합니다. 이는 샌드박스 워크스페이스의 스냅샷 정책이며, sessionState는 특정 샌드박스 백엔드를 재개하기 위한 직렬화된 연결 상태입니다.
로컬에 지속적으로 보관할 스냅샷에는 로컬 스냅샷을 사용하고, 앱에서 원격 스냅샷 클라이언트를 제공하는 경우에는 원격 스냅샷을 사용하세요. 마운트된 경로와 임시 경로는 영구 워크스페이스 콘텐츠로 스냅샷에 복사되지 않습니다. 복원 중 SDK는 아카이브를 워크스페이스에 쓰기 전에 보호된 마운트 경로나 임시 경로와 겹치는 아카이브 항목을 거부합니다. 워크스페이스 루트 자체가 임시 경로인 경우에는 빈 아카이브만 복원할 수 있습니다.
샌드박스 수명 주기
섹션 제목: “샌드박스 수명 주기”수명 주기 모드는 SDK 소유와 개발자 소유의 두 가지입니다.
sandbox.client를 전달합니다.러너가 샌드박스 세션을 생성하거나 재개합니다.
에이전트가 실행되며, 스냅샷 기반 워크스페이스 상태를 영구 저장할 수 있습니다.
러너가 소유한 리소스를 닫습니다.
session을 생성합니다.실행에
sandbox.session을 전달합니다.에이전트가 기존 워크스페이스를 사용합니다.
세션을 검사하고 재사용한 다음 직접 닫습니다.
샌드박스가 한 번의 실행 동안만 유지되면 되는 경우 SDK 소유 수명 주기를 사용하세요. client, 선택적인 manifest, 선택적인 snapshot, 클라이언트 options를 전달하면 러너가 샌드박스를 생성하거나 재개하고, 에이전트를 실행하고, 스냅샷 기반 워크스페이스 상태를 영구 저장한 다음 클라이언트가 러너 소유 리소스를 정리하도록 합니다.
import { run } from '@openai/agents';import { SandboxAgent } from '@openai/agents/sandbox';import { UnixLocalSandboxClient } 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 UnixLocalSandboxClient(), },});
console.log(result.finalOutput);샌드박스를 미리 생성하거나, 실행 중인 하나의 샌드박스를 여러 실행에서 재사용하거나, 실행 후 파일을 검사하거나, 직접 생성한 샌드박스에서 스트리밍하거나, 정리 시점을 정확히 결정하려면 개발자 소유 수명 주기를 사용하세요. 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 task.', { sandbox: { session } }); await run(agent, 'Follow-up task.', { sandbox: { session } });} finally { await session.close?.();}샌드박스 작업 관측
섹션 제목: “샌드박스 작업 관측”샌드박스 작업 이벤트는 러너가 관리하는 샌드박스 작업에 대해 프로세스 전반의 관측 가능성을 제공합니다. addSandboxEventSink()로 SandboxEventSink를 등록하면 sandbox_operation 이벤트를 받을 수 있습니다. 각 작업은 start 단계를 내보낸 다음 end 또는 error를 내보냅니다. 종료 이벤트에는 소요 시간이 포함되며, 오류 이벤트에는 제공업체가 노출하는 경우 코드나 재시도 가능 여부 같은 정규화된 오류 세부 정보가 포함됩니다.
실행에서 sandbox.cwd를 설정하면 sandbox.exec 이벤트 데이터는 cwd를 기준으로 실제 적용되는 workdir를 보고하고, sandbox.view_image 이벤트 데이터는 cwd를 기준으로 실제 적용되는 path를 보고합니다. 이 값은 샌드박스 세션에 전달되는 경로와 일치합니다.
이벤트를 JSONL 한 줄당 하나씩 기록하려면 createSandboxJsonlEventSink()를, 각 이벤트를 HTTP POST로 전송하려면 createSandboxHttpEventSink()를, 여러 싱크로 분배하려면 createChainedSandboxEventSink()를 사용하세요. addSandboxEventSink()는 제거 함수를 반환합니다. 애플리케이션에서 해당 싱크가 더 이상 필요하지 않으면 이 함수를 호출하거나, clearSandboxEventSinks()로 등록된 모든 싱크를 제거하세요.
이벤트 싱크는 관측용입니다. SDK는 등록된 싱크의 처리가 성공하거나 실패할 때까지 기다리지만, 싱크 실패가 샌드박스 작업의 결과나 오류를 대체하지는 않습니다. 애플리케이션에 더 강력한 전달 보장이 필요하면 전달 재시도, 버퍼링, 싱크별 실패를 싱크 내부에서 처리하세요.
sandbox 실행 옵션
섹션 제목: “sandbox 실행 옵션”sandbox 실행 옵션에는 샌드박스 세션을 어디에서 가져올지, 새 세션을 어떻게 초기화할지 결정하는 실행별 옵션이 들어갑니다.
샌드박스 소스
섹션 제목: “샌드박스 소스”이 옵션은 러너가 샌드박스 세션을 재사용, 재개 또는 생성할지 결정합니다.
| 옵션 | 사용 시점 | 참고 사항 |
|---|---|---|
client | 러너가 샌드박스 세션을 대신 생성, 재개, 정리하도록 하려는 경우 | 실행 중인 샌드박스 session을 제공하지 않으면 필수입니다. |
session | 실행 중인 샌드박스 세션을 이미 직접 생성한 경우 | 호출자가 수명 주기를 소유하며, 러너는 실행 중인 해당 샌드박스 세션을 재사용합니다. |
sessionState | 직렬화된 샌드박스 세션 상태는 있지만 실행 중인 샌드박스 세션 객체는 없는 경우 | client가 필요합니다. 러너가 해당 명시적 상태에서 세션을 재개하고 수명 주기를 소유합니다. |
작업 디렉터리
섹션 제목: “작업 디렉터리”sandbox 실행 설정에 cwd를 지정하면 워크스페이스 기준 상대 경로의 디렉터리를 해당 실행의 작업 디렉터리로 사용할 수 있습니다. 내장 exec_command, view_image, apply_patch 도구는 이 디렉터리를 기준으로 상대 경로를 해석하며, 다른 샌드박스 도구는 자체 경로 규약을 유지합니다. 이 설정은 경로 해석 방식을 변경하지만, 실행을 세션 워크스페이스의 나머지 부분으로부터 격리하지는 않습니다.
값은 비어 있지 않은 워크스페이스 기준 상대 POSIX 경로여야 합니다. 절대 경로, 백슬래시, 상위 디렉터리(..) 세그먼트는 거부됩니다. 러너는 매 모델 턴 전에 해당 디렉터리가 존재하고 샌드박스 에이전트의 runAs 사용자가 접근할 수 있는지 확인합니다. cwd와 함께 사용하는 사용자 정의 또는 주입된 세션은 directoryExists()를 구현해야 합니다.
새 세션 입력
섹션 제목: “새 세션 입력”이 옵션은 러너가 새 샌드박스 세션을 생성할 때만 적용됩니다.
| 옵션 | 사용 시점 | 참고 사항 |
|---|---|---|
manifest | 새 세션의 워크스페이스를 일회성으로 재정의하려는 경우 | Manifest 또는 매니페스트 초기화 객체를 받습니다. 생략하면 agent.defaultManifest를 사용합니다. |
snapshot | 새 샌드박스 세션을 스냅샷으로 초기화해야 하는 경우 | 재개와 유사한 흐름이나 원격 스냅샷 클라이언트에 유용합니다. |
options | 샌드박스 클라이언트에 생성 시점 옵션이 필요한 경우 | Docker 이미지, 제공업체 타임아웃 등 클라이언트별 설정에 주로 사용합니다. |
concurrencyLimits는 샌드박스 구체화 작업을 얼마나 병렬로 실행할 수 있는지 제어합니다. 대규모 매니페스트나 로컬 디렉터리 복사에 더 엄격한 리소스 제어가 필요하면 manifestEntries와 localDirFiles를 사용하세요.
구체화 제어
섹션 제목: “구체화 제어”구체화 제어는 의도적으로 실행별로 설정하도록 설계되었습니다. sandbox 실행 옵션 가까이에 두면 동일한 SandboxAgent에서도 대규모 로컬 디렉터리 복사에는 보수적인 제한을, 작은 매니페스트에는 더 완화된 제한을 사용할 수 있습니다.
매니페스트에 파일, 디렉터리, 저장소, 마운트처럼 독립적인 항목이 많으면 concurrencyLimits.manifestEntries를 사용하세요. localDir() 항목에 파일이 많아 로컬 복사 부하를 제한해야 하면 concurrencyLimits.localDirFiles를 사용하세요.
아카이브 안전 제한
섹션 제목: “아카이브 안전 제한”워크스페이스 복원 및 재개 시 아카이브 입력 바이트 수, 압축 해제된 바이트 수, 항목 수를 제한하려면 archiveLimits를 사용하세요. 빈 객체를 전달하면 아카이브 입력 1 GiB, 압축 해제된 데이터 4 GiB, 항목 100,000개의 기본값이 활성화됩니다. 개별 필드를 null로 설정하면 해당 제한만 비활성화됩니다. archiveLimits를 생략하거나 옵션 전체를 null로 설정하면 아카이브 제한이 완전히 비활성화됩니다.
전체 예제: 코딩 작업
섹션 제목: “전체 예제: 코딩 작업”다음 코딩 예제는 기본 출발점으로 사용하기 좋습니다.
import { run } from '@openai/agents';import { Capabilities, Manifest, SandboxAgent, localDir, skills,} from '@openai/agents/sandbox';import { UnixLocalSandboxClient, localDirLazySkillSource,} from '@openai/agents/sandbox/local';import { dirname, join } from 'node:path';import { fileURLToPath } from 'node:url';
const exampleDir = dirname(fileURLToPath(import.meta.url));const hostRepoDir = join(exampleDir, 'repo');const hostSkillsDir = join(exampleDir, 'skills');
const manifest = new Manifest({ entries: { repo: localDir({ src: hostRepoDir }), },});
const agent = new SandboxAgent({ name: 'Sandbox engineer', model: 'gpt-5.6-sol', instructions: 'Read `repo/task.md` before editing files. Load the `$invoice-total-fixer` skill before changing code. Stay grounded in the repository, preserve existing behavior, and mention the exact verification command you ran. If you edit files with apply_patch, paths are relative to the sandbox workspace root.', defaultManifest: manifest, capabilities: [ ...Capabilities.default(), skills({ lazyFrom: localDirLazySkillSource({ src: hostSkillsDir, }), }), ],});
const result = await run( agent, 'Open `repo/task.md`, fix the issue, run the targeted test, and summarize the change.', { sandbox: { client: new UnixLocalSandboxClient(), }, },);
console.log(result.finalOutput);일반적인 패턴
섹션 제목: “일반적인 패턴”위의 전체 예제에서 시작하세요. 대부분의 경우 동일한 SandboxAgent를 그대로 유지하면서 샌드박스 클라이언트, 샌드박스 세션 소스, 워크스페이스 소스만 변경할 수 있습니다.
샌드박스 클라이언트 전환
섹션 제목: “샌드박스 클라이언트 전환”에이전트 정의는 그대로 유지하고 실행 설정만 변경하세요. 컨테이너 격리나 이미지 일관성이 필요하면 Docker를, 제공업체가 관리하는 실행 환경이 필요하면 호스티드 제공업체를 사용하세요. 예제와 제공업체 옵션은 샌드박스 클라이언트를 참고하세요.
워크스페이스 재정의
섹션 제목: “워크스페이스 재정의”에이전트 정의는 그대로 유지하고 sandbox: { client, manifest }로 새 세션의 매니페스트만 바꾸세요. 에이전트를 다시 구성하지 않고 동일한 에이전트 역할을 서로 다른 저장소, 자료 모음, 작업 묶음에 적용해야 할 때 사용합니다.
샌드박스 세션 주입
섹션 제목: “샌드박스 세션 주입”명시적인 수명 주기 제어, 실행 후 검사, 출력 복사가 필요하면 실행 중인 샌드박스 세션을 주입하세요. 해당 실행에서 sandbox: { session }을 사용하고, 애플리케이션 코드에서 세션을 닫으세요.
세션 상태에서 재개
섹션 제목: “세션 상태에서 재개”RunState 외부에서 샌드박스 상태를 이미 직렬화했다면, sandbox: { client, sessionState }로 러너가 해당 상태에서 다시 연결하도록 하세요. 샌드박스 상태가 자체 스토리지나 작업 시스템에 있고 Runner가 여기서 직접 재개하도록 하려는 경우에 사용합니다.
스냅샷에서 시작
섹션 제목: “스냅샷에서 시작”sandbox: { client, snapshot }으로 저장된 파일과 결과물에서 새 샌드박스를 초기화하세요. 새 실행을 agent.defaultManifest만으로 시작하지 않고 저장된 워크스페이스 콘텐츠에서 시작해야 할 때 사용합니다.
Git에서 스킬 로드
섹션 제목: “Git에서 스킬 로드”skills({ from: gitRepo(...) })로 로컬 스킬 소스를 저장소 기반 소스로 바꾸세요. 스킬 묶음에 자체 릴리스 주기가 있거나 여러 샌드박스에서 공유해야 할 때 사용합니다.
도구로 노출
섹션 제목: “도구로 노출”도구 에이전트는 자체 샌드박스 세션을 확보하거나 상위 실행에서 실행 중인 샌드박스를 재사용할 수 있습니다. 재사용은 다른 샌드박스를 생성, 복원하거나 스냅샷을 만드는 비용 없이 상위 워크스페이스를 검사하기만 하면 되는 탐색 에이전트에 유용합니다. 세션을 공유하는 것만으로 읽기 전용 접근이 강제되지는 않습니다.
도구 에이전트에 별도의 워크스페이스, 백엔드, 이미지가 필요하면 sandboxAgent.asTool(...)을 통해 자체 runConfig를 제공하세요. 신뢰할 수 없는 명령에는 필요한 격리를 제공하는 백엔드와 설정을 선택하세요. 별도의 Unix-local 세션만으로는 OS 수준의 격리가 제공되지 않습니다.
로컬 도구 및 MCP와 결합
섹션 제목: “로컬 도구 및 MCP와 결합”샌드박스 워크스페이스를 유지하면서 같은 에이전트에서 일반 도구도 계속 사용할 수 있습니다. 샌드박스 기능은 tools, mcpServers, 핸드오프, 모델 설정, 출력 설정과 함께 사용할 수 있습니다.
에이전트 메모리
섹션 제목: “에이전트 메모리”향후 샌드박스 에이전트 실행이 이전 실행에서 학습해야 한다면 memory() 기능을 사용하세요. 메모리는 SDK의 대화형 Session 메모리와 별개입니다. 학습한 내용을 샌드박스 워크스페이스 내 파일로 정리하면 후속 실행에서 해당 파일을 읽을 수 있습니다.
설정, 읽기/생성 동작, 멀티 턴 대화, 레이아웃 격리는 에이전트 메모리를 참고하세요.
조합 패턴
섹션 제목: “조합 패턴”단일 에이전트 패턴을 이해했다면, 다음 설계 과제는 더 큰 시스템에서 샌드박스 경계를 어디에 둘지 결정하는 것입니다.
샌드박스 에이전트는 SDK의 다른 구성 요소와도 결합할 수 있습니다.
- 핸드오프: 문서 중심 작업을 샌드박스를 사용하지 않는 접수 에이전트에서 샌드박스 검토 에이전트로 넘깁니다.
- Agents as tools: 여러 샌드박스 에이전트를 도구로 노출합니다. 일반적으로 각
asTool(...)호출에 샌드박스 실행 설정을 전달하여 각 도구가 자체 세션을 갖도록 합니다. 각 세션이 제공하는 격리 수준은 백엔드와 설정에 따라 결정됩니다. - 모델 컨텍스트 프로토콜 (MCP) 및 일반 함수 도구: 샌드박스 기능은
mcpServers및 일반 도구와 함께 사용할 수 있습니다. - 에이전트 실행: 샌드박스 실행도 기존
run()및RunnerAPI를 사용합니다.
핸드오프에서는 여전히 최상위 실행 하나와 최상위 턴 루프 하나가 유지됩니다. 활성 에이전트는 바뀌지만 실행이 중첩되지는 않습니다.
asTool(...)에서는 관계가 다릅니다. 외부 오케스트레이터는 도구 호출을 결정하는 데 외부 턴 하나를 사용하며, 이 도구 호출은 샌드박스 에이전트의 중첩 실행을 시작합니다. 중첩 실행에는 자체 턴 루프, maxTurns, 승인이 있으며, 보통 자체 샌드박스 실행 설정도 있습니다. 외부 오케스트레이터 관점에서는 이 모든 작업이 여전히 하나의 도구 호출 뒤에서 이루어지므로, 중첩된 턴은 외부 실행의 턴 카운터를 증가시키지 않습니다.
추가 자료
섹션 제목: “추가 자료”- 빠른 시작: 샌드박스 에이전트 하나를 실행합니다.
- 샌드박스 클라이언트: 로컬, Docker, 호스티드, 마운트 옵션을 선택합니다.
- 에이전트 메모리: 이전 샌드박스 실행에서 학습한 내용을 보존하고 재사용합니다.