跳到主要内容

本地设备架构

本文档介绍本地设备支持的技术架构,包括通信协议、心跳机制和安全设计。


🏗 架构概述

系统组件

通信架构

下图展示了本地设备如何与 Wegent 系统通信:

设备类型

设备 CRD 使用 spec.deviceType 区分生命周期归属和前端能力入口:

类型生命周期归属连接方式典型入口
local用户本机 executorWebSocket本地安装脚本或手动启动 executor
cloudWegent 云设备服务WebSocket云设备创建、重启、释放流程
remote用户自管 Docker 容器或远端主机WebSocketWework 连接设置中的远程 Docker 命令

remote 设备复用本地 executor 的 WebSocket 注册、心跳、任务执行和 command RPC 通道,但由 RemoteDeviceProvider 独立列出和返回 remoteConfig。Backend 不保存生成命令中的 WEGENT_AUTH_TOKEN;Device CRD 只保存 provider、image、deviceId、deviceName、backendUrl、publicBaseUrl 和 createdAt 等非敏感元数据。

远程 Docker 设备启动后会发送 device:register,payload 中的 device_type=remote 会更新同名 Device CRD。在线状态仍存储在 Redis 的设备在线键中,因此任务调度、slot 统计、terminal/code-server session RPC 与本地设备保持同一套协议。前端不会对 remote 设备展示云设备生命周期操作;停止、重启、删除容器由用户在 Docker 主机上完成。


📡 WebSocket 协议

事件类型

事件方向描述
device:register设备 → 后端设备注册
device:heartbeat设备 → 后端心跳保活
task:execute后端 → 设备下发任务
task:progress设备 → 后端任务进度
task:complete设备 → 后端任务完成

消息格式

// device:register
{
"event": "device:register",
"data": {
"device_id": "uuid-xxx",
"name": "Darwin - MacBook-Pro.local",
"max_slots": 5
}
}

// device:heartbeat
{
"event": "device:heartbeat",
"data": {
"device_id": "uuid-xxx",
"running_task_ids": ["task-1", "task-2"]
}
}

// task:execute
{
"event": "task:execute",
"data": {
"subtask_id": "subtask-xxx",
"prompt": "用户消息",
"context": {}
}
}

💓 心跳机制

时序图

时间参数

参数描述
心跳间隔30 秒设备发送心跳
在线 TTL90 秒Redis 键过期时间
监控间隔60 秒后端检查过期设备
离线阈值3 次心跳缺失设备标记为离线

运行任务追踪

每次心跳包含当前运行的任务 ID,用于:

  • 实时槽位使用追踪
  • 孤立任务检测
  • 断开连接时自动清理

全局能力状态上报

本地设备还会通过心跳上报 Claude Code 全局能力状态。完整上报包含:

  • capabilities.revision:本地 Wegent 管理清单版本
  • capabilities.digestskillspluginsmcps 的内容摘要
  • capabilities.skills~/.claude/skills 中可用的 Skill
  • capabilities.plugins~/.claude/plugins/installed_plugins.json 中已安装的 Plugin
  • capabilities.mcps:Wegent 管理的全局 MCP 配置

Plugin 上报必须包含其内部 Skill 列表。Executor 会扫描每个 Plugin 安装目录下的 SKILL.md,并在 plugins[].skills[] 中返回:

{
"name": "context7",
"marketplace": "claude-plugins-official",
"version": "1057d02c5307",
"source": "wegent",
"installed_plugin_id": 301,
"skills": [
{
"name": "context7",
"description": "Look up version-specific documentation.",
"path": "skills/context7"
}
]
}

后端只在 capabilities.full = true 时保存完整能力状态;后续心跳如果只有相同 digest,只刷新在线状态,不重复写入完整列表。

全局能力同步

后端可以通过 device:sync_capabilities 向在线本地设备下发全局能力期望状态。当前同步内容包括:

  • skills:通过 backend 解析后的 InstalledSkill / Skill,由 executor 下载到 ~/.claude/skills
  • plugins:通过 backend 解析后的 InstalledPlugin,由 executor 写入 ~/.claude/plugins/installed_plugins.json
  • mcps:通过 backend 解析后的 InstalledMCP,由 executor 写入 Wegent 管理清单

replace 模式只会清理由 Wegent manifest 标记为 managed 且不在期望状态中的能力。用户直接在本机安装的 plugin 不会因为一次 Wegent 同步被删除。

