mcpField
B
blaxel

blaxel

github.com/blaxel-ai云与 DevOps344 次安装2 周前更新
代码仓库

关于 blaxel

介绍 Blaxel 云平台的参考技能,为 AI Agent 提供计算环境。文档涵盖沙箱工作流、可复用模板、共享存储,以及通过 SDK 和 `bl` 命令行部署 Agent、MCP 服务和作业。

主要功能

  1. 01创建和管理计算沙箱
  2. 02运行命令并生成预览 URL
  3. 03构建和部署可复用沙箱模板
  4. 04部署 Agent、MCP 服务和批处理作业
  5. 05通过 Agent Drive 共享文件

适用场景

  1. 01在隔离沙箱中运行开发服务器
  2. 02使用自定义镜像创建可复用环境
  3. 03将 Agent 或 MCP 服务部署为端点
  4. 04在沙箱和 Agent 之间共享数据

MCP 相关

Blaxel 支持将 MCP 服务部署为无服务器端点。`bl` 命令行可初始化并部署 MCP 资源。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/blaxel-ai/agent-skills --skill blaxel

安装后在 Claude Code 中输入/blaxel确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

metadata.json
.cursor-plugin/
plugin.json
references/
sdk-python.md
sdk-typescript.md

详细介绍

Blaxel 技能参考

什么是 Blaxel

