
AIエージェントタスクをサンドボックス化するためのセキュアなランタイム。信頼できないコードを隔離されたWebAssembly環境で実行します。
Capsule は、信頼されていないコードを分離された環境で実行するためのランタイムです。各タスクは独自の WebAssembly サンドボックス内で動作し、以下を提供します。
Python 関数に @task デコレータを付けるだけです:
from capsule import task
@task(name="analyze_data", compute="MEDIUM", ram="512MB", timeout="30s", max_retries=1)
def analyze_data(dataset: list) -> dict:
"""Process data in an isolated, resource-controlled environment."""
# Your code runs safely in a Wasm sandbox
return {"processed": len(dataset), "status": "complete"}
npm エコシステムにフルアクセスできる task() ラッパー関数を使用します:
import { task } from "@capsule-run/sdk";
export const analyzeData = task({
name: "analyze_data",
compute: "MEDIUM",
ram: "512MB",
timeout: "30s",
maxRetries: 1
}, (dataset: number[]): object => {
// Your code runs safely in a Wasm sandbox
return { processed: dataset.length, status: "complete" };
});
[!NOTE] ランタイムはエントリポイントとして
"main"という名前のタスクを必要とします。Python は定義されていない場合に自動的に作成しますが、明示的に設定することをお勧めします。
capsule run main.py(または main.ts)を実行すると、コードが WebAssembly モジュールにコンパイルされ、分離されたサンドボックスで実行されます。
各タスクは構成可能なリソース制限を持つ独自のサンドボックス内で動作し、障害が他のワークフロー部分に波及しないようにします。ホストシステムは、Wasm の燃料計測による CPU 割り当てからメモリ制約、タイムアウトの実施まで、実行のあらゆる側面を制御します。
pip install capsule-run
hello.py を作成します:
from capsule import task
@task(name="main", compute="LOW", ram="64MB")
def main() -> str:
return "Hello from Capsule!"
実行します:
capsule run hello.py
npm install -g @capsule-run/cli
npm install @capsule-run/sdk
hello.ts を作成します:
import { task } from "@capsule-run/sdk";
export const main = task({
name: "main",
compute: "LOW",
ram: "64MB"
}, (): string => {
return "Hello from Capsule!";
});
実行します:
capsule run hello.ts
[!TIP]
--verboseを追加すると、タスクの実行状況がリアルタイムで表示されます。
run() 関数を使うと、CLI ではなくコードからプログラム的にタスクを実行できます。args は自動的に main タスクのパラメータとして転送されます。
from capsule import run
result = await run(
file="./sandbox.py",
args=["code to execute"]
)
sandbox.py を作成します:
from capsule import task
@task(name="main", compute="LOW", ram="64MB")
def main(code: str) -> str:
return eval(code)
[!IMPORTANT] TypeScript でランナー関数を使用するには、依存関係に
@capsule-run/cliが必要です。
import { run } from '@capsule-run/sdk/runner';
const result = await run({
file: './sandbox.ts',
args: ['code to execute']
});
sandbox.ts を作成します:
import { task } from "@capsule-run/sdk";
export const main = task({
name: "main",
compute: "LOW",
ram: "64MB"
}, (code: string): string => {
return eval(code);
});
[!TIP] すぐに使える設定済みのソリューションをお探しの場合は、Python アダプター または TypeScript アダプター をご確認ください。
以下のパラメーターでタスクを構成します:
| パラメーター | 説明 | 型 | デフォルト | 例 |
|---|---|---|---|---|
name | タスク識別子 | str | 関数名 (Python) / 必須 (TS) | "process_data" |
compute | CPU 割り当てレベル: "LOW", "MEDIUM", または "HIGH" | str | "MEDIUM" | "HIGH" |
ram | タスクのメモリ制限 | str | 無制限 | "512MB", "2GB" |
timeout | 最大実行時間 | str | 無制限 | "30s", "5m", "1h" |
max_retries / maxRetries | 失敗時のリトライ回数 | int | 0 | 3 |
allowed_files / allowedFiles | サンドボックス内でアクセス可能なフォルダー(オプションのアクセスモード付き) | list | [] | ["./data"], [{"path": "./data", "mode": "ro"}] |
allowed_hosts / allowedHosts | サンドボックス内でアクセス可能なドメイン | list | [] | ["api.openai.com", "*.anthropic.com"] |
env_variables / envVariables | サンドボックス内でアクセス可能な環境変数 | list | [] | ["API_KEY"] |
Capsule は WebAssembly の 燃料メカニズム を通じて CPU 使用率を制御します。このメカニズムは命令実行を計測します。コンピュートレベルによって、タスクが受け取る燃料の量が決まります。
compute="1000000")。実行制限を精密に制御できます。すべてのタスクは、結果と実行メタデータの両方を含む構造化された JSON エンベロープを返します:
{
"success": true,
"result": "Hello from Capsule!",
"error": null,
"execution": {
"task_name": "data_processor",
"duration_ms": 1523,
"retries": 0,
"fuel_consumed": 45000,
"ram_used": 1200000,
"host_requests": [{...}]
}
}
レスポンスフィールド:
success — タスクが正常に完了したかどうかを示すブール値result — タスクからの実際の戻り値(json、文字列、失敗時は null など)error — タスクが失敗した場合のエラー詳細({ error_type: string, message: string })execution — パフォーマンスメトリクス:
task_name — 実行されたタスクの名前duration_ms — 実行時間(ミリ秒)retries — 発生したリトライ回数fuel_consumed — 使用された CPU リソース(コンピュートレベルを参照)ram_used — 使用されたピークメモリ(バイト)host_requests — タスクによって行われたホストリクエストのリストタスクは allowed_hosts で指定されたドメインに対して HTTP リクエストを行うことができます。デフォルトでは、アウトバウンドリクエストは許可されません([])。アクセスを許可するドメインの許可リストを指定するか、["*"] を使用してすべてのドメインを許可します。
import json
from capsule import task
from urllib.request import urlopen
@task(name="main", allowed_hosts=["api.openai.com", "*.anthropic.com"])
def main() -> dict:
with urlopen("https://api.openai.com/v1/models") as response:
return json.loads(response.read().decode("utf-8"))
import { task } from "@capsule-run/sdk";
export const main = task({
name: "main",
allowedHosts: ["api.openai.com", "*.anthropic.com"]
}, async () => {
const response = await fetch("https://api.openai.com/v1/models");
return response.json();
});
タスクは allowed_files で指定されたディレクトリ内のファイルの読み取りと書き込みを行うことができます。これらのディレクトリ外のファイルへのアクセスは不可能です。
[!NOTE]
allowed_filesはディレクトリパスのみをサポートし、個別のファイルはサポートしません。
各エントリはプレーンなパス(デフォルトで読み書き可能)または明示的な mode を持つ構造化オブジェクトにできます:
"read-only"(または "ro")"read-write"(または "rw")Python の標準ファイル操作は正常に動作します。open()、os、pathlib、または任意のファイル操作ライブラリを使用してください。
from capsule import task
@task(name="main", allowed_files=[
{"path": "./data", "mode": "read-only"},
{"path": "./output", "mode": "read-write"},
])
def main() -> str:
with open("./data/input.txt") as f:
content = f.read()
with open("./output/result.txt", "w") as f:
f.write(content)
return content
プレーンな文字列も引き続き受け付けられます: allowed_files=["./output"] はデフォルトで読み書き可能になります。
一般的な Node.js の組み込みモジュールが利用可能です。標準の fs モジュールを使用します:
import { task } from "@capsule-run/sdk";
import fs from "fs/promises";
export const main = task({
name: "main",
allowedFiles: [
{ path: "./data", mode: "read-only" },
{ path: "./output", mode: "read-write" },
]
}, async () => {
const content = await fs.readFile("./data/input.txt", "utf8");
await fs.writeFile("./output/result.txt", content);
return content;
});