---
date: 2025-12-22
---
# `Skill`:让 Agent 变得可复用、可控、可演进
## 前言:为什么要把“提示词经验”升级成 `Skill`
如果你只是偶尔问问 ChatGPT,一个“写得不错的 `Prompt`”已经足够。
但只要你开始用 `Agent` 做事(写代码、跑脚本、查资料、写文档、对接系统),很快会撞上三个工程层面的老问题:
- **不稳定**:同一个任务,今天能做对,明天换点上下文就跑偏。
- **不可控**:你知道它“可能会做”,但你说不清它“应该怎么做”,更别提调试。
- **难复用**:每次都要靠“临场发挥”去改提示词,经验沉淀不下来。
我倾向于把这类问题归因到一句话:**你把一段“工作方法”塞进了对话上下文,但它并不是一个“可调用的能力单元”。**
而 `Skill` 的目标很朴素:把“会做”变成“可调用”,把“经验”变成“资产”。
> 相关链接:
> - `Agent` 的工程视角定义:[`AI/Agent 原理.md`](Agent%20原理.md)
## 一、`Skill` 是什么
### 1.1 一句话定义:`Skill` 解决了什么问题
**`Skill` 是对某类任务的“稳定做法”的封装**:它把你希望 `Agent` 遵循的步骤、校验点、输入输出规范、以及可用工具边界,做成一个可以复用的能力单元。
你可以把它理解成:
- 在软件工程里,它更像一个“模块 / 函数”,而不是“临时写在控制台里的命令”;
- 在团队协作里,它更像一份“可执行的 `SOP`”,而不是“某个人脑子里的诀窍”。
### 1.2 `Skill` 的组成:说明、契约、边界、失败处理
一个最小可用的 `Skill`,建议至少回答四个问题:
- **它能做什么**:适用场景与目标(以及 `Non-Goals`:明确“不做什么”)。
- **怎么用它**:输入是什么、输出长什么样(可被下游消费)。
- **它怎么做**:步骤、关键决策点、每步的校验标准。
- **它在什么边界里做**:能调用哪些工具,能读写哪些资源,遇到失败怎么处理(重试/降级/请求用户补充信息)。
这里面最“反直觉”的,是 **输入输出契约**。
很多人写提示词只关注“你要做什么”,但忽略“你要输出什么结构”。结果就是:看起来像在执行,但产物不可用、不可组合、不可验证。
### 1.3 一张图看懂:`Skill` 的“可验收执行链”
如果只看文字,`Skill` 很容易被误解成“更长的 `Prompt`”。其实它更像一条**可中断、可回退、可验收**的执行链:
```mermaid
flowchart TB
A[Inputs 输入
必填/选填] --> B[Steps 执行步骤
可拆分/可复用]
B --> C[Checks 校验点
格式/范围/关键字段]
C -->|通过| D[Outputs 产物
结构固定/可被下游消费]
C -->|失败| E[Failure Modes 失败处理
补信息/重试/降级/停止]
E --> B
```
### 1.4 `Skill` 的颗粒度:什么时候拆,什么时候合
我的经验是:把 `Skill` 的颗粒度控制在“**一次对话里可以讲清楚、一次执行里可以验收**”。
一个粗糙但好用的判断方式:
- **该拆的信号**:
- 一个 `Skill` 里出现了多种完全不同的决策路径;
- 产物形态差异很大(时而写报告、时而写代码、时而查数据);
- 你发现自己想给它加越来越多的“如果……就……否则……”。
- **该合的信号**:
- 拆开后每个 `Skill` 都依赖前一个 `Skill` 的半成品;
- 你需要用户频繁“手动串联”多个 `Skill` 才能完成一个最小任务。
---
## 二、为什么需要 `Skill`
### 2.1 复用:把个人经验变成团队资产
在没有 `Skill` 的世界里,经验往往以三种形式存在:
- 某个“写得不错”的聊天记录;
- 某个人脑子里的“手感”;
- 一个越写越长、越改越乱的系统提示词。
`Skill` 的价值在于:**它让经验具备可复制性**。
| 维度 | 普通 Prompt | Skill (能力单元) |
| :--- | :--- | :--- |
| **主要载体** | 一段聊天记录 / 临时指令 | 独立文件 (.md / .mdc) |
| **复用性** | 依赖复制粘贴 | 可被路由、可被导入 |
| **关注点** | "帮我把这个做了" | "按这个标准流程做" |
| **稳定性** | 随机性强,依赖模型心情 | 有校验点,输出结构固定 |
| **维护方式** | 每次重写 | 版本管理 (Git) |
一旦你把能力写成 `Skill`,它就可以:
- 被别的 `Agent` 复用;
- 被同一个 `Agent` 在不同项目复用;
- 被团队评审、迭代、版本化。
### 2.2 可控:让结果稳定,过程可解释
“可控”不是指让模型不犯错,而是指:
- 你能明确它“应该按哪些步骤做”;
- 你能定位它“在哪一步偏了”;
- 你能以最小代价修复(改 `Skill` 的某个步骤/校验点),而不是重写整段提示词。
这其实就是把 `Agent` 从“玄学”拉回“工程”的核心手段。
### 2.3 降低上下文膨胀:按需注入,而不是永久塞进系统提示词
当你把所有经验都塞进系统提示词时,你会得到一个“看起来无所不能”的 `Agent`,但代价是:
- 上下文越来越大,模型注意力被稀释;
- 规则之间开始互相打架;
- 修改任何一处都可能引入连锁反应。
`Skill` 的思路是:**默认轻装上阵,需要某项能力时再加载该能力的说明与约束**。
### 2.4 团队协作视角:写 `Skill` 像写 `SOP`,用 `Skill` 像调用函数
当你把 `Skill` 当成团队资产后,很多工程问题会自然出现一套“正确做法”:
- 需要 review(否则每个人都会写出一套不兼容的输出格式);
- 需要版本号(否则你不知道线上用的是哪一版);
- 需要验收标准(否则你只是在写“更长的文字”)。
---
## 三、`Skill` 和 `MCP` 的区别
一句话概括:
- **`Skill` 解决“怎么做”**:方法、流程、校验、产物。
- **`MCP` 解决“能做什么”**:把外部工具/资源用标准协议接进来,让 `Agent` 可调用。
你可以把它理解成两层:
- **工具层(`MCP`)**:提供可调用的 `Tool` / 可读取的 `Resource` / 可复用的 `Prompt`。
- **方法层(`Skill`)**:把工具按某种可靠流程组织起来,形成稳定产物。
```mermaid
graph TD
User[用户 User] -->|自然语言指令| Agent
subgraph Agent Runtime
SystemPrompt[System Prompt
(人设、基础约束)]
Router[决策/路由层]
end
Agent --> SystemPrompt
SystemPrompt --> Router
subgraph Skill Layer [Skill 层 (怎么做)]
S_Write[写作 Skill
(SOP、校验、格式)]
S_Code[代码 Skill
(重构、测试、Review)]
S_Search[搜索 Skill
(关键词优化、总结)]
end
Router -->|匹配场景| S_Write
Router -->|匹配场景| S_Code
subgraph MCP Layer [MCP 工具层 (能做什么)]
T_File[文件读写 Tool]
T_DB[数据库 Tool]
T_Web[联网搜索 Tool]
end
S_Write -->|调用| T_File
S_Code -->|调用| T_File
S_Search -->|调用| T_Web
```
> 相关链接:
> - 如果你想完整理解 `MCP`:[`AI/MCP 原理及 Java 开发指南.md`](MCP%20原理及%20Java%20开发指南.md)
### 3.1 典型误区:把 `Skill` 当 `Tool`,或把 `MCP` 当工作流引擎
常见的两个走偏方式:
- **把 `Skill` 当 `Tool`**:把 `Skill` 写成“调用某个接口的说明书”,最后得到的是一个脆弱的、只在某个项目里能跑通的流程。
- **把 `MCP` 当工作流引擎**:以为“把工具接进来”就等于“事情能做好”,但缺少 `Skill` 的校验点与产物标准,最后输出仍然不可控。
真正的组合方式通常是:**`Skill` 调用 `MCP Tool`**。
### 3.2 一个直观类比:`Skill` 是“代码结构”,`MCP` 是“依赖注入”
如果把 `Agent` 当作一个软件系统:
- `MCP` 更像依赖注入:我把数据库、文件系统、内网 API 这些能力“接进来”;
- `Skill` 更像业务代码:我规定“什么时候查库”“什么时候读文件”“什么时候让用户确认”,并把产物结构固定下来。
再用一张图表达“谁依赖谁”会更直观:
```mermaid
flowchart TB
subgraph L2[方法层:`Skill`]
S1[Workflow / SOP
步骤编排]
S2[Contracts
输入输出契约]
S3[Checks
验收与中断点]
S2 --> S1
S3 --> S1
end
subgraph L1[工具层:`MCP`]
T1[Tool
File/DB/API]
T2[Resource
Docs/KB]
T3[Prompt
模板/片段]
end
S1 --> T1
S1 --> T2
S1 --> T3
```
---
## 四、如何设计一个“好用”的 `Skill`
这一节更偏方法论:你不需要任何框架,也不需要先写代码,只要把它当成“写给未来自己的 `SOP`”。
### 4.1 先写 `Non-Goals`:不做什么,比做什么更重要
一个 `Skill` 最容易失控的地方是“贪多”。
建议在开头直接写清楚:
- 这个 `Skill` **不处理**哪些情况;
- 这些情况应该交给哪个 `Skill` / 交给用户补充什么信息;
- 失败时允许的降级方案是什么。
这会显著减少 `Agent` 的“自作主张”。
### 4.2 再写校验点:每一步都可验证、可中断、可回退
好 `Skill` 的关键不是“步骤多”,而是“每步可验收”:
- **可验证**:每一步输出都能用简单规则检查(格式、范围、关键字段齐全)。
- **可中断**:发现不满足前置条件时,立即停下来问用户,而不是硬编。
- **可回退**:如果某一步失败,有明确的替代路径(例如改用另一种数据源,或先输出 `TODO` 列表)。
这类“校验点”越明确,`Agent` 越像工程系统,而不是聊天机器人。
把 4.1~4.2 合起来,其实就是一个“从目标到验收”的设计流:
```mermaid
flowchart LR
A[Goal 目标] --> B[Non-Goals 不做什么]
B --> C[Inputs/Outputs 输入输出契约]
C --> D[Steps 步骤编排]
D --> E[Checks 校验点]
E --> F[Failure Modes 失败处理]
F --> G[Examples & Version 示例与版本化]
```
### 4.3 最后写触发条件:什么时候该用这个 `Skill`
一个 `Skill` 如果没有“触发条件”,最终会变成“每次都想用,但每次都要解释一遍”。
建议写成三段:
- **适用场景**:满足哪些条件时,优先使用它。
- **不适用场景**:哪些情况不要用。
- **快速自检**:用户只要回答 2~3 个问题,你就能判断该不该启用。
### 4.4 一个可复用的 `Skill` 模板(推荐)
你可以把下面这个模板当成写 `Skill` 的骨架(放在 `SKILL.md` 里也好,放在内部文档里也好):
```text
Skill 名称:
目标(Goal):
不做什么(Non-Goals):
输入(Inputs):
- 必填:
- 选填:
输出(Outputs):
- 产物格式:
- 验收标准:
工具边界(Tooling Boundaries):
- 允许调用:
- 禁止调用:
- 权限与安全要求:
执行步骤(Steps):
1)
2)
3)
校验点(Checks):
- Step 1 校验:
- Step 2 校验:
失败处理(Failure Modes):
- 缺信息:
- 工具失败:
- 结果不可信:
```
### 4.5 实战案例:Java 代码审查 Skill
这是一个真实的 Skill 定义示例,你可以直接存为 `.cursor/rules/java-review.mdc`:
```markdown
---
description: 当用户要求 Review Java 代码时触发
globs: *.java
---
# Java Code Review Skill
## 目标
找出代码中的 NPE 风险、并发问题及不符合阿里巴巴规范的命名。
## Non-Goals
- 不负责重写整个架构
- 不关注缩进和空格(交给 Formatter)
## 审查步骤 (Steps)
1. **安全性检查**:扫描所有入参,检查是否有 `@Nullable` 或未判空的使用。
2. **性能检查**:检查循环中是否有数据库调用或 RPC。
3. **规范检查**:对比变量命名是否符合驼峰,常量是否大写。
## 校验点 (Checkpoints)
- [ ] 每一个指出的问题必须引用具体行号。
- [ ] 每一个修改建议必须提供 `Before` 和 `After` 代码对比。
## 失败处理
- 如果代码依赖缺失导致无法判断类型,请输出 "⚠️ 缺少上下文,假设为..."
```
---
## 五、在 `Claude Code` 和 `Cursor` 上落地 `Skill`
这一节我会尽量给你“可操作”的路径,但不同产品对 `Skill` 的实现细节会随版本变化:**文件放哪里、如何 reload,以你当前环境为准**。
### 5.1 `Claude Code`:把 `Skill` 当成“可发现的能力包”
概念上,你可以把 `Claude Code` 的 `Skill` 当成一个目录(一个能力包):
- 目录名:`skill` 的名字(也是它被发现/调用时的标识)
- `SKILL.md`:这项能力的说明与执行规范(建议按上面的模板写)
- 其他文件:脚本、示例输入输出、测试用例(可选)
一个推荐的组织方式是把它们放进项目内的 `skills/` 目录,形如:
```text
your-repo/
skills/
blog-writer/
SKILL.md
examples/
input.md
output.md
```
当你需要启用某个 `Skill` 时,核心不是“神秘指令”,而是两件事:
- **让 `Agent` 知道这个 `Skill` 存在**(可发现)
- **让 `Agent` 按 `SKILL.md` 的契约输出**(可验收)
如果你用的是 `Claude Code` 自带的 `Skill` 管理/重载能力(有的版本会提供类似 `/reload` 的命令),建议把它当成“开发态便利功能”,而不是系统设计的前提:真正重要的是目录结构与契约文本本身。
### 5.2 `Cursor`:用 `.cursor/rules/*.mdc` 组织“类 `Skill`”
`Cursor` 当前更偏“`Rules` 驱动”:你把一套稳定做法写进 `.cursor/rules/*.mdc`,它就能在对话/改代码时持续遵循这套约束。
你仓库里已经有一个规则文件:`.cursor/rules/yano-blog-writer.mdc`,它本质上就是一个非常标准的“写作类 `Skill`”:
- **明确流程**:先大纲,再正文(强制交互确认)
- **明确风格**:中文与 English 空格、术语用反引号
- **明确自检清单**:输出前过一遍
如果你要在 `Cursor` 里继续扩展 `Skill`,我建议的做法是:
- **一个 `Skill` 一个 `.mdc` 文件**:命名体现用途(例如 `agent-skill-design.mdc`)
- **默认 `alwaysApply: false`**:避免所有对话都被“规则污染”
- **需要长期生效时再开启**:把 `alwaysApply` 改为 `true`,或把关键规则复制到当前任务上下文里
### 5.3 与 `MCP` 的配合:用 `.cursor/mcp.json` 把工具接入作为能力底座
如果你的 `Skill` 需要“调用外部能力”(读文件、查数据库、访问内网 API),那就让 `MCP` 来解决“接入工具”。示例:
```json
{
"mcpServers": {
"local-dev": {
"command": "java",
"args": ["-jar", "mcp-server.jar"],
"env": {
"WORKSPACE_ROOT": "${workspaceFolder}"
}
}
}
}
```
我更推荐的组合方式是:
- `Skill`(规则/流程)写在 `.cursor/rules/*.mdc` 或 `skills/*/SKILL.md`
- 能力(工具/资源)通过 `.cursor/mcp.json` 接入
- **让 `Skill` 去“调用工具并验收产物”**,而不是让工具去“替你决定做法”
### 5.4 `Skill` 的测试与调试
`Skill` 既然是工程化的,就必须可测试。建议的测试策略:
- **黄金数据集**:保留一组 Input 和 期望的 Output。
- **回归测试**:当你修改 Skill 的步骤时,用上面的 Input 跑一遍,看 Output 格式是否崩坏。
- **调试技巧**:在 Skill 中显式要求 Agent 输出 `` 标签,打印它执行每一步时的决策过程。
---
## 六、结尾:`Skill` 的本质,是把“工作方法”产品化
我对 `Skill` 的最短总结是:
> **把“工作方法”写成可复用的能力单元,让 `Agent` 从“会聊”走向“会做”,从“能做”走向“稳定地做”。**
如果你已经在写 `Prompt`、写 `Rules`、接 `MCP` 工具,那你其实已经走在 `Skill` 的路上了:接下来只差把它们“模块化、契约化、可验收化”。
> 相关链接:
> - `Agent` 基础:[`AI/Agent 原理.md`](Agent%20原理.md)
> - `MCP` 基础:[`AI/MCP 原理及 Java 开发指南.md`](MCP%20原理及%20Java%20开发指南.md)
# 我的公众号
我的博客地址:[博客主页](https://yano-nankai.notion.site/yano-nankai/Yano-Space-ff42bde7acd1467eb3ae63dc0d4a9f8c)。
coding 笔记、读书笔记、点滴记录,以后的文章也会同步到公众号(Coding Insight)中,大家关注 `^_^`