Skip to content
tinAI
Go back

GitHub - amlalabs/amla-sandbox

Bài gốc: GitHub - amlalabs/amla-sandbox

Tác giả: Unknown

Ngày đăng: Dịch ngày:

TL;DR

amla-sandbox cung cấp một mô hình sandbox WASM an toàn cho phép thực thi mã mà không cần Docker hoặc VM. Nó giúp bảo vệ khỏi các mã độc tiềm tàng trong khi vẫn duy trì hiệu quả của mã.

amla-sandbox

Mọi framework của agent phổ biến chạy mã do LLM sinh ra qua subprocess hoặc exec(), dẫn đến rủi ro thực thi mã tuỳ ý. Một sơ suất và mã của bạn có thể bị xâm nhập.

Phương thức Thực thi của Framework

FrameworkPhương thức Thực thiNguồn
LangChainexec(command, globals, locals)CVE-2025-68664, GitHub #5294
AutoGensubprocess.run()Code Executors docs
SWE-Agentsubprocess.run(["bash", ...])SWE-ReX

Một số framework cung cấp cách ly Docker (OpenHands, AutoGen), nhưng điều này yêu cầu một Docker daemon và quản lý cơ sở hạ tầng Container.

amla-sandbox là một sandbox WASM với khả năng kiểm soát nghiêm ngặt. Agents chỉ có thể gọi các công cụ bạn cung cấp với các giới hạn do bạn định nghĩa. Hệ thống tệp ảo được cách ly, không có mạng và không có khả năng thoát lệnh.

pip install "git+https://github.com/amlalabs/amla-sandbox"

Không cần Docker hoặc VM. Một binary duy nhất, hoạt động ở mọi nơi.

from amla_sandbox import create_sandbox_tool

sandbox = create_sandbox_tool(tools=[stripe_api, database])

# Agent viết một script thay vì 10 lệnh tool (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")

# Hoặc với các shell pipelines
result = sandbox.run('''
 tool stripe.listTransactions --customer cus_123 | jq '[.[] | select(.disputed)] | .[0]'
''', language="shell")

Tại sao điều này quan trọng

Gọi công cụ rất tốn kém tài nguyên. Mỗi lần gọi là một chuyến đi khứ hồi qua mô hình:

LLM → tool → LLM → tool → LLM → tool → ...

Mười lần gọi công cụ = mười lần triệu gọi LLM. Chế độ mã giúp điều này trở nên đơn giản hơn:

LLM → script thực hiện tất cả 10 điều → kết quả

Nhưng bạn không thể chỉ đơn giản thực thi mã mà mô hình tạo ra. amla-sandbox cung cấp hiệu quả chế độ mã với sự cách ly thực sự.

Mô hình bảo mật

Sandbox chạy trong WebAssembly với WASI cho giao diện hệ thống cuộc gọi tối giản. WASM cung cấp cách ly bộ nhớ theo thiết kế—bộ nhớ tuyến tính được kiểm tra giới hạn, và không có cách nào để thoát ra không gian địa chỉ host.

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,
)

# This works
sandbox.execute('await stripe.charges.create({amount: 500, currency: "USD"})')

# This fails - amount exceeds capability
sandbox.execute('await stripe.charges.create({amount: 50000, currency: "USD"})')

Thiết kế này lấy ý tưởng từ bảo mật dựa trên khả năng, giống như trong hệ thống seL4. Truy cập được cấp phép rõ ràng và không có quyền hạn ngầm định.

Bắt đầu nhanh

from amla_sandbox import create_sandbox_tool

sandbox = create_sandbox_tool()

# JavaScript
sandbox.run("console.log('hello'.toUpperCase())", language="javascript")  # -> "HELLO"

# Shell
sandbox.run("echo 'hello' | tr 'a-z' 'A-Z'", language="shell")  # -> "HELLO"

# Với công cụ

def get_weather(city: str) -> dict:
    return {"city": city, "temp": 72}

sandbox = create_sandbox_tool(tools=[get_weather])
sandbox.run("const w = await get_weather({city: 'SF'}); console.log(w);", language="javascript")

Với các ràng buộc:

sandbox = create_sandbox_tool(
    tools=[transfer_money],
    constraints={
        "transfer_money": {
            "amount": "<=1000",
            "currency": ["USD", "EUR"],
        },
    },
    max_calls={"transfer_money": 10},
)

Ghi chú API JavaScript

// WORKS - công cụ luôn nhận đối số đối tượng
await get_weather({city: "SF"});
await transfer({to: "alice", amount: 500});

// FAILS - đối số vị trí không hoạt động
await get_weather("SF");  // Error: argument after ** must be a mapping
// Giá trị trả về được bắt và làm đầu ra
return await get_weather({city: "SF"});  // -> {"city":"SF","temp":72}
return {a: 1, b: 2};  // -> {"a":1,"b":2}
return "hello";  // -> hello (strings not double-quoted)

// console.log cũng hoạt động
console.log(JSON.stringify({a: 1}));  // -> {"a":1}

// Không có return = không có đầu ra
const x = 42;  // -> (no output)
// WORKS - /workspace và /tmp là ReadWrite
await fs.writeFile('/workspace/data.json', '{}');
await fs.mkdir('/tmp/cache');

// FAILS - root là read-only
await fs.mkdir('/mydir');  // EACCES: Permission denied

LangGraph

Để tích hợp với 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 viết JS/shell gọi các công cụ của bạn
)

Để kiểm soát khả năng chi tiết:

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()])

Kiến trúc

┌────────────────────────────────────────────────┐
│              WASM Sandbox                      │
│  ┌──────────────────────────────────────────┐  │
│  │         Async Scheduler                  │  │
│  │   tasks waiting/running/ready            │  │
│  └──────────────────────────────────────────┘  │
│  ┌────────────┐ ┌──────────┐ ┌──────────────┐  │
│  │  VFS       │ │ Shell    │ │ Capabilities │  │
│  │ /workspace │ │ builtins │ │ validation   │  │
│  └────────────┘ └──────────┘ └──────────────┘  │
│                    ↓ yield                     │
└════════════════════════════════════════════════┘


┌─────────────────────────────────────────────┐
│              Python Host                    │
│                                             │
│   while sandbox.has_work():                 │
│       req = sandbox.step()  # tool call     │
│       sandbox.resume(execute(req))          │
│                                             │
└─────────────────────────────────────────────┘

Sandbox nhả lệnh trên các call công cụ, host thực thi chúng (sau kiểm tra khả năng) và tiếp tục. QuickJS chạy trong WASM cho runtime JS.

Tiền biên dịch

Lần chạy đầu biên dịch module WASM (khoảng 300ms). Cache lại:

amla-precompile

Tải sau đó: khoảng 0.5ms.

DSL Ràng buộc

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/"),
])

Khớp mẫu cho tên phương thức:

Ưu nhược điểm

Nếu cần một VM thực sự với trạng thái thường trực và phụ thuộc tuỳ ý, hãy dùng e2b hoặc Modal. amla-sandbox phù hợp cho các tác vụ với mã sinh tự động và quyền truy cập công cụ được kiểm soát.

Giấy phép

Mã Python là MIT. Mã nhị phân WASM hiện đang là độc quyền - bạn có thể sử dụng cùng với gói này, nhưng không thể trích xuất hoặc phân phối riêng. Chúng tôi đang làm việc để mở mã nguồn runtime WASM.

Website · Ví dụ · Tài liệu


Read Original (EN) Quay lại Newsletter