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: 添加测试文件验证工作区路径
3.6 KiB
3.6 KiB
ZCLAW Skill系统问题修复 - 完成报告
问题诊断
用户报告的问题
对话过程中agent无法正确调用skill去完成任务。
根因分析
经过代码分析,发现两个核心问题:
问题1: Agent循环不完整
位置: crates/zclaw-runtime/src/loop_runner.rs
原始实现:
用户消息 → LLM → 工具调用 → 结果直接返回
正确实现应该是:
用户消息 → LLM → 工具调用 → 工具结果 → LLM(处理结果) → 最终响应
关键代码问题:
// 原始代码在工具执行后直接返回结果
full_response.push_str(&format!("\n[工具 {} 结果]: {}", name, ...));
问题2: 流式输出暴露内部细节
StreamChunk::ToolUseDelta事件被当作[工具参数]文本输出给用户,这是调试信息不应该暴露。
修复方案
1. 实现完整Agent循环
文件: crates/zclaw-runtime/src/loop_runner.rs
改动:
- 添加循环结构, 最多10次迭代
- 检查LLM响应中的工具调用
- 如果没有工具调用, 返回最终响应
- 如果有工具调用, 执行后添加结果到消息历史, 继续循环让LLM处理
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
改动:
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事件通知新迭代开始
验证
编译状态
✅ 编译通过,无错误
需要测试
- 单次工具调用 - "搜索腾讯财报"
- 多轮工具调用 - "搜索并分析数据"
- 无工具调用 - "你好"
后续步骤
- 手动测试 - 启动应用测试skill调用流程
- 前端适配 - 磁保前端正确处理新的事件类型
- 文档更新 - 更新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注入) |
测试命令
# 编译
cargo build -p zclaw-runtime
# 启动开发环境
pnpm start:dev
# 测试对话
# 发送: "帮我分析一下腾讯的财报"
# 预期: LLM调用execute_skill工具,返回分析结果