---
read_when:
    - 设计或实现云端工作节点预配、工作节点模式或会话移交
    - 更改 `environments.*`、工作节点协议、转录记录提取或推理代理 RPC 调用
    - 审查远程智能体执行的安全态势
summary: 在可通过 SSH 访问的临时机器上运行智能体会话，通过 Gateway 网关代理推理，并在侧边栏实时流式显示。
title: 云端工作节点计划
x-i18n:
    generated_at: "2026-07-11T20:39:29Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: 134c3f6e486837607225d95d12a3153525b14237b362b9f9957313d9bc379dc4
    source_path: plan/cloud-workers.md
    workflow: 16
---

## 状态

提案，第 3 次修订。尚未实现。方向已于 2026 年 7 月达成一致；第 2 次修订纳入了对抗性评审发现（专用工作节点协议、放置/环境状态机、感知 git 的入站同步、v1 单向交接、受控出站安全措辞）。第 3 次修订确定了同步所有权模型（工作节点生成提交，Gateway 网关接纳并发布），新增无 git 的普通同步模式，修复工作节点在机器内拥有完整权限时的 Exec 执行，将互联网策略移至预配阶段，并将智能体分派恢复至里程碑 3。

## 问题

OpenClaw 智能体会话在一台机器的 Gateway 网关进程内运行其循环、工具和推理。计算能力受该机器限制，长时间任务会持续占用它，并行工作也会争用其资源。托管产品（Cursor 云智能体、网页版 Claude Code、Codex 云端）通过为每项任务提供临时云沙箱来解决此问题，但它们需要供应商基础设施，并要求用户信任供应商。

已经拥有闲置机器（或能以较低成本租用机器）的操作员无法指定：在那台机器上运行此会话，像其他会话一样在我的侧边栏中显示它，并在任务结束后销毁该机器。

## 目标

- 在临时远程机器（“云端工作节点”）上运行完整的智能体会话（循环 + 工具），同时该会话在 Control UI 中的显示和流式传输效果与本地会话完全一致。
- 工作节点上不存放长期凭据（无提供商身份验证信息、无代码托管平台令牌），也不允许直接网络出站；该机器只需运行可访问的 `sshd`。
- 自动完成预配、同步、运行、收集和销毁，并支持可插拔提供商（首个提供商：Crabbox 风格的租约 CLI）。
- 在轮次边界将运行中的工作从 Gateway 网关分派至工作节点，同时不丢失对话记录、会话身份，也不破坏提供商缓存亲和性（前提是请求字节保持等效）；随后安全地拉回结果。
- 人类（通过 UI）和智能体（通过工具）都可以将工作分派至云端工作节点。
- 支持持续数天的会话；生命周期由策略决定，而不是硬编码上限。

## 非目标（v1）

- 工作节点上不运行外部编码执行框架（Claude Code、Codex CLI）。工作节点会话仅运行 OpenClaw 的嵌入式运行器。执行框架支持是 v2 的可选功能，因为执行框架会使用自身凭据独立执行推理。
- 不支持 N 选优或并行尝试扇出。
- 不依赖 VPN/tailnet。仅使用 SSH 传输。
- 不新增沙箱运行时。工作节点机器本身就是隔离边界；以后可以在机器内部叠加操作系统级沙箱隔离。
- v1 不支持对称实时迁移：分派方向为本地 → 工作节点；工作节点 → 本地要求会话已停止且工作区协调已完成。后续的双向实时交接将基于同一套屏障机制构建。
- Gateway 网关上不使用 JSON 辅助状态；环境、放置、游标和授权状态均存储在 SQLite 中。

## 现有方案（借鉴什么，反转什么）

