【Python】Cohere Terrariumで安全なPythonサンドボックス環境を構築する

# 

## はじめに

LLM（大規模言語モデル）が生成したPythonコードを安全に実行することは、AI開発において重要な課題の一つです。未検証のコードを実行することによるセキュリティリスクを最小限に抑えながら、必要な機能は維持したいというニーズに応えるため、Cohereがオープンソースプロジェクト「Terrarium」を公開しています。

本記事では、Terrariumの特徴と使い方について、実践的な観点から解説していきます。

## Terrariumとは

Terrariumは、信頼できないユーザーやLLMが生成したPythonコードを安全に実行するためのサンドボックス環境です。Docker上で動作し、例えばGCP Cloud Runにデプロイして使用することができます。

主な特徴は以下の通りです：

1. **高速な実行環境**
   - Matplotlib使用時の画像生成で約900ms（PNG）、500ms（SVG）という低レイテンシーを実現
   - GCP Cloud Run上で2GB メモリ + 1vCPUという軽量な構成で運用可能

2. **完全な隔離環境**
   - 呼び出しごとにサンドボックスが完全にリセット
   - 呼び出し間での状態の引き継ぎが一切なし
   - ファイルシステムへのアクセスを制限

3. **豊富なパッケージサポート**
   - numpy, pandas, matplotlib, sympyなど、データ分析でよく使用するパッケージを標準搭載
   - Pyodideベースの実装により、WebAssembly経由で多くのPythonパッケージを利用可能

## 技術的な仕組み

### なぜPyodideなのか？

Terrariumは、CPythonの代わりにPyodideを採用しています。PyodideはCPythonをWebAssemblyにコンパイルした実装で、Node.jsサーバー環境で使用する場合でも以下のような重要な利点があります：

1. **強力な分離とサンドボックス化**
   - WebAssemblyの仕様に基づく厳格なメモリ空間の分離
   - ホストシステムからの完全な隔離が実現可能
   - ファイルシステムやネットワークへのアクセスを細かく制御可能

2. **予測可能なリソース管理**
   - メモリ使用量の制限が容易
   - プロセス分離なしでの安全な実行環境
   - 実行時間の制御が可能

3. **最適化された科学計算環境**
   - numpy, pandas, matplotlibなどの主要パッケージが事前コンパイル済み
   - WebAssemblyレベルで最適化された実装により高いパフォーマンス
   - パッケージ間の依存関係が解決済み

4. **効率的なランタイム**
   - 軽量なコンテナ環境（2GB メモリ + 1vCPU）で動作
   - 実行環境の再起動が高速
   - 状態のリセットが確実

### サンドボックスの構造

Terrariumは、多層的なサンドボックス構造を採用しています：

1. **Pyodideレイヤー**
   - WebAssemblyにコンパイルされたCPythonを使用
   - Node.jsプロセス内でPythonコードをパース、コンパイル、実行
   - メモリ上の仮想ファイルシステムを提供
   - スレッド、マルチプロセス、サブプロセスの実行を制限
   - ネットワークアクセスを制限（デフォルト設定）

2. **コンテナレイヤー（GCP Cloud Run）**
   - 実行時間の制限
   - ホストネットワークからの隔離

## 実践：Terrariumの使い方

### 1. 基本的な使用方法

単純な数値計算を実行する例：

```bash
curl -X POST --url <デプロイされたCloud RunのURL> \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
--no-buffer \
--data-raw '{"code": "1 + 1"}'
```

レスポンス：
```json
{
  "output_files": [],
  "final_expression": 2,
  "success": true,
  "std_out": "",
  "std_err": "",
  "code_runtime": 16
}
```

### 2. データ可視化の例

Terrariumは、Matplotlibを使用したデータ可視化もサポートしています。以下は正弦波のグラフを生成し、PNG形式で保存する例です：

```bash
curl -X POST -H "Content-Type: application/json" \
  --url http://localhost:8080 \
  --data-raw '{
    "code": "import matplotlib.pyplot as plt\nimport numpy as np\n\n# データの準備\nx = np.linspace(0, 10, 100)\ny = np.sin(x)\n\n# グラフの作成\nplt.plot(x, y)\nplt.title(\"Sin Wave\")\nplt.xlabel(\"x\")\nplt.ylabel(\"sin(x)\")\n\n# PNGとして保存\nplt.savefig(\"sin_wave.png\", dpi=200)"
  }'
```

