Field note · 2026
Crabbox:让 Coding Agent 在远端盒子里跑命令
OpenClaw 作者 Peter Steinberger 出品的 Agent 远程执行层:一条 crabbox run 完成租机 → 同步含未提交改动的工作区 → 远端执行并回流输出与退出码 → 释放。81 个 provider(云 VM / 微VM 沙箱 / 本地容器与 VM / 自有 SSH)统一抽象,覆盖 Linux/macOS/Windows/WSL2;可选 Coordinator 集中托管凭据、预算与过期回收。

速览
- 定位:Coding Agent 的远程执行层,口号是 “warm a box, sync the diff, run the suite”。它是被 Agent 调用的 CLI,不编排 Agent,也不碰模型、prompt 和记忆
- 核心机制:控制面(租约、凭据、预算、回收)与数据面(CLI 经 SSH + rsync 直连 runner)分离;81 个 provider 收敛成 SSH lease / Delegated run / Service control 三种形态
- 成熟度:v0.78.1,5 个半月 3,400+ commits,MIT,可完全自托管(Coordinator 可选);迭代极快,要锁版本
- 结论:多 Agent 并发跑测试可以直接用;「租约 + 所有权 fail-closed + 证据回执」这套生命周期设计值得照抄
项目地址
GitHub:openclaw/crabbox
- 官网:crabbox.sh,文档站与仓库
docs/同源(docs/.i18n下有 zh-CN 等译本) - 作者:Peter Steinberger(steipete,OpenClaw 作者)与 OpenClaw 团队
| 维度 | 情况 |
|---|---|
| License | MIT |
| 创建 / 最新版本 | 2026-04-30 创建;v0.78.1(2026-10-15) |
| 热度(收录时) | 1,480 star / 199 fork |
| 提交 | 3,438 commits,steipete 2,057、vincentkoc 931 |
| 体量 | Go 非测试代码约 33.7 万行 + 测试约 49 万行;Coordinator(TypeScript)约 8.4 万行;docs 292 篇 |
| Provider | 81 个内置 + external(JSON over stdio) |
| 目标系统 | Linux / macOS / 原生 Windows / WSL2 |
| Agent 接口 | CLI、--json 输出和 Skill;不提供 MCP |
项目介绍
一句话定位
一条 crabbox run -- pnpm test 完成:租机 → 同步工作区(含未提交改动和未跟踪文件)→ 远端执行 → 流式回传输出与退出码 → 释放。对 Agent 来说语义和本地跑命令一样(stdout / stderr + exit code),机器在哪、怎么开、怎么删由 Crabbox 负责。
为什么需要它
- 并发 Agent 抢本机:几个 Codex / Claude Code 同时跑测试、构建、e2e,CPU、内存、端口、Docker 互相踩。git worktree 只隔离代码,不隔离运行时;Crabbox 把「运行」整体挪到远端,每个 Agent 一台盒子
- 跨 OS 真机验证:同一份工作区在 Linux / macOS / 原生 Windows / WSL2 上跑,不用为每个系统维护一套 CI
- 可视化 QA:desktop + WebVNC + code-server,Agent 用 computer use 操作远端桌面。steipete 的实际用法是让 Codex 当 QA,在 Crabbox 桌面里测 OpenClaw;Crabbox 本身也是 Codex 在 Crabbox 里构建的
- 团队治理:云凭据、预算上限、过期回收集中到可选的 Coordinator,不散落在每个开发者和 Agent 手里
能做什么
- 一次性 run:
crabbox run,用完即删 - 热盒复用:
warmup --slug起盒保留,run --id每轮只同步 diff 再执行,connect进 SSH,stop释放 - 证据:阶段事件、日志分块、JUnit 解析、
--require-artifact产物门禁、失败 bundle、--attest签名回执 +crabbox verify - 并行与复用:shard 分片、checkpoint fork、ready pool 预热池
- 交互:远端桌面、WebVNC、code-server、portal
- 衔接 CI:Actions hydration 复现 CI 工作区;capsule 把失败的 Actions run 变成可重复的调试用例
边界:它明确不做什么
VISION.md 列出的非目标:
- 被 Agent 使用,而不是编排 Agent:不托管 agent runtime、模型凭据、prompt、记忆
- 不做 workflow 引擎、Agent 框架、插件市场
- 不提供 MCP:入口就是 CLI + 生成的 Skill
判断:Crabbox 把自己钉在「Agent 的 shell 之下、云 API 之上」这一层,只回答两个问题:命令在哪台机器上跑、跑完怎么收尸。边界画得很克制,所以能同时适配 81 个 provider 而不膨胀成平台。对做 Agent 产品的人,它是一个能直接接进 harness 的执行后端,不是一个要整体迁进去的系统。
技术架构
分层