- Cursor 云智能体：智能体循环在其云端运行；VM 是工具执行目标；仅追加的对话存储会流式传输至所有客户端；安装后创建快照以便热启动；自托管工作节点是仅出站的工作进程。我们借鉴“对话事实来源保留在编排器上”和流式传输模型；反转循环的放置位置（参见下方决策）。
- Codex 云端：两阶段运行时——联网设置阶段，然后是移除机密信息的离线智能体阶段；使用容器状态缓存加快后续任务。我们借鉴这种阶段拆分作为出站策略，并计划在 v2 热镜像中采用缓存思路。
- 网页版 Claude Code：每个会话使用一台 VM；通过隔离凭据的 git 代理确保真实令牌永不进入沙箱，并将推送限制在会话分支；设置后创建文件系统快照；远程交接 = 已推送分支 + 已重放历史记录。我们借鉴凭据隔离和交接框架，但出站同步由 Gateway 网关通过 `rsync` 完成，因此未提交的工作树也能正常工作，并且机器附近不会存在任何代码托管平台令牌。
- Copilot 编码智能体：默认拒绝出站访问，仅允许访问软件包注册表白名单。我们的稳态默认策略更严格（完全不允许直接出站），因为推理和网络搜索通过 SSH 隧道传入——但请参阅“安全”部分，了解为何应称其为“受控出站”而非“零出站”。

## 架构决策：循环位于工作节点，推理由 Gateway 网关转发

考虑了三种放置方案：

1. 循环保留在 Gateway 网关，工作节点执行工具（Cursor 模型）。这是最安全的故障域（对话记录、推理、审批和重启恢复均保留在本地），也是评审者偏好的首个里程碑。该方案未被采纳为产品架构：OpenClaw 的非 Exec 工具是进程内文件系统操作，因此每次文件读取、编辑和 `grep` 都会变成一次网络往返，或者需要将大量工具接口重构为粗粒度工作区 RPC；运行时行为交互频繁，容易受延迟限制。我们在已有实现中沿用其思路（将 Exec 卸载至节点），但不会构建工具远程调用层。
2. 循环和推理都位于工作节点。故障域最简单，但必须将模型凭据（包括 OAuth 配置文件）发送至一次性机器，Gateway 网关会失去策略、路由和审计控制，而且迁移会切换调用提供商的身份，从而使提供商缓存失效。
3. 循环 + 工具位于工作节点，模型调用通过 Gateway 网关转发。采用此方案。每个模型轮次仅需一次网络往返，而不是每次工具调用都往返；工具在代码所在位置运行；Gateway 网关仍是身份验证配置文件、提供商路由和策略的唯一所有者；工作节点不持有任何机密信息。

方案 3 的代价是每个模型轮次都同步依赖 Gateway 网关，因此其持久性规则是该决策的一部分，而非事后补充：

- 在轮次进行期间丢失 Gateway 网关连接会导致当前提供商调用失败。该轮次会被标记为失败，并在重新连接后作为新轮次重试；不会透明重放进行中的提供商流（存在重复计费或重复工具调用的风险）。
- 每项工作节点 ↔ Gateway 网关操作都携带持久身份信息（参见“工作节点协议”），因此重新连接后会恢复操作或获取已缓存的终态结果，而不会产生悬空操作。
- Gateway 网关是受容量管理的组件：并发工作节点限制、流量控制和负载削减均属于 v1 范围（参见“容量”）。

由于 Gateway 网关既存储对话记录，又发起所有提供商流量，因此会话与位置无关：在 Gateway 网关和工作节点之间移动循环，不会改变提供商侧的任何行为，也不会改变 UI 数据路径。正因如此，分派和拉回的成本很低。

## 组件

### 1. 环境状态机 + 提供商契约

Gateway 网关协议中的 `environments.*` 目前只是状态投影。持久化核心是由 SQLite 管理的环境记录和状态机，并且先于 RPC 结构设计：

`requested → provisioning → bootstrapping → ready → (attached|idle) → draining → destroying → destroyed | failed | orphaned`

- 预配过程支持崩溃恢复：在调用提供商之前，先使用确定性的操作 ID 持久化意图记录，以便 Gateway 网关重启后接管进行中的租约，而不是重复预配或遗留一台持续计费的孤立机器。
- 重启协调和孤立资源清理器（比较提供商 `inspect` 结果与本地记录）是 v1 的必要要求，而非额外加固措施。

提供商契约（由插件实现；核心中不包含提供商名称或策略）：