Blaxel (https://blaxel.ai) 是一个云平台,为 AI Agent 提供专属计算环境。其旗舰产品是持久沙箱:可即时启动的微型虚拟机,能够在待机后于 25ms 内恢复,并在闲置几秒后缩容至零。

Blaxel 的主要用途:

  • 启动沙箱、安装依赖、运行开发服务器,并提供实时预览 URL
  • 构建和部署沙箱模板(自定义 Docker 镜像),以便复用环境
  • 将 AI Agent、MCP 服务和批处理任务部署为无服务器端点

SDK:TypeScript (@blaxel/core) 和 Python (blaxel) CLI:bl(从 https://docs.blaxel.ai/cli-reference/introduction 安装) 文档:https://docs.blaxel.ai

身份验证

SDK 按以下优先级顺序使用这些来源进行身份验证:

  1. 已登录的 Blaxel CLI
  2. .env 文件中的环境变量(BL_WORKSPACE、BL_API_KEY)
  3. 系统环境变量
  4. Blaxel 配置文件(~/.blaxel/config.yaml)

在本地登录(推荐用于开发):

bl login YOUR-WORKSPACE

或者设置环境变量(用于远程/CI 环境):

export BL_WORKSPACE=your-workspace
export BL_API_KEY=your-api-key

在 Blaxel 本身上运行时,会自动进行身份验证。

沙箱工作流(主要用例)

这是最常见的工作流:创建沙箱,在其中运行命令,然后获取预览 URL。

第 1 步:创建沙箱

使用 Blaxel Hub (https://github.com/blaxel-ai/sandbox/tree/main/hub) 中的公共镜像:

  • blaxel/base-image:latest — 最小化 Linux
  • blaxel/node:latest — Node.js
  • blaxel/nextjs:latest — Next.js
  • blaxel/vite:latest — Vite
  • blaxel/expo:latest — Expo (React Native)
  • blaxel/py-app:latest — Python

或者使用你自行部署的自定义模板镜像。

创建时声明所需的端口。创建后无法添加端口。端口 80、443 和 8080 为保留端口。

import { SandboxInstance } from "@blaxel/core";

const sandbox = await SandboxInstance.createIfNotExists({
  name: "my-sandbox",
  image: "blaxel/base-image:latest",
  memory: 4096,
  ports: [{ target: 3000, protocol: "HTTP" }],
});
from blaxel.core import SandboxInstance

sandbox = await SandboxInstance.create_if_not_exists({
  "name": "my-sandbox",
  "image": "blaxel/base-image:latest",
  "memory": 4096,
  "ports": [{"target": 3000, "protocol": "HTTP"}],
})

使用 createIfNotExists / create_if_not_exists 按名称复用现有沙箱,或创建新沙箱。

第 2 步:写入文件并运行命令
// Write files
await sandbox.fs.write("/app/package.json", JSON.stringify({
  name: "my-app",
  scripts: { dev: "astro dev --host 0.0.0.0 --port 3000" },
  dependencies: { "astro": "latest" }
}));

// Or write multiple files at once
await sandbox.fs.writeTree([
  { path: "src/pages/index.astro", content: "<h1>Hello</h1>" },
  { path: "astro.config.mjs", content: "import { defineConfig } from 'astro/config';\nexport default defineConfig({});" },
], "/app");

// Execute a command and wait for it to finish
const install = await sandbox.process.exec({
  name: "install",
  command: "npm install",
  workingDir: "/app",
  waitForCompletion: true,
  timeout: 60000,
});

// Start a long-running dev server (don't wait for completion)
const devServer = await sandbox.process.exec({
  name: "dev-server",
  command: "npm run dev",
  workingDir: "/app",
  waitForPorts: [3000],  // returns once port 3000 is open
});
await sandbox.fs.write("/app/package.json", '{"name":"my-app","scripts":{"dev":"astro dev --host 0.0.0.0 --port 3000"},"dependencies":{"astro":"latest"}}')

await sandbox.fs.write_tree([
  {"path": "src/pages/index.astro", "content": "<h1>Hello</h1>"},
  {"path": "astro.config.mjs", "content": "import { defineConfig } from 'astro/config';\nexport default defineConfig({});"},
], "/app")

install = await sandbox.process.exec({
  "name": "install",
  "command": "npm install",
  "working_dir": "/app",
  "wait_for_completion": True,
  "timeout": 60000,
})

dev_server = await sandbox.process.exec({
  "name": "dev-server",
  "command": "npm run dev",
  "working_dir": "/app",
  "wait_for_ports": [3000],
})

重要:开发服务器必须绑定到 0.0.0.0(而非 localhost),才能通过预览 URL 访问。使用 --host 0.0.0.0 或 HOST 环境变量。

第 3 步:创建预览 URL
const preview = await sandbox.previews.createIfNotExists({
  metadata: { name: "app-preview" },
  spec: { port: 3000, public: true },
});
const url = preview.spec?.url;
// url => https://xxxx.us-pdx-1.preview.bl.run
preview = await sandbox.previews.create_if_not_exists({
  "metadata": {"name": "app-preview"},
  "spec": {"port": 3000, "public": True},
})
url = preview.spec.url

对于私有预览,设置 public: false 并创建令牌:

const preview = await sandbox.previews.createIfNotExists({
  metadata: { name: "private-preview" },
  spec: { port: 3000, public: false },
});
const token = await preview.tokens.create(new Date(Date.now() + 10 * 60 * 1000));
// Access: preview.spec?.url + "?bl_preview_token=" + token.value
第 4 步:管理沙箱
// Reconnect to an existing sandbox
const sandbox = await SandboxInstance.get("my-sandbox");

// List files
const { subdirectories, files } = await sandbox.fs.ls("/app");

// Read a file
const content = await sandbox.fs.read("/app/src/pages/index.astro");

// Get process info / logs
const proc = await sandbox.process.get("dev-server");
const logs = proc.logs; // available if waitForCompletion was true

// Kill a process
await sandbox.process.kill("dev-server");

// Delete the sandbox (all data is erased)
await sandbox.delete();
sandbox = await SandboxInstance.get("my-sandbox")

result = await sandbox.fs.ls("/app")
content = await sandbox.fs.read("/app/src/pages/index.astro")

proc = await sandbox.process.get("dev-server")
# proc.logs available if wait_for_completion was True
await sandbox.process.kill("dev-server")
await sandbox.delete()

沙箱模板(自定义镜像)

如需可复用的环境(例如预装了所有依赖的 Astro 项目),请创建模板:

bl new sandbox my-astro-template
cd my-astro-template

这会创建:blaxel.toml、Dockerfile、entrypoint.sh、Makefile。

自定义 Dockerfile。务必包含 sandbox-api 二进制文件:

FROM node:22-alpine
WORKDIR /app
COPY --from=ghcr.io/blaxel-ai/sandbox:latest /sandbox-api /usr/local/bin/sandbox-api
RUN npm install -g astro
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh 必须启动 sandbox-api:

#!/bin/sh
/usr/local/bin/sandbox-api &
while ! nc -z 127.0.0.1 8080; do sleep 0.1; done
echo "Sandbox API ready"
# Optionally start a process via the sandbox API:
# curl http://127.0.0.1:8080/process -X POST -d '{"workingDir":"/app","command":"npm run dev","waitForCompletion":false}' -H "Content-Type: application/json"
wait

部署模板:

bl deploy

然后获取 IMAGE_ID,并用它创建沙箱:

bl get sandboxes my-astro-template -ojson | jq -r '.[0].spec.runtime.image'
const sandbox = await SandboxInstance.createIfNotExists({
  name: "project-sandbox",
  image: "IMAGE_ID",
  memory: 4096,
  ports: [{ target: 3000, protocol: "HTTP" }],
});

教程和示例

沙箱

Astro:https://docs.blaxel.ai/Tutorials/Astro Expo:https://docs.blaxel.ai/Tutorials/Expo Next.js:https://docs.blaxel.ai/Tutorials/Nextjs

Agent

概览:https://docs.blaxel.ai/Tutorials/Agents-Overview

核心 CLI 命令

对于可能提示输入(例如确认)的 CLI 命令,在非交互式/无 TTY 环境(例如脚本、CI、Agent)中运行时,请添加 -y 以自动确认。

命令用途
bl login验证工作区身份
bl new sandbox|agent|job|mcp NAME根据模板初始化新资源
bl deploy构建资源并将其部署到 Blaxel
bl deploy -d DIR从指定目录部署
bl serve在本地运行资源以进行测试
bl serve --hotreload在本地运行并启用热重载
bl get sandboxes|agents|jobs|functions列出资源
bl get sandbox NAME --watch监控沙箱部署状态
bl delete sandbox|agent|job|function NAME删除资源
bl connect sandbox NAME在沙箱中打开交互式终端
bl chat AGENT-NAME与已部署的 Agent 进行交互式聊天
bl run job NAME --data JSON执行已部署的批处理作业

blaxel.toml 结构

name = "my-resource"
type = "sandbox"  # sandbox, agent, function, job, volume-template

[env]
NODE_ENV = "development"  # NOT for secrets — use Variables-and-secrets

[runtime]
memory = 4096       # MB
generation = "mk3"
# timeout = 900     # seconds (agents max 900, jobs max 86400)

# Ports (sandbox only)
[[runtime.ports]]
name = "dev-server"
target = 3000
protocol = "tcp"

重要注意事项

  • 必须在创建沙箱时声明端口,之后无法添加
  • 端口 80、443、8080 已由 Blaxel 保留
  • 开发服务器必须绑定到 0.0.0.0,而不是 localhost,预览 URL 才能正常使用
  • 沙箱内存约有 50% 分配给内存文件系统(tmpfs)。如需更多存储空间,请使用卷
  • 沙箱在闲置约 5 秒后会自动缩容至零。状态会在待机期间保留,并可在 <25ms 内恢复
  • waitForCompletion 的最长超时时间为 60 秒。对于耗时更长的进程,请使用 process.wait() 并设置 maxWait
  • 切勿将密钥放入 [env],请在控制台中使用 Variables-and-secrets 页面

Agent Drive(共享文件系统)

Agent Drive 是由 SeaweedFS 提供支持的分布式文件系统,可随时挂载到多个沙箱或 Agent,包括在它们运行期间。与卷(仅在创建沙箱时附加的块存储)不同,Drive 支持多个沙箱并发读写,也可以动态挂载/卸载。

此功能目前处于私有预览阶段。预览期间,Agent Drive 仅在 us-was-1 区域可用。Drive 和沙箱都必须位于此区域。

适用场景:

  • 在沙箱之间传递数据,无需中间服务
  • 为其他 Agent 存储工具输出和上下文历史
  • 在多个 Agent 之间共享数据集
  • 创建共享文件系统缓存以存储软件包依赖项
创建 Drive
import { DriveInstance } from "@blaxel/core";

const drive = await DriveInstance.createIfNotExists({
  name: "my-drive",
  region: "us-was-1",
  displayName: "My Project Drive",     // optional; defaults to name
  labels: { env: "dev", project: "x" }, // optional
});
from blaxel.core.drive import DriveInstance

drive = await DriveInstance.create_if_not_exists(
    {
        "name": "my-drive",
        "region": "us-was-1",
        "display_name": "My Project Drive",
        "labels": {"env": "dev", "project": "x"},
    }
)
将 Drive 挂载到沙箱
import { SandboxInstance } from "@blaxel/core";

const sandbox = await SandboxInstance.get("my-sandbox");

await sandbox.drives.mount({
  driveName: "my-drive",
  mountPath: "/mnt/data",
  drivePath: "/",   // optional; defaults to root of the drive
});
from blaxel.core import SandboxInstance

sandbox = await SandboxInstance.get("my-sandbox")

await sandbox.drives.mount(
    drive_name="my-drive",
    mount_path="/mnt/data",
    drive_path="/",
)

挂载后,写入沙箱内挂载路径的任何文件都会存储在 Drive 上,即使删除沙箱,这些文件仍会保留。

挂载子目录
await sandbox.drives.mount({
  driveName: "my-drive",
  mountPath: "/app/project",
  drivePath: "/projects/alpha",
});
await sandbox.drives.mount(
    drive_name="my-drive",
    mount_path="/app/project",
    drive_path="/projects/alpha",
)
列出、卸载和删除 Drive
// List mounted drives on a sandbox
const mounts = await sandbox.drives.list();

// List all drives
const drives = await DriveInstance.list();

// Unmount
await sandbox.drives.unmount("/mnt/data");

// Delete a drive
await DriveInstance.delete("my-drive");
// or instance-level:
const drive = await DriveInstance.get("my-drive");
await drive.delete();
mounts = await sandbox.drives.list()

drives = await DriveInstance.list()

await sandbox.drives.unmount("/mnt/data")

await DriveInstance.delete("my-drive")
# or instance-level:
drive = await DriveInstance.get("my-drive")
await drive.delete()

CLI:bl get drives

Agent Drive 完整示例
import { SandboxInstance, DriveInstance } from "@blaxel/core";

// 1. Create a drive
const drive = await DriveInstance.createIfNotExists({
  name: "agent-storage",
  region: "us-was-1",
});

// 2. Create a sandbox (use image ID from custom template)
const sandbox = await SandboxInstance.createIfNotExists({
  name: "my-agent-sandbox",
  image: "my-sandbox-image-id",
  memory: 2048,
  region: "us-was-1",
});

// 3. Mount the drive
await sandbox.drives.mount({
  driveName: "agent-storage",
  mountPath: "/mnt/storage",
  drivePath: "/",
});

// 4. Write a file to the mounted drive
await sandbox.fs.write("/mnt/storage/hello.txt", "Hello from the drive!");

// 5. Read it back
const content = await sandbox.fs.read("/mnt/storage/hello.txt");
console.log(content); // "Hello from the drive!"

// 6. List mounted drives
const mounts = await sandbox.drives.list();
console.log(mounts);
import asyncio
from blaxel.core.drive import DriveInstance
from blaxel.core import SandboxInstance

async def main():
    drive = await DriveInstance.create_if_not_exists(
        {"name": "agent-storage", "region": "us-was-1"}
    )

    sandbox = await SandboxInstance.create_if_not_exists(
        {
            "name": "my-agent-sandbox",
            "image": "my-sandbox-image-id",
            "memory": 2048,
            "region": "us-was-1",
        }
    )

    await sandbox.drives.mount(
        drive_name="agent-storage",
        mount_path="/mnt/storage",
        drive_path="/",
    )

    await sandbox.fs.write("/mnt/storage/hello.txt", "Hello from the drive!")

    content = await sandbox.fs.read("/mnt/storage/hello.txt")
    print(content)

    mounts = await sandbox.drives.list()
    print(mounts)

asyncio.run(main())

文档:https://docs.blaxel.ai/Agent-drive/Overview

其他 Blaxel 资源

Agent 托管

将 AI Agent 部署为无服务器、自动扩缩的 HTTP 端点。与框架无关(LangChain、CrewAI、Claude SDK 等)。

bl new agent
# develop in src/agent.ts or src/agent.py
bl serve            # test locally
bl deploy           # deploy
bl chat AGENT-NAME  # query

同步端点处理请求的时限最长为 100 秒,异步端点最长为 10 分钟。 文档:https://docs.blaxel.ai/Agents/Overview

MCP 服务托管

部署符合 MCP 协议的自定义工具服务。

bl new mcp
# implement in src/server.ts or src/server.py
bl serve --hotreload  # test locally
bl deploy

Agent 通过 SDK 连接到已部署的 MCP 服务:

const tools = await blTools(["functions/my-mcp-server"]);

每个沙箱还会在 https://<SANDBOX_URL>/mcp 暴露自己的内置 MCP 服务,其中包含用于进程管理、文件系统和代码生成的工具。 文档:https://docs.blaxel.ai/Functions/Overview

批处理作业

为并行后台任务提供可扩缩的计算能力(耗时从几分钟到几小时)。

bl new job
# implement in src/index.ts or src/index.py
bl deploy
bl run job NAME --data '{"tasks": [...]}'

每项任务最长为 24 小时。在 blaxel.toml 中设置 maxConcurrentTasks。 文档:https://docs.blaxel.ai/Jobs/Overview

资源

阅读各个 SDK 文件,了解详细说明和代码示例:

  • ./references/sdk-python.md
  • ./references/sdk-typescript.md

每个 SDK README 都包含:

  • SDK 概述
  • 要求
  • 使用沙箱、卷、Agent、批处理作业和 MCP 的代码示例
  • 其他有用信息

如需更多文档,请参阅:https://docs.blaxel.ai/llms.txt

评论

支持 Markdown