LLM Sandbox について
LLM Sandbox は、LLM 生成コードをコンテナやローカルのサンドボックスで実行するための共通 API を開発者に提供します。リソース、ネットワーク、ホストアクセスを設定でき、多言語実行、ファイル操作、成果物の抽出に対応します。
主な機能
- 01コンテナおよびローカルの隔離バックエンド
- 02セキュリティポリシーとリソース制限
- 03サンドボックスのネットワーク制御
- 04多言語実行と依存関係のインストール
- 05ホストとサンドボックス間のファイル操作
- 06プロットなどの成果物の取得
活用シーン
- 01隔離環境で LLM 生成コードを実行
- 02実行リソースやネットワークアクセスを制限
- 03ライブラリを導入して複数言語のコードを実行
- 04入力ファイルを渡し、生成されたプロットを収集
MCP 対応
MCP サーバーを備えており、MCP クライアントから安全なサンドボックス内でコードを実行できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx llm-sandboxBACKENDContainer backend to use. Must match the installed extra: mcp-docker, mcp-podman, or mcp-k8s.DOCKER_HOSTDocker or Podman socket URL, e.g. unix:///var/run/docker.sockKUBECONFIGPath to kubeconfig file when BACKEND=kubernetes.NAMESPACEKubernetes namespace used for sandbox pods when BACKEND=kubernetes.COMMIT_CONTAINERCommit the container after a run so installed libraries persist between sessions.KEEP_TEMPLATEKeep the base image after the session ends to avoid re-pulling it on the next run.SANDBOX_NETWORK_MODENetwork mode for the sandbox container. Set to 'none' for hardened isolation. Docker and Podman backends only.SANDBOX_READ_ONLYMount the sandbox root filesystem read-only. Recommended: true. Docker and Podman backends only.SANDBOX_CAP_DROPComma-separated Linux capabilities to drop. Recommended: ALL. Docker and Podman backends only.SANDBOX_SECURITY_OPTComma-separated container security options, e.g. no-new-privileges. Docker and Podman backends only.SANDBOX_MEMORYMemory limit for the sandbox container, e.g. 4g. Docker and Podman backends only.SANDBOX_CPUSFractional CPU allocation for the sandbox container, e.g. 1.5. Docker and Podman backends only.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
3掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| code | string | はい | |
| timeout | integer | いいえ | |
| language | string | いいえ | |
| libraries | any | いいえ |
詳細
LLM サンドボックス
LLM が生成したコードを簡単かつ安全に実行
LLM Sandbox は、コンテナーおよびローカルの Linux と Windows のサンドボックスバックエンド向けに、共通 API を介して大規模言語モデル(LLM)が生成したコードを実行します。デプロイ環境に適した隔離バックエンドを選択し、セキュリティ制御を設定して、同じコード実行 API とファイル API を再利用できます。
ドキュメント:https://vndee.github.io/llm-sandbox/
バックエンドのベンチマークでは、起動、実行、ファイル転送、並行処理について Docker、Bubblewrap、NsJail を比較し、信頼区間と再現可能なエビデンスを掲載しています。

