Files
zclaw_openfang/plans/polymorphic-orbiting-pinwheel.md
iven aa6a9cbd84
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
feat: 新增技能编排引擎和工作流构建器组件
refactor: 统一Hands系统常量到单个源文件
refactor: 更新Hands中文名称和描述

fix: 修复技能市场在连接状态变化时重新加载
fix: 修复身份变更提案的错误处理逻辑

docs: 更新多个功能文档的验证状态和实现位置
docs: 更新Hands系统文档

test: 添加测试文件验证工作区路径
2026-03-25 08:27:25 +08:00

150 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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