```ts
type WorkerProvider = {
  id: string;
  provision(profile: WorkerProfile, opId: string): Promise<WorkerLease>; // → ssh host/port/user/key material
  inspect(lease: { leaseId: string; profile: WorkerProfile }): Promise<LeaseStatus>; // adopt/health/orphan sweep
  renew?(leaseId: string): Promise<void>; // long-lived sessions vs provider TTLs
  destroy(lease: { leaseId: string; profile: WorkerProfile }): Promise<void>; // idempotent, returns only on proof of teardown
};
```

RPC：`environments.create`、`environments.destroy`，以及扩展后的 `environments.list/status`（提供商、租约 ID、状态、已存续时间、空闲时间、已附加会话）。首批提供商包括：Crabbox 形态的租约 CLI 封装器（产品路径），以及标记为仅限开发用途的静态 SSH 主机提供商——共享主机上的工作节点可能读取其他无关的主机数据，因此静态主机仅用于功能开发，而不是默认安全方案。

### 2. 工作节点引导：在机器上安装 OpenClaw

不使用专用工作节点制品，也不依赖 npm 的可用性：

- 所有模式的规范安装方式：由 Gateway 网关生成带内容哈希的工作节点捆绑包（将 Gateway 网关自身的构建输出打包为 tarball），通过 SSH 推送并安装到机器上。此方式天然涵盖开发构建和未发布提交。
- 当 Gateway 网关运行已发布版本时，可使用 `npm i -g openclaw@<exact gateway version>` 作为优化；绝不使用 `latest`。
- 引导过程具有幂等性；具有匹配捆绑包哈希的热租约会跳过安装。原始机器可能需要联网的工具链阶段（Node 运行时）——该阶段属于设置阶段，完成后关闭网络访问。
- 握手会验证工作节点构建哈希、协议功能集和运行时兼容性。现有 Gateway 网关版本/协议检查无法满足此要求（通过 SSH 隧道连接的节点不受精确版本拒绝机制约束），因此工作节点准入会执行独立的精确构建检查。

工作节点模式（`openclaw worker`）是一个入口点，而不是分支版本：它包含连接处理和嵌入式智能体运行器，会话持久化和模型调用由 Gateway 网关 RPC 提供支持。它不得启动 Gateway 网关表面：不启动任何渠道，不自动启动会话工具集之外的插件，使用一次性状态目录，不包含本地身份验证配置文件。

### 3. 传输：全部通过 SSH

Gateway 网关负责连接；工作节点除 `sshd` 外无需其他组件：

- Gateway 网关连接至工作节点的 SSH（凭据来自提供商租约，主机密钥固定为预配输出中的密钥——不使用 `StrictHostKeyChecking=no`），并建立反向隧道，将工作节点本地套接字转发至 Gateway 网关的 WS 端点。
- 控制/模型流量和工作区传输使用独立 SSH 连接，并使用相同的固定信任材料，以免 `rsync` 的队头阻塞影响令牌流。
- 隧道生命周期（保活、带退避的重连）由 Gateway 网关上的环境运行时负责管理。隧道短暂中断在会话层面不可见：下述持久协议状态允许工作节点重新附加并恢复。

### 4. 工作节点协议（专用；不使用节点协议）

针对当前节点接口进行的对抗性评审否定了直接复用方案：待处理的节点调用是进程本地 Promise，会随连接断开而消失；节点幂等键虽然会被解析，但不会执行去重；更关键的是，已连接节点可以发出普通节点事件（包括智能体运行请求），因此“节点类型 + 能力上限”不能构成入口安全边界。因此，工作节点使用经过身份验证的 `worker` 角色，并采用封闭且带版本控制的 RPC/事件白名单；工作节点连接无法访问任何旧版节点事件处理程序。

身份和凭据：预配过程会生成短期工作节点凭据，并将其绑定至环境 ID、工作节点密钥、捆绑包哈希、唯一允许的会话、允许的 RPC 集合和过期时间。经 SSH 验证的配对仍然适用（机器由我们预配且密钥由我们持有），但授权来自生成的凭据，而不是声明的节点接口。

持久操作语义（结构借鉴现有 ACP 运行时及其事件账本——稳定句柄、按会话串行化、持久化 `(session, seq)` 重放）：

