다시 로드한 후 파일 유지
샌드박스 채팅이 있습니다. 에이전트가 파일을 작성한 후 공급자 샌드박스가 사라집니다. 다음 실행은 비어 있는 상태로 시작합니다.
이식 가능한 스냅샷은 터미널 실행이 성공할 때마다 해당 파일을 저장합니다. 이후
실행에서는 최신 체크포인트를 새로운 비공개 샌드박스로 복원합니다. 이 페이지를
마치면 chat()이 해당 체크포인트를 작성하고 복원하게 됩니다.
영속성 값 하나를 생성합니다. 동일한 값을 withPersistence와 snapshots 객체에
전달합니다. withPersistence를 withSandbox보다 앞에 배치합니다.
이 페이지는 자동 저장 및 복구에 충분합니다. 이름이 지정된 버전, 포크, 다운로드 또는 파일 정책을 필요로 할 때는 이름 지정 버전 저장, 버전에서 분기, 동결 파일 전송, 또는 보존할 파일 선택을 추가합니다.
새로운 영속성 생성
로컬 개발에는 memorySandboxSnapshots를 사용합니다. 영속성, 체크포인트 저장소,
스냅샷 메서드를 하나의 객체로 생성합니다. 런타임에
@tanstack/ai-persistence를 로드하지 않습니다.
import { chat } from '@tanstack/ai'
import { grokBuildText } from '@tanstack/ai-grok-build'
import { withPersistence } from '@tanstack/ai-persistence'
import {
defineSandbox,
defineWorkspace,
InMemorySandboxInstanceStore,
memorySandboxSnapshots,
withSandbox,
} from '@tanstack/ai-sandbox'
import { dockerSandbox } from '@tanstack/ai-sandbox-docker'
const instances = new InMemorySandboxInstanceStore()
const userId = 'user-123'
const sandbox = defineSandbox({
id: 'app-builder',
provider: dockerSandbox({ image: 'node:22' }),
workspace: defineWorkspace({ source: { type: 'none' } }),
lifecycle: { reuse: 'thread' },
})
const snapshots = await memorySandboxSnapshots({
sandbox,
instances,
})
const result = chat({
threadId: 'app-thread',
context: { userId },
adapter: grokBuildText('composer-2.5'),
messages: [{ role: 'user', content: 'Create a landing page.' }],
middleware: [
withPersistence(snapshots.persistence),
withSandbox(sandbox, {
instances,
snapshots,
}),
],
})
void result
sandbox, instances, tenant, 및 locks 을 생성 시점에 바인딩할 수 있습니다. 이후 snapshots.save 호출은 해당 값을 덮어쓸 수 있습니다. 이름이 지정된 버전 저장 을 참조하세요.
이 미들웨어와 동일한 서버 모듈에 instances를 유지합니다. 이름이 지정된 저장은
반드시 동일한 인스턴스 저장소를 사용해야 합니다.
모든 실행에서 세션의 userId를 context에 전달합니다. snapshots.save에서는
동일한 사용자 ID를 tenant.userId로 전달합니다.
기존 영속성 재사용
withPersistence가 이미 영속성 객체를 사용한다면 동일한 객체를
createSandboxSnapshots에 전달합니다. 두 번째 메시지 저장소를 생성하지 마세요.
영속성 객체에는 다음 저장소가 포함되어야 합니다.
messagesartifacts(withlistForThread)blobs
체크포인트 저장소도 필요합니다. 이 저장소는 영속성 저장소가 아닙니다.
이미 생성된 파일을 유지하고 있다면 artifacts와 blobs가 이미 있습니다.
동일한 저장소를 사용합니다.
messages만 있다면 동일한 어댑터에 artifacts와 blobs를 추가합니다.
필요한 저장소는 무엇인가요?와
생성 어댑터 빌드를 참조하세요.
import { chat } from '@tanstack/ai'
import { grokBuildText } from '@tanstack/ai-grok-build'
import { withPersistence } from '@tanstack/ai-persistence'
import {
createSandboxSnapshots,
InMemorySandboxCheckpointStore,
withSandbox,
} from '@tanstack/ai-sandbox'
import { instances, persistence, sandbox } from './sandbox-server'
const snapshots = createSandboxSnapshots({
persistence,
checkpoints: new InMemorySandboxCheckpointStore(),
sandbox,
instances,
})
const result = chat({
threadId: 'app-thread',
adapter: grokBuildText('composer-2.5'),
messages: [{ role: 'user', content: 'Create a landing page.' }],
middleware: [
withPersistence(snapshots.persistence),
withSandbox(sandbox, {
instances,
snapshots,
}),
],
})
void result
프로덕션에서 내구성 있는 저장소 사용
memorySandboxSnapshots는 로컬 개발과 테스트용입니다. 프로덕션에는 내구성 있는
메시지, 아티팩트, Blob 저장소와 내구성 있는 체크포인트 저장소가 필요합니다.
React 채팅 예제는 Node 22.5+ 서버용 sqliteSandboxSnapshots()를 내보냅니다.
이 함수는 예제 어댑터이며 패키지 export가 아닙니다.
각 체크포인트 쓰기, 헤드 업데이트, Blob 참조 수 업데이트에 하나의 SQLite 트랜잭션을 사용합니다. 포크에도 하나의 트랜잭션을 사용합니다. 포크 트랜잭션은 소스 대화도 복사해야 합니다. 이미 영속 상태가 있는 대상 스레드는 거부해야 합니다.
기록기 리스
각 스레드에는 체크포인트 기록기 리스가 하나씩 있습니다.
- 리스가 활성 상태인 동안 동일한 스레드의 두 번째 실행은 기록기 충돌을 받습니다.
- 미들웨어는 실행 중에 리스를 갱신합니다.
- 일시 중지 및 분리 경로는 리스를 해제합니다. 부분 체크포인트를 게시하지는 않습니다.
- 기록기가 리스를 잃으면 미들웨어는 체크포인트를 게시하지 않습니다. 이후 성공한 실행에서 새 체크포인트를 생성할 수 있습니다.
다음 실행에서 발생하는 일
이후 실행은 최신 체크포인트를 새로운 비공개 샌드박스에만 복원합니다. 실행이 재개된 활성 샌드박스는 현재 파일을 유지합니다. 해당 복원 규칙은 이식 가능한 샌드박스 스냅샷을 참조하세요.
인스턴스 내구성은 서버 프로세스 간에 공급자 샌드박스를 찾습니다. 해당 샌드박스가 사라지면 이식 가능한 스냅샷이 작업 공간을 다시 빌드합니다. 자세한 내용은 인스턴스 내구성을 참조하세요.
기본 정책은 .git, node_modules, .env* 경로를 제외합니다. 일부 파일 또는
파일 하나만 유지하려면 유지할 파일 선택을
참조하세요. 시크릿과 복원 안전성은 스냅샷에 저장되는 항목을
읽어보세요.