샌드박스는 에이전트에 격리된 유닉스 계열 실행 환경을 제공합니다. 에이전트는 이 환경에서 파일 시스템, 셸, 설치된 패키지, 마운트된 데이터, 외부에 노출된 포트, 스냅샷을 사용할 수 있습니다. 외부 시스템에는 허용된 범위에서 접근할 수 있습니다.
모델에 이런 워크스페이스가 필요한데 프롬프트 컨텍스트만 제공하면 에이전트 워크플로우가 안정적으로 작동하기 어렵습니다. 대량의 문서를 다루거나, 아티팩트를 생성하거나, 명령어를 실행하거나, 미리보기를 제공하거나, 중단한 작업을 재개하려면 에이전트가 직접 확인하고 변경할 수 있는 환경이 필요합니다.
샌드박스 에이전트는 TypeScript용 및 Python용 Agents SDK에서 사용할 수 있습니다.
이 가이드에서는 애플리케이션이 하네스를 실행하는 Agents SDK의 샌드박스를 다룹니다. OpenAI가 관리하는 하네스를 사용하려면 Agents API에서 샌드박스 연결하기를 참고하세요.
에이전트가 파일을 조작하거나, 명령어를 실행하거나, 데이터룸을 마운트하거나, 아티팩트를 생성하거나, 서비스를 외부에 노출하거나, 상태를 유지한 채 나중에 작업을 이어가야 할 때 샌드박스를 사용하세요.
하네스와 컴퓨팅 환경은 서로 다른 역할을 맡습니다. 하네스는 모델을 둘러싼 제어 영역으로, 에이전트 루프, 모델 호출, 도구 라우팅, 핸드오프, 승인, 추적, 복구, 실행 상태를 관리합니다. 컴퓨팅 환경은 모델의 지시에 따른 작업이 이루어지는 샌드박스 실행 영역입니다. 여기서 파일을 읽고 쓰고, 명령어를 실행하고, 종속성을 설치하고, 마운트된 스토리지를 사용하고, 포트를 노출하고, 현재 상태를 스냅샷으로 저장합니다.
두 영역을 분리하면 애플리케이션은 신뢰할 수 있는 인프라에서 민감한 제어 작업을 처리하고, 샌드박스는 공급자별 실행을 담당할 수 있습니다. 샌드박스는 범위가 제한된 자격 증명과 마운트를 사용해 파일을 대상으로 코드를 실행할 수 있습니다. 하네스는 인증, 결제, 감사 로그, 담당자 검토, 복구 상태를 개별 컨테이너 외부에서 관리할 수 있습니다.
샌드박스 안에서 하네스를 실행하면 프로토타입을 만들 때 편리할 수 있지만, 오케스트레이션과 모델이 지시하는 작업이 같은 컴퓨팅 환경에서 실행됩니다.
자체 인프라에서 하네스를 실행하고, 상태를 유지하며 작업을 실행하는 일은 공급자별 샌드박스에 맡길 수 있습니다.
샌드박스를 사용하는 경우
에이전트가 답변을 작성하는 데 프롬프트 컨텍스트를 바탕으로 한 추론만으로는 부족하고 샌드박스 워크스페이스에서 실제로 작업을 수행해야 한다면 샌드박스를 사용하세요.
대표적으로 다음과 같은 경우가 있습니다.
- 프롬프트 하나로는 작업을 수행할 수 없고 문서가 담긴 디렉터리가 필요합니다.
- 에이전트가 파일을 작성하고 애플리케이션이 나중에 그 파일을 확인해야 합니다.
- 에이전트가 작업을 완료하려면 명령어, 패키지 또는 스크립트가 필요합니다.
- 워크플로우에서 Markdown, CSV, JSONL, 스크린샷, 자동 생성된 웹사이트 등의 아티팩트를 생성합니다.
- 서비스, 노트북 또는 보고서 미리보기를 외부에 노출된 포트에서 실행해야 합니다.
- 담당자가 검토하는 동안 작업을 일시 중지했다가 같은 워크스페이스에서 재개합니다.
워크플로우에 짧은 모델 응답만 필요하고 워크스페이스를 유지할 필요가 없다면 Responses API를 직접 호출하거나 샌드박스 없이 기본 Agents SDK 런타임을 사용하세요.
여러 도구 중 셸을 가끔 사용하는 정도라면 도구 사용하기에 설명된 호스팅 셸 도구부터 사용하세요. 워크스페이스 격리, 샌드박스 공급자 선택 또는 파일 시스템 상태를 유지한 채 작업을 재개하는 기능이 제품 설계에 포함된다면 샌드박스 에이전트를 사용하세요.
샌드박스가 제공하는 기능
SandboxAgent도 Agent입니다. instructions, prompt, tools, handoffs, MCP 서버, 모델 설정, 구조화된 출력값, 가드레일, 훅 등 기존 에이전트 인터페이스를 그대로 사용할 수 있습니다. 달라지는 부분은 실행 영역입니다. 러너는 활성 샌드박스 세션에서 작업할 수 있도록 에이전트를 준비합니다. 이 세션이 파일, 명령어, 포트, 공급자별 격리를 담당합니다.
| 구성 요소 | 담당 범위 | 설계 시 고려할 질문 |
|---|---|---|
SandboxAgent |
에이전트 정의와 샌드박스 기본값 | 에이전트가 어떤 작업을 수행해야 하며, 어떤 샌드박스 기본값을 함께 정의할까요? |
Manifest |
새 세션의 워크스페이스 초기 구성 | 워크스페이스에 처음부터 어떤 파일, 디렉터리, 리포지터리, 마운트, 환경, 사용자 또는 그룹이 있어야 할까요? |
| 기능 | 에이전트에 추가하는 샌드박스 고유 동작 | 에이전트에 어떤 샌드박스 도구, 지침 또는 런타임 동작이 필요할까요? |
| 샌드박스 클라이언트 | 공급자 연동 | 워크스페이스를 Unix-local, Docker, 호스팅 공급자 중 어디에서 실행할까요? |
| 샌드박스 세션 | 현재 사용 중인 실행 환경 | 명령어 실행, 파일 변경, 포트 개방은 어디에서 이루어지며 공급자의 상태는 어디에 유지될까요? |
| 샌드박스 실행 설정 | 실행별 샌드박스 세션 소스, 클라이언트 옵션, 새 세션의 입력 | 이번 실행에서는 샌드박스 세션을 주입할까요, 재개할까요, 새로 만들까요? |
| 저장된 상태 | RunState, 직렬화된 세션 상태, 스냅샷 |
이후 실행에서 기존 작업에 다시 연결하거나 새 워크스페이스를 초기화하려면 어떻게 해야 할까요? |
샌드박스에 적용할 기본값은 SandboxAgent에 지정하세요. 실행마다 샌드박스 세션을 어떻게 사용할지는 해당 실행의 샌드박스 설정에 지정하세요.
샌드박스 에이전트에서도 턴을 세는 기준은 같습니다. 한 턴은 모델이 한 단계를 수행하는 단위입니다. 셸 명령어나 샌드박스 동작 하나마다 턴을 세지는 않습니다. 일부 작업은 샌드박스 실행 계층 안에서 끝날 수 있습니다. 에이전트 런타임은 샌드박스 작업 후 모델 응답이 한 번 더 필요할 때만 다음 턴을 사용합니다.
워크스페이스 만들기
Manifest는 새 샌드박스 워크스페이스의 초기 내용과 디렉터리 구조를 정의합니다. 에이전트에 제공할 파일, 리포지터리, 입력 아티팩트, 보조 파일, 마운트, 출력 디렉터리, 환경 설정을 여기에 지정하세요.
매니페스트는 새 세션의 초기 구성을 정의합니다. 이미 실행 중인 모든 샌드박스의 현재 상태를 나타내지는 않습니다. 실제 실행에 사용할 워크스페이스는 재사용하는 활성 샌드박스 세션, 직렬화된 샌드박스 세션 상태 또는 실행 시점에 선택한 스냅샷에서 가져올 수도 있습니다.
매니페스트 항목의 경로는 워크스페이스를 기준으로 한 상대 경로입니다. 절대 경로를 사용하거나 ..로 워크스페이스를 벗어날 수 없습니다. 따라서 로컬, Docker, 호스팅 클라이언트에서 같은 워크스페이스 구성을 사용할 수 있습니다.
| 매니페스트 입력 | 용도 |
|---|---|
File, Dir |
작은 합성 입력 데이터, 보조 파일 또는 출력 디렉터리 |
| 로컬 파일 또는 디렉터리 | 샌드박스에 복사해 둘 호스트의 파일 또는 디렉터리 |
| Git 리포지터리 | 워크스페이스로 가져올 리포지터리 |
S3Mount, GCSMount, R2Mount, AzureBlobMount, BoxMount, S3FilesMount |
샌드박스 안에서 사용할 외부 스토리지 |
environment |
샌드박스를 시작할 때 필요한 환경 변수 |
users 및 groups |
계정 프로비저닝을 지원하는 공급자에서 사용할 샌드박스 로컬 OS 계정과 그룹 |
매니페스트를 설계할 때는 다음 원칙을 따르세요.
- 리포지터리, 입력 아티팩트, 출력 디렉터리를 매니페스트에 포함하세요.
- 긴 작업 명세와 리포지터리별 지침은
repo/task.md또는AGENTS.md같은 워크스페이스 파일에 작성하세요. - 지침에서는
repo/task.md또는output/report.md처럼 워크스페이스 기준 상대 경로를 사용하세요. - 스토리지 마운트의 범위는 에이전트가 읽거나 써야 하는 입력으로 제한하세요.
- 마운트 항목은 워크스페이스의 임시 항목으로 취급하세요. 스냅샷을 만들거나 워크스페이스를 영구 저장할 때는 마운트된 원격 스토리지의 내용을 복사하지 않고 건너뜁니다.
파일과 스토리지 마운트하기
작업에 필요한 데이터가 이미 다른 위치에 있는 경우가 많습니다. 대용량 문서를 컨텍스트에 붙여 넣는 대신 샌드박스에 마운트하여 에이전트가 파일을 직접 다루게 하세요.
예를 들어 다음과 같이 사용할 수 있습니다.
- 실사에 사용하는 데이터룸을 마운트하고 에이전트에 출처를 인용한 요약을 요청하세요.
- 고객 지원 시스템에서 내보낸 데이터를 마운트하고 에이전트에 이슈를 유형별로 묶어 보고서를 작성하도록 요청하세요.
- 생성된 아티팩트를 다른 시스템에서 검토할 수 있도록 마운트하세요.
공급자마다 마운트 헬퍼, 자격 증명 처리 방식, 데이터 보존 방식이 다릅니다. 애플리케이션에서는 일관된 원칙을 적용하세요. 에이전트가 사용할 입력만 마운트하고, 어디에서 읽고 어디에 쓸지 알려 주고, 생성된 아티팩트는 사용하기 전에 확인하세요.
시크릿과 자격 증명 처리하기
샌드박스 자격 증명은 런타임 설정으로 제공하세요. 에이전트가 패키지 관리자, 스토리지 마운트 또는 공급자 API를 사용하려면 자격 증명에 접근해야 할 수 있습니다. 자격 증명이 사용자 프롬프트, 에이전트 지침, 작업 파일, 커밋한 매니페스트 또는 생성된 아티팩트에 포함되지 않도록 하세요.
다음 원칙을 따르세요.
- 호스팅 샌드박스에서는 공급자가 자체 제공하는 시크릿 관리 시스템을 우선 사용하세요.
- 클라우드 스토리지 자격 증명의 범위는 해당 자격 증명이 필요한 마운트 또는 공급자 옵션으로 제한하세요.
- 샌드박스 프로세스를 시작할 때 필요한 값은
Manifest.environment에 지정하세요. 민감한 항목이나 자동 생성된 항목을 저장하지 않고 다시 만들려면 임시 항목으로 표시하세요. - 시크릿, 자동 생성된 마운트 설정, 로컬 토큰, 실행이 끝난 후 남겨 두면 안 되는 파일은 저장하지 마세요.
- 아티팩트를 샌드박스 밖으로 옮기기 전에 검토하세요. 특히 에이전트가 비공개 문서나 마운트된 스토리지를 읽을 수 있다면 이 과정이 중요합니다.
SDK는 매니페스트의 환경 변수 값과 공급자별 마운트 자격 증명을 지원합니다. 시크릿 저장소와 연동하는 방법은 공급자마다 다릅니다. 공통으로 지켜야 할 원칙은 런타임이나 샌드박스 공급자가 자격 증명을 주입하고 모델에 전달하는 지침에는 자격 증명을 넣지 않는 것입니다.
에이전트에 기능 추가하기
기능을 추가하면 SandboxAgent에서 샌드박스 고유 동작을 사용할 수 있습니다. 기능을 통해 실행 전에 워크스페이스를 구성하고, 샌드박스 전용 지침을 추가하고, 활성 샌드박스 세션에 연결된 도구를 제공하고, 해당 에이전트의 모델 동작이나 입력 처리 방식을 조정할 수 있습니다.
| 기능 | 추가하는 경우 | 참고 사항 |
|---|---|---|
Shell |
에이전트에 셸 접근 권한이 필요할 때 | 명령어 실행 기능을 추가합니다. 샌드박스 클라이언트가 지원하면 대화형 입력도 사용할 수 있습니다. |
Filesystem |
에이전트가 파일을 편집하거나 로컬 이미지를 확인해야 할 때 | apply_patch와 view_image를 추가합니다. 패치 경로는 워크스페이스 루트를 기준으로 한 상대 경로입니다. |
Skills |
샌드박스에서 스킬을 검색하고 사용할 파일을 배치하려 할 때 | .agents 또는 .agents/skills를 수동으로 마운트하기보다 이 기능을 우선 사용하세요. |
Memory |
후속 실행에서 메모리 아티팩트를 읽거나 생성해야 할 때 | Shell이 필요합니다. 실행 중 메모리를 업데이트하려면 Filesystem도 필요합니다. |
Compaction |
오래 실행되는 플로우에서 컨텍스트를 줄여야 할 때 | 컨텍스트 압축 항목이 추가된 후 모델 동작과 입력 처리 방식을 조정합니다. |
기본적으로 SandboxAgent에는 파일 시스템, 셸, 컨텍스트 압축 기능이 포함됩니다. capabilities 목록을 전달하면 기본 목록 전체를 대체하므로 에이전트에 여전히 필요한 기본 기능도 목록에 포함하세요.
요구 사항에 맞는 기본 제공 기능을 우선 사용하세요. 기본 기능이 제공하지 않는 샌드박스 전용 도구나 지침 인터페이스가 필요할 때만 사용자 지정 기능을 작성하세요.
스킬 불러오기
일부 작업에는 에이전트를 시작하기 전에 준비해 둘 반복 사용 가능한 지침, 스크립트, 참고 자료 또는 에셋이 필요합니다. Skills 기능을 사용하면 에이전트가 실행 중에 작업에 필요한 자료를 찾아 사용할 수 있습니다.
import {
Capabilities,
SandboxAgent,
gitRepo,
skills,
} from "@openai/agents/sandbox";
const agent = new SandboxAgent({
name: "Tax prep assistant",
instructions: "Use the mounted skill before preparing the return.",
capabilities: [
...Capabilities.default(),
skills({
from: gitRepo({
repo: "owner/tax-prep-skills",
ref: "main",
}),
}),
],
});스킬 파일을 배치할 방식에 따라 소스를 선택하세요.
- 로컬 스킬 디렉터리가 크고 모델이 색인을 먼저 확인한 뒤 필요한 내용만 불러오게 하려면 지연 로딩 방식의 로컬 디렉터리 소스를 사용하세요.
- 작은 로컬 번들을 미리 배치하려면 로컬 디렉터리 소스를 사용하세요.
- 스킬 번들의 릴리스 주기가 별도로 정해져 있거나 여러 샌드박스가 같은 번들을 사용한다면 Git 리포지터리 소스를 사용하세요.
미리보기와 포트 노출하기
작업의 결과물이 실행 중인 프로세스일 수도 있습니다. 에이전트가 로컬 앱, 노트북, 보고서 서버, 브라우저 미리보기 또는 기타 서비스를 만들고 이를 샌드박스 외부에서 확인해야 한다면 포트를 노출하세요.
포트를 설정하는 방법은 공급자마다 다르지만 제품의 동작 방식은 같습니다. 에이전트가 샌드박스 안에서 서비스를 시작하면 샌드박스 클라이언트가 포트를 노출하고, 애플리케이션은 생성된 미리보기 URL을 공유하거나 해당 URL에서 결과를 확인합니다.
샌드박스 에이전트 실행하기
샌드박스 에이전트를 실행하는 기본 절차는 다음과 같습니다.
- 워크스페이스를 정의하는
Manifest를 작성하세요. - 모델에 필요한 기능을 갖춘
SandboxAgent를 만드세요. - 작업을 실행할 환경에 맞는 샌드박스 클라이언트를 선택하세요.
- 해당 실행에 적용할 샌드박스 설정으로 에이전트를 실행하세요.
- 애플리케이션에 필요한 아티팩트를 확인하거나 복사하고, 필요에 따라 작업을 재개하거나 스냅샷을 만드세요.
macOS 또는 Linux에서 로컬로 개발할 때는 Unix-local부터 사용하세요. 러너가 에이전트의 기본 매니페스트를 바탕으로 임시 워크스페이스를 만들고 실행 후 정리하므로 가장 간단한 절차로 로컬에서 반복 실행할 수 있습니다.
TypeScript용 SDK를 사용할 때는 UnixLocalSandboxClient로 세션을 만들기 전에 호스트에 신뢰할 수 있는 Python 3 인터프리터를 설치하세요. SDK는 로컬 파일에 안전하게 접근하기 위해 Python을 사용하며, /usr/bin/python3, /usr/local/bin/python3, /opt/homebrew/bin/python3에서 인터프리터를 찾습니다. Python을 다른 위치에 설치했다면 Node.js를 시작하기 전에 호스트의 환경 변수 OPENAI_AGENTS_PYTHON에 Python 실행 파일의 절대 경로를 지정하세요. 이 인터프리터는 호스트에 필요한 사전 요구 사항이며 샌드박스 안에 설치할 패키지가 아닙니다. 사용할 수 있는 적절한 Python 인터프리터가 없으면 세션 생성에 실패합니다.
import { run } from "@openai/agents";
import { Manifest, SandboxAgent, file, shell } from "@openai/agents/sandbox";
import { UnixLocalSandboxClient } from "@openai/agents/sandbox/local";
const manifest = new Manifest({
entries: {
"account_brief.md": file({
content:
"# Northwind Health\n\n" +
"- Segment: Mid-market healthcare analytics provider.\n" +
"- Renewal date: 2026-04-15.\n",
}),
"implementation_risks.md": file({
content:
"# Delivery risks\n\n" +
"- Security questionnaire is not complete.\n" +
"- Procurement requires final legal language by April 1.\n",
}),
},
});
const agent = new SandboxAgent({
name: "Renewal Packet Analyst",
model: "gpt-6-astra",
instructions:
"Review the workspace before answering. Keep the response concise, " +
"business-focused, and cite the file names that support each conclusion.",
defaultManifest: manifest,
capabilities: [shell()],
});
const result = await run(
agent,
"Summarize the renewal blockers and recommend the next two actions.",
{
sandbox: {
client: new UnixLocalSandboxClient(),
},
}
);
console.log(result.finalOutput);로컬에서 실행하는 전체 예제는 TypeScript 샌드박스 에이전트 빠른 시작과 Python unix_local_runner.py를 참고하세요.
공급자 전환하기
공급자는 실행 설정에서 선택합니다. SandboxAgent, 매니페스트, 기능은 그대로 두고 원하는 환경에 맞게 샌드박스 클라이언트와 공급자 옵션을 바꾸세요.
다음 예제에서는 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-6-astra",
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);실행 가능한 TypeScript 예제는 샌드박스 클라이언트 가이드와 기본 예제를 참고하세요. SDK 리포지터리의 Python 예제 중 basic.py는 공급자 선택을, docker_runner.py는 Docker 사용을, main.py는 데이터룸을 활용한 플로우를 보여 줍니다.
고급 패턴
기본 실행 절차가 작동하면, 프롬프트 컨텍스트를 더 제공하는 것만으로는 부족하고 에이전트에 실제 워크스페이스가 필요한 워크플로우에 샌드박스를 활용할 수 있습니다. 다음 예제는 같은 API를 활용하는 여러 워크플로우 패턴을 보여 줍니다. 하나의 하네스가 워크플로우의 라우팅, 일시 중지, 재개, 추적을 담당하고, 각 샌드박스는 필요한 파일, 도구, 포트가 있는 환경에서 작업을 실행합니다.
| 예제 | 설명 |
|---|---|
| 데이터룸 질의응답 | 마운트된 데이터룸의 자료를 바탕으로 질문에 답합니다. |
| 데이터룸에서 표 추출하기 | 마운트된 데이터룸에서 표를 추출합니다. |
| 리포지터리 코드 리뷰 | 리포지터리를 복제하고 코드를 검토해 리뷰 아티팩트를 생성합니다. |
| 비전으로 웹사이트 복제하기 | Vision API와 스크린샷 피드백을 사용해 웹사이트를 복제합니다. |
| 샌드박스 작업 재개하기 | 기존 샌드박스에서 작업을 재개합니다. |
작업을 재개하거나 저장된 내용으로 새 작업 시작하기
에이전트 작업은 요청 한 번으로 끝나지 않는 경우가 많습니다. 사용자가 아티팩트를 검토하거나, 특정 단계에 승인이 필요하거나, 나중에 이벤트가 발생해야 다음 단계로 진행할 수 있기 때문입니다.
다음 세 가지 상태를 구분하세요.
| 상태 유형 | 복원 대상 | 사용 시점 |
|---|---|---|
RunState |
모델 항목, 도구 상태, 승인, 현재 활성 에이전트의 위치 등 하네스 측 상태 | 러너가 일시 중지된 지점부터 워크플로우를 이어가야 할 때 |
| 세션 상태 | 클라이언트가 다시 연결할 수 있도록 직렬화한 샌드박스 세션 | 앱이나 작업 관리 시스템이 공급자의 세션 상태를 직접 저장할 때 |
snapshot |
새 샌드박스 세션의 초기 구성에 사용할 저장된 워크스페이스 내용 | 새 실행을 저장된 파일과 아티팩트가 있는 워크스페이스에서 시작해야 할 때 |
러너는 다음 순서로 사용할 샌드박스 세션을 결정합니다.
- 활성 샌드박스 세션을 전달하면 해당 세션을 그대로 재사용합니다.
- 활성 세션을 전달하지 않았고
RunState에서 실행을 재개한다면 저장된 샌드박스 세션 상태에서 재개합니다. - 위 조건에 해당하지 않고 직렬화된 샌드박스 상태를 명시적으로 전달했다면 해당 상태에서 재개합니다.
- 그 외에는 새 샌드박스 세션을 만듭니다. 해당 실행에 매니페스트를 지정했다면 그 매니페스트를 사용하고, 지정하지 않았다면 에이전트의 기본 매니페스트를 사용합니다.
샌드박스 재개 예제에서는 중지된 세션의 상태를 직렬화한 다음 같은 클라이언트로 세션을 재개하고, 재개한 세션을 다음 실행에 전달합니다.
import { run } from "@openai/agents";
import { Manifest, SandboxAgent } 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 agent = new SandboxAgent({
name: "Workspace builder",
model: "gpt-6-astra",
instructions: "Inspect the sandbox workspace before answering.",
});
const session = await client.create({ manifest });
let conversation = [];
let frozenSessionState;
try {
const firstResult = await run(agent, "Build the first version of the app.", {
maxTurns: 20,
sandbox: { session },
});
conversation = firstResult.history;
frozenSessionState = await client.serializeSessionState?.(session.state);
} finally {
await session.close?.();
}
if (!frozenSessionState || !client.deserializeSessionState || !client.resume) {
throw new Error("Sandbox client does not support session resume.");
}
const resumedSession = await client.resume(
await client.deserializeSessionState(frozenSessionState)
);
try {
conversation.push({
role: "user",
content: "Continue from the existing workspace and add tests.",
});
const secondResult = await run(agent, conversation, {
maxTurns: 20,
sandbox: { session: resumedSession },
});
console.log(secondResult.finalOutput);
} finally {
await resumedSession.close?.();
}manifest와 snapshot 같은 새 세션용 입력은 러너가 샌드박스 세션을 새로 만들 때만 적용됩니다. 활성 session을 주입하면 기능을 처리하는 과정에서 마운트가 아닌 호환 항목을 추가할 수 있습니다. 다만 이미 실행 중인 샌드박스의 루트, 환경, 사용자 또는 그룹을 변경하거나, 기존 항목을 삭제하거나, 항목 유형을 교체하거나, 마운트 항목을 추가 또는 변경할 수는 없습니다.
이렇게 역할을 분리하면 하네스는 에이전트 루프를 재개하고 샌드박스 공급자는 워크스페이스를 복원하거나 다시 만들 수 있습니다. 각 방식의 최신 샘플 코드는 TypeScript 세션 상태 재개 예제와 Python main.py 및 sandbox_agent_with_remote_snapshot.py에서 확인할 수 있습니다.
실행 간 메모리 유지하기
샌드박스 메모리를 사용하면 샌드박스 에이전트가 후속 실행에서 이전 작업의 경험을 활용할 수 있습니다. 샌드박스 메모리는 SDK가 관리하는 대화용 Session 메모리와 별개입니다. 세션은 메시지 기록을 보존하고, 샌드박스 메모리는 이전 워크스페이스 작업에서 얻은 유용한 교훈을 정리해 에이전트가 나중에 읽을 수 있는 파일에 저장합니다.
이전 턴을 모두 다시 처리하지 않고도 에이전트가 사용자 선호도, 수정 사항, 프로젝트별 교훈 또는 작업 요약을 다음 실행에서 활용해야 한다면 메모리를 사용하세요. 세션 재개와 스냅샷은 워크스페이스 상태를 보존하고, 메모리는 워크스페이스에서 수행한 작업을 바탕으로 다시 활용할 수 있는 지침을 보존합니다.
import {
Manifest,
SandboxAgent,
filesystem,
memory,
shell,
} from "@openai/agents/sandbox";
const manifest = new Manifest();
const agent = new SandboxAgent({
name: "Memory-enabled reviewer",
instructions:
"Inspect the workspace and retain useful lessons for follow-up runs.",
defaultManifest: manifest,
capabilities: [memory(), filesystem(), shell()],
});기본적으로 메모리 읽기와 생성이 모두 활성화됩니다. 에이전트가 메모리 파일을 검색하고 열려면 셸 접근 권한이 필요합니다. 기본 설정에서 실행 중 메모리를 업데이트하려면 파일 시스템 접근 권한도 필요합니다. 이 권한이 있으면 에이전트가 오래되어 부정확해진 메모리를 바로잡거나 사용자의 요청에 따라 메모리를 업데이트할 수 있습니다.
메모리를 읽을 때는 필요한 만큼 단계적으로 정보를 불러옵니다. SDK는 실행을 시작할 때 memory_summary.md를 주입합니다. 에이전트는 이전 작업이 관련 있어 보이면 MEMORY.md를 검색하고, 더 자세한 정보가 필요할 때만 롤아웃 요약을 엽니다.
| 메모리 모드 | 사용 시점 |
|---|---|
| 기본 읽기/쓰기 | 에이전트가 기존 메모리를 읽고 새 메모리를 생성해야 할 때 |
| 읽기 전용 메모리 | 에이전트가 메모리를 읽되 실행 후 새 메모리를 생성하지 않아야 할 때 |
| 생성 전용 메모리 | 기존 메모리를 사용하지 않고 새 메모리를 생성해야 할 때 |
| 읽기 설정 | 실행 중 업데이트를 비활성화해야 할 때 |
| 생성 설정 | 추가 프롬프트 등 메모리 생성 설정을 조정해야 할 때 |
| 레이아웃 설정 | 같은 샌드박스 워크스페이스에서 에이전트별로 메모리 레이아웃을 분리해야 할 때 |
기본적으로 메모리 아티팩트는 샌드박스 워크스페이스에 저장됩니다.
workspace/
sessions/
<rollout-id>.jsonl
memories/
memory_summary.md
MEMORY.md
raw_memories.md
phase_two_selection.json
raw_memories/
<rollout-id>.md
rollout_summaries/
<rollout-id>_<slug>.md
skills/
런타임은 샌드박스 세션이 진행되는 동안 실행 기록을 구간별로 덧붙입니다. 세션이 종료되면 메모리 생성 과정에서 먼저 대화 요약과 원시 메모리를 추출한 다음 원시 메모리를 MEMORY.md와 memory_summary.md에 통합합니다. 이후 실행에서 메모리를 재사용하려면 설정한 메모리 디렉터리를 보존하세요. 같은 활성 샌드박스 세션을 유지하거나, 세션 상태에서 재개하거나, 스냅샷에서 시작하거나, S3 같은 영구 스토리지를 마운트하면 됩니다.
샌드박스에서 여러 턴에 걸쳐 채팅할 때는 동일한 SDK 세션과 동일한 활성 샌드박스 세션을 함께 유지하세요. 메모리는 실행을 묶을 때 명시적으로 지정한 대화 ID를 우선 사용합니다. 이 값이 없으면 SDK 세션 ID, 실행 그룹 ID, 실행별로 생성한 ID 순으로 사용합니다. 샌드박스 세션 ID는 활성 워크스페이스의 식별자이며 메모리의 대화 ID와는 별개입니다.
실행 가능한 예제는 TypeScript 메모리 가이드를 참고하세요. Python 예제 중 memory.py는 로컬 스냅샷 플로우를, memory_s3.py는 S3에 메모리를 저장하는 방식을, memory_multi_agent_multiturn.py는 에이전트별로 메모리 레이아웃을 분리하는 방식을 보여 줍니다.
샌드박스 에이전트 조합하기
샌드박스 에이전트는 SDK의 다른 구성 요소와 함께 사용할 수 있습니다.
샌드박스를 사용하지 않는 에이전트가 요청을 접수하고 워크플로우 중 워크스페이스를 집중적으로 사용하는 부분만 샌드박스 에이전트에 위임해야 한다면 핸드오프를 사용하세요. 최상위 실행은 계속되며 다음 턴에는 샌드박스 에이전트가 활성 에이전트가 됩니다.
상위 오케스트레이터가 하나 이상의 샌드박스 에이전트를 중첩된 도구로 호출해야 한다면 에이전트를 도구로 사용하세요. 도구로 사용하는 각 샌드박스 에이전트에 별도의 샌드박스 실행 설정, 샌드박스 클라이언트, 매니페스트, 공급자 옵션을 지정할 수 있습니다.
예제는 handoffs.py와 sandbox_agents_as_tools.py를 참고하세요.
샌드박스 공급자
로컬에서 빠르게 수정하고 실행하려면 Unix-local부터 사용하고, 로컬 컨테이너 격리가 필요하다면 Docker를 사용하세요. 관리형 실행, 공급자별 격리, 확장, 미리보기, 스토리지 마운트, 스냅샷 또는 애플리케이션 서버 외부에서 관리해야 하는 자격 증명이 필요하다면 호스팅 공급자로 전환하세요.
공급자별 설정 방법, 자격 증명, 격리, 스토리지, 미리보기, 데이터 보존 방식은 각 공급자의 문서를 참고하세요.
| 공급자 | SDK 클라이언트 | 문서 및 예제 |
|---|---|---|
| Blaxel | BlaxelSandboxClient |
샌드박스 개요 |
| Cloudflare | CloudflareSandboxClient |
샌드박스 문서 OpenAI Agents 튜토리얼 Sandbox Bridge 예제 |
| Databricks | DatabricksSandboxClient |
Python을 사용한다면 databricks-openai[sandbox]를 설치하세요.샌드박스 문서 OpenAI Agents SDK 예제 Python용 Databricks SDK 가이드 |
| Daytona | DaytonaSandboxClient |
샌드박스 문서 OpenAI Agents SDK 가이드 |
| Docker | DockerSandboxClient |
Docker 문서 TypeScript용 Docker SDK 예제 Python용 Docker SDK 예제 |
| E2B | E2BSandboxClient |
샌드박스 문서 OpenAI Agents SDK 가이드 출시 안내 블로그 글 |
| Modal | ModalSandboxClient |
샌드박스 가이드 연동 방법을 소개하는 블로그 글 예제 리포지터리 Modal 확장 프로그램 레퍼런스 |
| Unix-local | UnixLocalSandboxClient |
TypeScript용 로컬 SDK 예제 Python용 로컬 SDK 예제 |
| Vercel | VercelSandboxClient |
샌드박스 문서 OpenAI Agents SDK 가이드 FastAPI 템플릿 샘플 앱 |