Files
zclaw_openfang/wiki/hands-skills.md
iven c10e50d58e docs(wiki): Phase D完成 — 6模块页重构(routing/chat/butler/hands-skills/pipeline/data-model)
- routing.md: 移除Store/lib列表+5节模板 (330→131行)
- chat.md: 添加集成契约+不变量 (180→134行)
- butler.md: 移除重复→引用memory/hands-skills (215→150行)
- hands-skills.md: 5节模板+契约+不变量 (281→170行)
- pipeline.md: 添加契约+重组 (157→154行)
- data-model.md: 添加契约+双库架构图 (181→153行)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 21:53:17 +08:00

7.5 KiB
Raw Blame History

title, updated, status, tags
title updated status tags
Hands + Skills + MCP 2026-04-22 active
module
hands
skills
mcp

Hands + Skills + MCP

index 导航。关联: chat middleware butler

1. 设计决策

Hands = 自主能力 (行动层), Skills = 知识技能 (认知层), MCP = 外部工具协议。

决策 WHY
7 注册 Hands (6 TOML + _reminder) 每个 Hand 有独立配置和 Rust 实现,启用/禁用由 enabled 字段控制。_reminder 由 kernel 代码注册,无 HAND.toml
75 Skills + 语义路由 SKILL.md 定义领域知识SemanticSkillRouter 用 TF-IDF 匹配(详见 butler 路由细节),增强 LLM 领域能力而不硬编码
MCP bridge 运行时发现外部工具服务器McpToolWrapper 适配 Tool trait让 LLM 在对话中直接调用 filesystem/database 等外部工具
LLM Tool Calling 触发 Skill 调用通过 LLM 生成 ToolUse不是直接函数调用。保持 LLM 主导决策权
定时提醒链路 NlScheduleParser 中文时间->cron + _reminder Hand + TriggerManager支持"每天早上9点提醒我查房"

2. 关键文件 + 数据流

核心文件

文件 职责
crates/zclaw-hands/src/hands/ 7 个 Hand 实现 (browser/collector/researcher/clip/twitter/quiz/reminder)
crates/zclaw-runtime/src/tool/registry.rs ToolRegistry 工具注册表
crates/zclaw-runtime/src/tool/builtin/execute_skill.rs KernelSkillExecutor 技能执行
crates/zclaw-skills/src/semantic_router.rs TF-IDF 语义路由 (路由细节见 butler)
crates/zclaw-skills/src/ 技能解析、索引、WASM runner
crates/zclaw-runtime/src/nl_schedule.rs 中文时间->cron 解析器 (6 种模式)
crates/zclaw-protocols/src/mcp_tool_adapter.rs MCP 工具适配器 + 服务管理
crates/zclaw-protocols/src/mcp.rs MCP 协议类型 + BasicMcpClient (stdio transport)
crates/zclaw-runtime/src/tool/builtin/mcp_tool.rs McpToolWrapper (Tool trait 桥接)
desktop/src/store/handStore.ts 前端 Hand 状态
desktop/src/lib/mcp-client.ts 前端 MCP 客户端

Hand 触发流

LLM 生成 ToolUse{hand_name, params}
  -> AgentLoop (loop_runner.rs) 检测 ContentBlock::ToolUse
    -> ToolRegistry.get(hand_name) -> HandExecutor
      -> needs_approval? -> 等待 approvalStore 确认 -> 用户批准
    -> Hand.execute(params) -> 结果
  -> ToolResult -> LLM 继续对话
  -> Tauri Event emit -> handStore 更新状态

集成契约

方向 模块 接口 / 触发点
Called by <- loop_runner Tool 执行
Calls -> browser/Twitter/etc External APIs
Provides -> middleware: SkillIndex@200 skill_index.rs
Provides -> mcp: McpToolWrapper Tool trait

Hand Tauri 命令 (8 个)

命令 状态 说明
hand_list @connected 列出可用 Hands
hand_execute @connected 执行 Hand
hand_approve @connected 审批 Hand 执行
hand_cancel @connected 取消执行
hand_get @connected 获取 Hand 详情
hand_run_status @connected 运行状态查询
hand_run_list @connected 运行列表
hand_run_cancel @reserved 取消运行 (无前端 UI)

MCP 命令 (4 个)

mcp_start_service, mcp_stop_service, mcp_list_services, mcp_call_tool。 MCP 工具在 ToolRegistry 中使用限定名 service_name.tool_name (如 filesystem.read_file)。 McpManagerStateKernel 共享 Arc<RwLock<Vec<McpToolAdapter>>>,通过 sync_to_kernel() 同步。

