OpenClaw 是开源 Agent 框架,支持 CLI 编程调用与 Gateway Web UI。本文聚焦真实任务场景:部署 Gateway、Agent CLI、自定义域名浏览器访问、安全模式与运维、Skill 扩展。镜像地址、构建 Template、环境与能力约定见 OpenClaw 模板。
前置条件
已完成 SDK 接入(E2B API Key、
api_url、domain)已按 OpenClaw 模板 构建出状态为
ready的模板,并记录模板名称(下文以TEMPLATE_NAME表示)与构建示例中的OPTS已准备模型 API Key,创建沙箱时通过
envs注入 — 镜像内不预置国际站:百炼控制台 获取 API Key(
sk-开头)
部署 Gateway
启动 OpenClaw Gateway,在浏览器中与 Agent 对话。以下完整流程:创建 Sandbox → 配置 → 启动 Gateway → 获取访问地址。服务端编程调用见 Agent CLI。
import time
from e2b_code_interpreter import Sandbox
# Gateway 鉴权 Token:自行设定任意字符串,无需从 API 获取。
# 启动时传给 openclaw gateway --token;浏览器访问时通过 URL ?token= 携带。
# 官方文档亦支持 OPENCLAW_APP_TOKEN 环境变量,本质相同。
TOKEN = "my-gateway-token"
PORT = 18789
BAILIAN_API_KEY = "<YOUR-BAILIAN-API-KEY>"
BAILIAN_BASE_URL = "[workspace-id].[region].maas.aliyuncs.com"
BAILIAN_MODEL = "qwen3.8-max"
# 1. 创建 Sandbox
sandbox = Sandbox.create(
template=TEMPLATE_NAME,
timeout=3600,
envs={
"ANTHROPIC_AUTH_TOKEN": BAILIAN_API_KEY,
"ANTHROPIC_BASE_URL": BAILIAN_BASE_URL,
"ANTHROPIC_MODEL": BAILIAN_MODEL,
},
**OPTS,
)
# 注册百炼 provider
sandbox.commands.run(
"openclaw onboard --non-interactive --accept-risk --skip-health "
"--auth-choice custom-api-key "
f"--custom-api-key {BAILIAN_API_KEY} "
f"--custom-base-url {BAILIAN_BASE_URL} "
"--custom-compatibility anthropic "
f"--custom-model-id {BAILIAN_MODEL} "
"--custom-provider-id bailian",
timeout=120,
)
# 2. 设置默认模型
sandbox.commands.run(
f"openclaw config set agents.defaults.model.primary bailian/{BAILIAN_MODEL}"
)
# 3. 配置 Control UI(云沙箱公网访问必需)
origin = f"https://{sandbox.get_host(PORT)}"
sandbox.commands.run(
f"openclaw config set gateway.controlUi.allowedOrigins '[\"{origin}\"]'"
)
# 4. 启动 Gateway(后台运行)
sandbox.commands.run(
f"bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && "
f"openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && "
f"openclaw gateway --allow-unconfigured --bind lan --auth token "
f"--token {TOKEN} --port {PORT}'",
background=True,
)
# 5. 等待 Gateway 就绪
for _ in range(45):
probe = sandbox.commands.run(
f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\''
)
if probe.stdout.strip() == "ready":
break
time.sleep(1)
url = f"https://{sandbox.get_host(PORT)}/?token={TOKEN}"
print(f"Gateway: {url}")Agent CLI
在服务端以编程方式调用 Agent,无需启动 Gateway。
若已按上文 部署 Gateway 创建了 Sandbox,直接在同一个 sandbox 上执行下方命令即可,无需再次创建。
若仅需 CLI、不启动 Gateway:
from e2b_code_interpreter import Sandbox
BAILIAN_API_KEY = "<YOUR-BAILIAN-API-KEY>"
BAILIAN_BASE_URL = "[workspace-id].[region].maas.aliyuncs.com"
BAILIAN_MODEL = "qwen3.8-max"
sandbox = Sandbox.create(
template=TEMPLATE_NAME,
timeout=3600,
envs={
"ANTHROPIC_AUTH_TOKEN": BAILIAN_API_KEY,
"ANTHROPIC_BASE_URL": BAILIAN_BASE_URL,
"ANTHROPIC_MODEL": BAILIAN_MODEL,
},
**OPTS,
)
# 注册百炼 provider
sandbox.commands.run(
"openclaw onboard --non-interactive --accept-risk --skip-health "
"--auth-choice custom-api-key "
f"--custom-api-key {BAILIAN_API_KEY} "
f"--custom-base-url {BAILIAN_BASE_URL} "
"--custom-compatibility anthropic "
f"--custom-model-id {BAILIAN_MODEL} "
"--custom-provider-id bailian",
timeout=120,
)
result = sandbox.commands.run(
f'openclaw agent --local --agent main --model bailian/{BAILIAN_MODEL} '
'-m "What is 2+2? Reply with just the number."',
timeout=120,
)
print(result.stdout)浏览器访问(云沙箱)
要在浏览器中打开云沙箱的 Gateway Control UI,须先绑定自定义域名。默认平台域名(*.sandbox.aliyuncs.com)会触发下载而非打开页面;绑定自定义域名后可正常访问。控制台添加域名、DNS 解析、HTTPS 证书及 SDK 配置的完整步骤,见 云沙箱自定义域名。
配置自定义域名
第一步:控制台配置。 在函数计算控制台为云沙箱绑定自定义域名,配置证书与 DNS(api.<你的自定义域名> / *.<你的自定义域名>)。
第二步:SDK 改 OPTS。 将 OpenClaw 模板 中的默认 OPTS:
OPTS = {
"api_key": "<你的 E2B API Key>",
"api_url": "https://api.cn-beijing.sandbox.aliyuncs.com",
"domain": "cn-beijing.sandbox.aliyuncs.com",
}替换为与控制台一致的自定义域名(api_key 须为绑定该自定义域名的同一账号下的 Key):
OPTS = {
"api_key": "<你的 E2B API Key>",
"api_url": "https://api.<你的自定义域名>",
"domain": "<你的自定义域名>",
}第三步:全流程传入 OPTS。Template.build(..., **OPTS)、Sandbox.create(..., **OPTS) 及文档中其他 SDK 调用均使用上述 OPTS,无需额外参数。
完成后 sandbox.get_host(PORT) 将返回 {PORT}-sbx-{sandbox_id}.<你的自定义域名>;Gateway 的 allowedOrigins、浏览器地址栏与下文 curl 中的 <host> 均使用该地址。
打开 Control UI
完成自定义域名配置并 部署 Gateway 后,公网访问还需鉴权:
鉴权 | 来源 | 作用 | 传递方式 |
Gateway Token | 代码中自行设定的 | OpenClaw Control UI | URL 参数 |
运行上文脚本,记录输出的
GatewayURL打开 Gateway URL(URL 中已含
?token=)
可用 curl 先验证:
curl -sI "https://<host>/?token=<Gateway Token>"期望响应含 200;响应头中的 Content-Type 为 text/html 即表示 Gateway 正常。
若出现“浏览器来源不被允许”,确认 allowedOrigins 与地址栏来源完全一致(https://{sandbox.get_host(PORT)},无尾部 /),修改后 重启 Gateway。
安全模式
测试阶段可关闭设备配对(上文已设置 dangerouslyDisableDeviceAuth true)。若启用安全模式,打开 URL 后需批准待配对设备:
import json
for _ in range(30):
try:
res = sandbox.commands.run(
f"openclaw devices list --json --url ws://127.0.0.1:{PORT} --token {TOKEN}"
)
data = json.loads(res.stdout)
if data.get("pending"):
rid = data["pending"][0]["requestId"]
sandbox.commands.run(
f"openclaw devices approve {rid} --token {TOKEN} "
f"--url ws://127.0.0.1:{PORT}"
)
print(f"Device approved: {rid}")
break
except Exception:
pass
time.sleep(2)重启 Gateway
修改模型或配置后,在当前 Sandbox 中执行:
origin = f"https://{sandbox.get_host(PORT)}"
sandbox.commands.run(
f"openclaw config set gateway.controlUi.allowedOrigins '[\"{origin}\"]'"
)
sandbox.commands.run(
"""bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do
for pid in $(pgrep -f "$p" || true); do kill "$pid" 2>/dev/null || true; done
done'"""
)
time.sleep(1)
sandbox.commands.run(
f"openclaw gateway --allow-unconfigured --bind lan --auth token "
f"--token {TOKEN} --port {PORT}",
background=True,
)
for _ in range(45):
probe = sandbox.commands.run(
f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\''
)
if probe.stdout.strip() == "ready":
break
time.sleep(1)关闭不安全配置
sandbox.commands.run(
"bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth false && "
"openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth false'"
)
sandbox.commands.run(
"""bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do
for pid in $(pgrep -f "$p" || true); do kill "$pid" 2>/dev/null || true; done
done'"""
)
sandbox.commands.run(
f"openclaw gateway --allow-unconfigured --bind lan --auth token "
f"--token {TOKEN} --port {PORT}",
background=True,
)使用 Skill 扩展能力
OpenClaw 通过 Skill(目录 + SKILL.md)扩展 Agent 能力,Gateway 与 Agent CLI 均可使用。详见 OpenClaw Skills。
以下示例假设已按上文创建 sandbox(Gateway 或 Agent CLI 均可)。镜像不预装自定义 Skill;可用 openclaw skills list 查看已加载 Skill(含 bundled)。路径约定见 OpenClaw 模板。
以下以阿里云百炼为例(BAILIAN_MODEL 见上文)。
写入 Managed Skill:
sandbox.files.write(
"/home/user/.openclaw/skills/summarize-changes/SKILL.md",
"""---
name: summarize-changes
description: Summarizes uncommitted changes and flags risks. Use when reviewing diffs or writing commit messages.
user-invocable: true
---
## Instructions
1. Run `git diff HEAD` and summarize changes in 2–3 bullets.
2. List risks such as missing error handling or hardcoded values.
3. If the diff is empty, say there are no uncommitted changes.
""",
)
# 确认已出现在列表中
print(sandbox.commands.run("openclaw skills list").stdout)
result = sandbox.commands.run(
f'openclaw agent --local --agent main --model bailian/{BAILIAN_MODEL} '
'--message "/summarize-changes"',
timeout=0,
)
print(result.stdout)写入 Workspace Skill:
sandbox.files.write(
"/home/user/.openclaw/workspace/skills/api-conventions/SKILL.md",
"""---
name: api-conventions
description: API design conventions. Use when adding or changing HTTP endpoints or /healthz.
user-invocable: true
---
When writing API endpoints:
- Use RESTful naming
- Return consistent error formats
- Include request validation
""",
)
result = sandbox.commands.run(
f'openclaw agent --local --agent main --model bailian/{BAILIAN_MODEL} '
'--message "/api-conventions Add a /healthz endpoint"',
timeout=0,
)
print(result.stdout)从本机上传多文件 Skill 目录:
若 Skill 含 scripts/、references/ 等附属文件,可以用 files.write_files 一次批量写入:
from pathlib import Path
def upload_skill_dir(sandbox, local_dir: str, remote_root: str) -> None:
local = Path(local_dir).resolve()
entries = []
for path in local.rglob("*"):
if path.is_file():
rel = path.relative_to(local).as_posix()
entries.append({
"path": f"{remote_root.rstrip('/')}/{rel}",
"data": path.read_bytes(),
})
sandbox.files.write_files(entries)
# 本机目录结构示例:
# ./my-skills/echo-marker/SKILL.md
# ./my-skills/echo-marker/scripts/marker.txt
upload_skill_dir(
sandbox,
"./my-skills/echo-marker",
"/home/user/.openclaw/skills/echo-marker", # Managed;Workspace 则用 workspace/skills/...
)
print(sandbox.commands.run("openclaw skills list").stdout)
result = sandbox.commands.run(
f'openclaw agent --local --agent main --model bailian/{BAILIAN_MODEL} '
'--message "/echo-marker"',
timeout=0,
)
print(result.stdout)关于 Template.copy:暂不支持Template.build时用.copy("local-dir", "/home/user/.openclaw/skills/...")预置文件。自定义 Skill 请用上方运行时files.write/files.write_files。
从 ClawHub 安装(可选):
沙箱默认具备公网出站,可直接搜索 / 安装社区 Skill(浏览 clawhub.ai):
# 搜索
result = sandbox.commands.run("openclaw skills search calendar", timeout=120)
print(result.stdout)
# 安装
sandbox.commands.run("openclaw skills install ws-calendar", timeout=180)参数说明
步骤 | 说明 |
| Gateway 监听 |
| 通过 URL 参数 |
浏览器打开 URL | Gateway 提供 UI,浏览器建立 WebSocket |
| 安全模式下需先批准设备 |
| 批准浏览器设备指纹 |
浏览器重连 | WebSocket 连接成功,UI 可用 |
清理
任务完成后释放资源:
sandbox.kill()计费说明
Sandbox 按 CPU、内存规格与运行时长计费;模型 API 调用费用由模型服务单独结算。详见 计费概述。
常见问题
现象 | 处理 |
Agent 无响应 | 确认 |
Gateway 浏览器打不开 | 确认 Gateway URL 含 |
浏览器触发下载 | 须绑定自定义域名,见 云沙箱自定义域名 与 浏览器访问(云沙箱) |
| API Key 与云沙箱自定义域名须为同一账号 |
来源不被允许 |
|
构建失败 | 确认 |
其他 SDK / 构建问题 | 见模板管理 |
相关文档
OpenClaw 模板:镜像地址、构建 Template、Gateway 参数、环境概览、Skill 能力约定