Files
docs/ai/skill-best-practices.md
T
wonder 1f895d60f7
Deploy Docs / deploy (push) Successful in 42s
docs: 添加 AI 章节 - Skill 编写最佳实践
2026-09-01 21:06:06 +08:00

352 lines
12 KiB
Markdown
Raw 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.
# 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 | 不用 `<placeholder>` 填参数,而是写清参数含义 | 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 示例