--- id: ai-code-interpreter-sandbox title: Code Interpreter — Sandbox / E2B / Daytona category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [ai, code-execution, sandbox, e2b, vibe-coding] tech_stack: { language: "TS / Python / Sandbox", applicable_to: ["Backend"] } applied_in: [] aliases: [code interpreter, E2B, Daytona, sandbox, jupyter, python execution] --- # Code Interpreter > LLM 이 작성한 코드를 안전 실행. **격리된 sandbox** 가 핵심. E2B / Daytona / Modal / Cloudflare Containers / 자체 K8s. OpenAI Code Interpreter, Anthropic Bash tool 도 같은 패턴. ## 📖 핵심 개념 - Sandbox: 격리 + 자원 제한 + 시간 제한. - Stateful: 한 세션 안 변수 유지 (Jupyter kernel). - File I/O: upload + 결과 download. - Streaming output. ## 💻 코드 패턴 ### E2B Code Interpreter ```ts import { Sandbox } from '@e2b/code-interpreter'; const sb = await Sandbox.create({ apiKey: process.env.E2B_API_KEY }); const exec = await sb.runCode(` import pandas as pd df = pd.read_csv('/data/sales.csv') df.groupby('region').sum() `); console.log(exec.text); // stdout console.log(exec.results); // 차트, table 등 rich result console.log(exec.error); await sb.kill(); ``` ### File upload / download ```ts await sb.files.write('/data/sales.csv', csvBuffer); const out = await sb.runCode(` import matplotlib.pyplot as plt df.plot() plt.savefig('/out/chart.png') `); const png = await sb.files.read('/out/chart.png', 'binary'); ``` ### Streaming ```ts const exec = await sb.runCode(longTask, { onStdout: (line) => stream.write(line), onStderr: (line) => stream.write(line), }); ``` ### LLM tool 로 wrap ```ts const tools = [{ name: 'execute_python', description: 'Execute Python code in a sandbox. Files in /data/. Save outputs to /out/. State persists between calls in the same conversation.', input_schema: { type: 'object', properties: { code: { type: 'string' } }, required: ['code'], }, }]; async function executeTool(name: string, input: { code: string }) { if (name === 'execute_python') { const r = await sb.runCode(input.code); return JSON.stringify({ stdout: r.text.slice(-2000), error: r.error?.value, results: r.results.map(x => ({ type: x.type, ...x })), }); } } ``` ### 자원 제한 ```ts const sb = await Sandbox.create({ template: 'code-interpreter-v1', timeoutMs: 60_000, // 세션 최대 1분 cpuCount: 1, memoryMB: 512, }); const exec = await sb.runCode(code, { timeoutMs: 30_000 }); // 1 cell 30초 ``` ### Persistent state (Jupyter) ```ts await sb.runCode('x = 42'); const r = await sb.runCode('print(x * 2)'); // 84 ``` ### 자체 sandbox (Docker) ```dockerfile FROM python:3.12-slim RUN useradd -m sandbox USER sandbox WORKDIR /home/sandbox RUN pip install pandas numpy matplotlib ``` ```ts import { spawn } from 'node:child_process'; async function runInDocker(code: string): Promise { return new Promise((resolve, reject) => { const p = spawn('docker', [ 'run', '--rm', '--network', 'none', '--memory', '512m', '--cpus', '0.5', '-i', 'python:3.12-slim', 'python', '-c', code, ]); let out = ''; let err = ''; p.stdout.on('data', (d) => { out += d.toString(); }); p.stderr.on('data', (d) => { err += d.toString(); }); p.on('close', (c) => c === 0 ? resolve(out) : reject(new Error(err))); setTimeout(() => p.kill(), 30_000); }); } ``` ⚠️ Docker 자체로 sandbox 부족 — gVisor / firecracker / E2B 권장. ### 출력 안전 처리 ```ts function sanitizeOutput(s: string): string { return s .replace(/[\x00-\x08\x0b-\x1f]/g, '') // control chars .slice(0, 10_000); // 길이 제한 } ``` ### 결과 caching (같은 코드) ```ts const key = sha256(code + ':' + dataHash); const cached = await cache.get(key); if (cached) return cached; const r = await sb.runCode(code); await cache.set(key, r); ``` ## 🤔 의사결정 기준 | 사용 | 추천 | |---|---| | ChatGPT-style data analysis | E2B Code Interpreter | | Long-running compute | Modal / Daytona | | Cloudflare 환경 | Cloudflare Containers | | Self-hosted K8s | Pod per session + gVisor | | 단순 calc | Python eval 위험 — math.js / sandbox js | | Untrusted user code (CTF, 강의) | gVisor / Firecracker / E2B | ## ❌ 안티패턴 - **`eval()` 직접**: RCE. sandbox 필수. - **Docker `--privileged`**: escape 가능. - **Network 허용 + 무제한**: SSRF / 외부 호출. - **Memory / CPU 무제한**: fork bomb / OOM. - **Output 무제한 → LLM 으로**: 다음 turn 비싸짐. - **Sandbox 재사용 cross-user**: state leak. - **Filesystem 무제한 write**: 디스크 채움. - **Timeout 없음**: 영원 hang. ## 🤖 LLM 활용 힌트 - E2B / Daytona 가 가장 modern. - Sandbox = network none + memory limit + cpu limit + timeout. - Output truncate 후 LLM 으로. ## 🔗 관련 문서 - [[AI_Function_Calling_Deep]] - [[AI_Agentic_Patterns]] - [[Security_OWASP_Top_10_Practical]]