- 每项操作的作用域为 `(sessionId, lifecycleRevision, runId, ownerEpoch, streamKind, seq)`。
- 所有权纪元用于隔离过期工作节点：替代工作节点会推进纪元；旧纪元迟到的结果会被确定性拒绝。
- 采用至少一次投递，并在 SQLite 中持久化 ACK 游标和缓存的终态结果；去重是确定性的。不承诺恰好一次。
- 为取消、关闭、恢复和终态结果提供显式帧；流采用基于信用额度/窗口的流量控制。
- 协议功能协商独立于通用节点协议版本。

### 5. 会话后端 RPC

两种不同的契约——当前代码库将持久化对话记录变更（由会话管理器所有，采用带父节点/叶节点状态的 JSONL 树）与进程本地实时事件（流式增量、工具生命周期、审批）分离，而工作节点协议必须保留这种划分：

- 持久化对话记录提交：工作节点提交带有 `runEpoch` 和基于叶节点的比较并交换语义追加批次；Gateway 网关会话管理器生成条目 ID 和父条目 ID。工作节点绝不能提供受信任的对话记录行、条目 ID、父条目 ID 或外部会话 ID。
- 可重放的实时事件：一种带工作节点序列号、Gateway 网关 ACK、有界保留和迟到事件隔离机制的类型化事件联合，接入现有智能体事件扇出，使聊天视图、工具行以及未读/状态逻辑的行为与本地会话完全一致。

推理代理：复用现有运行时代理流客户端（`src/agents/runtime/proxy.ts`）的事件词汇，但移动信任边界。工作节点仅发送会话/运行身份、已批准的模型引用、上下文和受约束的生成选项；Gateway 网关根据自己的目录解析提供商、端点、身份验证、请求头、路由和成本策略。工作节点提供的模型对象（例如攻击者控制的 `baseUrl`）将被拒绝。请求大小限制、取消、审计和终态结果重放同样适用。驻留在 Gateway 网关上的工具（websearch）在 Gateway 网关上执行，并通过同一渠道返回结果。

### 6. 工作区同步

同步锚点是由 Gateway 网关在本地维护并具有独占放置所有权的工作区：对于 git 工作区，使用专用的托管工作树（以现有托管工作树元数据——分支、基线、快照所有权——为基础）；对于非 git 工作区，使用 Gateway 网关所有的目标目录。绝不使用用户的实时检出目录。会话远程放置期间的独占所有权，从设计上保证入站同步不会发生冲突。

所有权划分——提交与发布：

- 工作节点侧的智能体在其副本中正常创建提交（`git commit` 是无需凭据的本地操作；作者身份由 Gateway 网关配置投射）。在 Gateway 网关接纳这些提交之前，它们只是惰性的对象。
- Gateway 网关执行所有需要信任的操作：验证入站提交基于记录的基线、快进本地工作树、推送、创建 PR，以及可选的签名/重新签名——全部使用 Gateway 网关本地凭据。工作节点绝不持有 git 或代码托管平台凭据，也绝不接触远程仓库。

根据工作区是否为 git 仓库，选择以下两种同步模式之一：

- Git 模式。出站：通过隧道的 SSH 身份使用 rsync 同步工作树（包括未提交文件和符合条件的未跟踪文件；采用 crabbox 风格的包含/排除规则，并遵循 `.worktreeinclude`），并将其记录为不可变的基线清单（内容哈希 + 基线提交）。入站：新提交以 git bundle 或相对于所记录基线的临时引用返回；未跟踪产物通过显式清单返回，并执行大小/类型/符号链接包含范围检查。接纳过程会验证基线祖先关系，并在出现分叉时停止——绝不会静默覆盖任何一方。删除、重命名、子模块和符号链接逃逸由清单规则处理，而非依赖 rsync 启发式规则。
- 普通模式（无 git——例如在工作节点上从零开始构建项目）。出站同样使用 rsync + 基线清单。入站则基于清单差异，将镜像同步回 Gateway 网关所有的目标目录，并传播删除操作。其安全原因与 Git 模式相同：独占所有权意味着不存在会造成冲突的并发本地编辑；基线清单仍会检测意外的本地漂移，并停止同步而非执行覆盖。

检查点机制可保护持续数天的会话免受租约丢失影响：定期执行入站检查点（Git 模式使用会话分支提交，普通模式使用清单快照）；频率由配置档案策略决定（默认按轮次执行）。