项目任务使用本地 executor 执行时,任务级 CLAUDE_CONFIG_DIR 会同时暴露全局 skillsplugins 目录,并从本机 ~/.claude/settings.json 继承 enabledPluginsextraKnownMarketplaces 等非敏感插件配置,使 Claude Code 能加载全局 Skill 以及 Plugin 内部提供的 Skill。模型、Token 等敏感配置仍通过运行时环境变量注入,不会从全局 settings 写入任务目录。

项目模式下访问 Claude 或 Codex 模型 API 时,executor 会在直接启动的运行时上下文中加入 wecode-project: <project_id> 请求头,并补齐 wecode-action: wegentwecode-source: wegent-localwecode-executor: <runtime> 来源标识,其中 Claude Code 使用 claudecode,Codex 使用 codex。Claude Code 本地模式会先合并 executor 启动进程环境和运行时环境里已有的 ANTHROPIC_CUSTOM_HEADERS,再追加 project 标识,并同时写入 ANTHROPIC_CUSTOM_HEADERSDEFAULT_HEADERS/default_headers 环境变量,保证直接 Claude Code 子进程和下游模型网关读取到一致的 header 集合;Codex 在 Wegent 管理 provider 配置时写入 provider 的 http_headers,使用个人 Codex 配置且显式指定 provider 时也会对该 provider 注入同一 project 请求头。


🔄 任务执行流程

任务状态流转


🔐 安全机制

认证流程

安全特性

特性描述
JWT 认证WebSocket 连接需要有效 token
Token 有效期7 天过期,需定期刷新
用户隔离设备只能执行其所有者的任务
硬件绑定设备 ID 基于硬件标识生成

本地执行器连接配置

本地执行器启动时按“环境变量、~/.wegent-executor/device-config.json、默认值”的顺序解析配置。其中 mode 决定启动模式,connection.backend_urlconnection.auth_token 分别用于连接 Backend 和完成设备认证。

EXECUTOR_MODE 覆盖 modeWEGENT_BACKEND_URL 覆盖 connection.backend_urlWEGENT_AUTH_TOKEN 覆盖 connection.auth_token。因此常规启动脚本不需要强制传入这些环境变量;只要设备配置文件中已有有效模式和连接信息,executor 就可以直接启动。

云设备启动身份变量

云设备通过 user data 启动脚本自动安装并运行 executor。启动脚本会注入以下身份相关环境变量:

变量来源用途
WEGENT_AUTH_TOKEN后端为云设备自动生成的 API Keyexecutor 连接后端并注册设备
WEGENT_USER_JWT_TOKEN创建云设备请求中的当前用户 Bearer JWT云设备内需要以当前用户身份访问后端能力的脚本或集成
WEGENT_USER_NAME当前登录用户名云设备内需要识别当前用户的脚本或集成

WEGENT_AUTH_TOKENWEGENT_USER_JWT_TOKEN 不能混用:前者代表设备认证身份,后者代表创建云设备时的用户身份。

云设备启动系统配置

创建云设备时,后端会生成 ubuntu 用户的初始化登录密码,并存储在 Device CRD 的 spec.cloudConfig.ubuntuInitialPassword 字段中。user data 启动脚本会使用该密码执行 chpasswd,完成 ubuntu 用户密码初始化。

同一个 user data 启动脚本还会创建 /etc/systemd/system/fstrim.timer.d/override.conf,将 fstrim.timer 配置为每天运行,并重新加载、重启、启用该 timer。

用户隔离

每个设备会话绑定到用户:

  • 设备只能接收其注册所有者的任务
  • 防止跨用户任务执行
  • 子任务根据用户命名空间进行验证

数据隐私

使用本地设备时:

  • 代码留在本地:源代码不会上传到云端
  • 本地执行:所有处理在用户机器上进行
  • 结果流式传输:只有输出文本被传输
  • 无持久存储:云端不存储本地文件

🔧 设备 ID 生成

Executor 自动生成稳定的设备 ID,基于以下优先级:

  1. 缓存 ID:存储在 ~/.wegent-executor/device_id(如存在)
  2. 硬件 UUID
    • macOS:系统硬件 UUID
    • Linux:/etc/machine-id
    • Windows:注册表中的 MachineGuid
  3. 后备方案:MAC 地址或随机 UUID

这确保设备在重启后保持一致的身份标识。


📊 并发控制

槽位管理

每个设备支持最多 5 个并发任务

  • 槽位使用通过心跳实时追踪
  • 所有槽位被占用时设备显示"繁忙"
  • 如果选择繁忙设备,任务会排队等待

负载均衡


🔗 相关文档


💬 获取帮助

需要帮助?