Code Mode 격리 드라이버
격리 드라이버는 Code Mode가 생성된 TypeScript를 실행하는 데 사용하는 안전한 샌드박스 런타임을 제공합니다. 모든 드라이버는 동일한 IsolateDriver 인터페이스를 구현하므로 다른 코드를 변경하지 않고 교체할 수 있습니다.
드라이버 선택
Node 드라이버 (isolated-vm) | QuickJS 드라이버 (WASM) | QuickJS Bun 드라이버 (bun:ffi) | Cloudflare Workers 드라이버 | Daytona 드라이버 | |
|---|---|---|---|---|---|
| 용도 | 서버 측 Node.js 앱 | 브라우저, 엣지, 이식성 | Bun 서버 | Cloudflare의 엣지 배포 | 전체 원격 Linux 샌드박스 |
| 성능 | 빠름(V8 JIT) | 느림(인터프리트) | 빠름(네이티브 QuickJS) | 빠름(Cloudflare 엣지의 V8) | 빠름(네이티브 런타임, 원격 호출) |
| 네이티브 종속성 | 있음(C++ 애드온) | 없음 | 없음(즉시 컴파일되는 TinyCC) | 없음 | 없음 |
| 브라우저 지원 | 아니요 | 예 | 아니요(Bun만) | 해당 없음 | 예 |
| 메모리 제한 | 구성 가능 | 구성 가능 | 구성 가능 | 해당 없음 | 구성 가능 |
| 스택 크기 제한 | 해당 없음 | 구성 가능 | 구성 가능 | 해당 없음 | 해당 없음 |
| 설정 | pnpm add | pnpm add | bun add | 먼저 Worker 배포 | Daytona 샌드박스 생성 또는 전달 |
Node.js 드라이버 (@tanstack/ai-isolate-node)
isolated-vm 네이티브 애드온을 통해 V8 격리를 사용합니다. 생성된 코드가 호스트와 동일한 V8 엔진에서 JIT 컴파일로 실행되며 도구 호출 경계 외에는 직렬화 오버헤드가 없으므로 서버 측 Node.js 애플리케이션에 가장 빠른 옵션입니다.
설치
pnpm add @tanstack/ai-isolate-node
isolated-vm은 네이티브 C++ 애드온이므로 플랫폼에 맞게 컴파일해야 합니다. Node.js 18 이상이 필요합니다.
사용법
import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
const driver = createNodeIsolateDriver({
memoryLimit: 128, // MB
timeout: 30_000, // ms
})
옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
memoryLimit | number | 128 | V8 격리의 최대 힙 크기(메가바이트)입니다. 이 제한을 초과하면 실행이 종료됩니다. |
timeout | number | 30000 | 실행당 최대 실제 경과 시간(밀리초)입니다. |
작동 방식
각 execute_typescript 호출은 새로운 V8 격리를 생성합니다. 도구는 비동기 참조 함수로 격리에 연결됩니다. 생성된 코드가 external_myTool(...)을 호출하면 호출이 격리 경계를 넘어 호스트 Node.js 프로세스로 돌아와 도구 구현을 실행하고 결과를 반환합니다. 콘솔 출력(log, error, warn, info)은 캡처되어 실행 결과와 함께 반환됩니다. 각 호출 후 격리는 삭제됩니다.
QuickJS 드라이버 (@tanstack/ai-isolate-quickjs)
QuickJS를 Emscripten을 통해 WebAssembly로 컴파일하여 사용합니다. 샌드박스가 WASM 모듈이므로 네이티브 종속성이 없으며 JavaScript가 실행되는 어디서나 실행됩니다. 별도의 Worker를 배포하지 않고 Node.js, 브라우저, Deno, Bun, Cloudflare Workers에서 사용할 수 있습니다.
설치
pnpm add @tanstack/ai-isolate-quickjs
사용법
import { createQuickJSIsolateDriver } from '@tanstack/ai-isolate-quickjs'
const driver = createQuickJSIsolateDriver({
memoryLimit: 128, // MB
timeout: 30_000, // ms
maxStackSize: 524288, // bytes (512 KiB)
wasmLocation: '/assets/quickjs/emscripten-module.wasm',
})
옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
memoryLimit | number | 128 | QuickJS VM의 최대 힙 메모리(메가바이트)입니다. |
timeout | number | 30000 | 실행당 최대 실제 경과 시간(밀리초)입니다. |
maxStackSize | number | 524288 | 최대 호출 스택 크기(바이트, 기본값: 512 KiB)입니다. 깊은 재귀 코드에는 늘리고, 무한 재귀를 더 빨리 감지하려면 줄입니다. |
wasmLocation | string | — | Emscripten이 QuickJS WASM 바이너리를 로드할 URL 또는 경로입니다. 생략하면 quickjs-emscripten이 번들된 바이너리를 확인합니다. |
WASM 바이너리 제공
QuickJS WASM 바이너리가 공개 디렉터리 또는 CDN에서 호스팅되는 경우 wasmLocation을 설정합니다.
import { createQuickJSIsolateDriver } from '@tanstack/ai-isolate-quickjs'
const driver = createQuickJSIsolateDriver({
wasmLocation: 'https://cdn.example.com/quickjs/emscripten-module.wasm',
})
@jitl/quickjs-wasmfile-release-sync/wasm에서 내보내는 동기 릴리스 바이너리를 제공합니다. 교차 출처 URL을 사용하는 경우 호스트가 교차 출처 요청을 허용하도록 구성합니다.
작동 방식
QuickJS는 동기 WASM 빌드를 실행하고 QuickJS promise를 통해 호스트 비동기 함수(도구)를 연결하여 WASM 스택이 중단되지 않도록 합니다. 치명적 오류(메모리 고갈, 스택 오버플로)를 감지하면 VM을 해제하고 구조화된 오류를 반환합니다. 콘솔 출력은 캡처되어 결과와 함께 반환됩니다.
성능 참고: QuickJS는 JavaScript를 JIT 컴파일하지 않고 인터프리트하므로 계산량이 많은 스크립트는 Node 드라이버보다 느리게 실행됩니다. 대부분
external_*도구 호출을 기다리는 일반적인 LLM 생성 스크립트에서는 이 차이가 크지 않습니다.
QuickJS Bun 드라이버 (@tanstack/ai-isolate-quickjs-bun)
quickjs-bun 패키지를 통해 bun:ffi로 Bun 런타임에서 QuickJS를 네이티브로 실행합니다. 네이티브 종속성과 빌드 단계가 없습니다. 벤더링된 QuickJS C 소스는 프로세스당 한 번, Bun에 내장된 TinyCC로 즉시 컴파일됩니다. 따라서 Bun에서 Code Mode에 사용할 수 있는 가장 빠른 샌드박스 옵션입니다.
설치
bun add @tanstack/ai-isolate-quickjs-bun
Bun 1.3.14 이상이 필요합니다. Windows에서는 QUICKJS_BUN_NATIVE_LIBRARY 환경 변수를 통해 미리 빌드된 QuickJS 동적 라이브러리를 제공합니다.
사용법
import { createQuickJSBunIsolateDriver } from '@tanstack/ai-isolate-quickjs-bun'
const driver = createQuickJSBunIsolateDriver({
memoryLimit: 128, // MB
timeout: 30_000, // ms
maxStackSize: 524288, // bytes (512 KiB)
})
옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
memoryLimit | number | 128 | QuickJS 런타임의 최대 힙 메모리(메가바이트)입니다. |
timeout | number | 30000 | 실행당 최대 실제 경과 시간(밀리초)입니다. |
maxStackSize | number | 524288 | 최대 호출 스택 크기(바이트, 기본값: 512 KiB)입니다. 깊은 재귀 코드에는 늘리고, 무한 재귀를 더 빨리 감지하려면 줄입니다. |
maxToolCalls | number | 1000 | 실행당 호스트 도구 호출 최대 횟수입니다. 신뢰할 수 없는 샌드박스 코드가 크게 분기할 때(예: 거대한 배열에 대한 Promise.all) 출력과 메모리 증가를 제한하며, 초과하면 샌드박스 내부에서 잡을 수 있는 오류가 발생합니다. |
작동 방식
각 컨텍스트에는 자체 메모리 제한, 스택 크기, 인터럽트 기반 타임아웃을 사용하는 전용 네이티브 QuickJS 런타임이 할당되므로 컨텍스트가 독립적으로 실행됩니다. 모든 실행을 하나의 공유 asyncified WASM 모듈로 직렬화하는 WASM 드라이버와 다릅니다. 치명적 오류(메모리 고갈, 스택 오버플로)를 감지하면 VM을 해제하고 구조화된 오류를 반환하므로 이후 새 컨텍스트를 생성합니다. 실행별 maxToolCalls 예산으로 호스트 도구 호출 분기를 제한합니다. 콘솔 출력은 캡처되어 결과와 함께 반환됩니다.
Bun 전용: 이 드라이버에는 Bun 1.3.14 이상이 필요하며 Node.js에서 컨텍스트를 생성하면 설명이 포함된 오류가 발생합니다. 해당 환경에서는 Node 또는 QuickJS WASM 드라이버를 사용합니다. Bun에서는 WASM 드라이버보다 이 드라이버를 우선 사용합니다. QuickJS를 네이티브로 실행하며, Bun에서 quickjs-emscripten의 asyncify 브리지는 비동기 호스트 도구 호출에 안정적이지 않기 때문입니다.
Cloudflare Workers 드라이버 (@tanstack/ai-isolate-cloudflare)
Cloudflare Worker의 엣지에서 생성된 코드를 실행합니다. 애플리케이션 서버는 HTTP를 통해 코드와 도구 스키마를 Worker로 보내고, Worker는 코드를 실행하다가 도구 결과가 필요하면 다시 호출합니다. 샌드박스 실행은 Cloudflare의 글로벌 네트워크에서 수행되는 동안 도구 구현은 서버에 유지됩니다.
설치
pnpm add @tanstack/ai-isolate-cloudflare
사용법
import { createCloudflareIsolateDriver } from '@tanstack/ai-isolate-cloudflare'
const driver = createCloudflareIsolateDriver({
workerUrl: 'https://my-code-mode-worker.my-account.workers.dev',
authorization: process.env.CODE_MODE_WORKER_SECRET,
timeout: 30_000,
maxToolRounds: 10,
})
옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
workerUrl | string | — | 필수입니다. 배포된 Cloudflare Worker의 전체 URL입니다. |
authorization | string | — | 모든 요청의 Authorization 헤더로 전송되는 선택적 값입니다. Worker에 대한 무단 접근을 방지하는 데 사용합니다. |
timeout | number | 30000 | 모든 도구 왕복을 포함한 전체 실행의 최대 실제 경과 시간(밀리초)입니다. |
maxToolRounds | number | 10 | 실행당 도구 호출/결과 사이클의 최대 횟수입니다. 생성된 코드가 반복해서 도구를 호출할 때 무한 루프를 방지합니다. |
Worker 배포
패키지는 @tanstack/ai-isolate-cloudflare/worker에서 바로 사용할 수 있는 Worker 핸들러를 내보냅니다. wrangler.toml과 Worker 진입 파일을 생성합니다.
# wrangler.toml
name = "code-mode-worker"
main = "src/worker.ts"
compatibility_date = "2024-01-01"
[unsafe]
bindings = [{ name = "eval", type = "eval" }]
// src/worker.ts
export { default } from '@tanstack/ai-isolate-cloudflare/worker'
배포합니다.
wrangler deploy
작동 방식
드라이버는 도구 실행을 위한 요청/응답 루프를 구현합니다.
Driver (your server) Worker (Cloudflare edge)
───────────────────── ─────────────────────────
Send: code + tool schemas ──────▶ Execute code
◀────── Return: needs tool X with args Y
Execute tool X locally
Send: tool result ──────▶ Resume execution
◀────── Return: final result / needs tool Z
...repeat until done...
각 왕복에는 네트워크 지연 시간이 추가되므로 maxToolRounds 제한은 무한 실행 스크립트를 방지하고 대륙 간 왕복의 최대 횟수도 제한합니다. 모든 라운드의 콘솔 출력은 집계되어 최종 결과로 반환됩니다.
보안: 임의의 코드를 실행하려면 Worker에
UNSAFE_EVAL(로컬 개발) 또는evalunsafe 바인딩(프로덕션)이 필요합니다.authorization옵션이나 Cloudflare Access 정책을 사용하여 접근을 제한합니다.
Daytona 드라이버 (@tanstack/ai-isolate-daytona)
sandbox.process.codeRun을 통해 Daytona 샌드박스 내부에서 생성된 코드를 실행합니다. 애플리케이션 프로세스가 여전히 TanStack 도구 구현을 소유하며, Daytona 샌드박스는 래핑된 생성 코드와 재생된 도구 결과만 받습니다.
설치
pnpm add @tanstack/ai-isolate-daytona
애플리케이션이 공식 Daytona SDK로 샌드박스를 생성한다면 SDK도 설치합니다.
pnpm add @daytona/sdk
사용법
import { Daytona } from '@daytona/sdk'
import { createDaytonaIsolateDriver } from '@tanstack/ai-isolate-daytona'
const daytona = new Daytona()
const sandbox = await daytona.create({ language: 'typescript' })
const driver = createDaytonaIsolateDriver({
sandbox,
timeout: 30_000,
maxToolRounds: 10,
})
옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sandbox | DaytonaSandboxLike | — | 필수입니다. process.codeRun(code, params?, timeout?)을 포함하는 호출자 소유의 Daytona 샌드박스 유사 객체입니다. |
timeout | number | 30000 | 재생 라운드를 포함한 전체 실행의 최대 실제 경과 시간(밀리초)입니다. |
maxToolRounds | number | 10 | 샌드박스와 호스트 간 도구 콜백 라운드의 최대 횟수입니다. 생성된 코드가 도구를 반복해서 요청할 때 무한 루프를 방지합니다. |
작동 방식
드라이버는 Cloudflare의 부모 Worker / Dynamic Worker 분할 없이 Cloudflare 드라이버와 동일한 호스트 소유 도구 재생 형식을 사용합니다.
Driver (your server) Daytona sandbox
───────────────────── ───────────────
Send: wrapped code ──────▶ Execute with process.codeRun
◀────── Return: need_tools with tool requests
Execute tools locally
Replay with toolResults ──────▶ Continue execution
◀────── Return: final result / more tool requests
...repeat until done...
프로세스 내 격리, QuickJS WASM 런타임 또는 Cloudflare Worker 대신 전체 Daytona 샌드박스에서 Code Mode를 실행하려는 경우 이 드라이버를 사용합니다. 샌드박스는 Code Mode가 생성한 JavaScript를 실행할 수 있는 언어/런타임을 사용해야 하며, 샌드박스 수명 주기, 파일 시스템, 네트워크, 정리 및 시크릿 정책은 애플리케이션이 계속 책임집니다. Code Mode 컨텍스트를 생성해도 Daytona 샌드박스가 생성되거나 삭제되지는 않습니다.
IsolateDriver 인터페이스
제공되는 모든 드라이버는 @tanstack/ai-code-mode에서 내보내는 이 인터페이스를 충족합니다.
import type { ToolBinding, NormalizedError } from "@tanstack/ai-code-mode";
interface IsolateDriver {
createContext(config: IsolateConfig): Promise<IsolateContext>
}
interface IsolateConfig {
bindings: Record<string, ToolBinding>
timeout?: number
memoryLimit?: number
}
interface IsolateContext {
execute(code: string): Promise<ExecutionResult>
dispose(): Promise<void>
}
interface ExecutionResult<T = unknown> {
success: boolean
value?: T
logs: Array<string>
error?: NormalizedError
}
이 인터페이스를 구현하여 사용자 지정 드라이버를 만들 수 있습니다. 예를 들어 Docker 기반 샌드박스나 Deno 하위 프로세스를 만들 수 있습니다.
다음 단계
- Code Mode — 핵심 설정, API 레퍼런스 및 시작 안내
- UI에 Code Mode 표시 — React 앱에 실행 진행률 표시
- 스니펫을 사용하는 Code Mode — 영속적이고 재사용 가능한 스니펫 라이브러리 추가