# 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工具,返回分析结果 ```