### 7. 放置状态机、会话和 UI

运行时放置是由 SQLite 所有、以会话为键的状态机，而不是一对松散的行字段：

`local → requested → provisioning → syncing → starting → active(worker) → draining → reconciling → local | reclaimed | failed`

它持久化环境 ID、转换代数、活动所有者纪元、工作区基线清单、工作节点 bundle 哈希和最后的 ACK 游标。轮次准入会在任一循环开始轮次前以原子方式声明放置权，因此，基于过期快照准入的本地消息绝不可能与工作节点轮次产生竞争——任何时候都只有一个循环拥有该会话。

UI：

- 工作节点会话是普通会话行加上放置元数据。它存储在常规存储中，通过 `sessions.list` 列出，并通过现有订阅进行流式传输——侧边栏和聊天无需新的数据路径，只需增加呈现内容：工作节点徽章及放置/环境状态（`provisioning / syncing / running / idle / reconciling / reclaimed`）。
- 创建体验：会话目标栏（会话侧边栏重新设计）除 Gateway 网关和节点外，还会增加云端工作节点目标。此功能要求配置提供商配置档案；在完成配置之前，该功能不可见。
- 智能体分派：会话工具允许智能体像人类一样将工作交给云端工作节点（由工作节点支持的子会话，采用子智能体风格）。该功能与人工分派在同一里程碑交付，并受相同的选择启用式提供商配置控制。递归通过结构进行限制（v1 中工作节点会话自身不能再分派工作节点）；支出控制采用按环境核算/审计，而非配额机制。

## 分派与移交

v1 特意采用非对称设计：

- 本地 → 工作节点（分派）：通过下述迁移屏障，预配或复用工作节点、执行同步、切换放置位置，下一轮在远程执行。
- 工作节点 → 本地（拉回）：停止会话（通过同一屏障排空工作节点）、完成入站协调、将放置位置切换为本地。这不是实时迁移。
- 对称实时移交（在不中止工作的情况下双向移动活动会话）会复用同一屏障和协调机制，并在故障注入测试验证屏障后交付。

迁移屏障（仅依靠“轮次边界”并不足够——审批、后台进程以及释放锁后的对话记录合并都可能跨越该边界）：

1. 停止新轮次准入（放置声明）。
2. 取消或排空活动运行。
3. 撤销待处理的 Exec 审批和执行授权。
4. 排空对话记录旁路写入和实时事件 ACK。
5. 终止工作节点子进程。
6. 通过推进所有者纪元隔离旧所有者。
7. 协调工作区（入站、可感知冲突）。
8. 激活新所有者。

缓存亲和性：由于两种放置方式中的提供商请求均源自 Gateway 网关，因此当序列化后的提供商请求保持等价时，缓存亲和性也会得到保留——工具顺序、系统指令、提供商封装器以及缓存元数据均相同（且都保留在 Gateway 网关侧）。这是可测试的属性，而不是假设：在引入工作节点循环的里程碑中，将包含针对每种受支持提供商传输方式的本地/工作节点放置字节等价性测试。

## 安全模型

准确地说：工作节点没有直接网络出站能力，也没有常驻的提供商/代码托管平台凭据。它并非“零出站”——推理和由 Gateway 网关执行的工具是受控出站渠道（受到提示注入的工作节点仍可能将工作区字节放入模型上下文或 websearch 查询）。因此：

- 受控出站核算：对推理代理和 Gateway 网关工具进行按环境审计，并提供操作员可见的核算。速率/字节限制作为协议流量控制（容量）存在，而非作为支出配额机制。
- 工作节点到 Gateway 网关的入口仅限封闭的工作节点协议允许列表；对话记录写入受到结构性约束（由 Gateway 网关生成 ID，并绑定到单一会话）。
- 工作节点 Exec 在工作节点内拥有完整权限。工作节点是一次性的且不含凭据，因此逐命令审批只会增加阻力，并不能保护任何内容；受保护的边界是入站协调和审计。Exec 绝不经过 Gateway 网关的节点审批路径。
- 互联网策略是预配时的提供商决策：环境配置档案在创建工作节点时决定网络策略（防火墙/安全组/无出站网络），还可选择提供联网设置阶段，并由提供商在智能体阶段开始前关闭网络。核心不实现运行时网络开关。
- 预配时的工作节点环境卫生：阻止云元数据端点或验证其不存在，不提供实例配置档案，不继承 SSH 智能体，不提供 Docker 套接字，并使用干净的环境变量/主目录。根据预配输出固定 SSH 主机密钥。
- 所有 Gateway 网关侧操作（推送、PR、提供商调用）的审批和策略继续在 Gateway 网关上运行。

