第七章:技能系统
🔧 本章详细介绍 MiniClaw 的技能系统,包括技能发现、缓存机制和技能扩展。
7.1 技能系统概述
7.1.1 什么是技能系统?
技能系统是 MiniClaw 的插件扩展机制,允许用户通过添加技能文件来扩展 Agent 的能力。
┌─────────────────────────────────────────────────────────────────────┐
│ 技能系统设计理念 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 传统 AI 助手 MiniClaw 技能系统 │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ │ │ │ │
│ │ 固定功能 │ │ 插件化技能 │ │
│ │ 无法扩展 │ │ 用户可添加 │ │
│ │ 需要修改代码 │ │ 仅需添加文件 │ │
│ │ │ │ │ │
│ └───────────────────┘ └───────────────────┘ │
│ │
│ ❌ 功能固定 ✅ 灵活扩展 │
│ ❌ 需要编程知识 ✅ Markdown 即可 │
│ ❌ 升级困难 ✅ 热插拔 │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.1.2 技能系统架构
┌─────────────────────────────────────────────────────────────────────┐
│ 技能系统架构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 技能目录 │ │
│ │ ~/.miniclaw/ │ │
│ │ skills/ │ │
│ └──────┬──────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ 技能 A │ │ 技能 B │ │ 技能 C │ │
│ │ SKILL.md │ │ SKILL.md │ │ SKILL.md │ │
│ │ references/ │ │ script.sh │ │ prompts/ │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │ │ │ │
│ └───────────────┼───────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ SkillCache │ │
│ │ │ │
│ │ • 扫描技能目录 │ │
│ │ • 解析 SKILL.md │ │
│ │ • 缓存技能元数据 │ │
│ │ • TTL = 5000ms │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ MCP 暴露 │ │
│ │ │ │
│ │ • Prompts (提示词) │ │
│ │ • Tools (工具) │ │
│ │ • Resources (资源) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.2 技能目录结构
7.2.1 标准技能目录
┌─────────────────────────────────────────────────────────────────────┐
│ 技能目录结构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ~/.miniclaw/skills/ │
│ │ │
│ ├── 📁 git-workflow/ # Git 工作流技能 │
│ │ ├── 📄 SKILL.md # 技能定义文件 │
│ │ └── 📁 references/ # 参考文档 │
│ │ ├── 📄 commit-style.md │
│ │ └── 📄 branch-strategy.md │
│ │ │
│ ├── 📁 code-review/ # 代码审查技能 │
│ │ ├── 📄 SKILL.md │
│ │ └── 📄 review-checklist.md │
│ │ │
│ ├── 📁 deployment/ # 部署技能 │
│ │ ├── 📄 SKILL.md │
│ │ ├── 📄 deploy.sh # 可执行脚本 │
│ │ └── 📁 references/ │
│ │ └── 📄 env-config.md │
│ │ │
│ └── 📁 api-testing/ # API 测试技能 │
│ ├── 📄 SKILL.md │
│ └── 📁 prompts/ # 提示词模板 │
│ ├── 📄 test-case.md │
│ └── 📄 report.md │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.2.2 SKILL.md 文件结构
┌─────────────────────────────────────────────────────────────────────┐
│ SKILL.md 文件结构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ --- │
│ name: git-workflow │
│ description: Git 工作流最佳实践 │
│ version: 1.0.0 │
│ author: user │
│ tags: [git, workflow, version-control] │
│ --- │
│ │
│ # Git 工作流技能 │
│ │
│ ## 概述 │
│ 本技能提供 Git 工作流的最佳实践指导。 │
│ │
│ ## 功能 │
│ - 分支命名规范 │
│ - 提交信息格式 │
│ - 合并策略建议 │
│ │
│ ## 使用场景 │
│ - 创建新分支时 │
│ - 编写提交信息时 │
│ - 解决合并冲突时 │
│ │
│ ## 参考文档 │
│ - [commit-style](references/commit-style.md) │
│ - [branch-strategy](references/branch-strategy.md) │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.3 技能发现机制
7.3.1 发现流程
┌─────────────────────────────────────────────────────────────────────┐
│ 技能发现流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ discoverSkills() │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Step 1: 扫描技能目录 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ const skillsDir = path.join(MINICLAW_DIR, 'skills')│ │ │
│ │ │ const entries = fs.readdirSync(skillsDir) │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Step 2: 过滤有效技能 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ for (entry of entries) { │ │ │
│ │ │ const skillPath = path.join(skillsDir, entry) │ │ │
│ │ │ const skillFile = path.join(skillPath, 'SKILL.md')│ │ │
│ │ │ if (fs.existsSync(skillFile)) { │ │ │
│ │ │ skills.push(entry) │ │ │
│ │ │ } │ │ │
│ │ │ } │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Step 3: 解析技能元数据 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ const content = fs.readFileSync(skillFile, 'utf-8')│ │ │
│ │ │ const frontmatter = parseFrontmatter(content) │ │ │
│ │ │ // 提取 name, description, version, tags 等 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Step 4: 缓存技能信息 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ skillCache.set(skillName, { │ │ │
│ │ │ name, description, version, tags, │ │ │
│ │ │ path: skillPath, │ │ │
│ │ │ timestamp: Date.now() │ │ │
│ │ │ }) │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.3.2 三种技能暴露方式
┌─────────────────────────────────────────────────────────────────────┐
│ 三种技能暴露方式 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1️⃣ Prompts (提示词) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ discoverSkillPrompts() │ │
│ │ │ │
│ │ 扫描技能目录下的 prompts/ 子目录 │ │
│ │ 每个 .md 文件作为一个提示词模板 │ │
│ │ │ │
│ │ 示例: │ │
│ │ skills/api-testing/prompts/test-case.md │ │
│ │ → 暴露为 prompt: "api-testing_test-case" │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 2️⃣ Tools (工具) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ discoverSkillTools() │ │
│ │ │ │
│ │ 扫描技能目录下的可执行文件 │ │
│ │ 支持 .sh, .py, .js 等脚本 │ │
│ │ │ │
│ │ 示例: │ │
│ │ skills/deployment/deploy.sh │ │
│ │ → 暴露为 tool: "skill_deployment_deploy" │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 3️⃣ Resources (资源) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ discoverSkillResources() │ │
│ │ │ │
│ │ 扫描技能目录下的所有文件 │ │
│ │ 作为可读取的资源暴露 │ │
│ │ │ │
│ │ 示例: │ │
│ │ skills/git-workflow/references/commit-style.md │ │
│ │ → 暴露为 resource: "miniclaw://skill/git-workflow/..." │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.4 技能缓存机制
7.4.1 SkillCache 类
┌─────────────────────────────────────────────────────────────────────┐
│ SkillCache 类实现 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ class SkillCache { │
│ private cache: Map<string, SkillCacheEntry>; │
│ private lastScanTime: number; │
│ private TTL_MS: number = 5000; // 5 秒缓存有效期 │
│ │
│ async getAll(): Promise<Map<string, SkillCacheEntry>> { │
│ // 检查缓存是否有效 │
│ if (Date.now() - this.lastScanTime < this.TTL_MS) { │
│ return this.cache; // 返回缓存 │
│ } │
│ // 缓存过期,重新扫描 │
│ await this.refresh(); │
│ return this.cache; │
│ } │
│ │
│ invalidate(): void { │
│ // 使缓存失效 │
│ this.lastScanTime = 0; │
│ } │
│ │
│ private async refresh(): Promise<void> { │
│ // 扫描技能目录 │
│ // 解析 SKILL.md 文件 │
│ // 更新缓存 Map │
│ this.lastScanTime = Date.now(); │
│ } │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.4.2 缓存优势
┌─────────────────────────────────────────────────────────────────────┐
│ 缓存机制优势 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ❌ 无缓存情况 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 每次请求上下文: │ │
│ │ 1. 扫描技能目录 │ │
│ │ 2. 读取每个 SKILL.md │ │
│ │ 3. 解析 frontmatter │ │
│ │ 4. 返回结果 │ │
│ │ │ │
│ │ 问题:N+1 查询,性能低下 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ✅ 有缓存情况 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 首次请求: │ │
│ │ 1. 扫描 + 解析 + 缓存 │ │
│ │ │ │
│ │ 后续请求(5 秒内): │ │
│ │ 1. 直接返回缓存 │ │
│ │ │ │
│ │ 优势:避免重复 I/O,性能提升 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ TTL = 5000ms 平衡了性能和数据新鲜度 │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.5 技能扩展示例
7.5.1 创建新技能
┌─────────────────────────────────────────────────────────────────────┐
│ 创建新技能示例 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: 创建技能目录 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ mkdir -p ~/.miniclaw/skills/my-skill │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Step 2: 创建 SKILL.md │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ --- │ │
│ │ name: my-skill │ │
│ │ description: 我的自定义技能 │ │
│ │ version: 1.0.0 │ │
│ │ tags: [custom, example] │ │
│ │ --- │ │
│ │ │ │
│ │ # 我的自定义技能 │ │
│ │ │ │
│ │ ## 功能 │ │
│ │ - 功能 1 │ │
│ │ - 功能 2 │ │
│ │ │ │
│ │ ## 使用方法 │ │
│ │ 1. 步骤 1 │ │
│ │ 2. 步骤 2 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Step 3: 添加参考文档(可选) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ mkdir -p ~/.miniclaw/skills/my-skill/references │ │
│ │ echo "# 参考文档" > ~/.miniclaw/skills/my-skill/... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Step 4: 重启 MCP 客户端 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 技能将自动被发现和加载 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.5.2 技能模板示例
┌─────────────────────────────────────────────────────────────────────┐
│ 技能模板示例 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 📁 code-review/ │
│ ├── 📄 SKILL.md │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ --- │ │
│ │ │ name: code-review │ │
│ │ │ description: 代码审查最佳实践 │ │
│ │ │ version: 1.0.0 │ │
│ │ │ tags: [code, review, quality] │ │
│ │ │ --- │ │
│ │ │ │ │
│ │ │ # 代码审查技能 │ │
│ │ │ │ │
│ │ │ ## 审查清单 │ │
│ │ │ - [ ] 代码风格一致性 │ │
│ │ │ - [ ] 错误处理完整性 │ │
│ │ │ - [ ] 测试覆盖率 │ │
│ │ │ - [ ] 性能考量 │ │
│ │ │ - [ ] 安全漏洞检查 │ │
│ │ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ └── 📄 checklist.md │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ # 详细审查清单 │ │
│ │ │ │
│ │ ## 代码风格 │ │
│ │ - 命名规范 │ │
│ │ - 注释完整性 │ │
│ │ - 代码格式化 │ │
│ │ │ │
│ │ ## 错误处理 │ │
│ │ - 异常捕获 │ │
│ │ - 边界条件 │ │
│ │ - 空值检查 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.6 技能使用统计
7.6.1 统计数据收集
┌─────────────────────────────────────────────────────────────────────┐
│ 技能使用统计 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Analytics 接口中的 skillUsage 字段 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ interface Analytics { │ │
│ │ // ... │ │
│ │ skillUsage: Record<string, number>; // 技能使用统计 │ │
│ │ } │ │
│ │ │ │
│ │ 示例数据: │ │
│ │ { │ │
│ │ "git-workflow": 15, │ │
│ │ "code-review": 8, │ │
│ │ "deployment": 3 │ │
│ │ } │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 收集时机: │
│ • 技能提示词被调用时 │
│ • 技能工具被执行时 │
│ • 技能资源被读取时 │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.6.2 统计数据应用
┌─────────────────────────────────────────────────────────────────────┐
│ 统计数据应用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 应用场景: │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1️⃣ 上下文优先级调整 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 高频使用的技能在上下文中优先级更高 │ │ │
│ │ │ 低频使用的技能可能被截断 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 2️⃣ 技能推荐 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 根据使用频率推荐相关技能 │ │ │
│ │ │ "您可能还需要 code-review 技能" │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 3️⃣ 性能优化 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 识别未使用的技能,考虑移除 │ │ │
│ │ │ 优化高频技能的加载策略 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
本章小结
┌─────────────────────────────────────────────────────────────────────┐
│ 第七章 核心要点 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 🔧 技能系统是 MiniClaw 的插件扩展机制 │
│ • 用户可通过添加文件扩展 Agent 能力 │
│ │
│ 📁 技能目录结构 │
│ • ~/.miniclaw/skills/<skill-name>/ │
│ • 必须包含 SKILL.md 文件 │
│ │
│ 🔍 三种暴露方式 │
│ • Prompts (提示词) │
│ • Tools (工具) │
│ • Resources (资源) │
│ │
│ 💾 SkillCache 缓存机制 │
│ • TTL = 5000ms │
│ • 避免 N+1 查询问题 │
│ │
│ 📊 技能使用统计 │
│ • 用于优先级调整和推荐 │
│ │
└─────────────────────────────────────────────────────────────────────┘
下一章:心跳与进化机制 →