一个高质量的 Skill 应该长什么样
文章摘要: Skill是AI Agent的领域专家手册,通过结构化文档让Agent掌握特定领域的知识和约束,避免重复输入背景知识。一个高质量Skill包含:1)描述清晰的SKILL.md主文件,分元数据和正文两部分;2)按需加载的参考资料;3)精确的触发条件描述。好Skill的关键是让Agent“读完就能干活”,需包含使用顺序、关键入口、必守约束和参考资料。适用场景包括重复性专业任务、项目特定知识
一个高质量的 Skill 应该长什么样
好 Skill 不是"写了就行",是"Agent 读完就能干活"。
目录
- Skill 是什么
- 什么场景该用 Skill
- Skill 长什么样:组成部分
- description:Skill 的门面
- 主文件:Agent 读完就能干活
- 约束怎么写:解释 Why,不堆 MUST
- 反模式清单
- 总结:好 Skill 的检查清单
Skill 是什么
你让 AI 帮你做代码审查。它看了一段代码,给出了几条通用建议:“变量命名可以更清晰”、“建议加单元测试”、“考虑异常处理”。说得都对,但没什么用——它不知道你项目的规范:Service 层禁止直接调用 Mapper、Controller 不允许写业务逻辑、所有接口必须返回统一的 Result<T> 格式。
你补充了这些背景知识,AI 的审查结果立刻好了很多。但下次开新对话,你又得重新说一遍。
Skill 解决的就是这个问题。
Skill 是一份给 AI Agent 看的"专家手册"。你把特定领域的知识、流程、约束写成 Agent 能理解的结构化文档,Agent 遇到相关任务时自动加载这份手册。不需要你每次重复输入背景知识。
具体来说,一个 Skill 就是文件系统上的一个文件夹,里面有一个主文件(SKILL.md)和一些可选的参考资料。Agent 根据主文件里的描述信息判断"这个任务跟哪个 Skill 有关",然后自动读取对应的指令。
一句话:Skill = 让 Agent 从"通用助手"变成"领域专家"的知识载体。
什么场景该用 Skill
不是所有任务都需要写 Skill。判断标准很简单:你是否在反复给 AI 补充同样的背景知识?
适合用 Skill 的场景
重复性的专业任务。 代码审查、PDF 处理、API 文档生成、数据库迁移——这些任务每次的流程差不多,但涉及特定工具、规范或约定。写一次 Skill,以后每次都不用重复说明。
项目特定的知识。 业务规则(“订单状态只能从 CREATED 到 PAID,不能跳过”)、架构约定(“所有数据库操作必须在 Repository 层”)、代码规范(“接口命名用 RESTful 风格”)。这些知识不存在于任何公开文档里,只存在于你的项目中。
多步骤的复杂流程。 部署流程(构建 → 测试 → 打包 → 推送 → 部署 → 验证)、数据迁移(备份 → 改表 → 回填 → 校验)、测试策略(单测 → 集成测试 → E2E)。步骤多、顺序重要、容易遗漏。
不需要 Skill 的场景
一次性的简单任务。 “帮我写个 Hello World”、“这个 JSON 格式对不对”——Agent 本身就能搞定,不需要额外知识。
Agent 本身就能做好的事。 通用的编程问题、算法题、正则表达式——这些是 Agent 的基础能力,写 Skill 反而是浪费上下文窗口。
一句话:如果你发现自己在反复给 AI 补充同样的背景知识,就该写个 Skill。
Skill 长什么样:组成部分
一个 Skill 就是文件系统上的一个文件夹。最简单的 Skill 只需要一个文件,完整的 Skill 可能长这样:
code-review/
├── SKILL.md # 必须:主文件
├── agents/
│ └── openai.yaml # 可选:UI 展示元数据
├── references/ # 可选:详细参考文档
│ ├── naming-rules.md # 命名规范
│ ├── layer-rules.md # 分层规范
│ └── api-standards.md # API 设计规范
├── scripts/ # 可选:自动化脚本
│ └── lint_check.py # 自动检查脚本
└── assets/ # 可选:模板等资源
└── review-template.md # 审查报告模板
SKILL.md 的两部分
每个 Skill 的核心是 SKILL.md 文件,它由两部分组成:
Frontmatter(YAML 头部):用 --- 包裹的元数据,包含 name 和 description 两个字段。这两个字段是 Agent 判断"要不要用这个 Skill"的唯一依据——Agent 在决定是否触发时只看这段元数据,不会读正文。
---
name: code-review
description: >
按照项目规范进行代码审查,检查分层架构、命名规范、
异常处理和 API 设计。当用户要求审查代码、检查 PR、
或询问代码质量时使用。不用于代码格式化或 lint 检查。
---
Body(Markdown 正文):Frontmatter 之后的所有内容。只有当 Skill 被触发后才会加载。这里是你的指令正文——告诉 Agent 怎么完成任务。
渐进式披露:三级加载
这里有一个关键设计:Skill 的内容不是一次性全部加载的,而是分三级按需加载。这个机制叫渐进式披露——在合适的时机给 Agent 合适的信息,既节省上下文窗口(Agent 一次能处理的文字量是有限的),又避免信息过载。
| 层级 | 何时加载 | 大小 | 内容 |
|---|---|---|---|
| 元数据(description) | 始终可见 | ~100 字 | Agent 用来判断要不要触发 |
| 主文件正文(SKILL.md body) | 触发时加载 | ≤3000 字 | Agent 用来理解任务、制定方案 |
| 引用详情(references/) | Agent 判断需要时 | 按需 | 具体的规范、API 定义、流程细节 |
这意味着:如果你把所有知识都塞进 SKILL.md 的正文里,每次触发都会消耗大量上下文窗口。把详细内容拆到 references/ 里,Agent 只在需要时才去读,效率高得多。
一句话:Skill 不是一个大文件,是分层的知识结构。
description:Skill 的门面
description 是整个 Skill 最关键的字段。它决定了 Agent 什么时候调用这个 Skill——写得好,Agent 能精准识别需要它的场景;写得差,要么该触发不触发,要么不该触发乱触发。
好 description 需要回答三个问题:做什么、什么时候用、什么时候不用。
Before / After
烂 description:
description: 处理 PDF 文件
问题:太宽泛。"处理"是读取还是编辑?是提取文本还是转格式?Agent 不知道什么时候该触发这个 Skill。
好 description:
description: >
读取、创建、编辑 PDF 文件,支持文本提取、页面渲染、
格式转换。当用户需要处理 .pdf 文件时使用,包括查看内容、
修改格式、合并拆分、添加水印等场景。不用于纯文本文件
(.txt / .md)的处理。
改进:明确了能力范围(读取、创建、编辑)、触发场景(.pdf 文件)、反面条件(不用于纯文本)。
反面条件的价值
写清楚"什么时候不用"比写清楚"什么时候用"更能减少误触发。
比如一个"API 文档生成"Skill,如果你只写"生成 API 文档",Agent 在用户问"这个 API 怎么调用"时也可能触发——但用户要的是使用说明,不是生成文档。加上"不用于 API 使用教程或接口调试",误触发率会明显下降。
一句话:description 是给 Agent 看的路由规则,不是给人看的产品介绍。 不要写成营销文案,要写成精准的触发条件。
主文件:Agent 读完就能干活
主文件是 Skill 被触发后 Agent 第一个读到的内容。它需要回答一个问题:Agent 读完这份文件后,能不能直接开始干活?
好主文件的结构通常包含四个部分。
1. 使用顺序
告诉 Agent “先看什么、再看什么”。不是所有 references 都需要读——Agent 需要根据当前任务选择性地加载。
## 使用顺序
- 先看 `references/naming-rules.md`,确认命名规范
- 再看 `references/layer-rules.md`,确认分层约束
- 改 API 时才看 `references/api-standards.md`
2. 关键入口
直接列出代码文件的完整路径。Agent 不需要自己去搜索——你告诉它入口在哪,它直接打开。
## 关键入口
- `src/main/java/com/example/controller/UserController.java`
- `src/main/java/com/example/service/UserService.java`
- `src/main/java/com/example/repository/UserRepository.java`
3. 必守约束
不能碰的红线。这部分非常重要,下一节单独展开。
4. 参考资料
指向 references/ 目录下的文件列表。Agent 在需要时按需读取。
Before / After
烂主文件:
# 代码审查 Skill
代码审查(Code Review)是软件开发中的重要环节,目的是
发现代码中的潜在问题,提高代码质量。好的代码审查应该关注
可读性、可维护性、性能和安全性……
常见的代码问题包括:命名不规范、缺少异常处理、硬编码、
重复代码、过度耦合……
问题:Agent 读完知道了"代码审查是什么",但不知道"在这个项目里怎么做"。这些概念性的知识 Agent 本来就知道,不需要你教。
好主文件:
# code-review
## 使用顺序
- 先看 `references/layer-rules.md`,确认分层约束
- 再看 `references/naming-rules.md`,确认命名规范
- 改 API 时才看 `references/api-standards.md`
## 关键入口
- Controller 层:`src/main/java/com/example/controller/`
- Service 层:`src/main/java/com/example/service/`
- Repository 层:`src/main/java/com/example/repository/`
## 必守约束
- Controller 不允许写业务逻辑,只能做参数校验和路由
- Service 层禁止直接调用 Mapper,必须通过 Repository
- 所有接口返回 `Result<T>`,不要裸返 POJO
- 异常统一在 GlobalExceptionHandler 处理,不要在业务代码里 try-catch
## 参考资料
- `references/layer-rules.md`
- `references/naming-rules.md`
- `references/api-standards.md`
改进:Agent 读完就知道去哪、看什么、哪些红线不能碰。不需要你再补充任何背景知识。
一句话:主文件是操作手册,不是百科全书。 Agent 不需要你解释业务概念,它需要你告诉它"改哪里、怎么改、不能改什么"。
约束怎么写:解释 Why,不堆 MUST
约束是 Skill 里最重要的部分。它告诉 Agent 哪些红线不能碰——但怎么写约束,效果差距很大。
堆命令 vs 解释原因
烂约束:
- 必须使用 HNSW 索引
- 绝不能在 Controller 里写业务逻辑
- 所有查询必须分页
Agent 会严格遵守这些命令。但问题是:当场景变化时,它不知道什么时候可以变通。“必须使用 HNSW”——如果数据量很小、写入很频繁呢?IVFFlat 可能更合适。但你写了"必须",Agent 就不敢换。
好约束:
- HNSW 在查询密集场景下延迟更低。RAG 的写入频率远低于
查询频率,所以默认选 HNSW。如果数据量小且写入频繁,
可以考虑 IVFFlat。
- Controller 的职责是接收请求、校验参数、返回响应。
业务逻辑放 Controller 会导致:1)无法复用;2)无法
做单元测试;3)改业务需求时要同时改 Controller 和 Service。
- 不分页的查询在数据量增长后会拖垮数据库。所有列表查询
默认分页,上限 100 条。
改进:Agent 理解了背后的原因,能在场景变化时自己判断。你给它理由,它能推导出 How。
口语化 vs 格式化
约束的语气也很重要。格式化的规范文档读起来像法律条文,Agent 能理解但执行时容易僵化。口语化的表述更容易被正确执行。
格式化:
sessionId 是会话主键语义,历史查询必须做归属校验。
口语化:
sessionId 是会话的身份证。查历史记录时必须确认是这个用户的,
不能让 A 看到 B 的对话。
口语化版本多了一个类比(“身份证”)和一个具体的错误场景(“A 看到 B 的对话”),Agent 更容易理解约束的实际含义和违反后果。
一句话:给 Agent 理由比给它命令更有效。 当你发现自己在写"ALWAYS"和"NEVER"的时候,停下来想想能不能换个方式解释清楚背后的原因。
反模式清单
写 Skill 时常见的五个反模式,每个都有简单的修正方法。
反模式一:description 写成产品介绍。
❌ "这是一个强大的代码审查工具,支持多种语言,提供智能建议。"
✅ "按照项目规范审查代码,检查分层、命名、异常处理。
当用户要求审查代码或检查 PR 时使用。不用于代码格式化。"
description 是路由规则,不是广告词。写触发条件和反面条件。
反模式二:主文件写成文档。
❌ 大段解释"什么是代码审查"、"为什么要做代码审查"
✅ 直接告诉 Agent:看哪个文件、改哪个函数、遵守哪些约束
Agent 本来就知道代码审查是什么。它不知道的是你项目的规范。
反模式三:约束堆 MUST / NEVER。
❌ "必须使用 HNSW 索引"
✅ "HNSW 查询更快,RAG 场景写少读多,所以选 HNSW"
解释 Why,让 Agent 能在场景变化时自己判断。
反模式四:所有知识塞一个文件。
❌ 一个 5000 字的 SKILL.md,所有规范平铺在里面
✅ SKILL.md 2000 字 + 3 个 reference 文件,按需加载
拆 references,让 Agent 只读需要的部分。上下文窗口是公共资源,不要浪费。
反模式五:没有关键入口路径。
❌ "代码在 src/main/java 目录下"
✅ "src/main/java/com/example/controller/UserController.java"
列出具体文件的完整路径。Agent 不需要自己去搜索,你告诉它入口在哪,它直接打开。
总结:好 Skill 的检查清单
写完一个 Skill 后,用这个清单自查:
- description 包含触发条件和反面条件——Agent 能准确判断什么时候用、什么时候不用
- 主文件是操作手册,不是百科全书——Agent 读完能直接干活,不需要你补充背景
- 约束解释了 Why,不只是堆 MUST——Agent 理解原因,能在场景变化时自己判断
- 关键入口有完整路径——Agent 不需要搜索,直接定位到文件
- 详细内容拆到了 references/——Agent 按需加载,不浪费上下文窗口
- 主文件不超过 3000 字——超过就该拆了
- 口语化表述,不写法律条文——Agent 更容易正确执行
好 Skill 是改出来的,不是一次写好的。先写一个能用的版本,然后在真实任务中迭代打磨——看 Agent 哪里卡住了、哪里理解错了、哪里做了无用功,针对性地改进。每改一轮,Skill 就上一个台阶。
更多推荐

所有评论(0)