工作节点会话被攻破时的影响范围：已同步的工作区副本，加上经过审计的代理渠道允许传输的内容——无凭据、无直接网络，除允许列表外无法访问任何 Gateway 网关接口。

## 容量

Gateway 网关会为 N 个工作节点中继每条提示和每个词元流，因此 v1 会明确规定容量模型，而不是在生产环境中被动发现问题：每个 Gateway 网关的并发工作节点限制、每条流的信用窗口（当前事件流队列无界，而节点套接字缓冲区达到上限时会强制关闭慢速消费者——二者都不适合未经修改直接使用）、用于应对突发流量的有界磁盘暂存，以及带 UI 可见背压状态的负载卸载。工作区传输继续使用独立的 SSH 渠道。

## 生命周期

- 空闲自动停止和 TTL 是提供商配置档案策略，而非固定常量。默认值较宽松，并提供显式保活机制；持续数天的工作是一等使用场景（对于基于租约的后端，提供商支持 `renew`）；存在进行中轮次或近期活动的会话绝不会被回收。
- 工作节点死亡或被回收时：放置状态转为 `reclaimed`，会话行继续保留；下一条消息会预配新的工作节点，并从最后一个检查点重新同步。对话绝不会丢失（存储位于 Gateway 网关侧）；最后一个检查点之后的工作区变更会丢失，UI 会明确提示。
- 从第一天起支持热租约复用（适用于支持该能力的提供商）；引导启动后的镜像快照是 v2 的快速启动路径。

## 配置界面

保持最小化并选择启用：提供商配置档案块（提供商 ID、凭据/CLI 引用、同步规则、生命周期策略、预算、可选设置阶段），外加按会话选择放置位置。不新增环境变量。未配置的安装环境不会显示任何相关内容。

## 里程碑

实现将以小型、可独立合并的 PR 交付；下列每个里程碑都是一个 PR 系列，而不是单次变更。

1. 基础：环境状态机 + 提供商契约 + crabbox 形态的提供商（使用 static-SSH 作为开发测试框架）、工作节点 bundle 引导启动 + 准入握手、SSH 隧道 + 主机密钥固定、托管工作树快照 + 出站同步（Git + 普通模式）。孤儿清理 + 重启后接纳。
2. 工作节点协议 + 工作节点循环：经过身份验证的工作节点角色、持久化操作/纪元/ACK 游标、对话记录提交 + 实时事件契约、使用 Gateway 网关解析模型的推理代理、流量控制。一个提供商，仅支持人工分派新会话，不支持移交。必须通过故障注入测试（隧道分区、Gateway 网关重启、工作节点死亡）才能完成该里程碑。
3. 分派 + 拉回 + 智能体分派：迁移屏障、连接到 UI 目标栏的放置状态机、入站协调 + 检查点、按环境审计、容量限制、智能体分派工具（工作节点会话不能递归）。提示缓存字节等价性测试。
4. 对称实时移交，在里程碑 3 的故障注入验证完成后实施。

后续：工作节点上的 ACP 测试框架，采用按环境选择启用的凭据注入；快照/热镜像快速启动；扇出（N 个租约，同一提示）；工作节点内操作系统沙箱隔离；通过产物模式实现更丰富的产物捕获。

## 待解决问题

- 工作节点上的插件/Skills 可用性：仓库自带的 Skills 会随工作区自动同步；通过 Gateway 网关配置的智能体 Skills/插件则需要明确决定同步或排除（无论采用哪种方式，工具/插件清单都是准入握手的一部分）。
- 检查点的默认生成频率：对于消息非常频繁的会话，是按轮次还是按时间生成。
- 环境配置文件如何与多智能体路由交互（每个智能体的默认配置文件与仅按会话选择的配置文件）。
