# Skills 管理系统 Skills 是 Yuxi 系统中用于扩展 Agent 能力的重要机制。通过 Skills,开发者可以将特定的工具、提示词模板或领域知识打包成可复用的技能包,让 Agent 在对话过程中能够调用这些额外能力。 ## 为什么需要 Skills 在实际业务场景中,我们常常会遇到一些特定的需求:比如需要 Agent 能够查询特定的 API、调用某个外部服务、或者使用特定的提示词模板来完成特定任务。传统的做法是在代码中硬编码这些功能,但这样会导致系统变得越来越臃肿,且难以复用。 Skills 系统的设计理念就是将这类"可插拔"的能力封装成独立的技能包。每个 Skill 包含完整的实现文件和元数据,Agent 可以根据配置动态加载所需的技能,实现能力的灵活组合。 ## 架构设计 Skills 系统采用「文件系统存内容,数据库存索引」的分离架构: ``` ┌─────────────────────────────────────────────────────────────┐ │ Skills 存储架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ /app/saves/skills/ 数据库索引 │ │ ├── skill-a/ ┌──────────────┐ │ │ │ ├── SKILL.md │ skills 表 │ │ │ │ ├── tools/ │ - slug │ │ │ │ └── prompts/ │ - name │ │ │ └── skill-b/ │ - description│ │ │ ├── SKILL.md │ - dir_path │ │ │ └── ... │ - deps... │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 存储结构 - **文件系统**:`/app/saves/skills` 目录下,每个 Skill 占用一个子目录 - **数据库索引**:`skills` 表存储元数据(slug、name、description、依赖关系等) - **关联机制**:通过 `dir_path` 字段关联文件系统目录与数据库记录 ::: tip 不能直接在文件系统创建 由于 Skills 的元数据需要写入数据库,因此不能直接在文件系统中创建 Skill。必须通过系统的导入功能或在线创建功能来完成,系统会自动处理数据库记录的创建。 ::: ## 创建方式 系统提供四种方式创建 Skills: 1. **ZIP 导入(推荐)**:将 Skill 目录打包成 ZIP,通过管理界面上传导入 2. **在线创建**:通过 Skills 管理页面在线创建目录和文件 3. **远程仓库安装**:在 Skills 管理页面填写 skills 仓库地址和 skill 名称,由后端调用 `npx skills` 下载后再导入系统 4. **手动导入**:直接操作数据库(不推荐,需要手动同步文件系统和数据库) ## Skills 来源 Skills 本质上是提示词和工具的封装,以下是一些可以参考的 Skills 实现: - **Anthropic 官方 Tools**:https://github.com/anthropics/skills 可以参考其 skills 的组织方式和提示词设计 - **MiniMax-AI CLI**:https://github.com/MiniMax-AI/cli 文本、图片、视频、语音和音乐生成 + Web 搜索(可通过 `MiniMax-AI/cli` 远程安装) - **社区 Skills**:各平台分享的 Agent 提示词模板 - **自定义开发**:根据业务需求自行开发 ## 快速开始 ### 创建你的第一个 Skill 一个标准的 Skill 目录结构如下: ``` my-awesome-skill/ ├── SKILL.md # 必选,Skill 的核心定义文件 ├── tools/ # 可选,相关的工具脚本 │ └── helper.py └── prompts/ # 可选,提示词模板 └── system.md ``` 其中 `SKILL.md` 是每个 Skill 必须包含的核心文件,它采用 Markdown + Frontmatter 格式: ```markdown --- name: my-awesome-skill description: 这是一个用于处理特定任务的技能 --- # Skill 使用说明 这里是技能的详细使用文档,Agent 会读取这部分内容来了解如何使用这个技能。 ## 功能列表 1. 功能一:xxx 2. 功能二:yyy ## 使用示例 当用户 xxx 时,可以调用此技能... ``` **Frontmatter 字段说明:** | 字段 | 必填 | 说明 | |------|------|------| | `name` | 是 | Skill 名称,必须是小写字母、数字、短横线的组合(如 `my-skill`) | | `description` | 是 | Skill 的功能描述,会在 Agent 配置时展示 | ### 导入 Skill 有三种方式可以导入 Skill: **方式一:通过 ZIP 包导入(推荐)** 1. 将 Skill 目录打包成 ZIP 文件(注意:ZIP 的根目录就是 Skill 目录) 2. 在系统设置的「Skills 管理」页面,点击「导入 Skill」 3. 上传 ZIP 文件即可 系统会自动: - 校验 ZIP 内容和路径安全性 - 检查 slug 冲突(如有冲突会自动追加 `-v2` 等后缀) - 解析 SKILL.md 的 frontmatter 并存储到数据库 **方式二:在线创建** 在 Skills 管理页面,你可以: - 新建目录或文件 - 在线编辑文本文件(支持 .md、.py、.js、.json 等格式) - 直接在网页上编写 SKILL.md 内容 **方式三:从远程 skills 仓库安装** 1. 在 Skills 管理页面的“远程安装”面板中填写仓库来源,例如 `anthropics/skills` 或完整 GitHub URL 2. 点击“查看可安装 Skills”获取该仓库中可发现的 skills 列表 3. 选择或输入目标 skill 名称后点击“安装” 系统会在后端: - 调用 `npx skills add --list` 校验来源并发现可安装的 skills - 使用隔离的临时 `HOME` 执行 `npx skills add --skill -g -y --copy` - 从临时目录中提取对应 skill,再按现有导入流程写入 `/app/saves/skills` 与数据库 ::: tip 远程安装不会把 ~/.agents/skills 作为系统主存储 远程安装只把 `skills.sh` CLI 作为“下载器”使用。Yuxi 仍然以 `/app/saves/skills + skills 表` 作为正式来源,这样才能与现有的权限、线程可见性和沙盒挂载机制保持一致。 ::: ## 依赖系统 Skills 之间可以建立依赖关系,形成一个松耦合的技能网络。 ### 依赖类型 每个 Skill 可以声明三类依赖: | 依赖类型 | 说明 | 加载时机 | |----------|------|----------| | `tool_dependencies` | 需要的内置工具 | 激活后按需加载 | | `mcp_dependencies` | 需要的 MCP 服务 | 激活后按需加载 | | `skill_dependencies` | 依赖的其他 Skill | 会话启动即生效 | ### 渐进式加载机制 系统采用三级渐进式加载策略,确保资源的高效利用: **阶段一:会话启动** 当 Agent 会话启动时,系统会: 1. 在创建 Graph 前读取已过滤的 `context.skills` 列表 2. 递归展开 `skill_dependencies`,派生 `_prompt_skills` 和 `_readable_skills` 3. 将 `_prompt_skills` 对应的技能说明注入到系统提示词中 这意味着:只要配置了某个 Skill,它的依赖 Skill 就会立即进入提示词和 `/home/gem/skills` 只读范围。 **阶段二:技能激活** 当 Agent 通过 `read_file` 工具读取 `/skills//SKILL.md` 时,视为"激活"该技能。系统会: 1. 验证该技能在可见列表中 2. 将其添加到 `activated_skills` 列表 3. 后续的模型调用会使用激活列表来加载依赖 **阶段三:按需加载** 每次模型调用时,系统会: 1. 检查 `activated_skills` 中的技能 2. 收集这些技能的 `tool_dependencies` 和 `mcp_dependencies` 3. 动态将需要的工具和 MCP 服务添加到可用工具集中 这种设计的好处是:不会在会话开始时加载所有工具,而是根据 Agent 实际使用情况按需加载,既节省资源又保证响应速度。 ### 依赖声明示例 假设我们有三个 Skills: - **base-skill**:基础技能,无依赖 - **advanced-skill**:依赖 `base-skill` - **pro-skill**:依赖 `advanced-skill` 当在 Agent 配置中只选择 `pro-skill` 时: 1. 启动阶段:`_readable_skills` = [`pro-skill`, `advanced-skill`, `base-skill`](自动展开依赖链) 2. Agent 首次调用任何 skill 时:所有三个 Skill 都可读 3. 当 Agent 读取 `pro-skill/SKILL.md` 时:触发激活,工具和 MCP 依赖被加载 ## 权限管理 Skills 管理采用基于角色的权限控制: | 角色 | 权限 | |------|------| | 超级管理员 | 完全控制:导入、导出、编辑、删除、配置依赖 | | 管理员 | 只读:查看 Skills 列表(用于 Agent 配置) | | 普通用户 | 无访问权限 | 管理员可以在创建或编辑 Agent 时,从 Skills 列表中选择需要的能力。 ## 运行时行为 ### Agent 如何使用 Skills 1. **提示词注入**:系统会在 Agent 的系统提示词开头自动插入可用 Skills 的描述 2. **文件访问**:Skills 目录以只读方式挂载到 `/skills//...` 3. **工具调用**:当 Agent 需要使用某个 Skill 时,会先读取对应的 SKILL.md 了解使用方法 ### 文件操作限制 运行时 `/skills` 路径有以下限制: - **只读**:Agent 只能读取文件内容 - **禁止写入**:不能创建、修改或删除文件 - **路径安全**:所有路径都经过安全校验,防止目录穿越攻击 ::: tip 虚拟文件系统限制 当前 Skills 目录挂载为虚拟文件系统,**不支持 shell 命令执行**。Skill 中的脚本仅作为提示词参考,Agent 无法直接执行这些脚本。如果需要执行特定功能,建议通过 MCP 工具或自定义工具实现。 ::: ### 会话隔离 每个 Agent 会话都有独立的 Skills 可见集: - 不同会话可以配置不同的 Skills - 同一会话内修改 `context.skills` 会触发快照重建 - 后台修改 Skills 内容后,已有会话不会自动刷新 ## 最佳实践 ### Skill 命名规范 - 使用小写字母、数字和短横线 - 具有描述性,如 `weather-query`、`sql-reporter` - 避免过长的名称 ### 依赖管理建议 - **保持依赖链简洁**:层级不宜过深,一般 1-2 层为宜 - **避免循环依赖**:系统会检测并阻止循环依赖 - **明确依赖必要性**:只在真正需要共享能力时才建立依赖 ### SKILL.md 编写技巧 ```markdown --- name: example-skill description: 简短描述技能功能 --- # 技能名称 这里是详细的使用说明... ## 何时使用 描述在什么场景下应该使用这个技能... ## 使用方法 1. 第一步... 2. 第二步... ## 示例 ``` 具体的使用示例... ``` ``` ## 常见问题 **Q:为什么我配置的 Skill 没有生效?** A:请检查以下几点: 1. Skill 的 slug 是否正确配置在 Agent 的 `context.skills` 中 2. SKILL.md 是否存在且 frontmatter 格式正确 3. 如果使用了依赖,确保依赖链完整 **Q:如何更新已导入的 Skill?** A:可以通过以下方式: 1. 导出当前 Skill,修改后重新导入 2. 在 Skills 管理页面在线编辑文件 3. 直接修改文件系统中的内容(需要重启服务使缓存失效) **Q:Skill 依赖的工具/MCP 不存在怎么办?** A:系统会在保存依赖配置时进行校验,如果引用的工具或 MCP 不存在,会报错并阻止保存。 --- 通过 Skills 机制,Yuxi 为 Agent 提供了一个灵活、可扩展的能力扩展框架。你可以将自己积累的业务知识、工具能力封装成 Skills,让不同的 Agent 复用这些能力,极大地提升了系统的可维护性和复用性。