接通"写了没接"的定时功能断链: - NlScheduleParser has_schedule_intent/parse_nl_schedule 接入 agent_chat_stream - 新增 _reminder 系统 Hand 作为定时触发器桥接 - TriggerManager hand_id 验证对 _ 前缀系统 Hand 放行 - 聊天消息含定时意图时自动拦截,创建触发器并返回确认消息 验证:cargo check 0 error, 49 tests passed, Tauri MCP "每天早上9点提醒我查房" → cron 0 9 * * * 确认正确显示
8.5 KiB
title, updated, status, tags
| title | updated | status | tags | ||||
|---|---|---|---|---|---|---|---|
| Hands + Skills + MCP | 2026-04-14 | active |
|
Hands + Skills + MCP
从 index 导航。关联模块: chat middleware butler
设计思想
Hands = 自主能力 (行动层), Skills = 知识技能 (认知层), MCP = 外部工具协议
- Hands: 浏览器自动化、数据收集、Twitter 操作等 — 执行动作
- Skills: 75 个 SKILL.md 文件 — 语义路由匹配,增强 LLM 的领域知识
- MCP: Model Context Protocol — 动态外部工具,运行时发现和调用
- 触发: 用户请求 → LLM 判断需要执行 → 选择 Hand/Skill/MCP Tool → 执行
代码逻辑
Hands (9 启用)
每个 Hand 有独立的 hands/<Name>.HAND.toml 配置和 crates/zclaw-hands/src/hands/ 下的 Rust 实现。
| Hand | 功能 | 依赖 | 测试数 | 配置 |
|---|---|---|---|---|
| Browser | 浏览器自动化 (23 Tauri命令) | WebDriver | 8 | hands/browser.HAND.toml |
| Collector | 数据收集聚合 | — | 8 | hands/collector.HAND.toml |
| Researcher | 深度研究 | LLM | 22 | hands/researcher.HAND.toml |
| Clip | 视频处理 | FFmpeg | 30 | hands/clip.HAND.toml |
| Twitter 自动化 (12 API v2) | OAuth 1.0a | 25 | hands/twitter.HAND.toml |
|
| Whiteboard | 白板演示 | — | — | hands/whiteboard.HAND.toml |
| Slideshow | 幻灯片生成 | — | 13 | hands/slideshow.HAND.toml |
| Speech | 语音合成 | Browser TTS | — | hands/speech.HAND.toml |
| Quiz | 测验生成 | — | — | hands/quiz.HAND.toml |
| _reminder | 定时提醒 (系统内部) | — | — | 无 TOML(代码注册) |
Hands 测试分布(前 5): Clip(30), Twitter(25), Researcher(22), Slideshow(13), Browser(8)
禁用 Hands
| Hand | 状态 | 说明 |
|---|---|---|
| Predictor | 禁用 | 无 TOML/无 Rust 实现,仅概念定义 |
| Lead | 禁用 | 无 TOML/无 Rust 实现,仅概念定义 |
触发流
UI 触发 → handStore.trigger(handName, params)
→ Tauri invoke('hand_execute', { handName, params })
→ Kernel → Hand 执行
→ needs_approval? → 等待 approvalStore 确认
→ 执行结果 → Tauri Event emit
→ handStore 更新状态 + 记录日志
定时提醒链路(NlScheduleParser → _reminder Hand)
用户在聊天中输入包含定时意图的消息(如"每天早上9点提醒我查房"),系统自动拦截并创建定时触发器:
用户消息 "每天早上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: "0 9 * * *" } }
→ kernel.create_trigger() → TriggerManager 存储
→ LoopEvent::Delta(确认消息) → 前端流式显示
→ 跳过 LLM 调用(省 token)
→ SchedulerService 每60秒轮询
→ should_fire_cron() 匹配 → execute_hand_with_source("_reminder")
→ ReminderHand.execute() → 记录日志
关键组件:
crates/zclaw-runtime/src/nl_schedule.rs— 中文时间→cron 转换(支持6种模式)crates/zclaw-hands/src/hands/reminder.rs— 系统内部 Hand(id=_reminder)crates/zclaw-kernel/src/trigger_manager.rs— 触发器 CRUD(_前缀 hand_id 免验证)crates/zclaw-kernel/src/scheduler.rs— 60秒轮询 + cron 匹配desktop/src-tauri/src/kernel_commands/chat.rs— 定时意图拦截入口
Hand 相关 Tauri 命令 (8 个):
hand_list, hand_execute, hand_approve, hand_cancel, hand_get, hand_run_status, hand_run_list, hand_run_cancel
Skills (75 个目录)
skills/
├── accessibility-auditor/ api-tester/
├── agentic-identity-trust/ app-store-optimizer/
├── agents-orchestrator/ backend-architect/
├── ai-engineer/ brand-guardian/
├── analytics-reporter/ chart-visualization/
├── chinese-writing/ classroom-generator/
├── code-review/ consulting-analysis/
├── content-creator/ data-analysis/
├── data-consolidation-agent/ deep-research/
├── devops-automator/ evidence-collector/
├── ... (75 个目录,每个含 SKILL.md)
每个 SKILL.md 定义:
- 技能名称和描述
- 触发条件
- 执行步骤
- 输入/输出格式
语义路由
crates/zclaw-skills/src/semantic_router.rs
用户消息 → SemanticSkillRouter
→ TF-IDF 计算消息与 75 个技能的相似度
→ 返回 { skill_id, confidence }
→ ButlerRouter 使用 RoutingHint 增强 system prompt
在 kernel 中通过 SemanticRouterAdapter 桥接到 ButlerRouterBackend trait。
Skill 调用链路(LLM Tool Calling)
Skills 目录 → SkillRegistry 加载 → SkillIndexMiddleware(P200) 注入系统提示
→ LLM 看到 skill_load + execute_skill 工具定义
→ LLM 生成 ToolUse{skill_load} → AgentLoop 执行 → 返回技能详情
→ LLM 生成 ToolUse{execute_skill} → AgentLoop 执行 → KernelSkillExecutor
→ Skill 执行结果 → ToolResult → LLM 继续对话
关键路径:
kernel/mod.rs:create_tool_registry()注册 7 个内置工具(含 skill_load, execute_skill)runtime/loop_runner.rs检测ContentBlock::ToolUse→ 调用Tool::execute()runtime/tool/builtin/execute_skill.rs→KernelSkillExecutor::execute_skill()- Anthropic Driver: ToolResult 必须用
ContentBlock::ToolResult{tool_use_id, content}格式
MCP (Model Context Protocol)
概述
MCP 允许 ZCLAW 在运行时连接外部工具服务器(如 filesystem、database、custom tools),让 LLM 在对话中直接调用这些工具。
架构
前端 UI (MCPServices.tsx)
→ mcp-client.ts → Tauri invoke('mcp_start_service', {config})
→ McpManagerState → McpServiceManager → BasicMcpClient (stdio transport)
→ MCP Server 进程 → list_tools → 注册 adapters
LLM 对话调用:
Kernel.create_tool_registry()
→ 遍历 mcp_adapters (Arc<RwLock<Vec<McpToolAdapter>>>)
→ McpToolWrapper 包装为 Tool trait
→ 注册到 ToolRegistry → LLM API tool definitions
LLM 生成 ToolUse{filesystem.read_file}
→ AgentLoop → McpToolWrapper.execute()
→ McpToolAdapter.execute() → MCP Server → 结果返回
关键桥接机制
McpManagerState 和 Kernel 共享同一个 Arc<RwLock<Vec<McpToolAdapter>>>:
- Kernel boot 时,
kernel_init将McpManagerState.kernel_adaptersArc 注入到 Kernel - MCP 服务启动/停止时,
sync_to_kernel()更新共享列表 create_tool_registry()每次对话时读取最新 adapters
MCP Tauri 命令 (4 个)
| 命令 | 功能 |
|---|---|
mcp_start_service |
启动 MCP 服务 + 发现工具 + 同步到 Kernel |
mcp_stop_service |
停止服务 + 从 Kernel 移除工具 |
mcp_list_services |
列出所有运行中的服务和工具 |
mcp_call_tool |
手动调用 MCP 工具(支持 service_name 精确路由) |
限定名规则
MCP 工具在 ToolRegistry 中使用限定名 service_name.tool_name 避免冲突。
例如:filesystem.read_file, database.query。
关联模块
- chat — 消息流中可能触发 Hand/Skill
- butler — ButlerRouter 使用语义路由匹配技能
- middleware — SkillIndex 中间件注入技能索引
关键文件
| 文件 | 职责 |
|---|---|
crates/zclaw-hands/src/hands/ |
10 个 Hand 实现 (含 _reminder) |
crates/zclaw-runtime/src/nl_schedule.rs |
中文时间→cron 解析器 |
crates/zclaw-skills/src/semantic_router.rs |
TF-IDF 语义路由 |
crates/zclaw-skills/src/ |
技能解析和索引 |
skills/*/SKILL.md |
75 个技能定义 |
hands/*.HAND.toml |
9 个 Hand 配置 |
crates/zclaw-protocols/src/mcp_tool_adapter.rs |
MCP 工具适配器 + 服务管理 |
crates/zclaw-protocols/src/mcp.rs |
MCP 协议类型 + BasicMcpClient |
crates/zclaw-runtime/src/tool/builtin/mcp_tool.rs |
McpToolWrapper (Tool trait 桥接) |
crates/zclaw-runtime/src/driver/anthropic.rs |
Anthropic Driver (含 ToolResult 格式) |
desktop/src/store/handStore.ts |
前端 Hand 状态 |
desktop/src/store/browserHandStore.ts |
Browser Hand 专用 |
desktop/src/lib/mcp-client.ts |
前端 MCP 客户端 |
desktop/src-tauri/src/kernel_commands/mcp.rs |
MCP Tauri 命令 (4) + Kernel 桥接 |
desktop/src-tauri/src/kernel_commands/hand.rs |
Hand Tauri 命令 (8) |