Code Mode
Code Mode를 사용하면 LLM이 보안 샌드박스 안에서 TypeScript 프로그램을 작성하고 실행할 수 있습니다. 모델은 도구를 한 번에 하나씩 호출하는 대신 루프, 조건문, Promise.all, 데이터 변환으로 여러 도구를 오케스트레이션하는 짧은 스크립트를 작성한 다음 단일 결과를 반환합니다.
이미 도구를 사용하는 채팅 앱이 있습니다. 이 가이드를 마치면 LLM이 TypeScript에서 해당 도구를 조합하고 한 번의 샌드박스 호출로 실행하도록 Code Mode가 설정됩니다.
Code Mode를 사용하는 이유
컨텍스트 윈도우 사용량 감소
기존 에이전트 루프에서는 도구 호출마다 메시지 왕복이 추가됩니다. 모델의 도구 호출 요청, 도구 결과, 그리고 모델의 다음 추론 단계가 차례로 이어집니다. 다섯 개의 도구를 사용하는 작업은 왕복 과정에서 쉽게 수천 개의 토큰을 소비할 수 있습니다.
Code Mode에서는 모델이 완전한 프로그램을 담은 하나의 execute_typescript 호출을 생성합니다. 다섯 번의 도구 호출은 샌드박스 안에서 수행되고 최종 결과만 돌아옵니다. 요청 하나와 응답 하나로 끝납니다.
LLM이 도구 출력을 해석하는 방법을 결정
도구를 개별적으로 호출하면 모델은 새로운 턴마다 각 결과로 무엇을 할지 결정해야 합니다. Code Mode에서는 모델이 필터링, 집계, 비교, 분기 로직을 미리 작성합니다. 10개의 API 호출을 Promise.all로 실행하고 가장 좋은 결과를 선택해 요약을 반환하는 모든 작업을 한 번의 실행으로 처리할 수 있습니다.
타입 안전한 도구 실행
Code Mode에 전달한 도구는 시스템 프롬프트에 표시되는 타입 지정 함수 스텁으로 변환됩니다. 모델은 정확한 입력/출력 타입을 확인하므로 매개변수 이름이나 형태를 추측하지 않고 올바른 호출을 생성합니다. 생성된 코드의 TypeScript 주석은 실행 전에 자동으로 제거됩니다.
안전한 샌드박싱
생성된 코드는 호스트 파일 시스템, 네트워크 또는 프로세스에 접근할 수 없는 격리된 환경(V8 isolate, QuickJS WASM, Bun의 native QuickJS, Cloudflare Worker 또는 Daytona sandbox)에서 실행됩니다. 샌드박스에는 구성 가능한 타임아웃과 메모리 제한이 있습니다.
시작하기
1. 패키지 설치
pnpm add @tanstack/ai @tanstack/ai-code-mode zod
격리 드라이버를 선택하십시오:
# Node.js — fastest, uses V8 isolates (requires native compilation)
pnpm add @tanstack/ai-isolate-node
# QuickJS WASM — no native deps, works in browsers and edge runtimes
pnpm add @tanstack/ai-isolate-quickjs
# QuickJS Bun — native QuickJS via bun:ffi, fastest option on Bun
bun add @tanstack/ai-isolate-quickjs-bun
# Cloudflare Workers — run on the edge
pnpm add @tanstack/ai-isolate-cloudflare
# Daytona sandboxes — run in a remote Daytona sandbox
pnpm add @tanstack/ai-isolate-daytona @daytona/sdk
2. 도구 정의
toolDefinition()으로 도구를 정의하고 .server()로 서버 측 구현을 제공합니다. 이 도구는 샌드박스 안에서 사용할 수 있는 external_* 함수가 됩니다.
import { toolDefinition } from "@tanstack/ai";
import { z } from "zod";
const fetchWeather = toolDefinition({
name: "fetchWeather",
description: "Get current weather for a city",
inputSchema: z.object({ location: z.string() }),
outputSchema: z.object({
temperature: z.number(),
condition: z.string(),
}),
}).server(async ({ location }) => {
const res = await fetch(`https://api.weather.example/v1?city=${location}`);
return res.json();
});
3. Code Mode 도구와 시스템 프롬프트 생성
import { createCodeMode } from "@tanstack/ai-code-mode";
import { createNodeIsolateDriver } from "@tanstack/ai-isolate-node";
const { tool, systemPrompt } = createCodeMode({
driver: createNodeIsolateDriver(),
tools: [fetchWeather],
timeout: 30_000,
});
4. chat()과 함께 사용
import { chat } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
const result = await chat({
adapter: openaiText("gpt-5.5"),
systemPrompts: [
"You are a helpful weather assistant.",
systemPrompt,
],
tools: [tool],
messages: [
{
role: "user",
content: "Compare the weather in Tokyo, Paris, and New York City",
},
],
});
모델은 다음과 비슷한 코드를 생성합니다.
const cities = ["Tokyo", "Paris", "New York City"];
const results = await Promise.all(
cities.map((city) => external_fetchWeather({ location: city }))
);
const warmest = results.reduce((prev, curr) =>
curr.temperature > prev.temperature ? curr : prev
);
return {
comparison: results.map((r, i) => ({
city: cities[i],
temperature: r.temperature,
condition: r.condition,
})),
warmest: cities[results.indexOf(warmest)],
};
세 API 호출은 모두 샌드박스 안에서 병렬로 수행됩니다. 모델은 세 번의 개별 도구 호출 왕복 대신 하나의 구조화된 결과를 받습니다.
API 레퍼런스
createCodeMode(config)
단일 config 객체에서 execute_typescript 도구와 이에 대응하는 시스템 프롬프트를 모두 생성합니다. 권장되는 진입점입니다.
const { tool, systemPrompt } = createCodeMode({
driver, // IsolateDriver — required
tools, // Array<ServerTool | ToolDefinition> — required, at least one
timeout, // number — execution timeout in ms (default: 30000)
memoryLimit, // number — memory limit in MB (default: 128, Node + QuickJS drivers)
getSnippetBindings, // () => Promise<Record<string, ToolBinding>> — optional dynamic bindings
});
Config 속성:
| 속성 | 타입 | 설명 |
|---|---|---|
driver | IsolateDriver | 코드를 실행할 샌드박스 런타임 |
tools | Array<ServerTool | ToolDefinition> | external_* 함수로 노출되는 도구입니다. .server() 구현이 있어야 합니다 |
timeout | number | 밀리초 단위 실행 타임아웃(기본값: 30000) |
memoryLimit | number | MB 단위 메모리 제한(기본값: 128)입니다. Node 및 QuickJS 드라이버에서 지원됩니다 |
getSnippetBindings | () => Promise<Record<string, ToolBinding>> | 실행 시 추가 바인딩을 반환하는 선택적 함수 |
도구는 CodeModeToolResult를 반환합니다.
interface CodeModeToolResult {
success: boolean;
result?: unknown; // Return value from the executed code
logs?: Array<string>; // Captured console output
error?: {
message: string;
name?: string;
line?: number;
};
}
createCodeModeTool(config) / createCodeModeSystemPrompt(config)
도구만 필요하거나 프롬프트만 필요한 경우 사용하는 하위 수준 함수입니다. createCodeMode가 내부적으로 두 함수를 모두 호출합니다.
import { createCodeModeTool, createCodeModeSystemPrompt } from "@tanstack/ai-code-mode";
import { config } from "./config";
const tool = createCodeModeTool(config);
const prompt = createCodeModeSystemPrompt(config);
IsolateDriver
샌드박스 런타임이 구현하는 인터페이스입니다. 직접 구현하지 말고 제공되는 드라이버 중 하나를 선택합니다.
import type { IsolateConfig, IsolateContext } from "@tanstack/ai-code-mode";
interface IsolateDriver {
createContext(config: IsolateConfig): Promise<IsolateContext>;
}
사용 가능한 드라이버:
| 패키지 | 팩토리 함수 | 환경 |
|---|---|---|
@tanstack/ai-isolate-node | createNodeIsolateDriver() | Node.js |
@tanstack/ai-isolate-quickjs | createQuickJSIsolateDriver() | Node.js, 브라우저, 엣지 |
@tanstack/ai-isolate-quickjs-bun | createQuickJSBunIsolateDriver() | Bun |
@tanstack/ai-isolate-cloudflare | createCloudflareIsolateDriver() | Cloudflare Workers |
@tanstack/ai-isolate-daytona | createDaytonaIsolateDriver() | Daytona 샌드박스 |
각 드라이버의 전체 구성 옵션은 Isolate Drivers를 참조하세요.
고급
다음 유틸리티는 내부적으로 사용되며 사용자 지정 파이프라인을 위해 내보내집니다.
stripTypeScript(code)— sucrase를 사용해 TypeScript 구문을 제거하고 일반 JavaScript로 변환합니다(엣지 환경에 안전하며 native binary가 필요하지 않음).toolsToBindings(tools, prefix?)— 샌드박스 주입을 위해 TanStack AI 도구를Record<string, ToolBinding>으로 변환합니다.generateTypeStubs(bindings, options?)— 시스템 프롬프트를 위해 도구 바인딩에서 TypeScript 타입 선언을 생성합니다.
드라이버 선택
모든 구성 옵션을 포함한 드라이버 전체 비교는 Isolate Drivers를 참조하세요.
간단히 말하면 서버 측 Node.js에는 Node driver(가장 빠른 V8 JIT), 브라우저나 이식 가능한 엣지 배포에는 QuickJS(native deps 없음), Bun 서버에는 QuickJS Bun(bun:ffi를 통한 native QuickJS), Cloudflare Workers에 배포할 때는 Cloudflare driver, 완전한 원격 Linux 샌드박스 안에서 실행하려면 Daytona driver를 사용합니다.
사용자 지정 이벤트
Code Mode는 실행 중 사용자 지정 이벤트를 생성하며 TanStack AI 이벤트 시스템을 통해 이를 관찰할 수 있습니다. 실행 진행 상황을 표시하는 UI 구축, 디버깅 또는 로깅에 유용합니다.
| 이벤트 | 언제 | 페이로드 |
|---|---|---|
code_mode:execution_started | 코드 실행 시작 시 | { timestamp, codeLength } |
code_mode:console | 각 console.log/error/warn/info 호출 시 | { level, message, timestamp } |
code_mode:external_call | external_* 함수 실행 전 | { function, args, timestamp } |
code_mode:external_result | 성공한 external_* 호출 후 | { function, result, duration } |
code_mode:external_error | external_* 호출 실패 시 | { function, error, duration } |
이 이벤트를 React 앱에서 표시하려면 UI 에서 코드 모드 표시를 참조하세요.
모델 호환성
Code Mode는 모델에 샌드박스 브리지를 통해 도구를 호출하는 유효한 TypeScript를 작성하도록 요청합니다. 모든 모델이 이를 동일하게 처리하는 것은 아닙니다. 시스템 프롬프트가 명확해도 많은 소형 또는 이전 모델이 external_* 호출 규칙을 잘못 처리합니다. 세 테이블 조인, 모든 제품 카테고리에서 구매한 고객 필터링, 카테고리별 지출 집계로 구성된 단일 다단계 벤치마크를 gold reference와 비교해 추적합니다. 전체 하네스는 packages/ai-code-mode/models-eval/에 있습니다.
| 순위 | 모델 | 별점 | Acc | Comp | TS | CME | 지연 시간 | 토큰 |
|---|---|---|---|---|---|---|---|---|
| 1 | grok:grok-4-1-fast-non-reasoning | ★★★ | 10 | 9 | 6 | 10 | 7.0s | — |
| 2 | ollama:gpt-oss:20b | ★★★ | 10 | 8 | 6 | 5 | 45.1s | 23.6k |
| 3 | anthropic:claude-haiku-4-5 | ★★★ | 10 | 10 | 7 | 10 | 9.4s | 8.5k |
| 4 | gemini:gemini-2.5-flash | ★★★ | 10 | 7 | 5 | 9 | 7.3s | 6.9k |
| 5 | ollama:nemotron-cascade-2 | ★★★ | 10 | 9 | 5 | 5 | 60.4s | 11.7k |
| 6 | openai:gpt-4o-mini | ★★☆ | 10 | 8 | 8 | 10 | 19.2s | 8.7k |
| 7 | ollama:gemma4:31b | ★★☆ | 10 | 8 | 4 | 5 | 264.2s | 6.4k |
Columns
- Stars — 정확성, 포괄성, 코드 품질, code-mode 효율성, 속도, 토큰 효율성, 안정성을 결합한 종합 가중 평점(1-3)입니다.
- Acc / Comp / TS / CME — Anthropic이 평가한 10점 만점 하위 점수입니다. gold 대비 정확성, 포괄성, TypeScript 품질, code-mode 효율성(낭비되는 시도가 적을수록 좋음)을 나타냅니다.
- Latency — 전체 에이전트 루프의 실제 경과 시간입니다.
- Tokens — 프롬프트와 completion 토큰의 합계입니다. Grok의 어댑터는 사용량을 보고하지 않습니다.
Takeaways
- 가장 강력한 클라우드 선택: Grok 4.1 Fast, Claude Haiku 4.5, Gemini 2.5 Flash는 모두 10초 이내에 완료하며 다단계 작업을 안정적으로 처리합니다. Claude Haiku 4.5의 포괄성 점수가 가장 높습니다(10/10).
- 가장 강력한 로컬 선택:
ollama:gpt-oss:20b는 컴파일 실패 없이 45초 만에 가장 뛰어난 로컬 성능을 보입니다.ollama:nemotron-cascade-2가 근소한 차이로 다음입니다. - 피해야 할 모델: 더 작은
gemma4(9.6 GB)와eval-config.ts상단에서 주석 처리된 다른 로컬 모델(granite4:3b,ministral-3,mistral:7b,qwen3:8b등)입니다. 이 모델들은external_queryTable형태를 무시하거나 결과를 환각하거나execute_typescript호출을 거부합니다. - 주의: 단일 프롬프트 벤치마크입니다. 로컬 모델 결과는 실행마다 크게 달라질 수 있으므로 확정적인 순위가 아니라 대략적인 성능 선별 기준으로 사용하세요.
로컬에서 재현:
cd packages/ai-code-mode/models-eval
pnpm install
pnpm eval # full suite (needs cloud API keys + Anthropic for judging)
pnpm eval -- --ollama-only # local models only
pnpm eval -- --no-judge # skip Anthropic-based judging
팁
- 간단하게 시작하세요. 모델에 2~3개의 도구와 명확한 작업을 제공하세요. 모델이 집중된 기능 집합을 사용할 때 Code Mode가 가장 잘 작동합니다.
Promise.all작업을 우선하세요. 순차적인 도구 호출이 될 작업을 모델이 병렬화할 수 있을 때 Code Mode의 장점이 잘 드러납니다.- 디버깅에는
console.log를 사용하세요. 로그가 캡처되어 결과에 반환되므로 샌드박스 안에서 발생한 일을 쉽게 확인할 수 있습니다. - 도구의 역할을 명확히 유지하세요. 각 도구는 한 가지 일을 잘 수행해야 합니다. 모델이 코드에서 도구를 조합합니다.
- 시스템 프롬프트를 확인하세요.
createCodeModeSystemPrompt(config)를 호출하고 출력을 검사하면 생성된 타입 스텁을 포함해 모델이 정확히 무엇을 보게 되는지 확인할 수 있습니다.
다음 단계
- UI 에서 코드 모드 표시 — React 앱에서 실행 진행 상황을 표시합니다
- Code Mode with Snippets — 영속적이고 재사용 가능한 스니펫 라이브러리 추가
- Isolate Drivers — Node, QuickJS, QuickJS Bun, Cloudflare, Daytona 샌드박스 런타임 비교