5.0 KiB
5.0 KiB
id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id | title | category | status | source_trust_level | verification_status | created_at | updated_at | tags | tech_stack | applied_in | aliases | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ai-code-interpreter-sandbox | Code Interpreter — Sandbox / E2B / Daytona | Coding | draft | B | conceptual | 2026-05-09 | 2026-05-09 |
|
|
|
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
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
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
const exec = await sb.runCode(longTask, {
onStdout: (line) => stream.write(line),
onStderr: (line) => stream.write(line),
});
LLM tool 로 wrap
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 })),
});
}
}
자원 제한
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)
await sb.runCode('x = 42');
const r = await sb.runCode('print(x * 2)'); // 84
자체 sandbox (Docker)
FROM python:3.12-slim
RUN useradd -m sandbox
USER sandbox
WORKDIR /home/sandbox
RUN pip install pandas numpy matplotlib
import { spawn } from 'node:child_process';
async function runInDocker(code: string): Promise<string> {
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 권장.
출력 안전 처리
function sanitizeOutput(s: string): string {
return s
.replace(/[\x00-\x08\x0b-\x1f]/g, '') // control chars
.slice(0, 10_000); // 길이 제한
}
결과 caching (같은 코드)
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 으로.