mcpField
L
LLM Sandbox

LLM Sandbox

ローカル
vndee.github.io開発ツール1.1k3 日前に更新

LLM Sandbox について

LLM Sandbox は、LLM 生成コードをコンテナやローカルのサンドボックスで実行するための共通 API を開発者に提供します。リソース、ネットワーク、ホストアクセスを設定でき、多言語実行、ファイル操作、成果物の抽出に対応します。

主な機能

  1. 01コンテナおよびローカルの隔離バックエンド
  2. 02セキュリティポリシーとリソース制限
  3. 03サンドボックスのネットワーク制御
  4. 04多言語実行と依存関係のインストール
  5. 05ホストとサンドボックス間のファイル操作
  6. 06プロットなどの成果物の取得

活用シーン

  1. 01隔離環境で LLM 生成コードを実行
  2. 02実行リソースやネットワークアクセスを制限
  3. 03ライブラリを導入して複数言語のコードを実行
  4. 04入力ファイルを渡し、生成されたプロットを収集

MCP 対応

MCP サーバーを備えており、MCP クライアントから安全なサンドボックス内でコードを実行できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"vndee-llm-sandbox": {
"command": "uvx",
"args": [
"llm-sandbox"
],
"env": {
"BACKEND": "<BACKEND>",
"DOCKER_HOST": "<DOCKER_HOST>",
"KUBECONFIG": "<KUBECONFIG>",
"NAMESPACE": "<NAMESPACE>",
"COMMIT_CONTAINER": "<COMMIT_CONTAINER>",
"KEEP_TEMPLATE": "<KEEP_TEMPLATE>",
"SANDBOX_NETWORK_MODE": "<SANDBOX_NETWORK_MODE>",
"SANDBOX_READ_ONLY": "<SANDBOX_READ_ONLY>",
"SANDBOX_CAP_DROP": "<SANDBOX_CAP_DROP>",
"SANDBOX_SECURITY_OPT": "<SANDBOX_SECURITY_OPT>",
"SANDBOX_MEMORY": "<SANDBOX_MEMORY>",
"SANDBOX_CPUS": "<SANDBOX_CPUS>"
}
}
}
}
起動コマンドuvx llm-sandbox
設定が必要な環境変数
BACKENDContainer 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.sock
KUBECONFIGPath 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 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypillm-sandbox0.3.43

ツール

3

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
codestringはい
timeoutintegerいいえ
languagestringいいえ
librariesanyいいえ

詳細

LLM サンドボックス

LLM が生成したコードを簡単かつ安全に実行

SonarQube Cloud

Quality Gate Status PyPI Downloads Release Build status CodeFactor codecov MCP Enabled DOI

LLM Sandbox は、コンテナーおよびローカルの Linux と Windows のサンドボックスバックエンド向けに、共通 API を介して大規模言語モデル(LLM)が生成したコードを実行します。デプロイ環境に適した隔離バックエンドを選択し、セキュリティ制御を設定して、同じコード実行 API とファイル API を再利用できます。

ドキュメント:https://vndee.github.io/llm-sandbox/

バックエンドのベンチマークでは、起動、実行、ファイル転送、並行処理について Docker、Bubblewrap、NsJail を比較し、信頼区間と再現可能なエビデンスを掲載しています。

README の画像

✨ 新機能: このプロジェクトは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/ ディレクトリを参照してください。

🤖 LLM フレームワークとの統合

11 種類のエージェントフレームワークで実行可能な、バージョンを固定したサンプルを examples/agent_sdks/ に用意しています。

OpenAI Agents SDKClaude Agent SDKLangChain
DeepAgentsLlamaIndexGoogle ADK
CrewAIPydantic AIsmolagents
Strands AgentsAG2

各ファイルは単独で動作し、検証済みの 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

📚 ドキュメント

🤝 コントリビューション

コントリビューションを歓迎します!詳細はコントリビューションガイドをご覧ください。

開発環境のセットアップ
# 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 でスターを付けていただけると幸いです!

📞 サポートとコミュニティ

コントリビューター

README の画像 ## Star History

Star History Chart

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。