
2026/01/30 23:34
Show HN:Amla Sandbox – AI エージェント向け WASM ベースの bash シェルサンドボックス
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Amla‑sandbox は、軽量で WebAssembly ベースの環境であり、LLM エージェントがユーザー生成コードを安全かつ効率的に実行できるようにします。
ほとんどの人気エージェントフレームワーク(LangChain、AutoGen、SWE‑Agent)は、Python のやexec()を使って生成されたスクリプトを実行し、任意のホスト実行や CVE‑2025‑68664 などのプロンプト注入攻撃に対して脆弱です。Amla‑sandbox は、WASM サンドボックスで WASI を使用してコードを実行することでこれらのリスクを軽減し、メモリ分離、ネットワークアクセスなし、書き込み可能な仮想ファイルシステムがsubprocess.run()と/workspaceに限定されます。/tmp
主な技術機能
• 制約強制:各ツール呼び出しは、MethodCapability、およびConstraintSet定義(例:amount ≤ 10000、currency ∈ {USD, EUR})に対して検証されてから実行されます。Param
• Yield ベースの実行:サンドボックスは各ツール呼び出し後に一時停止し、Python ホストが機能チェックを行い、ツールを実行し、スクリプトを再開します。これによりリソース使用量を制御できます。
• 単一スクリプト最適化:エージェントは複数のツールを呼び出す JavaScript またはシェルスクリプトを1つだけ書くことができ、LLM → tool × N から1回の呼び出しへと LLM の往復回数を削減します。
• JavaScript API:ツールはオブジェクトとして呼び出されます(例:)、結果はawait get_weather({city:"SF"})またはreturnを介して返ります。console.log()
• 非同期スケジューラ & VFS:WASM 内でシェルビルトイン、ファイルシステム操作、および機能検証を処理します。
サンドボックスは単一の pip コマンド()でインストールされ、Docker や VM のオーバーヘッドなしに1つのバイナリのみを必要とします。パフォーマンスベンチマークでは、初回コンパイル時間が約300 ms、その後のロードが約0.5 ms であることが示されています。pip install "git+https://github.com/amlalabs/amla-sandbox"
統合:LangChain ツールとしてラップできます()、これにより LangGraph、React エージェント、およびその他のフレームワークと互換性があります。sandbox.as_langchain_tool()
制限事項と将来の作業:現在の環境は完全な Linux 機能、ネイティブモジュール、GPU サポート、および無限ループ保護を欠いており、永続状態や任意の依存関係を必要としない典型的なエージェントユースケースに最適です。将来のリリースでは不足している Linux 機能と GPU アクセスが追加される可能性があります。
本文
amla‑sandbox
1. 背景
ほとんどの人気エージェントフレームワークは、LLM が生成したコードを
subprocess や exec() で実行します。これはホスト上で任意コードが実行されることを意味し、プロンプトインジェクション一発で破綻してしまいます。
| フレームワーク | 実行方法 | ソース |
|---|---|---|
| LangChain | | CVE‑2025‑68664, GitHub #5294 |
| AutoGen | | Code Executors docs |
| SWE‑Agent | | SWE‑ReX |
Docker 分離を提供するフレームワーク(OpenHands、AutoGen など)もありますが、Docker デーモンの起動とコンテナ管理が必要です。
2. amla‑sandbox の概要
WebAssembly(WASM)サンドボックスで機能制御を行います。
- ツール呼び出しは明示的に許可されたもののみ
- 仮想ファイルシステム:ネットワーク不可、シェル逃走不可
uv pip install "git+https://github.com/amlalabs/amla-sandbox"
from amla_sandbox import create_sandbox_tool sandbox = create_sandbox_tool(tools=[stripe_api, database]) # 10 個のツール呼び出しを一つの JavaScript スクリプトで実行 result = sandbox.run( ''' const txns = await stripe.listTransactions({customer: "cus_123"}); const disputed = txns.filter(t => t.disputed); console.log(disputed[0]); ''', language="javascript" ) # シェルパイプラインを使う例 result = sandbox.run( ''' tool stripe.listTransactions --customer cus_123 | jq '[.[] | select(.disputed)] | .[0]' ''', language="shell" )
3. なぜ重要か
ツール呼び出しはコストが高い:
LLM → ツール → LLM → ツール … のようにラウンドトリップが発生します。10 回呼び出すと 10 回のインボケーションです。コードモードでは「全てを一度に実行する」スクリプトでこれを圧縮できます。
LLM → スクリプト(10 つ全てを処理)→ 結果
ただし、生成されたコードをそのまま
eval したり実行したりすることはできません。そこで「安全に実行」か「トークンコストが増える」という二択になります。amla‑sandbox は両方のメリットを提供します:コードモードの効率性 + 実際の隔離。
4. セキュリティモデル
サンドボックスは WebAssembly(WASI)で実行され、最小限のシステムコールインターフェースを持ちます。
WASM はメモリが線形メモリとしてバウンダリチェック付きで隔離されており、ホストアドレス空間への脱出は不可能です。
使用している
wasmtime ランタイムは防御層設計で構築され、メモリ安全性が形式的に検証されています。
さらに、ツール呼び出しは権限ベースの認可を通過します:
from amla_sandbox import Sandbox, MethodCapability, ConstraintSet, Param sandbox = Sandbox( capabilities=[ MethodCapability( method_pattern="stripe/charges/*", constraints=ConstraintSet([ Param("amount") <= 10000, Param("currency").is_in(["USD", "EUR"]), ]), max_calls=100, ), ], tool_handler=my_handler, ) # 成功例 sandbox.execute('await stripe.charges.create({amount: 500, currency: "USD"})') # 失敗例(額が上限を超える) sandbox.execute('await stripe.charges.create({amount: 50000, currency: "USD"})')
この設計は seL4 のような権限ベースセキュリティに倣っており、エージェントには「暗黙の権限」が与えられません。
プロンプトインジェクションが未解決問題であるため、権限制御による防御層設計は攻撃範囲を大幅に縮小します。
5. クイックスタート
from amla_sandbox import create_sandbox_tool sandbox = create_sandbox_tool() # JavaScript print(sandbox.run("console.log('hello'.toUpperCase())", language="javascript")) # -> "HELLO" # シェル print(sandbox.run("echo 'hello' | tr 'a-z' 'A-Z'", language="shell")) # -> "HELLO"
ツール付き例:
def get_weather(city: str) -> dict: return {"city": city, "temp": 72} sandbox = create_sandbox_tool(tools=[get_weather]) print( sandbox.run("const w = await get_weather({city: 'SF'}); console.log(w);", language="javascript") )
制約付き例:
sandbox = create_sandbox_tool( tools=[transfer_money], constraints={ "transfer_money": { "amount": "<=1000", "currency": ["USD", "EUR"], }, }, max_calls={"transfer_money": 10}, )
6. JavaScript API の注意点
- オブジェクト構文が必須
await get_weather({city: "SF"}); await transfer({to: "alice", amount: 500}); - 位置引数は不可:
→ エラーawait get_weather("SF"); - 出力は
またはreturn
を使うconsole.log()return await get_weather({city: "SF"}); // -> {"city":"SF","temp":72} console.log(JSON.stringify({a: 1})); // -> {"a":1} - VFS は
と/workspace
のみ書き込み可能/tmp
ルートは読み取り専用です。
7. LangGraph との統合
from langgraph.prebuilt import create_react_agent from langchain_anthropic import ChatAnthropic from amla_sandbox import create_sandbox_tool sandbox = create_sandbox_tool(tools=[get_weather, search_db]) agent = create_react_agent( ChatAnthropic(model="claude-sonnet-4-20250514"), [sandbox.as_langchain_tool()] # LLM が JS/シェルを書き、ツールを呼び出す )
細かい権限制御:
from amla_sandbox import SandboxTool, MethodCapability, ConstraintSet, Param caps = [ MethodCapability( method_pattern="mcp:search_db", constraints=ConstraintSet([Param("query").starts_with("SELECT")]), max_calls=5, ) ] sandbox_tool = SandboxTool.from_functions([search_db], capabilities=caps) agent = create_react_agent(model, [sandbox_tool.as_langchain_tool()])
8. アーキテクチャ
┌───────────────────────┐ │ WASM Sandbox │ ├───────────────────────┤ │ Async Scheduler │ (タスク待機/実行/完了) ├───────────────────────┤ │ VFS /workspace │ │ Shell builtins │ │ Capability validation│ └─────────────▲─────────┘ │ ▼ ┌───────────────────────┐ │ Python Host │ │ │ │ while sandbox.has_work(): │ │ req = sandbox.step() # ツール呼び出しリクエスト │ │ sandbox.resume(execute(req)) │ └───────────────────────┘
サンドボックスはツール呼び出しで yield します。ホスト側が実行(権限チェック後)し、再開します。JS ランタイムは QuickJS が WASM 内で動作しています。
9. プリコンパイル
- 初回起動時に WASM モジュールをコンパイル(約300 ms)。
- キャッシュすると以降のロードが約0.5 ms です。
10. 制約 DSL
from amla_sandbox import Param, ConstraintSet constraints = ConstraintSet([ Param("amount") >= 100, Param("amount") <= 10000, Param("currency").is_in(["USD", "EUR"]), Param("path").starts_with("/api/"), ])
メソッド名のパターンマッチ:
– 完全一致stripe/charges/create
– 単一セグメントstripe/charges/*
– 0 個以上のセグメントstripe/**
11. トレードオフ
| 取得できるもの | 取得できないもの |
|---|---|
| インフラ不要で隔離 | 完全な Linux 環境 |
| 権限制御 | ネイティブモジュールサポート |
| トークン効率 | GPU アクセス |
| - | 無限ループ保護( はハングする可能性あり) |
VM が必要で永続的な状態や任意の依存関係が欲しい場合は e2b や Modal を利用してください。amla‑sandbox は「生成コードを制御付きツールアクセスで安全に実行」したい一般的ケース向けです。
12. ライセンス
Python コードは MIT、WASM バイナリは現在プロプライエタリ(パッケージ内で自由使用できますが、別途抽出・再配布は禁止)。WASM 実行環境をオープンソース化する予定です。
公式サイト · サンプル · ドキュメント