# QwenPaw Skill 编写最佳实践 !!! note "本文总结了基于 todo 和 wiki 两个真实 skill 提炼出的 SKILL.md 编写规范,帮助开发者写出仅靠一份文件就能让 agent 独立运行的 skill。" --- ## 核心概念 1. **SKILL.md 是 agent 的唯一指令源** — agent 只读这一份文件就能完成所有操作,不依赖外部搜索 2. **Frontmatter 是触发入口** — `name` 和 `description` 决定了 agent 何时加载这个 skill 3. **References 是按需展开的辅助材料** — setup、模板、参考数据等不放进正文,避免上下文膨胀 4. **可执行性优先** — 每条操作指南必须是可直接复制执行的 SQL/命令,不留占位符 ## 详解 ### Frontmatter 写法 Frontmatter 是 SKILL.md 最关键的部分。agent 通过它判断"这个 skill 是否和当前用户请求相关"。 ```yaml --- name: todo description: | 任务待办管理 skill。通过自然语言操作 MySQL 数据库中的待办事项。 当用户提到待办、任务管理、todo list、添加任务、查看任务、标记完成、 清理任务、归档旧任务时,使用此 skill。 支持增删改查和基于 LRU 策略的自动归档。 --- ``` #### `name` 字段 - 使用小写 kebab-case 或纯小写:`todo`、`wiki`、`file-reader` - 与 skill 目录名保持一致 - 简短,不超过 2 个单词 #### `description` 触发词设计 `description` 是 agent 路由决策的核心依据。写好它需要遵循以下原则: | 原则 | 说明 | 反例 | |------|------|------| | 枚举用户可能的原话 | 把触发词直接写进去,而不是描述功能 | ~~"管理任务的工具"~~ | | 覆盖中英文 | 中文用户和英文用户都可能触发 | 只写中文触发词 | | 包含近义词和口语化表达 | "记一下"、"提醒我"、"todo list" | 只写正式术语 | | 一句话说明核心能力 | 让 agent 知道这个 skill 能做什么 | 只列触发词不说明功能 | | 末尾写一句话总结支撑能力 | 便于 agent 快速理解 scope | — | 好的 description 示例: ``` 任务待办管理 skill。通过自然语言操作 MySQL 数据库中的待办事项。 当用户提到待办、任务管理、todo list、添加任务、查看任务、标记完成、 清理任务、归档旧任务时,使用此 skill。 支持增删改查和基于 LRU 策略的自动归档。 ``` 差的 description 示例: ``` 管理任务。 ← 太模糊,agent 不知道何时触发 ``` ### 正文结构 正文遵循固定结构,让 agent 能按顺序读取并理解整个 skill 的能力边界。 ``` # Skill 名称 一句话概述 ## 工具说明 ← 依赖什么外部工具,不可用时怎么办 ## 表/数据结构 ← 数据库 schema、文件格式等 ## 操作指南 ← 核心:触发词 + 可执行命令 ## LRU/策略 ← 业务逻辑(如有) ## 交互原则 ← agent 的行为边界 ## 输出格式 ← 展示规范 ``` #### 工具说明 必须明确告诉 agent: 1. **依赖什么工具**:如 `mysql_query` MCP 工具 2. **调用方式**:通过 `execute_shell_command` 执行,还是直接使用 MCP 3. **不可用时的降级方案**:引导用户参考 `references/setup.md` 完成配置 ```markdown ## 工具说明 本 skill 依赖 **MySQL MCP 工具** `mysql_query`。所有数据库操作都通过该工具执行。 调用方式:使用 `execute_shell_command` 执行 MySQL MCP 查询,或直接使用 MCP 工具(如可用)。 如果 MCP 工具不可用,引导用户参考 `references/setup.md` 完成配置。 ``` #### 表/数据结构 完整展示 schema,不要省略字段。agent 需要知道所有字段才能写出正确的 SQL。 ```markdown ## 表结构 \```sql CREATE TABLE IF NOT EXISTS todos ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(500) NOT NULL, ... ); \``` ``` #### 操作指南(核心) 每个操作包含三个要素:**触发词**、**SQL/命令**、**边界条件**。 ```markdown ### 添加任务 触发词:添加任务 / 新建待办 / 提醒我做 / 记一下 \```sql INSERT INTO todos (title, description, priority) VALUES ('<标题>', '<描述>', '<优先级>'); \``` - 优先级默认 `medium` - 用户说"紧急/urgent/马上/ASAP" → `urgent` - 用户说"重要" → `high` - 添加后执行 LRU 检查(见下方淘汰策略) ``` 关键设计点: | 设计点 | 说明 | 为什么重要 | |--------|------|------------| | 列出触发词 | `触发词:添加任务 / 新建待办 / 提醒我做 / 记一下` | agent 直接匹配用户意图 | | 可复制的 SQL | 不用 `` 填参数,而是写清参数含义 | agent 知道该填什么 | | 参数映射规则 | 明确自然语言到字段值的映射 | agent 说"紧急"时知道映射为 `urgent` | | 边界条件 | 列出每种操作的限制和特殊情况 | 避免 agent 做出不合理操作 | | 关联操作 | 指向其他操作(如"见下方淘汰策略") | agent 能自动串联操作流 | ### References 目录组织 References 用于存放按需展开的辅助材料,避免 SKILL.md 正文过长。 ``` skills/todo/ ├── SKILL.md ← agent 始终加载 └── references/ └── setup.md ← 仅在需要配置时读取 skills/wiki/ ├── SKILL.md └── references/ ├── article-template.md ← 写文档时参考 └── mkdocs-nav.md ← 更新导航时参考 ``` #### 什么内容放 references | 放 references | 放 SKILL.md 正文 | |---------------|-------------------| | 安装配置指南(setup) | 核心操作指南 | | 模板和格式规范 | 数据结构定义 | | 参考数据(如现有目录结构) | 交互原则 | | 第三方文档摘要 | 工具依赖说明 | #### references 文件的命名 - 使用 kebab-case:`setup.md`、`article-template.md`、`mkdocs-nav.md` - 文件名应直观表达内容 - 一个文件聚焦一个主题 ### 让 Agent 仅看 SKILL.md 就能运行 以下是确保 agent 不需要额外搜索就能独立运行的关键设计: #### 1. 自包含的命令模板 每个操作指南必须包含完整的、可直接执行的 SQL/命令。不要写"根据需要构造 SQL",而是写出来: ```markdown \```sql INSERT INTO todos (title, description, priority) VALUES ('<标题>', '<描述>', '<优先级>'); \``` ``` #### 2. 自然语言到结构化数据的映射 明确告诉 agent 如何理解用户的口语化表达: ```markdown - 用户说"紧急/urgent/马上/ASAP" → `urgent` - 用户说"重要" → `high` - 用户说"不急/有空/low" → `low` ``` #### 3. 工作流串联 在操作指南中明确标注操作之间的依赖关系: ```markdown - 添加后执行 LRU 检查(见下方淘汰策略) - 匹配多条时列出匹配项让用户确认 - 用 `SELECT` 先查再改,避免误操作 ``` #### 4. 工具查找方式 如果 skill 有自己的脚本或模板,告诉 agent 如何定位它们: ```markdown ## 工作流程 ### 1. 查找 skill 路径 \``` # 用 glob_search 找到本 skill 的位置 glob_search(pattern="**/wiki/SKILL.md") \``` 找到后,skill 目录路径为结果中 `SKILL.md` 所在的目录(去掉 `/SKILL.md` 后缀)。 ``` #### 5. 降级方案 当依赖的外部工具不可用时,告诉 agent 该怎么做: ```markdown 如果 MCP 工具不可用,引导用户参考 `references/setup.md` 完成配置。 ``` ### 交互原则 SKILL.md 末尾必须定义 agent 的行为边界,防止 agent 做出用户不期望的操作: ```markdown ## 交互原则 - **模糊匹配时确认**:关键词匹配多条任务,列出选项让用户选 - **操作前预览**:删除/归档前,先 `SELECT` 显示受影响的事项 - **自然语言理解**:用户说"帮我记一下明天要买菜" → 添加任务"买菜" - **状态转换合理**:不允许 archived → in_progress 等不合理跳转 ``` 交互原则的核心模式: | 模式 | 说明 | 示例 | |------|------|------| | 确认机制 | 破坏性操作前必须确认 | 删除前先列出受影响条目 | | 预览机制 | 执行前展示将要发生的事 | SQL 执行前先 SELECT | | 合理性检查 | 拒绝不合理的状态跳转 | archived 不能直接变 in_progress | | 意图理解 | 从口语中提取结构化信息 | "明天要买菜" → title="买菜" | ### 输出格式 定义 agent 的展示规范,让输出风格一致: ```markdown ## 输出格式 查询结果用表格展示: | ID | 标题 | 状态 | 优先级 | 更新时间 | |----|------|------|--------|----------| | 1 | xxx | 待办 | 高 | 08-31 | 操作结果用简洁确认: - ✓ 已添加任务:XXX - ✓ 已完成任务:XXX ``` ## 常见陷阱 !!! warning "陷阱一:使用占位符而非完整命令" 不要写 `INSERT INTO table (col) VALUES (?)`,agent 不知道 `?` 该填什么。写完整模板并说明参数来源。 !!! warning "陷阱二:依赖 agent 自己搜索" 不要写"参考官方文档"或"搜索相关 API"。agent 的 SKILL.md 必须自包含所有必要信息。 !!! warning "陷阱三:description 太简略" 只写"任务管理工具"会导致 agent 无法准确判断何时触发。必须枚举具体触发词。 !!! warning "陷阱四:references 目录缺失" 安装配置、模板等辅助材料不放正文,但必须放在 references 中。否则 agent 在需要时无处可查。 !!! warning "陷阱五:缺少交互原则" 不定义行为边界,agent 可能直接删除数据而不确认,或在模糊匹配时随机选择。交互原则是安全网。 ## 两个 Skill 的设计模式对比 | 维度 | todo skill | wiki skill | |------|------------|------------| | 核心操作 | CRUD(SQL) | 文件操作(shell) | | 数据结构 | MySQL 表结构 | MkDocs 目录结构 | | 外部依赖 | MySQL MCP | SSH + Git | | references | setup.md(配置指南) | article-template.md + mkdocs-nav.md | | 工作流特点 | 每次操作独立 | 多步骤流水线(检查→克隆→编辑→推送) | | 交互原则重点 | 模糊匹配确认、操作前预览 | 章节不确定时必须询问 | ## 练习题 ??? question "题目一:为一个「笔记管理」skill 设计 frontmatter" ??? success "答案" ```yaml --- name: notes description: | 笔记管理 skill。支持添加、搜索、编辑和删除 Markdown 笔记。 当用户提到记笔记、写笔记、查找笔记、搜索笔记、 编辑笔记、删除笔记、笔记管理时,使用此 skill。 支持标签分类和全文搜索。 --- ``` ??? question "题目二:以下 SKILL.md 有哪些问题?" ```markdown --- name: mytool description: 一个好用的工具 --- # MyTool 这个工具可以帮你做很多事情。 需要用什么命令请参考官方文档。 ``` ??? success "答案" 1. **name 不规范**:应使用小写 kebab-case 2. **description 太模糊**:没有触发词,agent 不知道何时加载 3. **正文缺乏结构**:没有工具说明、操作指南、交互原则 4. **依赖外部搜索**:写了"参考官方文档",agent 无法独立运行 5. **没有 references**:没有提供任何辅助材料 ??? question "题目三:什么时候应该把内容放 references 而不是正文?" ??? success "答案" 当内容满足以下任一条件时,应放 references: 1. **按需使用**:不是每次调用都需要(如安装配置指南) 2. **内容较长**:放正文会膨胀上下文(如模板、参考数据) 3. **独立性强**:本身是一份完整的参考文档(如 API 文档摘要) 正文应该只放:核心操作指南、数据结构定义、交互原则、工具依赖说明。 ## 相关链接 - [QwenPaw 官方文档](https://qwenpaw.agentscope.io/) — 框架使用指南 - [QwenPaw GitHub](https://github.com/agentscope-ai/QwenPaw) — 源码与示例 - [todo skill](https://github.com/agentscope-ai/QwenPaw) — 本文分析的 todo skill 示例 - [wiki skill](https://github.com/agentscope-ai/QwenPaw) — 本文分析的 wiki skill 示例