feat: 新增技能编排引擎和工作流构建器组件
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

refactor: 统一Hands系统常量到单个源文件
refactor: 更新Hands中文名称和描述

fix: 修复技能市场在连接状态变化时重新加载
fix: 修复身份变更提案的错误处理逻辑

docs: 更新多个功能文档的验证状态和实现位置
docs: 更新Hands系统文档

test: 添加测试文件验证工作区路径
This commit is contained in:
iven
2026-03-25 08:27:25 +08:00
parent 9c781f5f2a
commit aa6a9cbd84
110 changed files with 12384 additions and 1337 deletions

View File

@@ -0,0 +1,714 @@
# ZCLAW 功能验证计划
> **版本**: v0.2.5
> **创建日期**: 2026-03-24
> **验证范围**: 所有已实现功能的完整性、可用性验证
---
## 一、验证概述
### 1.1 验证目标
基于 `docs/features` 目录的文档,系统化验证 ZCLAW 所有已实现功能的:
- **完整性** - 功能是否完整实现
- **可用性** - 功能是否可正常使用
- **集成性** - 前后端是否正确集成
- **持久性** - 数据是否正确持久化
### 1.2 验证范围统计
| 模块 | 功能数量 | 验证点数量 |
|------|---------|-----------|
| 架构层 | 3 | 45 |
| 核心功能 | 6 | 38 |
| 智能层 | 6 | 42 |
| 技能系统 | 3 | 15 |
| Hands 系统 | 9 | 20 |
| 后端集成 | 100+ | 25 |
| **总计** | **127+** | **185** |
---
## 二、Phase 1: 架构层验证
### 2.1 通信层验证 (01-communication-layer.md)
#### 2.1.1 LLM Provider 连接验证
| # | 验证项 | 测试方法 | 预期结果 |
|---|--------|---------|---------|
| 1.1 | Kimi Provider | 配置 Kimi API Key发送消息 | 流式响应正常 |
| 1.2 | Qwen Provider | 配置通义千问 API Key | 流式响应正常 |
| 1.3 | DeepSeek Provider | 配置 DeepSeek API Key | 流式响应正常 |
| 1.4 | 智谱 Provider | 配置智谱 API Key | 流式响应正常 |
| 1.5 | OpenAI Provider | 配置 OpenAI Key | 流式响应正常 |
| 1.6 | Anthropic Provider | 配置 Claude API Key | 流式响应正常 |
| 1.7 | Gemini Provider | 配置 Gemini API Key | 流式响应正常 |
| 1.8 | Local Provider (Ollama) | 启动 Ollama配置 localhost:11434 | 流式响应正常 |
| 1.9 | 自定义 baseUrl | 配置自定义 URL | 请求发送到自定义地址 |
**关键文件**: `desktop/src/lib/kernel-client.ts`, `crates/zclaw-runtime/src/driver/`
#### 2.1.2 Tauri 命令验证
| # | 命令 | 验证方法 | 预期结果 |
|---|------|---------|---------|
| 2.1 | `kernel_init` | 首次启动应用 | `initialized: true` |
| 2.2 | `kernel_status` | 调用状态 API | 返回当前状态 |
| 2.3 | `kernel_shutdown` | 关闭应用 | 优雅关闭 |
| 2.4 | `agent_create` | 创建新 Agent | 返回 `{ id, name, state }` |
| 2.5 | `agent_list` | 调用列表 API | 返回 Agent 数组 |
| 2.6 | `agent_get` | 获取 Agent 详情 | 返回完整信息 |
| 2.7 | `agent_delete` | 删除 Agent | 成功删除 |
| 2.8 | `agent_chat` | 发送非流式消息 | 返回完整响应 |
| 2.9 | `agent_chat_stream` | 发送流式消息 | 收到流式事件 |
**关键文件**: `desktop/src-tauri/src/kernel_commands.rs`
#### 2.1.3 流式响应验证
| # | 验证项 | 测试方法 | 预期结果 |
|---|--------|---------|---------|
| 3.1 | delta 事件 | 发送消息 | UI 逐字显示 |
| 3.2 | tool_start 事件 | 触发工具调用 | 显示工具开始状态 |
| 3.3 | tool_end 事件 | 工具完成 | 显示工具输出 |
| 3.4 | complete 事件 | 消息完成 | 停止流式,显示 token 统计 |
| 3.5 | error 事件 | 模拟错误 | 显示错误信息 |
| 3.6 | sessionId 路由 | 并发发送多条 | 事件正确路由 |
| 3.7 | 流式取消 | 调用 cancelStream | 清理监听器 |
#### 2.1.4 错误处理验证
| # | 场景 | 预期行为 |
|---|------|---------|
| 4.1 | 未配置模型 | 显示中文提示 |
| 4.2 | API Key 无效 | 显示 401 错误 |
| 4.3 | 网络中断 | 显示连接失败 |
| 4.4 | 流式错误 | UI 恢复可交互 |
| 4.5 | 自动重连 | reconnecting 状态 |
---
### 2.2 状态管理验证 (02-state-management.md)
#### 2.2.1 Store 持久化验证
| # | Store | 验证项 | 测试方法 |
|---|-------|--------|---------|
| 5.1 | chatStore | 对话历史保留 | 刷新页面后验证 |
| 5.2 | chatStore | partialize | 检查 localStorage 内容 |
| 5.3 | configStore | 配置保留 | 修改后刷新验证 |
| 5.4 | offlineStore | 离线队列保留 | 离线发送后刷新 |
**关键文件**: `desktop/src/store/chatStore.ts`, `desktop/src/store/configStore.ts`
#### 2.2.2 Store 间通信验证
| # | 验证项 | 测试方法 |
|---|--------|---------|
| 6.1 | 客户端注入 | 检查 initializeStores() |
| 6.2 | 连接状态同步 | 连接后验证 Agent 自动加载 |
| 6.3 | 跨 Store 访问 | 发送消息时检查连接状态 |
| 6.4 | 单例模式 | 多次调用验证同一实例 |
#### 2.2.3 Date 对象恢复验证
| # | 验证项 | 测试方法 |
|---|--------|---------|
| 7.1 | 日期转换 | 刷新后验证时间显示 |
| 7.2 | streaming 清除 | 流式中刷新验证 |
| 7.3 | 当前会话恢复 | 切换对话后刷新 |
---
### 2.3 安全认证验证 (03-security-auth.md)
#### 2.3.1 设备认证验证
| # | 验证项 | 测试方法 |
|---|--------|---------|
| 8.1 | 密钥生成 | 清空存储后启动 |
| 8.2 | 密钥持久化 | 验证 Keyring 调用 |
| 8.3 | JWT Token 存储 | 验证非明文存储 |
| 8.4 | Token 刷新 | 过期后自动刷新 |
**关键文件**: `desktop/src/lib/secure-storage.ts`
#### 2.3.2 存储后端验证
| # | 平台 | 存储后端 |
|---|------|---------|
| 9.1 | Windows | DPAPI |
| 9.2 | macOS | Keychain |
| 9.3 | Linux | Secret Service |
| 9.4 | 降级 | AES-GCM 加密 localStorage |
---
## 三、Phase 2: 核心功能验证
### 3.1 聊天界面验证
| # | 功能 | 验证方法 | 预期结果 |
|---|------|---------|---------|
| 10.1 | 流式响应展示 | 发送消息 | 实时显示 |
| 10.2 | Markdown 渲染 | 发送 Markdown 内容 | 正确渲染 |
| 10.3 | 代码块渲染 | 发送代码 | 语法高亮 |
| 10.4 | 多会话管理 | 创建/切换/删除 | 状态正确 |
| 10.5 | 模型选择 | 切换模型 | 使用新模型 |
| 10.6 | 消息自动滚动 | 长对话 | 自动滚动到底部 |
| 10.7 | 输入框调整 | 输入多行 | 高度自动调整 |
| 10.8 | 记忆增强注入 | 发送相关历史 | 自动注入上下文 |
| 10.9 | 上下文压缩 | 超过阈值 | 自动压缩 |
**关键文件**: `desktop/src/components/ChatArea.tsx`, `desktop/src/store/chatStore.ts`
### 3.2 Agent 分身管理验证
| # | 功能 | 验证方法 | 预期结果 |
|---|------|---------|---------|
| 11.1 | 创建 Agent | 通过向导创建 | 成功创建 |
| 11.2 | 配置 Agent | 修改 SOUL.md | 配置生效 |
| 11.3 | 切换 Agent | 切换当前 Agent | 状态更新 |
| 11.4 | 人格预设 | 选择不同预设 | SOUL.md 不同 |
| 11.5 | 身份持久化 | 重启应用 | Agent 保留 |
**关键文件**: `desktop/src/components/AgentOnboardingWizard.tsx`, `desktop/src/lib/personality-presets.ts`
### 3.3 多 Agent 协作验证
| # | 模式 | 验证方法 | 预期结果 |
|---|------|---------|---------|
| 12.1 | Sequential | 创建链式任务 | 按顺序执行 |
| 12.2 | Parallel | 创建并行任务 | 并发执行 |
| 12.3 | Debate | 创建辩论任务 | 多轮讨论后综合 |
**关键文件**: `desktop/src/components/SwarmDashboard.tsx`, `desktop/src/lib/agent-swarm.ts`
---
## 四、Phase 3: 智能层验证
### 4.1 Agent 记忆系统验证 (00-agent-memory.md)
#### 4.1.1 记忆类型验证
| # | 类型 | 测试方法 | 预期结果 |
|---|------|---------|---------|
| 13.1 | fact | 存储事实记忆 | 正确存储 |
| 13.2 | preference | 存储偏好记忆 | 正确存储 |
| 13.3 | lesson | 存储教训记忆 | 正确存储 |
| 13.4 | context | 存储上下文记忆 | 正确存储 |
| 13.5 | task | 存储任务记忆 | 正确存储 |
#### 4.1.2 记忆操作验证
| # | 操作 | Tauri 命令 | 验证方法 |
|---|------|-----------|---------|
| 14.1 | 初始化 | `memory_init` | 调用成功 |
| 14.2 | 存储 | `memory_store` | 存储成功 |
| 14.3 | 获取 | `memory_get` | 正确获取 |
| 14.4 | 搜索 | `memory_search` | 返回相关记忆 |
| 14.5 | 删除 | `memory_delete` | 删除成功 |
| 14.6 | 统计 | `memory_stats` | 返回统计 |
| 14.7 | 导出 | `memory_export` | 导出 Markdown |
| 14.8 | 导入 | `memory_import` | 导入成功 |
**关键文件**: `desktop/src-tauri/src/memory_commands.rs`, `desktop/src/components/MemoryPanel.tsx`
#### 4.1.3 记忆 UI 集成验证
| # | 组件 | 验证方法 |
|---|------|---------|
| 15.1 | MemoryPanel | 点击 RightPanel | 显示记忆面板 |
| 15.2 | MemoryGraph | 查看记忆图谱 | 正确渲染 |
| 15.3 | 统计显示 | 查看统计 | 显示正确 |
| 15.4 | 清理功能 | 点击清理 | 正确执行 |
### 4.2 身份演化验证 (01-identity-evolution.md)
| # | 功能 | API/命令 | 验证方法 |
|---|------|---------|---------|
| 16.1 | 获取身份 | `identity_get` | 返回身份文件 |
| 16.2 | 更新文件 | `identity_update_file` | 更新成功 |
| 16.3 | 变更提案 | `identity_propose_change` | 创建提案 |
| 16.4 | 批准提案 | `identity_approve_proposal` | 应用变更 |
| 16.5 | 拒绝提案 | `identity_reject_proposal` | 丢弃提案 |
| 16.6 | 快照历史 | `identity_get_snapshots` | 返回历史 |
| 16.7 | 回滚 | `identity_restore_snapshot` | 恢复成功 |
**关键文件**: `desktop/src/lib/intelligence-client.ts`, `desktop/src/components/IdentityChangeProposal.tsx`
### 4.3 反思引擎验证 (03-reflection-engine.md)
| # | 功能 | Tauri 命令 | 验证方法 |
|---|------|-----------|---------|
| 17.1 | 记录对话 | `reflection_record_conversation` | 记录成功 |
| 17.2 | 触发检查 | `reflection_should_reflect` | 返回是否触发 |
| 17.3 | 执行反思 | `reflection_reflect` | 返回结果 |
| 17.4 | 获取历史 | `reflection_get_history` | 返回历史 |
**验证触发条件**:
- 对话次数: 每 5 次后
- 时间间隔: 每 24 小时
- 首次触发: 3 次对话后
**关键文件**: `desktop/src-tauri/src/intelligence/reflection.rs`, `desktop/src/components/ReflectionLog.tsx`
### 4.4 心跳引擎验证 (04-heartbeat-engine.md)
| # | 功能 | Tauri 命令 | 验证方法 |
|---|------|-----------|---------|
| 18.1 | 初始化 | `heartbeat_init` | 初始化成功 |
| 18.2 | 启动 | `heartbeat_start` | 开始跳动 |
| 18.3 | 停止 | `heartbeat_stop` | 停止跳动 |
| 18.4 | 手动触发 | `heartbeat_tick` | 执行检查 |
| 18.5 | 获取配置 | `heartbeat_get_config` | 返回配置 |
| 18.6 | 更新配置 | `heartbeat_update_config` | 更新成功 |
| 18.7 | 获取历史 | `heartbeat_get_history` | 返回历史 |
**验证检查函数**:
- `check_pending_tasks` - 待办任务积压
- `check_memory_health` - 记忆健康
- `check_idle_greeting` - 长时间未互动
- `check_personality_improvement` - 人格改进
- `check_learning_opportunities` - 学习机会
**关键文件**: `desktop/src-tauri/src/intelligence/heartbeat.rs`
### 4.5 自主授权验证 (05-autonomy-manager.md)
#### 4.5.1 自主级别验证
| # | 级别 | 行为 | 验证方法 |
|---|------|------|---------|
| 19.1 | supervised | 所有操作需确认 | 设置后验证 |
| 19.2 | assisted | 低风险自动,中高需确认 | 设置后验证 |
| 19.3 | autonomous | 低中风险自动,高需确认 | 设置后验证 |
#### 4.5.2 风险等级验证
| # | 等级 | 操作类型 | 验证方法 |
|---|------|---------|---------|
| 20.1 | Low | memory_save, reflection_run | 验证自动执行 |
| 20.2 | Medium | hand_trigger, skill_install | 验证需确认 |
| 20.3 | High | memory_delete, identity_update | 验证始终需确认 |
**关键文件**: `desktop/src/lib/autonomy-manager.ts`, `desktop/src/components/AutonomyConfig.tsx`
### 4.6 上下文压缩验证
| # | 功能 | Tauri 命令 | 验证方法 |
|---|------|-----------|---------|
| 21.1 | Token 估算 | `compactor_estimate_tokens` | 返回估算值 |
| 21.2 | 阈值检查 | `compactor_check_threshold` | 返回是否超阈值 |
| 21.3 | 执行压缩 | `compactor_compact` | 返回压缩结果 |
**压缩配置**:
- 阈值: 15000 tokens
- 策略: 滑动窗口 + 摘要
---
## 五、Phase 4: 技能系统验证
### 5.1 技能发现验证
| # | 验证项 | 测试方法 | 预期结果 |
|---|--------|---------|---------|
| 22.1 | 技能扫描 | 调用 `skill_list` | 返回 77 个技能 |
| 22.2 | 技能刷新 | 调用 `skill_refresh` | 重新扫描成功 |
| 22.3 | 技能分类 | 检查分类 | 14 个分类正确 |
**关键文件**: `crates/zclaw-skills/src/registry.rs`, `desktop/src/lib/skill-discovery.ts`
### 5.2 技能执行验证
| # | 验证项 | 测试方法 | 预期结果 |
|---|--------|---------|---------|
| 23.1 | 执行技能 | 调用 `skill_execute` | 正确执行 |
| 23.2 | 触发词匹配 | 发送触发词消息 | 自动推荐技能 |
| 23.3 | 工具权限 | 检查 SKILL.md tools | 正确限制 |
### 5.3 技能分类抽样验证
| 分类 | 代表技能 | 验证项 |
|------|---------|-------|
| 开发工程 | senior-developer | 代码生成 |
| 测试/QA | code-reviewer | 代码审查 |
| 设计/UX | ui-designer | 设计建议 |
| 安全 | security-engineer | 安全分析 |
| 数据分析 | analytics-reporter | 数据报告 |
| 运维/DevOps | devops-automator | 自动化 |
---
## 六、Phase 5: Hands 系统验证
### 6.1 已实现 Hands 验证 (9/11)
| # | Hand | 触发方式 | 需审批 | 验证方法 |
|---|------|---------|-------|---------|
| 24.1 | browser | 手动/Webhook | 是 | 启动浏览器会话 |
| 24.2 | researcher | 手动/事件 | 否 | 执行研究任务 |
| 24.3 | collector | 定时/事件/手动 | 否 | 数据收集 |
| 24.4 | slideshow | 手动 | 否 | 生成幻灯片 |
| 24.5 | speech | 手动/事件 | 否 | 语音合成 |
| 24.6 | quiz | 手动 | 否 | 生成测验 |
| 24.7 | whiteboard | 手动 | 否 | 白板协作 |
| 24.8 | clip | 手动/定时 | 否 | **需 FFmpeg** |
| 24.9 | twitter | 定时/事件 | 是 | **需 API Key** |
**关键文件**: `crates/zclaw-hands/src/hands/`, `desktop/src/store/handStore.ts`
### 6.2 依赖检查验证
| # | Hand | 依赖 | 验证方法 |
|---|------|------|---------|
| 25.1 | clip | FFmpeg | 检测 FFmpeg 可用性 |
| 25.2 | twitter | Twitter API Key | 检测 API Key |
| 25.3 | browser | WebDriver | 检测浏览器驱动 |
### 6.3 审批流程验证
| # | 验证项 | 测试方法 |
|---|--------|---------|
| 26.1 | 状态流转 | 触发需审批 Hand | pending → needs_approval → completed |
| 26.2 | 批准操作 | 点击批准 | 继续执行 |
| 26.3 | 拒绝操作 | 点击拒绝 | 取消执行 |
---
## 七、Phase 6: 后端集成验证
### 7.1 Kernel 集成验证
| # | 验证项 | 测试方法 | 预期结果 |
|---|--------|---------|---------|
| 27.1 | 内部 Kernel | 调用 `kernel_init` | initialized: true |
| 27.2 | 多 LLM 支持 | 配置不同 Provider | 正确切换 |
| 27.3 | Agent 生命周期 | 创建/删除 Agent | 正确管理 |
| 27.4 | 流式响应 | 发送流式消息 | 事件正确 |
| 27.5 | MCP 协议 | 检查 MCP 支持 | 已实现 |
**关键文件**: `crates/zclaw-kernel/src/lib.rs`
### 7.2 浏览器自动化验证
| # | 命令 | 验证方法 |
|---|------|---------|
| 28.1 | `browser_create_session` | 创建会话 |
| 28.2 | `browser_navigate` | 导航页面 |
| 28.3 | `browser_click` | 点击元素 |
| 28.4 | `browser_type` | 输入文本 |
| 28.5 | `browser_screenshot` | 截图 |
| 28.6 | `browser_execute_script` | 执行 JS |
| 28.7 | `browser_scrape_page` | 抓取页面 |
---
## 八、验证执行顺序
### 8.1 推荐执行顺序
```
Phase 1 (架构层)
├── 通信层 (45 min)
├── 状态管理 (30 min)
└── 安全认证 (30 min)
Phase 2 (核心功能)
├── 聊天界面 (30 min)
├── Agent 管理 (20 min)
└── 多 Agent 协作 (20 min)
Phase 3 (智能层)
├── 记忆系统 (30 min)
├── 身份演化 (20 min)
├── 反思引擎 (15 min)
├── 心跳引擎 (15 min)
├── 自主授权 (15 min)
└── 上下文压缩 (10 min)
Phase 4 (技能系统)
└── 技能验证 (30 min)
Phase 5 (Hands 系统)
└── Hands 验证 (45 min)
Phase 6 (后端集成)
└── Kernel 验证 (30 min)
```
**预计总时间**: 约 6 小时
### 8.2 自动化测试
| 类型 | 位置 | 命令 |
|------|------|------|
| 单元测试 | `tests/desktop/` | `pnpm vitest run` |
| E2E 测试 | `desktop/tests/e2e/` | `pnpm test:e2e` |
| 类型检查 | - | `pnpm tsc --noEmit` |
---
## 九、验证记录模板
### 9.1 功能验证记录
```markdown
## [功能名称] 验证记录
**日期**: YYYY-MM-DD
**验证人**:
**环境**: Windows/macOS/Linux
### 验证结果
| # | 验证项 | 状态 | 备注 |
|---|--------|------|------|
| 1 | xxx | ✅/❌ | |
### 发现的问题
1. [问题描述]
- 严重程度: 高/中/低
- 复现步骤:
- 预期结果:
- 实际结果:
### 建议
- [改进建议]
```
---
## 十、关键文件路径汇总
### 10.1 前端文件
| 模块 | 路径 |
|------|------|
| Kernel Client | `desktop/src/lib/kernel-client.ts` |
| 智能客户端 | `desktop/src/lib/intelligence-client.ts` |
| 技能发现 | `desktop/src/lib/skill-discovery.ts` |
| 自主管理 | `desktop/src/lib/autonomy-manager.ts` |
| 安全存储 | `desktop/src/lib/secure-storage.ts` |
| 聊天 Store | `desktop/src/store/chatStore.ts` |
| Hand Store | `desktop/src/store/handStore.ts` |
### 10.2 后端文件
| 模块 | 路径 |
|------|------|
| Kernel 命令 | `desktop/src-tauri/src/kernel_commands.rs` |
| 记忆命令 | `desktop/src-tauri/src/memory_commands.rs` |
| 心跳引擎 | `desktop/src-tauri/src/intelligence/heartbeat.rs` |
| 反思引擎 | `desktop/src-tauri/src/intelligence/reflection.rs` |
| 身份管理 | `desktop/src-tauri/src/intelligence/identity.rs` |
| Kernel 核心 | `crates/zclaw-kernel/src/lib.rs` |
| 技能注册 | `crates/zclaw-skills/src/registry.rs` |
| Hands 实现 | `crates/zclaw-hands/src/hands/` |
### 10.3 文档文件
| 文档 | 路径 |
|------|------|
| 功能索引 | `docs/features/README.md` |
| 通信层 | `docs/features/00-architecture/01-communication-layer.md` |
| 状态管理 | `docs/features/00-architecture/02-state-management.md` |
| 记忆系统 | `docs/features/02-intelligence-layer/00-agent-memory.md` |
| 身份演化 | `docs/features/02-intelligence-layer/01-identity-evolution.md` |
| 技能系统 | `docs/features/04-skills-ecosystem/00-skill-system.md` |
| Hands 系统 | `docs/features/05-hands-system/00-hands-overview.md` |
---
## 十一、验收标准
### 11.1 通过标准
| 指标 | 标准 |
|------|------|
| 功能完整性 | ≥ 95% 验证点通过 |
| 关键功能 | 100% 通过 (聊天、Agent、记忆) |
| 无阻塞性问题 | 0 个 High 严重度问题 |
| 数据持久化 | 100% 正确 |
### 11.2 阻塞问题定义
- **High**: 功能完全不可用
- **Medium**: 功能部分可用,有规避方案
- **Low**: UI/体验问题,不影响核心功能
---
## 十二、硬编码问题审计报告
> **审计日期**: 2026-03-24
> **触发原因**: 发现 `skills_dir: None` 导致技能系统完全失效
### 12.1 已修复问题
#### 问题 #1: `skills_dir: None` 导致技能不加载 (CRITICAL - 已修复)
**文件**: `crates/zclaw-kernel/src/config.rs:337`
**问题描述**:
```rust
// 修复前
Self {
database_url: default_database_url(),
llm,
skills_dir: None, // ← 硬编码为 None
}
```
**影响**: 通过 Tauri 初始化 Kernel 时,技能目录永远不会被扫描,导致:
- `skills.list()` 返回空列表
- 系统提示词中没有任何技能信息
- LLM 无法调用 `execute_skill` 工具
**修复**:
```rust
// 修复后
skills_dir: default_skills_dir(), // 使用默认的 ./skills 目录
```
**验证方法**:
1. 启动应用,发送 "查询腾讯财报"
2. 预期: LLM 应调用 `execute_skill("finance-tracker", {...})`
---
### 12.2 待修复问题清单
#### 高优先级 (HIGH)
| # | 问题 | 文件:行号 | 影响 |
|---|------|----------|------|
| H1 | `default_skills_dir()` 依赖 `current_dir()` | `config.rs:161-165` | 工作目录不同时技能加载失败 |
| H2 | `categorize_skills()` 包含 50+ 硬编码技能 ID | `kernel.rs:173-185` | 新增/重命名技能后分类失效 |
| H3 | 前端 Hand ID 硬编码在多处 | `automation.ts`, `hands.ts` | Hand 配置变更后前端不一致 |
#### 中优先级 (MEDIUM)
| # | 问题 | 文件:行号 | 影响 |
|---|------|----------|------|
| M1 | 默认模型不一致 | `kernel_commands.rs` vs `config-parser.ts` | `gpt-4o-mini` vs `gpt-4` |
| M2 | API URL 硬编码在多处 | `config.rs`, `llm/mod.rs`, driver 文件 | 无法统一配置 |
| M3 | 系统提示词示例硬编码 `finance-tracker` | `kernel.rs:162` | 技能重命名后示例过时 |
| M4 | 前端存储键硬编码 | `gateway-storage.ts`, 多个 store | 无法自定义前缀 |
#### 低优先级 (LOW)
| # | 问题 | 文件:行号 | 影响 |
|---|------|----------|------|
| L1 | 工具名称有常量但未使用 | `tool.rs:79-90` vs builtin/*.rs | 代码不一致 |
| L2 | 超时/阈值等配置硬编码 | `compactor.rs`, `heartbeat.rs` | 无法动态调整 |
| L3 | Tauri 允许来源硬编码 | `lib.rs:97` | 安全配置不灵活 |
---
### 12.3 硬编码位置详细列表
#### 后端 (Rust)
| 类别 | 文件 | 内容 |
|------|------|------|
| **配置默认值** | `config.rs:200-247` | 9 个 LLM Provider URL |
| **配置默认值** | `config.rs:285-326` | 8 个 fallback URL |
| **驱动 URL** | `driver/local.rs:27,31,35` | Ollama/LM Studio/vLLM localhost |
| **驱动 URL** | `driver/gemini.rs:25` | Google Generative Language API |
| **驱动 URL** | `driver/anthropic.rs:27` | Anthropic API |
| **驱动 URL** | `driver/openai.rs:31` | OpenAI API |
| **模型默认值** | `kernel_commands.rs:43-46` | openai, gpt-4o-mini, 4096, 0.7 |
| **技能分类** | `kernel.rs:173-185` | 11 个分类50+ 技能 ID |
| **阈值配置** | `compactor.rs:38-44` | 15000, 20000, 4000, 6, 800 |
| **心跳配置** | `heartbeat.rs:36-37` | 30s interval, 5 max alerts |
| **浏览器** | `browser/commands.rs:63` | localhost:4444 WebDriver |
| **网关** | `lib.rs:554` | ws://127.0.0.1:4200 |
#### 前端 (TypeScript)
| 类别 | 文件 | 内容 |
|------|------|------|
| **网关 URL** | `gateway-storage.ts:47,51` | 127.0.0.1:50051, 127.0.0.1:4200 |
| **模型默认值** | `config-parser.ts:77,81-82` | gpt-4, openai |
| **模型默认值** | `llm-service.ts:57-66` | gpt-4o-mini, doubao-pro-32k |
| **内核默认值** | `kernel-client.ts:248,340-341` | openai, anthropic, claude-sonnet-4 |
| **存储键** | 多个 store 文件 | zclaw-*, zclaw-main |
| **Hand ID** | `automation.ts:49-57,267-279` | 7 个 Hand 映射 |
| **Hand 定义** | `hands.ts:97-189` | 完整 Hand 定义 |
| **技能 ID** | `skillMarketStore.ts:304+` | 技能市场定义 |
---
### 12.4 建议修复方案
#### H1: `default_skills_dir()` 改进
```rust
// 当前 (不可靠)
fn default_skills_dir() -> Option<PathBuf> {
std::env::current_dir().ok().map(|cwd| cwd.join("skills"))
}
// 建议 (更可靠)
fn default_skills_dir() -> Option<PathBuf> {
// 1. 优先使用可执行文件目录
std::env::current_exe()
.ok()
.and_then(|exe| exe.parent().map(|p| p.join("skills")))
// 2. 回退到当前目录
.or_else(|| std::env::current_dir().ok().map(|cwd| cwd.join("skills")))
}
```
#### H2: 技能分类改为动态
```rust
// 当前 (硬编码)
let category_patterns = [
("开发工程", vec!["senior-developer", ...]),
...
];
// 建议 (从 SKILL.md 读取)
// 在 SKILL.md frontmatter 中添加 category 字段
// categories:
// - development
// 或从目录结构推断
```
#### H3: Hand ID 集中管理
```typescript
// 创建常量文件
// hands/constants.ts
export const HAND_IDS = {
BROWSER: 'browser',
RESEARCHER: 'researcher',
COLLECTOR: 'collector',
...
} as const;
// 所有地方引用常量而非硬编码字符串
```
---
### 12.5 验证检查清单
修复后需验证:
- [ ] 从不同工作目录启动应用,技能仍能正确加载
- [ ] 新增技能后,系统提示词自动包含
- [ ] 重命名技能后,分类仍正确(如使用动态分类)
- [ ] 前端 Hand 配置与后端一致
---
*本验证计划基于 ZCLAW v0.2.5 代码状态生成*

View File

@@ -0,0 +1,308 @@
# ZCLAW 功能完善计划
## 背景
根据功能验证结果ZCLAW 项目存在以下需要完善的问题:
| 问题 | 严重程度 | 影响范围 |
|------|---------|---------|
| **Hands 后端缺失** | 高 | 10/11 Hands 不可用 |
| **Skills 动态扫描未实现** | 中 | 61 个技能无法被发现 |
| **自主授权模块分散** | 中 | 功能不完整 |
| **LLM 集成未激活** | 中 | 高级功能受限 |
| **向量嵌入未使用** | 低 | 语义搜索不可用 |
---
## 一、Hands 后端实现计划
### 1.1 实现优先级
| 优先级 | Hand | 复杂度 | 工作量 | 理由 |
|--------|------|--------|--------|------|
| **P1** | Slideshow | 低 | 2-3天 | 实现简单,教育场景价值高 |
| **P1** | Speech | 低 | 2-3天 | 实现简单,无障碍功能 |
| **P1** | Quiz | 中 | 3-4天 | 教育场景核心功能 |
| **P1** | Researcher | 中 | 3-5天 | 核心能力,用户需求高 |
| **P1** | Collector | 中 | 3-5天 | 与 Researcher 协同 |
| **P2** | Whiteboard | 中 | 4-6天 | 教育场景 |
| **P2** | Clip | 高 | 5-7天 | 依赖 FFmpeg |
| **P2** | Twitter | 中 | 3-5天 | 需要外部 API Key |
| **P3** | Lead | 高 | 7-10天 | 依赖多个付费 API |
| **P3** | Predictor | 高 | 7-14天 | ML 复杂度高 |
### 1.2 公共模块提取
```
desktop/src-tauri/src/hands/
├── mod.rs # 模块导出
├── common/
│ ├── http_client.rs # HTTP 客户端 (供 Researcher/Collector/Lead/Twitter)
│ ├── html_parser.rs # HTML 解析 (供 Researcher/Collector)
│ ├── scheduler.rs # 任务调度 (供支持 schedule 的 Hands)
│ └── approval.rs # 审批流程 (供 requires_approval 的 Hands)
├── slideshow/ # P1 - 幻灯片控制
├── speech/ # P1 - 语音合成
├── quiz/ # P1 - 测验系统
├── researcher/ # P1 - 深度研究
└── collector/ # P1 - 数据收集
```
### 1.3 参考实现
Browser Hand 已有完整实现,位于 `desktop/src-tauri/src/browser/`
- `client.rs` - 核心客户端 (494行)
- `session.rs` - 会话管理 (191行)
- `commands.rs` - Tauri 命令 (534行)
- `actions.rs` - 动作定义 (314行)
- `error.rs` - 错误类型 (90行)
---
## 二、Skills 动态扫描实现计划
### 2.1 当前问题
- 存在 73 个 SKILL.md 文件
- `skill-discovery.ts` 使用静态 `BUILT_IN_SKILLS` 数组(仅 12 个)
- Rust 后端 `SkillRegistry.discover_skills()` 已存在但未连接到 Tauri
### 2.2 实现方案
**方案:后端扫描 + Tauri 命令暴露**
```
Tauri 启动
kernel_init()
SkillRegistry::add_skill_dir("skills/")
discover_skills() + parse_skill_md()
kernel_list_skills 命令暴露
前端调用 Tauri 命令
```
### 2.3 实现任务
| 任务 | 文件 | 工作量 |
|------|------|--------|
| 增强 SKILL.md 解析器 | `crates/zclaw-skills/src/loader.rs` | 2-4小时 |
| 添加 skill_registry 到 Kernel | `crates/zclaw-kernel/src/kernel.rs` | 2-4小时 |
| 创建 kernel_list_skills 命令 | `desktop/src-tauri/src/kernel_commands.rs` | 1-2小时 |
| 更新前端调用 | `desktop/src/store/configStore.ts` | 2-3小时 |
| 添加索引缓存 | 新建文件 | 2-4小时 |
**总工作量**: 9-17 小时
---
## 三、智能层功能完善计划
### 3.1 自主授权管理器
**当前状态**: 功能分散在 `HeartbeatConfig.proactivity_level`
**实现任务**:
| 任务 | 工作量 |
|------|--------|
| 创建 `autonomy_manager.rs` 模块 | 3天 |
| 定义操作风险分级 | 1天 |
| 扩展审批流程 | 2天 |
**新建文件**: `desktop/src-tauri/src/intelligence/autonomy.rs`
```rust
pub enum AutonomyLevel {
Supervised, // 所有操作需确认
Assisted, // 低风险自动,中高风险需确认
Autonomous, // 低中风险自动,高风险需确认
}
pub enum RiskLevel {
Low, // memory_save, reflection_run
Medium, // hand_trigger, skill_install
High, // memory_delete, identity_update
}
```
### 3.2 LLM 集成激活
**当前状态**:
- `compactor.rs`: `use_llm: false`
- `reflection.rs`: `use_llm: true` 但未实际调用
**实现任务**:
| 任务 | 工作量 |
|------|--------|
| 定义 LLM 客户端接口 | 2天 |
| 实现 Compactor LLM 摘要 | 2天 |
| 实现 Reflection LLM 分析 | 3天 |
| 添加降级策略 | 1天 |
### 3.3 向量嵌入
**当前状态**: `PersistentMemory.embedding` 字段已定义但未使用
**实现任务**:
| 任务 | 工作量 |
|------|--------|
| 选择并集成 Embedding 模型 | 2天 |
| 实现语义搜索 | 2天 |
| 添加 FTS5 全文搜索 | 1天 |
| 实现混合搜索 | 2天 |
**推荐模型**: `paraphrase-multilingual-MiniLM-L12-v2` (支持中文, 118MB)
---
## 四、实施时间线
### Week 1-2: P0 基础设施
```
Week 1:
├── 统一自主授权管理器 (5天)
└── LLM 客户端接口 (2天)
Week 2:
├── Skills 动态扫描 (3天)
├── Compactor LLM 摘要 (2天)
└── Reflection LLM 分析 (开始)
```
### Week 3-4: P1 Hands 实现
```
Week 3:
├── Slideshow Hand (2-3天)
├── Speech Hand (2-3天)
└── Quiz Hand (开始)
Week 4:
├── Quiz Hand (完成)
├── Researcher Hand (3-5天)
└── Collector Hand (开始)
```
### Week 5-6: P1 智能层 + P2 Hands
```
Week 5:
├── Collector Hand (完成)
├── Embedding 模型集成 (2天)
└── 语义搜索实现 (2天)
Week 6:
├── Whiteboard Hand (4-6天)
├── Clip Hand (开始)
└── Twitter Hand (开始)
```
---
## 五、关键文件清单
### 需要修改的文件
| 文件 | 修改内容 |
|------|---------|
| `desktop/src-tauri/src/intelligence/mod.rs` | 添加 autonomy 模块 |
| `desktop/src-tauri/src/intelligence/compactor.rs` | 激活 LLM 摘要 |
| `desktop/src-tauri/src/intelligence/reflection.rs` | 实现 LLM 分析 |
| `desktop/src-tauri/src/memory/persistent.rs` | 添加向量搜索 |
| `desktop/src-tauri/src/kernel_commands.rs` | 添加 skill_list 命令 |
| `desktop/src-tauri/src/lib.rs` | 注册新命令 |
| `desktop/src/store/configStore.ts` | 更新技能加载逻辑 |
| `docs/features/05-hands-system/00-hands-overview.md` | 更新实现状态 |
### 需要新建的文件
| 文件 | 用途 |
|------|------|
| `desktop/src-tauri/src/intelligence/autonomy.rs` | 自主授权管理器 |
| `desktop/src-tauri/src/intelligence/llm_client.rs` | LLM 客户端接口 |
| `desktop/src-tauri/src/hands/mod.rs` | Hands 模块入口 |
| `desktop/src-tauri/src/hands/common/*.rs` | 公共模块 |
| `desktop/src-tauri/src/hands/slideshow/*.rs` | Slideshow Hand |
| `desktop/src-tauri/src/hands/speech/*.rs` | Speech Hand |
| `desktop/src-tauri/src/hands/quiz/*.rs` | Quiz Hand |
| `desktop/src-tauri/src/hands/researcher/*.rs` | Researcher Hand |
| `desktop/src-tauri/src/hands/collector/*.rs` | Collector Hand |
---
## 六、验证方法
### 单元测试
```bash
# Rust 测试
cd desktop/src-tauri
cargo test
# TypeScript 测试
cd desktop
pnpm vitest run
```
### 集成测试
```bash
# 启动应用
pnpm desktop
# 验证 Skills 动态扫描
# - 打开技能市场
# - 确认显示 73 个技能
# 验证 Hands
# - 触发 Slideshow Hand
# - 触发 Speech Hand
# - 触发 Quiz Hand
# 验证智能层
# - 测试 LLM 摘要功能
# - 测试语义搜索
# - 测试自主授权级别
```
### 手动验证清单
- [ ] Skills 市场显示全部 73 个技能
- [ ] Slideshow Hand 可控制幻灯片
- [ ] Speech Hand 可进行语音合成
- [ ] Quiz Hand 可生成测验
- [ ] Researcher Hand 可执行研究任务
- [ ] Collector Hand 可收集数据
- [ ] LLM 摘要生成正常
- [ ] 语义搜索返回相关结果
- [ ] 自主授权级别切换正常
---
## 七、风险评估
| 风险 | 影响 | 缓解措施 |
|------|------|----------|
| Embedding 模型体积大 | 下载存储成本 | 提供模型管理,支持用户选择 |
| LLM API 调用成本 | 频繁使用增加费用 | 配置阈值,提供降级策略 |
| 外部 API 依赖 | Twitter/Lead 需付费 | 标注为可选功能 |
| FFmpeg 依赖 | Clip Hand 需预装 | 检测依赖并提示用户 |
---
## 八、成功标准
| 指标 | 当前 | 目标 |
|------|------|------|
| 可用 Hands | 1/11 (9%) | 6/11 (55%) |
| 可发现 Skills | 12/73 (16%) | 73/73 (100%) |
| LLM 功能激活 | 0% | 100% |
| 语义搜索 | 不可用 | 可用 |
| 自主授权 | 分散 | 统一管理 |

View File

@@ -0,0 +1,644 @@
# Pipeline DSL 架构设计
> **目标**: 在 ZCLAW 中实现 OpenMagic 类教育功能,支持多步骤自动化工作流
> **原则**: 用户只看到 PipelineHands/Skills 作为内部实现被隐藏
---
## 1. 背景
### 1.1 问题
当前 Hands + Skills 架构存在以下局限:
- **流程编排**: Skills 是静态提示模板,无法定义执行流程
- **状态管理**: 复杂场景需要跨多个步骤传递状态
- **可扩展性**: 不同行业需要不同的生成流程
- **前端绑定**: Hands 动作无法直接映射到 UI 组件
### 1.2 需求
- 输入课题 → 自动生成大纲 → 并行生成场景 → 渲染预览 → 导出文件
- 支持垂直扩展(不同学科)和水平扩展(跨行业)
- 内部播放预览 + 文件导出PPTX/HTML/PDF
---
## 2. 架构设计
### 2.1 分层架构
```
┌─────────────────────────────────────────────────────────┐
│ User Interface │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Pipeline List│ │ Pipeline Run│ │ Result Preview │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Pipeline Engine (新增) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ DSL Parser │ │ Executor │ │ State Manager │ │
│ │ YAML/TOML │ │ DAG Runner │ │ Context Store │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐
│ Skills (隐藏) │ │ Hands (隐藏)│ │ Exporters │
│ prompt templates│ │ executors │ │ pptx/html/pdf │
└─────────────────┘ └─────────────┘ └─────────────────┘
```
### 2.2 核心组件
#### A. Pipeline DSL (声明式配置)
```yaml
# pipelines/education/classroom.yaml
apiVersion: zclaw/v1
kind: Pipeline
metadata:
name: classroom-generator
displayName: 互动课堂生成器
category: education
description: 输入课题,自动生成完整互动课堂
spec:
inputs:
- name: topic
type: string
required: true
label: 课题名称
placeholder: 例如:牛顿第二定律
- name: difficulty
type: select
options: [初级, 中级, 高级]
default: 中级
- name: export_formats
type: multi-select
options: [pptx, html, pdf]
default: [pptx, html]
steps:
# Step 1: 解析输入
- id: parse_input
action: llm.generate
template: skills/classroom-generator/parse.md
input:
topic: ${inputs.topic}
difficulty: ${inputs.difficulty}
output: parsed_data
# Step 2: 生成大纲
- id: generate_outline
action: llm.generate
template: skills/classroom-generator/outline.md
input: ${steps.parse_input.output}
output: outline
# Step 3: 并行生成场景
- id: generate_scenes
action: parallel
each: ${steps.generate_outline.output.items}
max_workers: 4
step:
action: llm.generate
template: skills/classroom-generator/scene.md
input:
item: ${item}
index: ${index}
output: scenes[]
# Step 4: 渲染课堂
- id: render
action: classroom.render
input:
outline: ${steps.generate_outline.output}
scenes: ${steps.generate_scenes.output}
output: classroom_data
# Step 5: 导出文件
- id: export
action: file.export
formats: ${inputs.export_formats}
input: ${steps.render.output}
output: export_paths
outputs:
classroom_id: ${steps.render.output.id}
preview_url: /classroom/${steps.render.output.id}
export_files: ${steps.export.output}
```
#### B. Pipeline Executor (执行引擎)
```rust
// crates/zclaw-pipeline/src/executor.rs
pub struct PipelineExecutor {
skill_registry: Arc<SkillRegistry>,
hand_registry: Arc<HandRegistry>,
llm_driver: Arc<dyn LlmDriver>,
state: PipelineState,
}
impl PipelineExecutor {
pub async fn execute(&self, pipeline: &Pipeline, inputs: Value) -> Result<PipelineOutput> {
let mut context = ExecutionContext::new(inputs);
for step in &pipeline.spec.steps {
match &step.action {
Action::LlmGenerate { template, input } => {
let prompt = self.render_template(template, &context)?;
let response = self.llm_driver.generate(prompt).await?;
context.set_output(&step.id, response);
}
Action::Parallel { each, step, max_workers } => {
let items = context.resolve(each)?;
let results = self.execute_parallel(step, items, *max_workers).await?;
context.set_output(&step.id, results);
}
Action::ClassroomRender { input } => {
let data = context.resolve(input)?;
let classroom = self.render_classroom(data).await?;
context.set_output(&step.id, classroom);
}
Action::FileExport { formats, input } => {
let paths = self.export_files(formats, input).await?;
context.set_output(&step.id, paths);
}
}
}
Ok(context.extract_outputs(&pipeline.outputs))
}
}
```
#### C. State Manager (状态管理)
```rust
// crates/zclaw-pipeline/src/state.rs
pub struct ExecutionContext {
inputs: Value,
steps_output: HashMap<String, Value>,
variables: HashMap<String, Value>,
}
impl ExecutionContext {
// 解析表达式 ${steps.generate_outline.output.items}
pub fn resolve(&self, expr: &str) -> Result<Value> {
// 支持的表达式:
// ${inputs.topic} - 输入参数
// ${steps.xxx.output} - 步骤输出
// ${item} - 循环变量
// ${index} - 循环索引
}
pub fn set_output(&mut self, step_id: &str, value: Value) {
self.steps_output.insert(step_id.to_string(), value);
}
}
```
---
## 3. 文件结构
### 3.1 新增 Crate
```
crates/zclaw-pipeline/
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── parser.rs # YAML/TOML DSL 解析
│ ├── executor.rs # 执行引擎
│ ├── state.rs # 状态管理
│ ├── actions/ # 内置动作
│ │ ├── mod.rs
│ │ ├── llm.rs # LLM 调用
│ │ ├── parallel.rs # 并行执行
│ │ ├── render.rs # 渲染
│ │ └── export.rs # 导出
│ └── types.rs # 类型定义
```
### 3.2 Pipeline 配置目录
```
pipelines/
├── education/ # 教育类
│ ├── classroom.yaml # 互动课堂
│ ├── quiz-generator.yaml # 测验生成
│ └── flashcard.yaml # 闪卡生成
├── marketing/ # 营销类
│ ├── campaign.yaml # 营销方案
│ └── content-calendar.yaml # 内容日历
├── legal/ # 法律类
│ └── contract-review.yaml # 合同审查
└── _templates/ # 模板
└── base.yaml
```
### 3.3 隐藏 Skills/Hands
Skills 和 Hands 文件保留,但:
- 不在 UI 中直接展示
- 只通过 Pipeline DSL 引用
- 作为内部实现细节
---
## 4. 前端集成
### 4.0 设计原则
- **Pipeline 页面** - 类似 Hands 页面,展示所有可用 Pipeline
- **双触发入口** - 页面直接触发 + 对话中 Agent 引导触发
- **Agent 智能推荐** - 识别用户意图,推荐合适的 Pipeline
### 4.1 Pipeline 页面 (新增)
#### 页面布局 (参考 Hands 页面)
```
┌─────────────────────────────────────────────────────────────┐
│ Pipelines [+ 新建] │
├─────────────────────────────────────────────────────────────┤
│ [全部] [教育] [营销] [法律] [研发] [更多...] │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 📚 互动课堂生成 │ │ 📝 测验生成器 │ │
│ │ │ │ │ │
│ │ 输入课题,自动 │ │ 根据内容生成 │ │
│ │ 生成完整课堂 │ │ 选择题/填空题 │ │
│ │ │ │ │ │
│ │ [开始生成] │ │ [开始生成] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 📊 营销方案生成 │ │ ⚖️ 合同审查 │ │
│ │ │ │ │ │
│ │ 输入产品信息, │ │ 上传合同文档, │ │
│ │ 生成营销策略 │ │ 自动审查风险点 │ │
│ │ │ │ │ │
│ │ [开始生成] │ │ [开始生成] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### Pipeline 卡片组件
```typescript
interface PipelineCard {
id: string;
icon: string; // emoji 或图标
displayName: string;
description: string;
category: string;
tags: string[];
usage_count: number; // 使用次数(用于排序推荐)
last_used?: Date;
}
```
#### Pipeline 运行对话框
```
┌─────────────────────────────────────────┐
│ 互动课堂生成器 [×] │
├─────────────────────────────────────────┤
│ │
│ 课题名称 * │
│ ┌───────────────────────────────────┐ │
│ │ 牛顿第二定律 │ │
│ └───────────────────────────────────┘ │
│ │
│ 难度等级 │
│ ○ 初级 ● 中级 ○ 高级 │
│ │
│ 导出格式 │
│ ☑ PPTX ☑ HTML ☐ PDF │
│ │
│ [取消] [开始生成] │
└─────────────────────────────────────────┘
```
### 4.2 对话中触发 (Agent 引导)
#### Agent 系统提示词注入
```typescript
// 在 Agent 系统提示词中注入 Pipeline 信息
const systemPrompt = `
你是一个智能助手。用户可能会描述一些任务需求,你可以推荐使用合适的 Pipeline 工具。
可用的 Pipeline 工具:
${pipelines.map(p => `- ${p.displayName}: ${p.description}`).join('\n')}
当用户的需求匹配某个 Pipeline 时:
1. 简要说明该 Pipeline 能做什么
2. 询问用户是否要使用
3. 如果用户同意,调用 run_pipeline 工具启动
示例:
用户: "帮我做一个关于光合作用的课件"
你: "我可以使用【互动课堂生成器】为你自动生成完整课件,包括幻灯片、讲解和测验。需要开始吗?"
`;
```
#### Agent 推荐行为模式
**主动推荐策略**(需求模糊时也推荐):
```typescript
// Agent 识别潜在需求的模式
const intentPatterns = [
// 教育类
{ keywords: ["准备.*课", "备课", "教案", "教学"], pipeline: "classroom-generator", confidence: 0.7 },
{ keywords: ["学生.*测验", "出题", "考试"], pipeline: "quiz-generator", confidence: 0.8 },
// 营销类
{ keywords: ["推广.*方案", "营销计划", "宣传"], pipeline: "marketing-campaign", confidence: 0.75 },
{ keywords: ["内容.*日历", "发布.*计划"], pipeline: "content-calendar", confidence: 0.7 },
// 法律类
{ keywords: ["合同.*审查", "条款.*风险", "法律.*检查"], pipeline: "contract-review", confidence: 0.8 },
];
// Agent 行为:
// 1. 监听用户对话内容
// 2. 匹配潜在需求模式
// 3. 当 confidence > 0.6 时,主动询问
// 4. 用户确认后启动 Pipeline
```
#### 对话触发流程
**场景 1: 需求明确**
```
用户: 帮我做一个关于牛顿第二定律的课件
┌─────────────────────────────────────┐
│ Agent 分析意图 │
│ - 关键词: 课件、牛顿第二定律 │
│ - 匹配 Pipeline: classroom-generator │
│ - confidence: 0.95 (直接推荐) │
└─────────────────────────────────────┘
```
**场景 2: 需求模糊(主动推荐)**
```
用户: 我在准备下周的物理课,讲力学部分
┌─────────────────────────────────────┐
│ Agent 分析意图 │
│ - 关键词: 准备课、物理、力学 │
│ - 匹配 Pipeline: classroom-generator │
│ - confidence: 0.72 (主动询问) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Agent 回复 │
│ "物理课准备啊!力学是个重要主题。 │
│ │
│ 我可以帮你:【互动课堂生成器】 │
│ • 自动生成力学课件大纲 │
│ • 创建互动幻灯片 │
│ • 生成课后测验 │
│ │
│ 要试试吗?课题就是'力学基础'" │
└─────────────────────────────────────┘
```
┌─────────────────────────────────────┐
│ Agent 回复 │
│ "我可以使用【互动课堂生成器】为你 │
│ 自动生成完整课件,包括: │
│ • 结构化大纲 │
│ • 互动幻灯片 │
│ • AI 老师讲解 │
│ • 课后测验 │
│ │
│ 需要开始生成吗?" │
└─────────────────────────────────────┘
▼ (用户: 好的)
┌─────────────────────────────────────┐
│ Agent 调用工具 │
│ run_pipeline( │
│ id: "classroom-generator", │
│ inputs: { │
│ topic: "牛顿第二定律", │
│ difficulty: "中级" │
│ } │
│ ) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Pipeline 执行 & 进度反馈 │
│ Agent: "正在生成课堂大纲..." │
│ Agent: "正在生成第 3/8 个场景..." │
│ Agent: "课堂生成完成!" │
│ [预览课堂] [下载 PPTX] │
└─────────────────────────────────────┘
```
### 4.3 API 设计
```typescript
// kernel-client.ts 扩展
// 列出 Pipelines
async listPipelines(options?: {
category?: string;
search?: string;
}): Promise<Pipeline[]>
// 获取 Pipeline 详情
async getPipeline(id: string): Promise<PipelineDetail>
// 运行 Pipeline
async runPipeline(request: {
pipelineId: string;
inputs: Record<string, any>;
}): Promise<{ runId: string }>
// 获取运行进度
async getPipelineProgress(runId: string): Promise<{
status: 'running' | 'completed' | 'failed';
currentStep: string;
percentage: number;
message: string;
}>
// 获取运行结果
async getPipelineResult(runId: string): Promise<{
outputs: Record<string, any>;
files: { name: string; url: string; size: number }[];
}>
// 订阅进度事件
onPipelineProgress(runId: string, callback: (progress) => void): () => void
```
### 4.4 结果预览页
- 白板/幻灯片渲染器
- Agent 授课播放器
- 测验交互组件
- 导出文件下载
### 4.5 路由结构
```typescript
// 新增路由
/pipelines // Pipeline 列表页
/pipelines/:id // Pipeline 详情/运行页
/pipelines/run/:runId // 运行结果/进度页
/classroom/:id // 课堂预览页 (Pipeline 产出)
```
---
## 5. 实现步骤
### Phase 1: Pipeline 基础 (1 周)
1. 创建 `zclaw-pipeline` crate
2. 实现 DSL Parser (YAML → Pipeline struct)
3. 实现 ExecutionContext 状态管理
4. 实现基础 Executor (顺序执行)
### Phase 2: 核心动作 (1 周)
1. 实现 `llm.generate` 动作
2. 实现 `parallel` 动作
3. 实现 `classroom.render` 动作
4. 实现 `file.export` 动作
### Phase 3: 前端集成 (1 周)
1. Pipeline 列表 API
2. Pipeline 运行 API
3. 进度订阅
4. 结果获取
### Phase 4: 教育模板 (1 周)
1. classroom-generator.yaml
2. 前端预览组件
3. 测试验证
---
## 6. 验证方案
### 6.1 单元测试
```rust
#[test]
fn test_pipeline_parse() {
let yaml = r#"
apiVersion: zclaw/v1
kind: Pipeline
...
"#;
let pipeline = PipelineParser::parse(yaml).unwrap();
assert_eq!(pipeline.metadata.name, "classroom-generator");
}
#[test]
fn test_expression_resolve() {
let ctx = ExecutionContext::new(json!({
"inputs": {"topic": "test"},
"steps": {"parse": {"output": {"items": [1, 2, 3]}}}
}));
let value = ctx.resolve("${steps.parse.output.items}").unwrap();
assert_eq!(value, json!([1, 2, 3]));
}
```
### 6.2 集成测试
```bash
# 启动 Pipeline
curl -X POST http://localhost:50051/pipelines/classroom-generator/run \
-d '{"topic": "牛顿第二定律", "difficulty": "中级"}'
# 检查进度
curl http://localhost:50051/pipelines/runs/{run_id}/progress
# 获取结果
curl http://localhost:50051/pipelines/runs/{run_id}/result
```
### 6.3 E2E 测试
1. 在 UI 中选择 "互动课堂生成器"
2. 输入课题,点击生成
3. 观察进度条,等待完成
4. 预览生成的课堂
5. 下载 PPTX/HTML 文件
---
## 7. 扩展性设计
### 7.1 添加新 Pipeline
只需创建新的 YAML 文件:
```yaml
# pipelines/marketing/campaign.yaml
apiVersion: zclaw/v1
kind: Pipeline
metadata:
name: marketing-campaign
category: marketing
spec:
steps:
- id: analyze_brand
action: llm.generate
template: skills/marketing/brand-analysis.md
# ...
```
### 7.2 添加新 Action
```rust
// 在 actions/ 目录添加新动作
pub struct CustomAction;
impl ActionExecutor for CustomAction {
async fn execute(&self, ctx: &ExecutionContext, config: &Value) -> Result<Value> {
// 实现自定义逻辑
}
}
```
### 7.3 条件分支 (未来)
```yaml
steps:
- id: check_type
action: condition
branches:
- when: ${inputs.type == 'video'}
then: generate_video
- when: ${inputs.type == 'text'}
then: generate_text
```

File diff suppressed because it is too large Load Diff

View File

@@ -301,3 +301,60 @@ pnpm start:dev
- [ ] 记忆统计同步正常(启动 + 周期)
- [ ] 提案审批流程正常
- [ ] 错误信息清晰可读
---
## 深度复验报告 (2026-03-24)
### 前端修复验证
| 修复项 | 文件 | 状态 | 说明 |
|--------|------|------|------|
| Fix 1.1 | intelligence-client.ts | ✅ 已正确实现 | `updateMemoryStats``recordCorrection` 使用 snake_case |
| Fix 1.2 | App.tsx | ✅ 已正确实现 | 5分钟周期同步 + 清理逻辑完整 |
| Fix 2.1 | intelligence-backend.ts | ✅ 已正确实现 | `MemoryStats` 使用 `total_entries` 等 |
| Fix 2.1 | intelligence-client.ts | ✅ 已正确实现 | `toFrontendStats` 正确映射字段 |
| Fix 2.2 | IdentityChangeProposal.tsx | ✅ 已正确实现 | `parseProposalError` 函数 + 3处调用 |
| Fix 3.1 | intelligence-client.ts | ✅ 已正确实现 | `fallbackMemory.stats()` 计算 `storageSizeBytes` |
**前端修复验证结果**: 全部 6/6 通过 ✅
### 后端修复验证
| 修复项 | 文件 | 状态 | 说明 |
|--------|------|------|------|
| Fix 1.3 | heartbeat.rs:451-480 | ✅ 已正确实现 | `check_pending_tasks` 缓存为空时返回告警 |
| Fix 1.3 | heartbeat.rs:484-521 | ⚠️ 设计偏差 | `check_memory_health` 缓存为空时返回 None避免重复告警 |
| Fix 2.3 | heartbeat.rs:347 | ✅ 已正确实现 | `LAST_INTERACTION` 静态变量 |
| Fix 2.3 | heartbeat.rs:366-368 | ✅ 已正确实现 | `get_last_interaction_map()` 函数 |
| Fix 2.3 | heartbeat.rs:371-376 | ✅ 已正确实现 | `record_interaction()` 函数 |
| Fix 2.3 | heartbeat.rs:524-559 | ✅ 已正确实现 | `check_idle_greeting` 完整实现24小时阈值 |
| Fix 2.3 | heartbeat.rs:736-741 | ✅ 已正确实现 | `heartbeat_record_interaction` Tauri 命令 |
| 命令注册 | lib.rs:1432 | ✅ 已正确注册 | `heartbeat_record_interaction` 已注册 |
**后端修复验证结果**: 7/8 完全通过1/8 设计偏差(合理)
### 设计偏差说明
**`check_memory_health` 缓存为空时返回 None**
原计划要求:返回告警
实际实现:返回 None
设计理由(代码注释):
> Cache is empty - skip check (already reported in check_pending_tasks)
**评估**: 这是合理的设计决策,避免在缓存为空时产生重复告警。`check_pending_tasks` 已经报告了缓存未同步的问题,`check_memory_health` 无需再次告警。
### 复验结论
| 类别 | 结果 |
|------|------|
| 前端修复 | 6/6 ✅ 通过 |
| 后端修复 | 7/8 ✅ 通过 |
| 设计偏差 | 1 ⚠️ 合理(不视为问题)|
| 总体评估 | **全部修复已正确实现** |
**编译验证**:
- TypeScript 类型检查: ✅ 通过
- Rust 编译: ✅ 通过(仅有预先存在的警告)

View File

@@ -0,0 +1,149 @@
# ZCLAW Skill系统问题修复 - 完成报告
## 问题诊断
### 用户报告的问题
对话过程中agent无法正确调用skill去完成任务。
### 根因分析
经过代码分析,发现**两个核心问题**
#### 问题1: Agent循环不完整
**位置**: `crates/zclaw-runtime/src/loop_runner.rs`
**原始实现**:
```
用户消息 → LLM → 工具调用 → 结果直接返回
```
**正确实现应该是**:
```
用户消息 → LLM → 工具调用 → 工具结果 → LLM(处理结果) → 最终响应
```
**关键代码问题**:
```rust
// 原始代码在工具执行后直接返回结果
full_response.push_str(&format!("\n[工具 {} 结果]: {}", name, ...));
```
#### 问题2: 流式输出暴露内部细节
`StreamChunk::ToolUseDelta`事件被当作`[工具参数]`文本输出给用户,这是调试信息不应该暴露。
---
## 修复方案
### 1. 实现完整Agent循环
**文件**: `crates/zclaw-runtime/src/loop_runner.rs`
**改动**:
- 添加循环结构, 最多10次迭代
- 检查LLM响应中的工具调用
- 如果没有工具调用, 返回最终响应
- 如果有工具调用, 执行后添加结果到消息历史, **继续循环让LLM处理**
```rust
loop {
iterations += 1;
if iterations > max_iterations { return error; }
// 调用LLM
let response = self.driver.complete(request).await?;
// 提取工具调用
let tool_calls = response.content.iter().filter_map(|b| match b {
ContentBlock::ToolUse { id, name, input } => Some((id, name, input)),
_ => None
}).collect();
// 没有工具调用 - 返回最终响应
if tool_calls.is_empty() {
return Ok(AgentLoopResult { response: text, ... });
}
// 添加工具调用到消息历史
for (id, name, input) in &tool_calls {
messages.push(Message::tool_use(id, ToolId::new(name), input));
}
// 执行工具
for (id, name, input) in tool_calls {
let result = self.execute_tool(&name, input, &context).await;
messages.push(Message::tool_result(id, ToolId::new(&name), result));
}
// 继续循环 - LLM将处理工具结果
}
```
### 2. 简化LoopEvent
**改动**:
```rust
pub enum LoopEvent {
Delta(String),
ToolStart { name: String },
ToolEnd { name: String, output: serde_json::Value },
IterationStart { iteration: usize, max_iterations: usize },
Complete(AgentLoopResult),
Error(String),
}
```
**隐藏的信息**:
- `ToolUseDelta` - 工具参数增量(内部处理)
- 工具的详细input/output只记录到消息历史
### 3. 多轮流式支持
**run_streaming方法**:
- 实现与`run`相同的循环逻辑
- 支持流式输出
- 发送`IterationStart`事件通知新迭代开始
---
## 验证
### 编译状态
✅ 编译通过,无错误
### 需要测试
1. **单次工具调用** - "搜索腾讯财报"
2. **多轮工具调用** - "搜索并分析数据"
3. **无工具调用** - "你好"
---
## 后续步骤
1. **手动测试** - 启动应用测试skill调用流程
2. **前端适配** - 磁保前端正确处理新的事件类型
3. **文档更新** - 更新skill系统文档
---
## 关键文件
| 文件 | 改动说明 |
|------|----------|
| `crates/zclaw-runtime/src/loop_runner.rs` | 核心循环逻辑重写 |
| `crates/zclaw-types/src/message.rs` | 已有`tool_result`方法(无需修改) |
| `crates/zclaw-kernel/src/kernel.rs` | System prompt构建已有skill注入 |
## 测试命令
```bash
# 编译
cargo build -p zclaw-runtime
# 启动开发环境
pnpm start:dev
# 测试对话
# 发送: "帮我分析一下腾讯的财报"
# 预期: LLM调用execute_skill工具返回分析结果
```