- Create docs/README.md as documentation index - Add WORK_SUMMARY_2026-03-16.md for today's work - Move test reports to docs/test-reports/ - Move completed plans to docs/archive/completed-plans/ - Move research reports to docs/archive/research-reports/ - Move technical reference to docs/knowledge-base/ - Move all plans from root plans/ to docs/plans/ New structure: docs/ ├── README.md # Documentation index ├── DEVELOPMENT.md # Development guide ├── OPENVIKING_INTEGRATION.md # OpenViking integration ├── USER_MANUAL.md # User manual ├── ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md ├── archive/ # Archived documents ├── knowledge-base/ # Technical knowledge ├── plans/ # Execution plans └── test-reports/ # Test reports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12 KiB
ZClaw 项目深度分析与改进计划
一、现状分析
1.1 核心发现
基于 docs/openclaw-deep-dive.md 的目标与实际代码的对比:
| 模块 | 目标状态 | 实际状态 | 差距程度 |
|---|---|---|---|
| Gateway 连接 | 设备认证 + Challenge 签名 | ✅ 完整实现 | 无差距 |
| 分身系统 | 映射到 OpenClaw agents.list |
⚠️ 独立存储在 zclaw-data.json |
严重 |
| 设置页 | OpenClaw Runtime 配置面板 | ⚠️ 大部分是前端本地状态 | 严重 |
| 右侧面板 | 真实 Agent 身份与状态 | ⚠️ 混合真实数据与硬编码值 | 中等 |
1.2 关键差距详解
差距 1:分身与 Agent 断层(最严重)
当前架构:
┌─────────────────────────────────────────────────────────────┐
│ ZClaw 分身系统 (zclaw-data.json) │
│ clone_1: { name: "程序员", workspaceDir: "...", ... } │
│ clone_2: { name: "设计师", workspaceDir: "...", ... } │
└────────────────────────┬────────────────────────────────────┘
│ ❌ 无同步
▼
┌─────────────────────────────────────────────────────────────┐
│ OpenClaw agents.list (openclaw.json) │
│ 只有: [{ id: "main", groupChat: {...} }] │
└─────────────────────────────────────────────────────────────┘
后果:
- 所有分身实际共用同一个
mainAgent - 聊天时不传递
agentId,OpenClaw 不知道当前是哪个分身 - Bootstrap 文件(IDENTITY.md, SOUL.md 等)生成了但未被运行时使用
差距 2:设置页是"假状态"
| 设置页 | 当前实现 | 应该实现 |
|---|---|---|
| 模型选择 | 存在 chatStore.currentModel(前端状态) |
调用 config.patch 修改 OpenClaw 配置 |
| MCP 服务 | 存 quickConfig,部分同步到 Gateway |
管理 plugins.load.paths |
| 技能目录 | 存 quickConfig |
管理 skills.load.extraDirs |
| IM 频道 | 存 quickConfig,只显示状态 |
管理 channels.* 配置 |
| 工作区 | 存 quickConfig |
管理 agents.defaults.workspace |
| 隐私 | 存 quickConfig |
管理 telemetry/优化计划 |
缺失的 RPC 方法:
config.get- 读取 OpenClaw 配置config.patch- 修改配置config.apply- 热更新配置
差距 3:右侧面板数据不真实
// 硬编码的默认值(RightPanel.tsx)
const credits = 2268; // 完全假数据
const defaultUserName = '用户7141'; // 假用户名
二、根因分析
2.1 架构层面的偏差
文档期望:
ZClaw 应该是 OpenClaw Runtime 的控制界面
实际实现:
ZClaw 是一个有自己数据模型的前端应用,与 OpenClaw 是松耦合
2.2 数据模型的分裂
OpenClaw 数据模型:
openclaw.json → agents.list → Agent workspace → Bootstrap files
ZClaw 数据模型:
zclaw-data.json → clones[] → (独立的) workspace 路径
两套数据模型没有桥接,导致:
- 分身不能路由到正确的 Agent
- 设置不能影响 OpenClaw 行为
- Bootstrap 文件与运行时脱节
三、头脑风暴:改进方案
3.1 方案 A:完全对齐 OpenClaw(推荐)
核心思路:让 ZClaw 分身直接映射到 OpenClaw Agent
改进后架构:
┌─────────────────────────────────────────────────────────────┐
│ ZClaw 分身 = OpenClaw Agent │
│ │
│ clone_1 ↔ agents.list[0] (id: "programmer") │
│ clone_2 ↔ agents.list[1] (id: "designer") │
│ │
│ 分身 CRUD → 同步修改 agents.list │
│ 聊天时 → 传递 agentId 到 Gateway │
└─────────────────────────────────────────────────────────────┘
优点:
- 符合
openclaw-deep-dive.md的设计哲学 - 分身真正有独立人格、记忆、工具权限
- 设置页可以直接操作 OpenClaw 配置
缺点:
- 改动较大,需要修改多个模块
- 需要处理数据迁移
3.2 方案 B:保持独立,增强桥接
核心思路:保持 zclaw-data.json,但增加同步逻辑
改进后架构:
┌─────────────────────────────────────────────────────────────┐
│ ZClaw 分身系统 (主) │
│ zclaw-data.json → clones[] │
│ │ │
│ ▼ (单向同步) │
│ openclaw.json → agents.list (从分身生成) │
└─────────────────────────────────────────────────────────────┘
优点:
- 改动较小
- 保持现有分身管理逻辑
缺点:
- 数据冗余,需要维护同步
- 不符合 OpenClaw 的设计哲学
3.3 方案 C:混合模式
核心思路:
- 简单分身:共用
mainAgent,通过 Bootstrap 文件区分 - 高级分身:映射到独立 OpenClaw Agent
四、推荐实施路线(方案 A)
P0:让分身真正工作(最小可行)
目标:创建分身时同步到 OpenClaw agents.list,聊天时传递 agentId
关键修改:
-
plugins/zclaw-ui/index.tscreateClone时调用 OpenClaw API 添加到agents.listdeleteClone时从agents.list移除- 新增
zclaw.agents.sync方法
-
desktop/src/lib/gateway-client.tschat()方法增加agentId参数
async chat(message: string, opts?: { agentId?: string; sessionKey?: string }): Promise<...> -
desktop/src/store/chatStore.tssendMessage时传递currentAgent.id作为agentId
-
新增 Gateway RPC
zclaw.config.get- 读取 OpenClaw 配置zclaw.config.patch- 修改配置
验收标准:
- 创建分身后,
openclaw.json的agents.list包含新 Agent - 切换分身后,聊天请求携带正确的
agentId - 每个分身有独立的对话上下文
P1:设置页 Runtime 化
目标:设置修改直接影响 OpenClaw Runtime
关键修改:
-
desktop/src/lib/gateway-client.ts- 实现
configGet()、configPatch()、configApply()方法
- 实现
-
各设置页改造
- 模型与 API:调用
config.patch修改agents.defaults.model - MCP 服务:管理
plugins.load.paths - 技能目录:管理
skills.load.extraDirs - 工作区:管理
agents.defaults.workspace - 隐私:管理 telemetry 相关配置
- 模型与 API:调用
-
UI 反馈
- 显示配置保存状态
- 配置变更后显示"需要重启"提示(如需要)
验收标准:
- 模型选择后,
openclaw.json的agents.defaults.model更新 - 添加技能目录后,
skills.load.extraDirs更新 - Gateway 重启后配置生效
P2:完整的 Agent 管理系统
目标:分身管理 = Agent 全生命周期管理
功能扩展:
- 分身绑定渠道(飞书账号、微信群等)
- 分身 Heartbeat 配置
- 分身工具权限/沙箱配置
- 分身间路由规则
UI 改进:
- 右侧面板显示真实 Agent 状态(非硬编码)
- 分身详情页增加完整配置选项
P3:产品化封装
目标:开箱即用的桌面体验
功能:
- Tauri sidecar 管理 Gateway 进程
- 首次安装配置向导
- 错误诊断与自动修复
- 一键更新
五、关键文件清单
| 文件 | 修改内容 |
|---|---|
plugins/zclaw-ui/index.ts |
分身 CRUD 同步到 agents.list |
desktop/src/lib/gateway-client.ts |
增加 agentId 参数、config RPC |
desktop/src/store/chatStore.ts |
sendMessage 传递 agentId |
desktop/src/store/gatewayStore.ts |
管理 Agent 配置状态 |
desktop/src/components/CloneManager.tsx |
显示同步状态 |
desktop/src/components/RightPanel.tsx |
显示真实 Agent 数据 |
desktop/src/components/Settings/*.tsx |
改造为 Runtime 配置面板 |
config/openclaw.default.json |
更新默认 Agent 模板 |
六、风险与缓解
| 风险 | 缓解措施 |
|---|---|
| 数据迁移复杂 | 提供迁移脚本,保留 zclaw-data.json 作为备份 |
| OpenClaw 版本兼容 | 检测 OpenClaw 版本,低版本降级到兼容模式 |
| 破坏现有功能 | 灰度发布,支持回滚 |
| 性能下降 | 懒加载 Agent 配置,缓存 RPC 结果 |
七、确认的方案
选择:方案 A - 完全对齐 OpenClaw
理由:
- 符合
openclaw-deep-dive.md的设计哲学 - 分身真正有独立人格、记忆、工具权限
- 设置页可以直接操作 OpenClaw 配置
- 长期维护成本最低
八、下一步行动(P0 详细任务)
Task 1: 修改 zclaw-ui 插件 - 分身同步到 agents.list
文件: plugins/zclaw-ui/index.ts
修改点:
createClone方法增加:- 调用 OpenClaw 内部 API 将分身添加到
agents.list - 设置
agentId字段关联分身与 Agent
- 调用 OpenClaw 内部 API 将分身添加到
deleteClone方法增加:- 从
agents.list移除对应 Agent
- 从
updateClone方法增加:- 同步更新 Agent 配置
- 新增
zclaw.agents.sync方法:- 读取当前
agents.list - 与
zclaw-data.json比对 - 修复不一致
- 读取当前
Task 2: 修改 GatewayClient - 支持 agentId
文件: desktop/src/lib/gateway-client.ts
修改点:
chat()方法签名改为:async chat(message: string, opts?: { agentId?: string; // 新增 sessionKey?: string; model?: string; }): Promise<{ runId: string; acceptedAt: string }>request('agent', ...)时传递agentId
Task 3: 修改 chatStore - 传递 agentId
文件: desktop/src/store/chatStore.ts
修改点:
sendMessage方法调用client.chat()时传递currentAgent.id
Task 4: 新增配置 RPC 方法
文件: desktop/src/lib/gateway-client.ts + plugins/zclaw-ui/index.ts
新增方法:
zclaw.config.get- 读取 OpenClaw 配置zclaw.config.patch- 修改配置(不重启)zclaw.config.apply- 热更新配置(如需重启)
Task 5: 数据迁移脚本
创建: scripts/migrate-clones-to-agents.ts
功能:
- 读取现有
zclaw-data.json中的分身 - 为每个分身在
agents.list创建对应条目 - 更新分身的
agentId字段 - 备份原始文件
九、验收标准
P0 完成标准
- 创建分身后,
~/.openclaw/openclaw.json的agents.list包含新 Agent - 删除分身后,对应 Agent 从
agents.list移除 - 切换分身后,聊天请求携带正确的
agentId - 每个分身有独立的对话上下文(不串聊)
- 现有分身数据成功迁移,无数据丢失
- 单元测试覆盖新增逻辑 ≥ 80%