3. 代码逻辑

7 注册 Hands

Hand 功能 依赖 测试 配置
Browser 浏览器自动化 (23 Tauri 命令) WebDriver 11 hands/browser.HAND.toml
Collector 数据收集聚合 -- 9 hands/collector.HAND.toml
Researcher 深度研究 + 网络搜索 网络 25 hands/researcher.HAND.toml
Clip 视频处理 FFmpeg 32 hands/clip.HAND.toml
Twitter Twitter 自动化 (12 API v2) OAuth 1.0a 30 hands/twitter.HAND.toml
Quiz 测验生成 -- 5 hands/quiz.HAND.toml
_reminder 定时提醒 (系统内部) -- -- 无 TOML (代码注册)

Researcher 搜索能力 (04-22 修复)

  • 搜索引擎: Baidu + Bing CN 并行 (国内可用)DuckDuckGo fallback
  • 网页获取: Jina Reader API (优先,干净 Markdown) -> HTTP fetch (降级)
  • LLM 兼容: 扁平化 input_schema (action/query/url/urls/engine),兼容 glm-5.1 等国产模型
  • 空参数回退: LLM 发送空 {}loop_runner 注入 _fallback_query 自动搜索

定时提醒链路

用户消息 "每天早上9点提醒我查房"
  -> agent_chat_stream (chat.rs)
    -> has_schedule_intent() 关键词检测 (提醒我/定时/每天/每周等)
    -> parse_nl_schedule() -> cron 表达式
    -> ScheduleParseResult::Exact (confidence >= 0.8)
      -> TriggerConfig { hand_id: "_reminder", trigger_type: Schedule { cron } }
      -> kernel.create_trigger() -> TriggerManager 存储
    -> 跳过 LLM 调用 (省 token)
  -> SchedulerService 每60秒轮询 -> should_fire_cron() -> ReminderHand.execute()

Skill 调用链路 (LLM Tool Calling)

skills/ -> SkillRegistry 加载 -> SkillIndexMiddleware@200 注入系统提示
  -> LLM 看到 skill_load + execute_skill 工具定义
  -> LLM 生成 ToolUse{skill_load} -> AgentLoop -> 返回技能详情
  -> LLM 生成 ToolUse{execute_skill} -> KernelSkillExecutor -> Skill 执行
  -> ToolResult -> LLM 继续对话

关键: Anthropic Driver 要求 ToolResult 必须用 ContentBlock::ToolResult{tool_use_id, content} 格式。

不变量

  • Hand 配置中 enabled=false 的 Hand 不会注册到 ToolRegistry
  • Skill 调用通过 LLM Tool Calling不是直接函数调用
  • MCP 限定名 service_name.tool_name 避免与内置工具冲突
  • 已删除空壳 Hands (04-17): Whiteboard/Slideshow/Speech净减 ~5400 行

4. 活跃问题 + 陷阱

活跃

问题 状态 说明
Clip 依赖 FFmpeg P3 用户需本地安装 FFmpeg否则视频处理 Hand 不可用
Hands E2E 通过率 ~70% P2 10 Hand 全部启用,审批机制正常,但部分 Hand 边界场景未覆盖
hand.rs TODO P2 tool_count/metric_count 待从实际 Hand 实例填充

历史 (已修复)

问题 修复
skill_execute 反序列化崩溃 SEC2-P0-01 04-02 已修复
Researcher 空参数 (glm-5.1 不理解 oneOf+const schema) 04-22 schema 扁平化 + empty-input fallback
排版乱码 (stripToolNarration 句子级拆分破坏 markdown) 04-22 行级过滤

5. 变更日志

日期 变更 关联
2026-04-22 Wiki 5-section 重构: 281->~195 行,语义路由细节引用 butler wiki/
2026-04-22 Researcher 搜索修复: schema 扁平化 + 空参数回退 + 排版修复 commit 5816f56+81005c3
2026-04-17 空壳 Hand 清理: Whiteboard/Slideshow/Speech 删除,净减 ~5400 行 Phase 5 清理
2026-04-16 3 项 P0 修复 + 5 项 E2E Bug 修复 三端联调测试
2026-04-09 管家模式交付: 语义路由 TF-IDF 接入 ButlerRouter 6 交付物完成

测试概览

功能 Crate 测试数
Hands (7 实现) zclaw-hands 117
语义路由 + WASM + 编排 zclaw-skills 26
合计 143