このリクエストを実行すると、以下のような応答が返されます：

```json
{
  "output_files": [
    {
      "name": "sin_wave.png",
      "data": "..." // Base64エンコードされた画像データ
    }
  ],
  "final_expression": null,
  "success": true,
  "std_out": "",
  "std_err": "",
  "code_runtime": 150
}
```

出力ファイル`sin_wave.png`には、Base64エンコードされた画像データが含まれています。このデータをデコードすることで、生成されたグラフを表示できます。

注意点：
- Matplotlibの`plt.show()`は使用できません（これはTerrariumの制限事項です）
- 代わりに`plt.savefig()`を使用して画像を保存します
- `dpi`パラメータは200程度が推奨されます（高すぎるとエラーが発生する可能性があります）

### 3. ローカルでの開発環境構築

Terrariumはnpmを使用して簡単にローカル環境を構築できます。以下の手順で環境を準備します：

```bash
# リポジトリのクローン
git clone https://github.com/cohere-ai/cohere-terrarium.git
cd cohere-terrarium

# 依存関係のインストール
npm install

# Pyodideのキャッシュディレクトリを作成
mkdir pyodide_cache

# 開発サーバーの起動
npm run dev
```

開発サーバーが起動したら、curlコマンドで動作確認ができます：

```bash
curl -X POST -H "Content-Type: application/json" \
  --url http://localhost:8080 \
  --data-raw '{"code": "print(\"Hello, Terrarium!\")"}'
```

期待される応答：
```json
{
  "output_files": [],
  "final_expression": null,
  "success": true,
  "std_out": "Hello, Terrarium!\n",
  "std_err": "",
  "code_runtime": 20
}
```

より実践的な例として、numpyを使用した計算を試してみましょう：

```bash
curl -X POST -H "Content-Type: application/json" \
  --url http://localhost:8080 \
  --data-raw '{
    "code": "import numpy as np\nx = np.array([1, 2, 3])\nprint(f\"Mean: {np.mean(x)}\")"
  }'
```

この例では、Terrariumに組み込まれているnumpyパッケージを使用して簡単な統計計算を行います。Terrariumは科学技術計算パッケージが事前に組み込まれているため、追加のインストール作業なしで利用できます。

## デプロイ方法

### Docker環境へのデプロイ

```bash
# ビルド
docker build -t terrarium .

# 実行
docker run -p 8080:8080 terrarium
```

### GCP Cloud Runへのデプロイ

```bash
gcloud run deploy <デプロイ名> \
--region=us-central1 \
--source . \
--concurrency=1 \
--min-instances=3 \
--max-instances=100 \
--cpu=2 \
--memory=4Gi \
--no-cpu-throttling \
--cpu-boost \
--timeout=100
```

## 現状の制限事項

1. **パッケージインストールの制限**
   - Pyodideが提供するパッケージのみ使用可能
   - カスタムパッケージのインストールは不可

2. **実行時の制限**
   - 複雑な計算での「Maximum call stack size exceeded」エラーの可能性
   - Matplotlibの高DPI設定での画像生成時にエラーが発生することがある

3. **ネットワークアクセス**
   - デフォルトでは外部ネットワークへのアクセスが無効
   - 設計上の選択であり、将来的に変更される可能性あり

## まとめ

Terrariumは、LLMが生成したPythonコードを安全に実行するための優れたソリューションを提供しています。完全な隔離環境での実行、豊富なパッケージサポート、そして低レイテンシーな実行環境という特徴は、AI開発における重要なユースケースをカバーしています。

制限事項はありますが、セキュリティと利便性のバランスを考慮した設計となっており、特にAIアプリケーションの開発において有用なツールとなることでしょう。

## 参考リンク

- [Cohere Terrarium GitHub リポジトリ](https://github.com/cohere-ai/cohere-terrarium)
- [Pyodide 公式ドキュメント](https://pyodide.org/en/stable/index.html)