架构图:控制面(蓝虚线)只发租约;数据面(绿实线)由 CLI 经 SSH + rsync 直连 runner;委托沙箱不走 SSH 数据面,同步和执行由平台自己负责。
Mermaid 源码
flowchart LR
subgraph CALL["调用方"]
A1["Coding Agent<br/>Codex / Claude Code"]
A2["Harness / 脚本"]
A3["开发者 / CI"]
end
CLI["crabbox CLI(Go,本地)<br/>配置合并 · 租约 SSH key · provider 路由<br/>同步引擎 · 执行回传 · 心跳 · 证据"]
subgraph CO["Coordinator(可选,TypeScript)"]
C1["CF Worker + Durable Object<br/>或 Node + PostgreSQL + pg-boss"]
C2["托管凭据 · 串行化 fleet 变更 · spend cap<br/>过期回收 · run 记录 · WebVNC / code bridge"]
end
subgraph PV["Provider adapters:81 内置 + external"]
P1["SSH lease<br/>aws · azure · gcp · hetzner · tart · ssh"]
P2["Delegated run<br/>e2b · modal · cloudflare · vercel-sandbox"]
P3["Service control<br/>railway · fastapi-cloud · unikraft-cloud"]
end
R["Runners<br/>Linux · macOS · Windows · WSL2<br/>/work/crabbox/{lease}/{repo}"]
CALL --> CLI
CLI -.->|"控制面:HTTPS + /v1/control WS"| CO
CO -.->|"provision / release"| PV
CLI -.->|"direct:本地凭据"| PV
PV -->|"创建 / 删除 / 快照"| R
CLI ==>|"数据面:SSH + rsync"| R一次 run 发生了什么
- 规划:配置按 flags > env > 仓库
.crabbox.yaml> 用户配置 > 默认值合并;按 ProviderSpec 声明的 Kind / Features 选路,无法兑现的参数直接拒绝 - 租约:brokered 模式向 Coordinator 申请(凭据在服务端、预算 admission、fleet 变更串行化);direct 模式用本地凭据直接创建。每个租约生成独立的 ed25519 key;runner bootstrap 只装 SSH、Git、rsync、curl、jq,完成后写
crabbox-ready - 同步:取 workspace owner 锁 → 生成清单和指纹 → 无变化就跳过,否则 Git seed + delta rsync,空盒走流式 tar
- 执行:经 SSH 执行,stdout / stderr 实时回流,返回远端退出码;执行期心跳按需续期;产出阶段事件、日志分块、JUnit 和产物
- 释放:一次性租约随 run 删除;
--keep的交给空闲时钟;兜底 cleanup 只删能证明归属的资源
委托沙箱(e2b、modal 等)的第 3、4 步交给平台:backend 实现 Warmup / Run / List / Status / Stop,负责预热、执行、流式输出和停止,声明 FeatureArchiveSync 的可以上传 checkout 归档;core 仍负责 provider 选择、配置、本地 claim、slug、计时和 list / status 渲染。
机制演示(可交互)
六个值得记住的设计决定
1. 控制面与数据面分离
Coordinator 只处理租约、凭据、预算、回收和 run 记录;同步与执行始终是 CLI → runner 直连(SSH 默认 2222 端口,回落 22),runner 不回调 Coordinator。所以 Coordinator 可以是单副本的 Cloudflare Worker + Durable Object,不扛任何大流量;它不在数据路径上,短暂不可用也不会打断已建立的同步和执行。两套实现(CF Worker + DO / Node + PostgreSQL + pg-boss)状态不互通,选定后不要来回切。
2. Providers configure backends. Core commands own workflows.
provider 只声明能力,run / warmup / sync / list / stop 这些工作流只在 core 实现一份。81 个 provider 被压成三种 ProviderSpec Kind:
| 形态 | 分工 | 代表 |
|---|---|---|
| SSH lease | provider 只交出一台能 SSH 的机器,同步、执行、回传全走 Crabbox 自己的数据面 | aws、azure、gcp、hetzner、tart、proxmox、ssh(自有主机,不创建不删除) |
| Delegated run | 平台自己执行;backend 负责预热、执行、流式输出、停止,必须拒绝自己兑现不了的 run / sync 参数 | e2b、modal、cloudflare、vercel-sandbox |
| Service control | 管理长期服务而不是一次性盒子 | railway、fastapi-cloud、unikraft-cloud |
- external provider:子进程 + JSON over stdio,不 fork 仓库就能接私有云或内部平台
- 部署模式与形态正交:brokered(经 Coordinator)/ direct(本地凭据)/ registered(direct 创建,但把元数据登记到 Coordinator,换来 portal、WebVNC 和库存可见性)/ static SSH(
provider: ssh) - 国内云:内置只有 tencentcloud 和 sealos-devbox,其他都要走 external 或 static SSH
- 账单盲区:direct 与 delegated 的花费不经过 Coordinator,
crabbox usage统计不到
3. 同步引擎:清单 + 指纹 + Git seed + delta
- 清单:
git ls-files --cached --others --exclude-standard -z,天然包含未提交改动和未跟踪文件,尊重 .gitignore;同时生成删除列表 - 指纹:清单指纹一致就直接跳过(“No changes detected, skipping sync”),Agent 反复 run 时同步几乎零成本
- Git seed:远端先从 origin 取到本地 HEAD,再只传本地 delta 和远端被改动的跟踪文件;seed 验证不过就回退到完整清单 rsync(
--files-from=- --from0) - 冷启动:新的空 POSIX 工作区且不用 Git seed 时,走单条 SSH 通道的流式 tar(gzip fast,不落地)
- Windows:同一份清单打 tar,经 OpenSSH 上传后解包,不走 rsync
- 护栏:workspace owner 锁、large-sync 预检(warnFiles / failFiles)、prune 只删同步过的文件、大规模删除守卫(需要
CRABBOX_ALLOW_MASS_DELETIONS=1才放行);sync.timeout15m 是 I/O 不活跃时长,不是总时长
4. 租约是成本与清理的最小单位
expiresAt = min(createdAt + min(ttl, maxTTL), lastTouchedAt + idleTimeout),默认 TTL 30m、idle 30m,direct provider 的 maxTTL 默认 4h(上限 24h),brokered 请求由 Coordinator 钳制。
- 心跳不等于续期:心跳走
/v1/controlWebSocket,失败回落 HTTPS;到期后的心跳一律被拒 - 只在真实工作时续期:只有用户命令执行期间,剩余不足 10 分钟时才 +30 分钟,直到 maxTTL(需策略与 provider 能力允许);setup、sync-only、SSH、desktop 都不续期
- 预算先占:admission 时按「最坏寿命 × 单价」预留,超限返回 429
cost_limit_exceeded;续期同样过预算,预留按新 TTL 原子替换、只补差额;显式 extend 超预算返回 403,心跳触发的续期超预算则跳过并带回 policyNotice - 价格源:
CRABBOX_COST_RATES_JSON> 实时价格 > 内置兜底 > 通用兜底
5. 生命周期 fail-closed
删除前必须有所有权证明:provider、资源、claim 三者一致。名字、标签、ID 都不算证据,任何一环校验失败就不删。付费 provider 合并进主干前,要提交 create → use → destroy 零残留的实测证明。
6. 证据是一等公民
每次 run 产出结构化阶段事件、日志分块、JUnit 结果、产物门禁(--require-artifact)和失败 bundle(stdout / stderr、计时、脱敏后的 env / config)。失败时给出 blockedStage / retryLikely,Agent 据此判断该重试还是该改代码;--attest 生成签名回执,crabbox verify 在本地校验。
进阶原语速查
| 原语 | 作用 | 适合场景 |
|---|---|---|
warmup / prewarm | 预先起盒并保留,后续 run --id 复用 | Agent 多轮迭代、冷启动敏感 |
checkpoint | 保存准备好的远端状态(装好依赖、停在 bug 现场),再 fork 多份 | 并行复现、批量试错 |
shard | 测试分片到多台盒子并行跑 | 大测试套件 |
pool | 有界借用的预热池(实验性,需要 Coordinator 支持) | 高频短任务 |
capsule | 把失败的 GitHub Actions run 变成可重复的调试用例 | CI 红了交给 Agent 修 |
actions hydrate | 在 Actions 环境里复现 CI 工作区,之后的同步与命令都用它 | 和现有 CI 对齐 |
pond | 用 pond=<name> 给一组租约分组、发现、一起释放 | 多服务联调 |
watch | 在热盒上跑命令,本地文件一变就同步并重跑 | TDD 循环 |
desktop / webvnc / code | 远端桌面、浏览器内 VNC、code-server | 可视化 QA、computer use |
egress | 盒子里的浏览器或应用经由运行 egress host 的机器出网 | 需要特定出口网络 |
media / bench | 桌面录屏转轻量审阅产物 / 本地基准计时证据 | 结果审阅 |
判断:Crabbox 真正的壁垒不是 81 个 provider,而是租约生命周期这一整套:所有权证明、预算预留、只在命令执行期续期、fail-closed 清理。provider 适配是体力活,生命周期安全才是团队敢把云账号交给 Agent 的前提。
文档
仓库 docs/ 共 292 篇,和 crabbox.sh 同源。按价值排序:
| 文档 | 看点 |
|---|---|
| How it works | 端到端心智模型,每个行为归哪个组件 |
| VISION.md | 定位、非目标、lifecycle safety 原则 |
| Architecture | CLI / Coordinator / Runner 职责与控制面接口 |
| Sync | 清单、指纹、Git seed、tar 冷启动、删除守卫 |
| Lifecycle cleanup | expiresAt 公式、续期规则、预算与回收 |
| Provider backends | SSH lease 与 Delegated run 的契约边界 |
| External providers | JSON over stdio 外部 provider 协议,接内部平台从这里看 |
| Configuration | 全部配置字段:broker / lease / sync / env / profiles |
| Pricing | 价格源优先级与成本预留 |
| Security | 共享 broker、secret 转发、谁能访问租到的盒子 |
文档有漂移:architecture.md 表格里的 TTL 默认值(5400s / 86400s)和 lifecycle-cleanup.md(1800s / 14400s)不一致,以后者和 crabbox --help 为准。
Quick Start
最快路径:本机容器,零凭据
brew install openclaw/tap/crabbox
crabbox --version && crabbox doctor
# 在一个可信仓库里,用本机 Docker / Podman 跑通完整链路
crabbox run --provider local-container -- pnpm test上云:一次性 run
crabbox providers recommend # 按场景比较 provider
crabbox init --detect # 识别项目,生成 .crabbox.yaml
crabbox run --provider hetzner --class small -- pnpm test热盒复用:Agent 多轮迭代
crabbox warmup --provider hetzner --slug fix-auth # 起盒并保留
crabbox run --id fix-auth -- pnpm test:changed # 每轮只同步 diff
crabbox run --id fix-auth --sync-only # 只同步不执行
crabbox connect fix-auth # 进 SSH 排查
crabbox extend fix-auth --by 30m # 手动续期
crabbox stop fix-auth # 释放仓库配置
# .crabbox.yaml(仓库根目录;优先级 flags > env > 仓库 > 用户 > 默认)
provider: hetzner
target: linux
class: small # 默认是 beast,先调小
lease:
ttl: 30m
idleTimeout: 30m
sync:
gitSeed: true
exclude:
- node_modules
- .turbo
env:
allow:
- CI
- NODE_OPTIONS
- PROJECT_*团队与 Agent 接入
crabbox login --url https://broker.example.com # 之后租约由 Coordinator 托管凭据与预算
crabbox usage # 花费统计(direct / delegated 不计入)
# 给 Codex / Claude Code 装 Skill
npx skills add https://github.com/openclaw/crabbox --skill crabbox
npx skills add https://github.com/openclaw/crabbox --skill crabbox-quickstart失败时怎么办
| 场景 | 做法 |
|---|---|
| 保留现场排查 | --keep-on-failure,再 crabbox connect 进去 |
| 远端工作区状态可疑 | --full-resync 重置清单和指纹 |
| 拿回远端产物 | --download remote=local(只在成功时生效,失败用 --download-on-failure) |
| 产物必须存在才算成功 | --require-artifact |
| 需要可验证的结果 | --attest 生成签名回执,crabbox verify receipt.json 校验 |
踩坑清单
- 只对可信仓库用:远端会执行仓库里的 setup 和命令
- 环境变量默认只转发
CI、NODE_OPTIONS,其他要写进env.allow(支持尾部通配) - 默认 class 是 beast(大机型),试用先用
--class tiny/small --provider不是全局 flag,要写在子命令后面go install只装 CLI,缺crabbox-runtimepack;用 brew 或 Release 归档,runtime 目录要和 CLI 放在一起- Hostinger:
crabbox stop只停 VPS,不退订阅,账单继续;machine0:保留的算力和快照持续计费;boxd:用 org 隔离的 key 时要配CRABBOX_BOXD_ORG,否则 list / cleanup 会拒绝处理 org 计费的机器;Morph:要先备好含 bash / git / rsync / tar 的快照 warmup默认保留盒子;direct provider 如果没有自动空闲回收,要设warmup.keep: false并定期跑crabbox cleanup(cleanup 会跳过 kept 的盒子),或显式 stop- 文档滞后时,以
crabbox --help和crabbox providers --json为准
生态位
Crabbox 在栈里的位置:编排层之下、沙箱平台之上的执行适配层。
| 项目 | 所在层 | 与 Crabbox 的关系 |
|---|---|---|
| Orca:并行 Agent 编排 ADE / Paseo | Agent 编排 / 控制台(worktree 并行) | 互补:它们管同时开多少个 Agent,Crabbox 管这些 Agent 的命令在哪跑。worktree 只隔离代码,运行时隔离靠 Crabbox 这一层 |
| Cloudflare Computer | Agent 运行时(权威状态在 DO) | 路线相反:CF 把状态放进 Durable Object;Crabbox 的权威状态是开发者本地的 git 工作区,远端盒子只是可丢弃的执行副本 |
| E2B / Modal / Daytona / 云 VM | 沙箱与算力平台 | 被 Crabbox 收编为 provider,Crabbox 是它们之上的统一 CLI 与生命周期层 |
| agent-browser | 浏览器操作工具 | 可以跑在 Crabbox 的桌面盒子里,配合 WebVNC 做可视化 QA |
| GitHub Actions / CI | 合并前验证 | 互补:Crabbox 是 Agent 迭代中的快速循环;Actions hydration 对齐 CI 环境,capsule 把 CI 失败拉回本地循环 |
典型用法
- 多 Agent 并发跑测试:每个 Agent 一台热盒,
run --id每轮只同步 diff,本机只负责编辑 - 跨 OS 验证:同一工作区切
--target linux / macos / windows,或 Windows 的 WSL2 模式 - 可视化 QA:Codex 通过 WebVNC + computer use 在远端桌面上测 OpenClaw(steipete 的日常用法)
- 自举:Codex 在 Crabbox 盒子里构建 Crabbox 自己
- CI 红了交给 Agent:capsule 把失败的 Actions run 变成可复现用例,Agent 在同样环境里修
对我做 Agent 项目的启示
值得直接抄的
- 控制面只发租约,数据不过控制面。 调度服务只管「谁、在哪、多久、花多少」,素材上传和产物下载由 worker 直连对象存储。对 Hyperframes 云渲染、视频生成这类大流量任务,这是调度服务能做成单副本、近乎无状态的前提。
- 租约 = 成本单位 + 清理单位。 每个 GPU / 渲染任务带 TTL、idle、maxTTL,admission 时按「最坏寿命 × 单价」预留预算,续期只补差额,超限直接拒绝。比事后对账可靠。
- 心跳不等于续期。 只有真实命令执行期才续,SSH 挂着、桌面开着都不续,直接掐掉「Agent 忘了关机」的长尾账单。
- 所有权证明 + fail-closed 回收。 后台回收孤儿资源时,只删 provider、资源、claim 三方一致的;名字、标签、ID 都不算证据,校验失败宁可不删。
- 清单指纹 + delta 同步。 Agent 多轮修改工程目录或产物时,先比指纹再决定是否同步,只传 diff;再加大规模删除守卫,防止 Agent 一次误删整个目录。
- 阶段事件 + 可重试判定。 每个 run 按 sync / setup / command 等阶段打事件,带 blockedStage / retryLikely,直接映射成 Langfuse 的 span 和 tag,让上层 Agent 自动决定重试还是改代码。
- CLI +
--json+ Skill,不做 MCP。 对能跑 shell 的 coding agent,CLI 是最便宜的接口:零常驻进程、天然可组合,Skill 负责教模型怎么用。
现在就能用的方式
- 先用
--provider local-container在本机零凭据跑通链路,确认仓库能同步、能执行 - 字节内部 devbox 或自有机器:
provider: ssh(static SSH,不创建不删除),把现成机器直接纳入crabbox run - 火山引擎:没有内置 provider,用 external(JSON over stdio)写适配器,先只实现 SSH lease 形态最省事
- 给 Codex / Claude Code 装 crabbox Skill,让 Agent 自己决定什么时候把测试挪到远端
不建议照搬的
它不是安全沙箱,也不是稳定 API。 远端执行的是仓库里的任意脚本,隔离强度取决于 provider(VM、容器、自有 SSH 主机差别很大);v0.x 阶段 5 个半月发到 v0.78,CLI 和配置字段还在变,要锁版本。33 万行 Go 大部分是 provider 适配和边角守卫,自研时抄结构不抄体量:
| Crabbox 组件 | 自研对应物 |
|---|---|
| Coordinator(租约 / 凭据 / 预算 / 回收) | 算力调度服务:只发租约,不经手素材和产物流量 |
| ProviderSpec 三种形态 | 算力后端接口:自有 GPU 机(SSH lease)/ 托管推理或批处理平台(Delegated run)/ 常驻服务(Service control) |
| expiresAt 公式 + 预算预留 | 每个渲染 / 生成 job 的 TTL、idle 与预算预留 |
| 所有权 claim + fail-closed cleanup | 孤儿资源回收任务:只删能证明归属的资源 |
| 同步引擎(清单 + 指纹 + delta) | 工程目录 / 素材的增量同步 |
| run 事件 + blockedStage / retryLikely | Langfuse span + tag,驱动重试策略 |
| CLI + Skill | 给 Agent 的执行工具:一个命令 + JSON 输出 |