echo_agent 0.1.1

AI Agent framework with ReAct loop, multi-provider LLM, tool execution, and A2A HTTP server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# Skill 系统设计

本文档介绍 echo-agent 的 Skill 系统设计,该系统对齐 [agentskills.io](https://agentskills.io/) 规范。

---

## 概述

Skill(技能)是比 Tool(工具)更高层的能力抽象。一个 Skill 可以包含多个相关工具 + 可选的系统提示词注入,形成完整的能力包。

### Skill vs Tool

| 维度 | Tool | Skill |
|------|------|-------|
| 粒度 | 单个原子操作 | 领域能力包(多工具 + 提示词) |
| 注册方式 | `agent.add_tool(box)` | `agent.add_skill(box)` |
| 提示词 || 可注入系统提示词 |
| 语义 | "做一件事" | "我精通某个领域" |

---

## 两种 Skill 类型

echo-agent 支持两种 Skill 类型:

### 1. Code-based Skill(代码型)

直接在 Rust 代码中定义,注册时立即生效。

```rust
// src/skills/mod.rs
pub trait Skill: Send + Sync {
    /// 唯一标识(小写,如 "calculator")
    fn name(&self) -> &str;
    
    /// 人类可读描述
    fn description(&self) -> &str;
    
    /// 提供的工具列表(每次调用返回新实例)
    fn tools(&self) -> Vec<Box<dyn Tool>>;
    
    /// 可选:注入到系统提示词的文本
    fn system_prompt_injection(&self) -> Option<String> {
        None
    }
}
```

**示例:计算器技能**

```rust
pub struct CalculatorSkill;

impl Skill for CalculatorSkill {
    fn name(&self) -> &str { "calculator" }
    
    fn description(&self) -> &str { 
        "数学计算能力,支持加减乘除" 
    }
    
    fn tools(&self) -> Vec<Box<dyn Tool>> {
        vec![
            Box::new(AddTool),
            Box::new(SubtractTool),
            Box::new(MultiplyTool),
            Box::new(DivideTool),
        ]
    }
    
    fn system_prompt_injection(&self) -> Option<String> {
        Some("你有精确的数学计算能力。对于任何数学计算任务,请使用计算器工具。".into())
    }
}

// 注册
agent.add_skill(Box::new(CalculatorSkill));
```

### 2. File-based Skill(文件型)

通过 `SKILL.md` 文件定义,支持渐进式披露(Progressive Disclosure)。

**目录结构:**

```
skills/
├── code_review/
│   ├── SKILL.md          # 技能定义(必需)
│   └── references/
│       ├── checklist.md  # 参考文档
│       └── style_guide.md
│
├── data_analyst/
│   ├── SKILL.md
│   └── references/
│       └── statistical_methods.md
│
└── web_researcher/
    ├── SKILL.md
    └── references/
        ├── research_template.md
        └── source_evaluation.md
```

**SKILL.md 格式:**

```markdown
---
name: code_review
description: Comprehensive code review capability
version: 1.0.0
author: echo-agent
---

# Code Review Skill

You are an expert code reviewer. When reviewing code, consider:

1. **Correctness**: Does the code do what it's supposed to?
2. **Performance**: Are there any obvious inefficiencies?
3. **Security**: Are there potential vulnerabilities?
4. **Readability**: Is the code easy to understand?

## Tools

- `review_file`: Review a single file
- `suggest_fix`: Suggest improvements

## References

- [Review Checklist]references/checklist.md
- [Style Guide]references/style_guide.md
```

---

## 渐进式披露

文件型 Skill 采用三级渐进式披露,减少初始上下文占用:

```
┌─────────────────────────────────────────────────────────────────────┐
│                   Progressive Disclosure                             │
│                                                                      │
│   Level 1: Discovery (发现)                                         │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  Agent 启动时扫描 skills/ 目录                               │   │
│   │  为每个 SKILL.md 创建 SkillDescriptor                       │   │
│   │  注册 DiscoverySkillTool 用于后续激活                       │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                              │                                       │
│                              ▼                                       │
│   Level 2: Activation (激活)                                        │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  LLM 调用 discovery_skill 激活某个 skill                     │   │
│   │  加载完整 SKILL.md 内容注入系统提示词                       │   │
│   │  注册该 skill 的所有工具                                     │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                              │                                       │
│                              ▼                                       │
│   Level 3: Usage (使用)                                             │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  LLM 调用具体工具完成任务                                    │   │
│   │  可访问 references/ 下的参考文档                             │   │
│   │  通过 hooks 拦截和增强工具调用                               │   │
│   └─────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘
```

### 内置发现工具

```rust
// src/skills/external/discovery.rs

/// 发现可用技能
pub struct DiscoverySkillTool;

impl Tool for DiscoverySkillTool {
    fn name(&self) -> &str { "discovery_skill" }
    fn description(&self) -> &str { "发现并激活一个技能" }
    
    fn execute(&self, params: ToolParameters) -> BoxFuture<'_, Result<ToolResult>> {
        Box::pin(async move {
            let skill_name: String = params.get("name")?;
            // 激活技能
            // 注入提示词 + 注册工具
            Ok(ToolResult::success(format!("技能 {} 已激活", skill_name)))
        })
    }
}
```

---

## SkillRegistry

```rust
// src/skills/registry.rs
pub struct SkillRegistry {
    // Code-based skills
    skills: HashMap<String, Box<dyn Skill>>,
    
    // File-based skills (descriptors only)
    descriptors: Vec<SkillDescriptor>,
    
    // Hooks for tool call interception
    hooks: HookRegistry,
}

impl SkillRegistry {
    /// 注册代码型 Skill
    pub fn register(&mut self, skill: Box<dyn Skill>) {
        let info = SkillInfo {
            name: skill.name().to_string(),
            description: skill.description().to_string(),
            tool_names: skill.tools().iter().map(|t| t.name().to_string()).collect(),
            has_prompt_injection: skill.system_prompt_injection().is_some(),
        };
        self.skills.insert(info.name.clone(), skill);
    }
    
    /// 发现文件型 Skills
    pub fn discover(&mut self, path: &Path) -> Result<Vec<SkillDescriptor>> {
        for entry in fs::read_dir(path)? {
            let skill_path = entry?.path().join("SKILL.md");
            if skill_path.exists() {
                let descriptor = SkillDescriptor::from_file(&skill_path)?;
                self.descriptors.push(descriptor);
            }
        }
        Ok(self.descriptors.clone())
    }
    
    /// 激活文件型 Skill
    pub fn activate(&mut self, name: &str) -> Result<SkillContent> {
        let descriptor = self.descriptors.iter()
            .find(|d| d.name == name)
            .ok_or(SkillError::NotFound)?;
        
        let content = descriptor.load_content()?;
        // 注册工具、注入提示词
        Ok(content)
    }
}
```

---

## Hook 系统

Skill 可以定义 Hooks 来拦截和增强工具调用:

```rust
// src/skills/hooks.rs
pub struct HookRegistry {
    rules: Vec<HookRule>,
}

pub struct HookRule {
    pub skill_name: String,
    pub tool_pattern: Regex,
    pub event: HookEvent,
    pub action: HookAction,
}

pub enum HookEvent {
    BeforeCall,
    AfterCall,
    OnError,
}

pub enum HookAction {
    Transform(Box<dyn Fn(&mut Value) -> Result<()> + Send + Sync>),
    Validate(Box<dyn Fn(&Value) -> Result<()> + Send + Sync>),
    Log(Box<dyn Fn(&str, &Value) + Send + Sync>),
}
```

**示例:代码审查 Skill 的 Hook**

```yaml
# skills/code_review/SKILL.md
---
name: code_review
hooks:
  - tool: "review_file"
    event: before_call
    action: validate_file_exists
  - tool: "suggest_fix"
    event: after_call
    action: format_as_diff
---
```

---

## 使用示例

### 代码型 Skill

```rust
use echo_agent::prelude::*;
use echo_agent::skills::Skill;

// 定义 Skill
struct WeatherSkill;

impl Skill for WeatherSkill {
    fn name(&self) -> &str { "weather" }
    fn description(&self) -> &str { "天气查询能力" }
    fn tools(&self) -> Vec<Box<dyn Tool>> {
        vec![
            Box::new(GetWeatherTool),
            Box::new(GetForecastTool),
        ]
    }
    fn system_prompt_injection(&self) -> Option<String> {
        Some("你可以查询全球城市的实时天气和天气预报。".into())
    }
}

// 注册
let mut agent = ReactAgentBuilder::simple("qwen3-max", "助手")?;
agent.add_skill(Box::new(WeatherSkill));
```

### 文件型 Skill

```rust
use echo_agent::skills::SkillRegistry;

// 发现
let mut registry = SkillRegistry::new();
let discovered = registry.discover(Path::new("skills/"))?;

println!("发现 {} 个技能:", discovered.len());
for desc in &discovered {
    println!("  - {}: {}", desc.name, desc.description);
}

// 在 Agent 中使用
agent.set_skill_registry(registry);

// LLM 可以调用 discovery_skill 激活需要的技能
```

---

## agentskills.io 规范

echo-agent 的 Skill 系统对齐 [agentskills.io](https://agentskills.io/specification) 规范:

| 规范要求 | echo-agent 实现 |
|----------|-----------------|
| SKILL.md 格式 | ✓ 支持 YAML frontmatter |
| 渐进式披露 | ✓ 三级:发现 → 激活 → 使用 |
| 工具注册 | ✓ 自动注册 |
| 提示词注入 | ✓ 系统提示词追加 |
| 参考文档 | ✓ references/ 目录 |
| Hooks | ✓ 拦截和增强 |

---

## 最佳实践

### 1. Skill 命名

- 使用小写字母和下划线:`code_review`, `data_analyst`
- 命名应反映领域:`web_researcher` 而非 `research`
- 避免与内置 Skill 冲突

### 2. 提示词注入

```rust
fn system_prompt_injection(&self) -> Option<String> {
    Some(r#"
## 计算器技能

你有精确的数学计算能力。使用以下工具进行计算:

- add: 两数相加
- subtract: 两数相减
- multiply: 两数相乘
- divide: 两数相除

注意:除法时检查除数是否为零。
"#.into())
}
```

### 3. 工具设计

- 每个 Skill 的工具应该相关且内聚
- 避免在一个 Skill 中混合不相关的工具
- 工具描述要清晰说明用途

### 4. 文件型 Skill 目录结构

```
skills/
└── my_skill/
    ├── SKILL.md              # 必需
    ├── references/           # 可选:参考文档
    │   ├── guide.md
    │   └── examples.md
    └── scripts/              # 可选:脚本工具
        └── helper.py
```

---

## 参考资料

- [agentskills.io 规范]https://agentskills.io/specification
- [LangChain Tools]https://python.langchain.com/docs/modules/tools/
- [CrewAI Tools]https://docs.crewai.com/core-concepts/Tools