✨ 新機能: このプロジェクトはModel Context Protocol (MCP) サーバーに対応しました。これにより、MCP クライアント(Claude Desktop など)から、LLM が生成したコードを安全なサンドボックス環境で実行できます。
🚀 主な機能
🛡️ セキュリティを最優先
- 隔離された実行:明示的に設定されたホストアクセスを使用して、コンテナーまたはローカル OS のサンドボックス化を実現
- セキュリティポリシー:コード実行を制御するカスタムセキュリティポリシーを定義
- リソース制限:CPU、メモリ、実行時間の上限を設定
- ネットワーク隔離:サンドボックス内のコードのネットワークアクセスを制御
🏗️ 柔軟なサンドボックスバックエンド
- Docker:最も人気があり、幅広くサポートされている選択肢
- Kubernetes:スケーラブルなデプロイに適したエンタープライズグレードのオーケストレーション
- Podman:セキュリティを強化するルートレスコンテナー
- Bubblewrap:Docker やデーモンを使わない、ローカル Linux の名前空間と seccomp
- NsJail:デーモンを使わない、ローカル Linux の名前空間とネイティブ seccomp ポリシー
- Windows MXC:Microsoft の MXC/PSEC API によるネイティブな Windows プロセス隔離
- WSL2 Bubblewrap:明示的に選択した WSL2 ディストリビューションでの Linux 名前空間と seccomp
- バックエンドレジストリ:追加のアダプターを登録し、対応機能を確認
🌐 マルチ言語サポート
依存関係を自動管理しながら、複数のプログラミング言語でコードを実行できます。
- Python - pip パッケージを含む、エコシステム全体をサポート
- JavaScript/Node.js - npm パッケージのインストール
- Java - Maven と Gradle による依存関係管理
- C++ - コンパイルと実行
- Go - モジュールのサポートとコンパイル
- R - CRAN パッケージを使った統計計算とデータ分析
🔌 LLM フレームワークとの連携
11 種類のエージェントフレームワーク(OpenAI Agents SDK、Claude Agent SDK、LangChain、DeepAgents、LlamaIndex、Google ADK、CrewAI、Pydantic AI、smolagents、Strands、AG2)で実行可能なサンプルを用意しています。詳細は examples/agent_sdks/ をご覧ください。
📊 高度な機能
- 成果物の抽出:プロットや可視化を自動的に取得します
- ライブラリ管理:依存関係をその場でインストールします
- ファイル操作:サンドボックス環境との間でファイルをコピーします
- カスタムイメージ:独自のコンテナーイメージを使用します
- 高速な本番モード:環境のセットアップを省略して、コンテナーの起動を高速化します
- コンテナープーリング:コンテナーを事前に起動して再利用し、パフォーマンスを向上させます(NEW!)
📦 インストール
基本インストール
pip install llm-sandbox
特定のバックエンドのサポートを含める場合
# For Docker support (most common)
pip install 'llm-sandbox[docker]'
# For Kubernetes support
pip install 'llm-sandbox[k8s]'
# For Podman support
pip install 'llm-sandbox[podman]'
# All optional container SDKs
pip install 'llm-sandbox[docker,k8s,podman]'
Bubblewrap と NsJail は、ベースの Python パッケージに加えてシステム実行ファイルを使用します。コンテナー SDK の追加パッケージは不要です。Linux の前提条件については、ローカルバックエンドの要件を参照してください。
Windows アダプターにもコンテナー SDK は不要です。windows-mxc には互換性のある Windows ホストとネイティブヘルパーが必要です。一方、wsl2-bubblewrap には、対応する Python パッケージと Linux の前提条件を備えた WSL2 ディストリビューションの設定が必要です。Windows の要件を参照してください。どちらのアダプターも OS ランタイムをインストールせず、サンドボックス化されていない実行にフォールバックすることもありません。
開発用インストール
開発用の依存関係はdevのuv 依存関係グループに含まれているため、uv(またはmake installのショートカット)を使ってインストールしてください。
git clone https://github.com/vndee/llm-sandbox.git
cd llm-sandbox
make install # uv sync + pre-commit install
ワークフロー全体については、CONTRIBUTING.mdを参照してください。
🏃♂️ クイックスタート
基本的な使い方
from llm_sandbox import SandboxSession
# Create and use a sandbox session
with SandboxSession(lang="python") as session:
result = session.run("""
print("Hello from LLM Sandbox!")
print("I'm running in a secure container.")
""")
print(result.stdout)
Docker を使わない Linux でのローカル実行
Debian/Ubuntu では、sudo apt install bubblewrap libseccomp2 python3-venvを実行して、システムの前提条件をインストールしてください。Bubblewrap はバージョン 0.8.0 以降で、--disable-usernsをサポートしている必要があります。Ubuntu 22.04 などの古いディストリビューションでは、新しいパッケージまたは上流のビルドが必要です。ホストで非特権ユーザー名前空間が許可されている必要があります。ディストリビューションのセキュリティポリシーによっては、使用が制限される場合があります。
from llm_sandbox import SandboxSession
with SandboxSession(backend="bubblewrap", lang="python") as session:
result = session.run("print('Hello from a local Linux sandbox!')")
print(result.stdout)
ローカルのデフォルト設定では、名前空間の分離と seccomp システムコール拒否リストを組み合わせ、ネットワークアクセスを無効にし、ランタイムパスを読み取り専用で公開して、専用の書き込み可能なワークスペースと一時ディレクトリを用意します。Python のセットアップでは、オフラインで仮想環境を作成します。先にホストのランタイムとそのvenvサポートをインストールしてください。インストール済みの NsJail バイナリを使用するには、backend="nsjail"を選択します。
Linux アダプターは、run()、execute_command()、install()、ファイルコピー、および成果物ラッパーをサポートします。コンテナーイメージ、プーリング、インタラクティブセッションはサポートしていません。セッション内ではコマンド間でファイルが保持されますが、バックグラウンドプロセスは保持されません。これらのバックエンドはホストのカーネルを共有し、VM と同等の分離境界ではありません。設定、セキュリティ、およびバックエンドのロードマップを参照してください。
Docker を使わない Windows での利用
ネイティブの Windows Python 実行には、互換性のある Windows ホストにヘルパーをインストールしたうえで、MXC アダプターを使用してください。
from llm_sandbox import SandboxSession
with SandboxSession(backend="windows-mxc", lang="python") as session:
print(session.run("import platform; print(platform.system())").stdout)
Windows の Python アプリケーションから Linux ツールを実行するには、WSL2 ディストリビューションを明示的に選択してください。
from llm_sandbox import SandboxSession
with SandboxSession(
backend="wsl2-bubblewrap",
distribution="Ubuntu",
lang="python",
) as session:
print(session.run("import platform; print(platform.system())").stdout)
これらは前提条件と API の制限が異なる実験的なアダプターです。MXC は当初、Python と JavaScript、および事前にインストールされた依存関係をサポートします。WSL2 は Linux の Bubblewrap ランタイムを再利用し、seccomp を必要とします。また、Windows との相互運用性を利用できないように、マウント先を組み込みの Linux ランタイムパスに制限します。どちらもデフォルトではネットワークが無効になっています。バックエンドのセットアップと制限を参照してください。
ライブラリのインストール
from llm_sandbox import SandboxSession
with SandboxSession(lang="python") as session:
result = session.run("""
import numpy as np
# Create an array
arr = np.array([1, 2, 3, 4, 5])
print(f"Array: {arr}")
print(f"Mean: {np.mean(arr)}")
""", libraries=["numpy"])
print(result.stdout)
マルチ言語サポート
JavaScript
with SandboxSession(lang="javascript") as session:
result = session.run("""
const greeting = "Hello from Node.js!";
console.log(greeting);
const axios = require('axios');
console.log("Axios loaded successfully!");
""", libraries=["axios"])
Java
with SandboxSession(lang="java") as session:
result = session.run("""
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello from Java!");
}
}
""")
C++
with SandboxSession(lang="cpp") as session:
result = session.run("""
#include <iostream>
int main() {
std::cout << "Hello from C++!" << std::endl;
return 0;
}
""")
Go
with SandboxSession(lang="go") as session:
result = session.run("""
package main
import "fmt"
func main() {
fmt.Println("Hello from Go!")
}
""")
R
with SandboxSession(
lang="r",
image="ghcr.io/vndee/sandbox-r-451-bullseye",
verbose=True,
) as session:
result = session.run(
"""
# Basic R operations
print("=== Basic R Demo ===")
# Create some data
numbers <- c(1, 2, 3, 4, 5, 10, 15, 20)
print(paste("Numbers:", paste(numbers, collapse=", ")))
# Basic statistics
print(paste("Mean:", mean(numbers)))
print(paste("Median:", median(numbers)))
print(paste("Standard Deviation:", sd(numbers)))
# Work with data frames
df <- data.frame(
name = c("Alice", "Bob", "Charlie", "Diana"),
age = c(25, 30, 35, 28),
score = c(85, 92, 78, 96)
)
print("=== Data Frame ===")
print(df)
# Calculate average score
avg_score <- mean(df$score)
print(paste("Average Score:", avg_score))
"""
)
インタラクティブセッション
ノートブック形式のワークフローでは、複数回の run 呼び出しにわたって Python インタープリターの状態を保持する InteractiveSandboxSession を使用できます。
from llm_sandbox import InteractiveSandboxSession
with InteractiveSandboxSession(
lang="python",
kernel_type="ipython",
history_size=200,
) as session:
session.run("value = 21 * 2")
result = session.run("print(f'Result: {value}')")
print(result.stdout) # -> Result: 42
# Use magic command to install libraries
session.run("%pip install pandas")
result = session.run("import pandas as pd; print(pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}))")
print(result.stdout)
インタラクティブセッションは Docker、Podman、Kubernetes のバックエンドに対応しており、現在は Python 言語を対象としています。サンドボックス内で長時間実行される IPython カーネルを起動するため、各 run() はノートブックのセルのように動作します。コンテキストマネージャーを終了するまで、状態、インポート、マジックコマンドが維持され、追加のネットワーク処理や手動でのシリアル化は不要です。
プロットと可視化のキャプチャ
Python のプロット
from llm_sandbox import ArtifactSandboxSession
import base64
from pathlib import Path
with ArtifactSandboxSession(lang="python") as session:
result = session.run("""
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y)
plt.title("Sine Wave")
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.grid(True)
plt.savefig("sine_wave.png", dpi=150, bbox_inches="tight")
plt.show()
""", libraries=["matplotlib", "numpy"])
# Extract the generated plots
print(f"Generated {len(result.plots)} plots")
# Save plots to files
for i, plot in enumerate(result.plots):
plot_path = Path(f"plot_{i + 1}.{plot.format.value}")
with plot_path.open("wb") as f:
f.write(base64.b64decode(plot.content_base64))
R のプロット
from llm_sandbox import ArtifactSandboxSession
import base64
from pathlib import Path
with ArtifactSandboxSession(lang="r") as session:
result = session.run("""
library(ggplot2)
# Create sample data
data <- data.frame(
x = rnorm(100),
y = rnorm(100)
)
# Create ggplot2 visualization
p <- ggplot(data, aes(x = x, y = y)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE) +
labs(title = "Scatter Plot with Trend Line",
x = "X values", y = "Y values") +
theme_minimal()
print(p)
# Base R plot
hist(data$x, main = "Distribution of X",
xlab = "X values", col = "lightblue", breaks = 20)
""", libraries=["ggplot2"])
# Extract the generated plots
print(f"Generated {len(result.plots)} R plots")
# Save plots to files
for i, plot in enumerate(result.plots):
plot_path = Path(f"r_plot_{i + 1}.{plot.format.value}")
with plot_path.open("wb") as f:
f.write(base64.b64decode(plot.content_base64))
🔧 設定
基本設定
from llm_sandbox import SandboxSession
# Create a new sandbox session
with SandboxSession(image="python:3.9.19-bullseye", keep_template=True, lang="python") as session:
result = session.run("print('Hello, World!')")
print(result)
# With custom Dockerfile
with SandboxSession(dockerfile="Dockerfile", keep_template=True, lang="python") as session:
result = session.run("print('Hello, World!')")
print(result)
# Or default image
with SandboxSession(lang="python", keep_template=True) as session:
result = session.run("print('Hello, World!')")
print(result)
LLM Sandbox は、ホストとサンドボックス間でファイルをコピーする機能にも対応しています。
from llm_sandbox import SandboxSession
with SandboxSession(lang="python", keep_template=True) as session:
# Copy a file from the host to the sandbox
session.copy_to_runtime("test.py", "/sandbox/test.py")
# Run the copied Python code in the sandbox
result = session.execute_command("python /sandbox/test.py")
print(result)
# Copy a file from the sandbox to the host
session.copy_from_runtime("/sandbox/output.txt", "output.txt")
カスタムランタイム設定
from llm_sandbox import SandboxSession
pod_manifest = {
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "test",
"namespace": "test",
"labels": {"app": "sandbox"},
},
"spec": {
"containers": [
{
"name": "sandbox-container",
"image": "test",
"tty": True,
"volumeMounts": {
"name": "tmp",
"mountPath": "/tmp",
},
}
],
"volumes": [{"name": "tmp", "emptyDir": {"sizeLimit": "5Gi"}}],
},
}
with SandboxSession(
backend="kubernetes",
image="python:3.9.19-bullseye",
dockerfile=None,
lang="python",
keep_template=False,
verbose=False,
pod_manifest=pod_manifest,
) as session:
result = session.run("print('Hello, World!')")
print(result)
リモート Docker ホスト
import docker
from llm_sandbox import SandboxSession
tls_config = docker.tls.TLSConfig(
client_cert=("path/to/cert.pem", "path/to/key.pem"),
ca_cert="path/to/ca.pem",
verify=True
)
docker_client = docker.DockerClient(base_url="tcp://<your_host>:<port>", tls=tls_config)
with SandboxSession(
client=docker_client,
image="python:3.9.19-bullseye",
keep_template=True,
lang="python",
) as session:
result = session.run("print('Hello, World!')")
print(result)
Kubernetes サポート
from kubernetes import client, config
from llm_sandbox import SandboxSession
# Use local kubeconfig
config.load_kube_config()
k8s_client = client.CoreV1Api()
with SandboxSession(
client=k8s_client,
backend="kubernetes",
image="python:3.9.19-bullseye",
lang="python",
pod_manifest=pod_manifest, # None by default
) as session:
result = session.run("print('Hello from Kubernetes!')")
print(result)
⚠️ カスタム Pod マニフェストに関する重要事項:
カスタム Pod マニフェストを使用する場合は、コンテナー設定に以下が含まれていることを確認してください。
"tty": True(コンテナーを起動状態に保ちます)- Pod レベルとコンテナーレベルの両方に適切な
securityContext - コンテナー名には有効な名前を任意に指定できます(制限はありません)
必要な条件の詳細については、設定ガイドを参照してください。
Podman サポート
from llm_sandbox import SandboxSession
with SandboxSession(
backend="podman",
lang="python",
image="python:3.9.19-bullseye"
) as session:
result = session.run("print('Hello from Podman!')")
print(result)
⚡ コンテナープーリング(パフォーマンス最適化)
コンテナープーリングでは、新しいコンテナーを実行ごとに作成する代わりに、事前にウォームアップしたコンテナーを再利用することで、パフォーマンスを大幅に向上させます。コードを頻繁に実行するアプリケーションで特に効果的です。
主なメリット
- 実行の高速化:コンテナー作成のオーバーヘッドをなくします(最大10倍高速)
- ウォームアップ済み環境:コンテナーは依存関係を含めて初期化されます
- スレッドセーフ:同時リクエストを安全に処理します
- 効率的なリソース利用:コンテナーのライフサイクルを自動管理します
- 柔軟な設定:プールのサイズ、タイムアウト、動作を制御できます
基本的なプールの使用方法
from llm_sandbox import SandboxSession
from llm_sandbox.pool import PoolConfig, create_pool_manager
# Create a pool manager explicitly
pool = create_pool_manager(
backend="docker",
config=PoolConfig(
max_pool_size=10, # Maximum containers
min_pool_size=3, # Keep at least 3 warm
idle_timeout=300.0, # Recycle idle containers after 5 min
enable_prewarming=True, # Create containers on startup
),
lang="python",
)
# Use the pool in a session
with SandboxSession(
lang="python",
pool=pool,
) as session:
result = session.run("print('Hello from pool!')")
# Container is automatically returned to pool when the session closes
# Clean up the pool when done
pool.close()
複数のセッション間でプールを共有する
効率を最大限に高めるには、複数のセッション間で単一のプールを共有します。
from llm_sandbox import SandboxSession
from llm_sandbox.pool import create_pool_manager, PoolConfig
# Create a shared pool manager
pool = create_pool_manager(
backend="docker",
config=PoolConfig(
max_pool_size=10,
min_pool_size=3,
),
lang="python",
libraries=["numpy", "pandas"], # Pre-install libraries in all containers
)
# Use the pool in multiple sessions
with SandboxSession(lang="python", pool=pool) as session1:
result1 = session1.run("import pandas; print(pandas.__version__)")
with SandboxSession(lang="python", pool=pool) as session2:
result2 = session2.run("import numpy; print(numpy.__version__)")
# Clean up when done
pool.close()
並行実行
コンテナープールはスレッドセーフで、同時リクエストを効率的に処理します。
from concurrent.futures import ThreadPoolExecutor
from llm_sandbox import SandboxSession
from llm_sandbox.pool import create_pool_manager, PoolConfig
# Create shared pool
pool = create_pool_manager(
backend="docker",
config=PoolConfig(max_pool_size=5),
lang="python",
)
def run_code(task_id: int):
with SandboxSession(lang="python", pool=pool) as session:
return session.run(f'print("Task {task_id}")')
try:
# Execute 20 tasks concurrently using only 5 containers
with ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(run_code, range(20)))
finally:
pool.close()
プール設定オプション
from llm_sandbox.pool import PoolConfig, ExhaustionStrategy, create_pool_manager
config = PoolConfig(
# Pool size limits
max_pool_size=10, # Maximum containers in pool
min_pool_size=2, # Minimum warm containers
# Timeout configuration
idle_timeout=300.0, # Recycle idle containers (seconds)
acquisition_timeout=30.0, # Wait time for available container
# Health and lifecycle
health_check_interval=60.0, # Health check frequency
max_container_lifetime=3600.0, # Max container lifetime
max_container_uses=100, # Max uses before recycling
# Pool exhaustion behavior
exhaustion_strategy=ExhaustionStrategy.WAIT, # WAIT, FAIL_FAST, or TEMPORARY
# Pre-warming
enable_prewarming=True, # Pre-warm containers
)
pool = create_pool_manager(
backend="docker",
config=config,
lang="python",
libraries=["requests", "numpy"], # Pre-install libraries
)
プール枯渇時の動作
すべてのコンテナーが使用中の場合、プールは複数の方法で対応できます。
1. WAIT(デフォルト)
コンテナーが利用可能になるまで待機します。
config = PoolConfig(
max_pool_size=5,
exhaustion_strategy=ExhaustionStrategy.WAIT,
acquisition_timeout=30.0, # Wait up to 30 seconds
)
2. FAIL_FAST
直ちにエラーを発生させます。
config = PoolConfig(
max_pool_size=5,
exhaustion_strategy=ExhaustionStrategy.FAIL_FAST,
)
3. TEMPORARY
プールの外部に一時コンテナーを作成します。
config = PoolConfig(
max_pool_size=5,
exhaustion_strategy=ExhaustionStrategy.TEMPORARY,
)
プール統計のモニタリング
from llm_sandbox.pool import create_pool_manager
pool = create_pool_manager(backend="docker", lang="python")
# Get pool statistics
stats = pool.get_stats()
print(f"Total containers: {stats['total_size']}")
print(f"Idle containers: {stats['state_counts']['idle']}")
print(f"Busy containers: {stats['state_counts']['busy']}")
pool.close()
プーリングによるアーティファクトの抽出
コンテナープーリングでプロットや可視化をキャプチャするには、次のいずれかの方法を使用できます。
from llm_sandbox import ArtifactSandboxSession
from llm_sandbox.pool import create_pool_manager, PoolConfig
import base64
from pathlib import Path
# Create pool with pre-installed visualization libraries
pool = create_pool_manager(
backend="docker",
config=PoolConfig(max_pool_size=5, min_pool_size=2),
lang="python",
libraries=["matplotlib", "numpy"],
)
try:
# Option 1: Use pool parameter (recommended for API consistency)
with ArtifactSandboxSession(pool=pool, enable_plotting=True) as session:
result = session.run("""
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Pooled Execution - Sine Wave')
plt.show()
""")
# Save generated plots
for i, plot in enumerate(result.plots):
Path(f"plot_{i}.{plot.format.value}").write_bytes(
base64.b64decode(plot.content_base64)
)
print(f"Generated {len(result.plots)} plots using pooled container")
# Option 2: Use ArtifactPooledSandboxSession (explicit class)
# Both approaches work identically
from llm_sandbox.pool import ArtifactPooledSandboxSession
with ArtifactPooledSandboxSession(pool_manager=pool, enable_plotting=True) as session:
result = session.run("print('Same functionality, different API')")
finally:
pool.close()
例
詳しいデモについては、examples/ ディレクトリを参照してください。
- pool_basic_demo.py - プールの基本的な使用方法と設定
- pool_concurrent_demo.py - 並行実行のパターン
- pool_monitoring_demo.py - ヘルスモニタリングとライフサイクル管理
- pool_artifact_demo.py - プーリングによるアーティファクトの抽出(プロット、CSV、複合アーティファクト)
🤖 LLM フレームワークとの統合
11 種類のエージェントフレームワークで実行可能な、バージョンを固定したサンプルを
examples/agent_sdks/ に用意しています。
| OpenAI Agents SDK | Claude Agent SDK | LangChain |
| DeepAgents | LlamaIndex | Google ADK |
| CrewAI | Pydantic AI | smolagents |
| Strands Agents | AG2 |
各ファイルは単独で動作し、検証済みの SDK バージョンを明記しており、コンテナーのセキュリティ強化も適用しています。どのサンプルも、モデルが記述したコードに必要な制御機能を備えたサンドボックス呼び出しという、共通の中核を共有しています。
from llm_sandbox import SandboxSession
SANDBOX_RUNTIME = {
"network_mode": "none", # no egress
"mem_limit": "512m",
"pids_limit": 128, # bounds fork bombs
"security_opt": ["no-new-privileges:true"],
}
def run_python(code: str) -> str:
with SandboxSession(
lang="python",
keep_template=True, # else the image is re-pulled each call
runtime_configs=SANDBOX_RUNTIME,
) as session:
result = session.run(code, timeout=30)
return result.stdout if result.exit_code == 0 else result.stderr
重要
セキュリティポリシーは助言にすぎません。
session.is_safe(code)は判定を返しますが、 実行を阻止するわけではなく、ポリシーで問題ありと判定されたコードもrun()で実行されます。run()を呼び出す前に、ご自身で確認してください。 セキュリティガイドをご覧ください。
🔌 Model Context Protocol (MCP) サーバー
LLM Sandbox は、Claude Desktop などの AI アシスタントがサンドボックス環境でコードを安全に実行できるようにする、Model Context Protocol (MCP) サーバーを提供しています。この統合により、LLM は自動的に可視化を取得し、複数の言語をサポートしながら、コードを直接実行できます。
機能
- 安全なコード実行:お好みのバックエンドを使用して、分離されたコンテナー内でコードを実行します
- 複数言語のサポート:Python、JavaScript、Java、C++、Go、R、Ruby のコードを実行します
- 可視化の自動取得:プロットや可視化を自動的に取得して返します
- ライブラリ管理:パッケージや依存関係を必要に応じてインストールします
- 柔軟なバックエンドのサポート:Docker、Podman、Kubernetes のバックエンドから選択できます
インストール
お好みのバックエンドに対応した MCP サポート付きの LLM Sandbox をインストールします。
# For Docker backend
pip install 'llm-sandbox[mcp-docker]'
# For Podman backend
pip install 'llm-sandbox[mcp-podman]'
# For Kubernetes backend
pip install 'llm-sandbox[mcp-k8s]'
設定
以下の設定を MCP クライアントに追加します(例:Claude Desktop の場合は claude_desktop_config.json)。
{
"mcpServers": {
"llm-sandbox": {
"command": "python3",
"args": ["-m", "llm_sandbox.mcp_server.server"],
}
}
}
バックエンド固有の設定
使用するバックエンドに合わせて、BACKEND 環境変数を設定する必要があります。使用するバックエンドによっては、ほかの環境変数の設定も必要になる場合があります。たとえば、DOCKER_HOST がシステムで自動設定されていない場合は、使用するホストを指定する DOCKER_HOST 環境変数の設定が必要になることがあります。
Docker(デフォルト):
{
"mcpServers": {
"llm-sandbox": {
"command": "python3",
"args": ["-m", "llm_sandbox.mcp_server.server"],
"env": {
"BACKEND": "docker",
"DOCKER_HOST": "unix:///var/run/docker.sock" // change this to the actual host you are using
}
}
}
}
Podman:
{
"mcpServers": {
"llm-sandbox": {
"command": "python3",
"args": ["-m", "llm_sandbox.mcp_server.server"],
"env": {
"BACKEND": "podman",
"DOCKER_HOST": "unix:///var/run/podman/podman.sock" // change this to the actual host you are using
}
}
}
}
Kubernetes の場合は、kubeconfig ファイルのパスを指定する KUBECONFIG 環境変数の設定が必要になることがあります。
Kubernetes:
{
"mcpServers": {
"llm-sandbox": {
"command": "python3",
"args": ["-m", "llm_sandbox.mcp_server.server"],
"env": {
"BACKEND": "kubernetes",
"KUBECONFIG": "/path/to/kubeconfig" // change this to the actual path to your kubeconfig file
}
}
}
}
ランタイム設定の環境変数
Docker、Podman、Micromamba バックエンドでは、MCP サーバーが SANDBOX_* 環境変数をセッションの runtime_configs に変換できます。
{
"mcpServers": {
"llm-sandbox": {
"command": "python3",
"args": ["-m", "llm_sandbox.mcp_server.server"],
"env": {
"BACKEND": "podman",
"DOCKER_HOST": "unix:///run/podman/podman.sock",
"SANDBOX_NETWORK_MODE": "none",
"SANDBOX_READ_ONLY": "true",
"SANDBOX_CAP_DROP": "ALL",
"SANDBOX_SECURITY_OPT": "no-new-privileges:true",
"SANDBOX_MEMORY": "4g",
"SANDBOX_CPU_COUNT": "1"
}
}
}
}
対応している変数:SANDBOX_NETWORK_MODE、SANDBOX_READ_ONLY、SANDBOX_MEMORY、SANDBOX_MEM_LIMIT、
SANDBOX_CPUS、SANDBOX_CPU_COUNT、SANDBOX_CAP_DROP、SANDBOX_SECURITY_OPT、SANDBOX_PRIVILEGED。
SANDBOX_MEMORY は、バックエンドで安全に使用できる mem_limit ランタイム設定に正規化されます。SANDBOX_CPUS と
SANDBOX_CPU_COUNT は、Linux と互換性のある CPU クォータ設定に正規化されます。
セキュリティに関する注意:セキュリティを強化したサンドボックスでは、
SANDBOX_NETWORK_MODE=none、SANDBOX_READ_ONLY=true、SANDBOX_CAP_DROP=ALL、および制限的なSANDBOX_SECURITY_OPT値を優先してください。 明示的に必要な場合を除き、SANDBOX_PRIVILEGED=trueは使用しないでください。CPU とメモリの制限は最小限に抑え、 権限を再び有効にする設定の組み合わせは必ず監査してください。SANDBOX_*設定は、この MCP サーバーの Kubernetes バックエンドには適用されません。 Kubernetes 固有のリソース制御やセキュリティ制御が必要な場合は、カスタム MCP ラッパーを介してカスタムのpod_manifestを指定するか、llm-sandbox の Python API を直接使用してください。
利用可能なツール
MCP サーバーは次のツールを提供します。
execute_code:安全なサンドボックス内でコードを実行し、生成されたビジュアライゼーションを自動的にキャプチャしますget_supported_languages:対応しているプログラミング言語の一覧を取得しますget_language_details:特定の言語に関する詳細情報を取得します
使用例
設定が完了すると、AI アシスタントにコードの実行を依頼でき、自動的に LLM Sandbox MCP サーバーが使用されます。
"Create a scatter plot showing the relationship between x and y data points using matplotlib"
アシスタントは安全なサンドボックス内で Python コードを実行し、生成されたプロットやビジュアライゼーションを自動的にキャプチャします。
🏗️ アーキテクチャ
graph LR
A[LLM Client] --> B[LLM Sandbox]
B --> C[Container Backend]
A1[OpenAI] --> A
A2[Anthropic] --> A
A3[Local LLMs] --> A
A4[LangChain] --> A
A5[LangGraph] --> A
A6[LlamaIndex] --> A
A7[MCP Clients] --> A
C --> C1[Docker]
C --> C2[Kubernetes]
C --> C3[Podman]
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e8
style A1 fill:#fff3e0
style A2 fill:#fff3e0
style A3 fill:#fff3e0
style A4 fill:#fff3e0
style A5 fill:#fff3e0
style A6 fill:#fff3e0
style A7 fill:#fff3e0
style C1 fill:#e0f2f1
style C2 fill:#e0f2f1
style C3 fill:#e0f2f1
📚 ドキュメント
- ドキュメント全文 - ドキュメント一式
- はじめに - インストールと基本的な使い方
- 設定 - 設定オプションの詳細
- セキュリティ - セキュリティポリシーとベストプラクティス
- バックエンド - コンテナバックエンドの詳細
- 言語 - 対応しているプログラミング言語
- インテグレーション - LLM フレームワークとのインテグレーション
- API リファレンス - API ドキュメント一式
- 使用例 - 実際の使用例
🤝 コントリビューション
コントリビューションを歓迎します!詳細はコントリビューションガイドをご覧ください。
開発環境のセットアップ
# Clone the repository
git clone https://github.com/vndee/llm-sandbox.git
cd llm-sandbox
# Install in development mode
make install
# Run pre-commit hooks
uv run pre-commit run -a
# Run tests
make test
📖 引用
研究で LLM Sandbox を使用する場合は、次の形式で引用してください。
@software{huynh_llm_sandbox,
author = {Huynh, Duy V.},
title = {{LLM Sandbox: a portable runtime for securely executing LLM-generated code}},
publisher = {Zenodo},
doi = {10.5281/zenodo.21760525},
url = {https://doi.org/10.5281/zenodo.21760525}
}
上記の DOI は最新リリースを参照します。特定のバージョンを引用するには、Zenodo のレコードにある該当リリース固有の DOI を使用してください。
📄 ライセンス
このプロジェクトは MIT License のもとでライセンスされています。詳細は LICENSE ファイルをご覧ください。
🌟 スター履歴
LLM Sandbox が役に立った場合は、GitHub でスターを付けていただけると幸いです!
📞 サポートとコミュニティ
- GitHub Issues:バグの報告や機能のリクエスト
- GitHub Discussions:コミュニティに参加
- PyPI:pypi.org/project/llm-sandbox
- ドキュメント:vndee.github.io/llm-sandbox
コントリビューター
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。