# 核心链路硬化设计文档 > 2026-04-21 | 状态: 实施中 | 计划文件: `plans/skill-mellow-valiant.md` ## 1. 问题定义 ZCLAW 经过 20+ 轮审计修复,仍频繁发现功能链路断链。根因不是"Bug 修不完",而是 **系统复杂度超出了可验证范围**: - 190 个 Tauri 命令 × 137 个 API 端点 × 15 层中间件 = 数千个集成点 - 手动审计永远无法覆盖全部集成点 ### 1.1 胶水层诊断 架构骨架健康(crate 分层无环、中间件设计优雅),但 3 个"胶水点"是断链重灾区: | 胶水点 | 文件 | 行数 | 问题 | |--------|------|------|------| | Tauri 命令层 | `desktop/src-tauri/src/kernel_commands/chat.rs` | 548 | 业务逻辑未下沉,`agent_chat_stream` ~390行 | | 流式状态管理 | `desktop/src/store/chat/streamStore.ts` | 886 | `sendMessage` ~397行,嵌套回调,依赖 5 个 Store | | 连接管理 | `desktop/src/store/connectionStore.ts` | 891 | 连接 + 模型配置 + 网关生命周期混杂 | ### 1.2 影响范围 断链集中在 3 条核心链路: 1. **对话链路** — 用户消息 → 流式响应 → 消息持久化 2. **Hands 链路** — LLM tool_call → Hand 注册分发 → 执行回调 → 结果回传 3. **记忆链路** — 对话 → 经验提取 → FTS5 存储 → 检索 → system prompt 注入 --- ## 2. 方案设计 ### 2.1 策略:先建安全网再瘦身 混合路径,避免"边修边破": ``` Phase 1 (Week 1): 缝测试安全网 — 自动检测断链 Phase 2 (Week 2): 瘦身 chat.rs — 消除 Rust 侧 Bug 温床 Phase 3 (Week 3): 瘦身 Store 层 — 消除前端侧 Bug 温床 Phase 4 (Week 4): 全量冒烟验证 — 建立发布前信心基线 ``` ### 2.2 缝测试策略 "缝测试"(seam test) 验证的是**集成点之间的契约**,不是单元行为: ``` [Store] --缝1--> [Tauri invoke] --缝2--> [Kernel] --缝3--> [LLM Driver] --缝4--> [UI Event] ``` 每个缝测试只验证一个集成点的输入/输出格式是否正确。 #### MockLlmDriver(已有) `crates/zclaw-runtime/src/test_util.rs` 已包含完整的 `MockLlmDriver`: - Builder 风格响应队列:`with_text_response()`, `with_tool_call()`, `with_error()` - 调用检查:`call_count()`, `last_request()` - 流式模拟:默认发射 `TextDelta("mock stream")` + `Complete` - 线程安全:`Arc>` + `AtomicUsize` **无需新建**,只需在集成测试中引用。 ### 2.3 缝测试清单 #### 对话链路(4 缝) | 缝 | 位置 | 验证内容 | |----|------|---------| | Store→Tauri | Vitest (mock invoke) | `sendMessage()` 调用参数格式正确 | | Tauri→Kernel | Rust 集成测试 | `chat_command` 正确转发给 kernel | | Kernel→LLM | Rust 集成测试 | 中间件处理后 prompt 正确传递给 MockLlmDriver | | LLM→UI | Rust + Vitest | 事件顺序: delta → delta → complete | #### Hands 链路(3 缝) | 缝 | 位置 | 验证内容 | |----|------|---------| | 工具路由 | Rust 集成测试 | LLM tool_call → HandRegistry 正确分发 | | 执行回调 | Rust + Vitest | Hand 完成 → Tauri event → Store 收到结果 | | Approval | Rust 集成测试 | needs_approval=true → 确认后继续 | #### 记忆链路(3 缝) | 缝 | 位置 | 验证内容 | |----|------|---------| | 提取存储 | Rust 集成测试 | 对话 → 经验提取 → FTS5 写入 | | 检索注入 | Rust 集成测试 | 新对话 → FTS5 检索 → system prompt 包含记忆 | | 去重 | Rust 集成测试 | 同一经验不重复存储 | ### 2.4 chat.rs 瘦身方案 将 `agent_chat_stream`(~390行)从 Tauri 命令层下沉到 kernel/runtime: | 下沉项 | 当前位置 | 目标位置 | |--------|---------|---------| | 调度拦截 | `chat_command` 内联 | kernel `chat_stream()` | | 会话守卫 | `chat_command` 内联 | kernel `SessionGuard` | | 事件翻译 | `LoopEvent→StreamChatEvent` 内联 | runtime `StreamEventTranslator` | | Intelligence Hooks | `chat_command` 内联 | kernel `chat_stream()` | 预期效果:`chat.rs` 548→~200行,Tauri 命令层只做参数验证和调用转发。 ### 2.5 Store 层瘦身方案 #### streamStore.sendMessage 拆分(~397行 → 5 个函数) ``` sendMessage() → startStream() + bufferDeltas() + handleToolCalls() + handleHandEvents() + completeStream() ``` #### connectionStore 拆分(891行 → 3 个 Store) | 新 Store | 职责 | 预计行数 | |----------|------|---------| | `connectionStore` | 只管连接状态 | ~300 | | `modelConfigStore` | 模型列表 + 当前模型 + API Key | ~300 | | `gatewayStore` | 外部网关 start/stop/restart | ~300 | --- ## 3. 执行时间线 | 周 | Phase | 交付物 | 验证标准 | |----|-------|--------|---------| | W1 | 缝测试 | 13 缝测试 + 3 冒烟测试 | 能自动检测 3 条核心链路断链 | | W2 | chat.rs 瘦身 | chat.rs 548→~200行 | 所有缝测试 + 987 Rust 测试通过 | | W3 | Store 瘦身 | streamStore 886→~300行, connectionStore 拆分 3×~300行 | 所有缝测试 + 前端测试通过 | | W4 | 全量验证 | 发布前信心基线 | 全量测试 + 生产构建 + 手动验证 | --- ## 4. 约束 - **不新增功能** — 只做内部重组和测试覆盖 - **不新增 API 端点** — 稳定化约束 - **不新增 Tauri 命令** — 只瘦身已有命令 - **每步验证** — 重构前先有缝测试,重构后验证通过 - **立即提交** — 每完成一个独立工作单元立即 commit + push --- ## 5. 验证命令 ```bash # Rust 全量 cargo test --workspace --exclude zclaw-saas # 缝测试(新增) cargo test -p zclaw-kernel --test chat_chain --test smoke_chat --test smoke_hands cargo test -p zclaw-growth --test memory_chain --test smoke_memory cargo test -p zclaw-runtime --test hand_chain # 前端全量 cd desktop && pnpm vitest run # 前端缝测试(新增) cd desktop && pnpm vitest run chat-seam hand-seam # 类型检查 pnpm tsc --noEmit cargo check --workspace --exclude zclaw-saas # 生产构建 pnpm build ``` --- ## 6. 风险与缓解 | 风险 | 概率 | 缓解 | |------|------|------| | 缝测试发现新断链 | 高 | Phase 1 的目的就是发现断链,发现后立即修复 | | chat.rs 下沉破坏现有功能 | 中 | 缝测试作为安全网,每步验证 | | Store 拆分导致 import 风暴 | 中 | 逐步迁移,保留旧 Store re-export | | 测试环境搭建复杂 | 低 | MockLlmDriver 已就绪,FTS5 用临时文件 |