你有没有遇到过这种情况:写了一个函数,需要补充单元测试。打开 AI 助手发了一句话,AI 给了几个测试用例,但边界条件没有覆盖,Jest 框架也没用,覆盖率没有任何说明。你只好重新发一条:"要用 Jest 框架,要覆盖边界情况,要生成覆盖率报告……"下周同样的事情再发生一次,又要从头解释一遍。
问题不是 AI 不聪明,而是它没有一套稳定的、可复用的能力链来完成这类任务。每次都要重新解释,每次执行结果都不一样,每次都是一次性的。Agent Skills 要解决的,就是这个问题。

什么是 Agent Skills?
Skill 是一个可被 Agent 在运行时发现、理解、调用和组合的能力模块。这句话里有四个动词——发现、理解、调用、组合——缺少任何一个,它都不能叫 Skill。
用一个生活场景来理解:你手机里装了几十个 App。想导航的时候,不需要自己写路线规划算法,直接打开地图 App 就好。App 帮你把"导航这件事"封装好了。Agent Skills 的逻辑完全一样:
- Agent 是那部手机,负责理解你的意图并调度能力
- Skill 是那个 App,给 Agent 增加一项可调用的能力
- 生态 是应用商店,让能力被发现、安装和管理
再讲一个更贴近工程场景的类比:你刚入职一家公司,智商很高但完全不懂业务。老板让你"处理一下这批退款并生成财务报告"。如果没有任何参考资料,你大概率会做错。但如果书架上有一本《退款处理与财务报告生成 SOP》,你只需要按照手册里的步骤,用公司的工具一步步执行,结果就会是对的。这本手册,就是 Skill。
Skill 和 Prompt 的本质区别
很多人第一反应是:Skill 不就是一个很长的 Prompt 吗?不一样,差别很大。从三个维度来看:
| 维度 | Prompt | Skill |
|---|---|---|
| 发现性 | 需要用户主动提供,每次都要粘贴 | Agent 根据任务描述自动匹配,不需要知道名字 |
| 执行性 | 告诉 AI 做什么,执行过程自由发挥 | 内部有结构化 Workflow,每一步怎么做有明确规定 |
| 复用性 | 一次性的,散落在对话历史里 | 独立模块,一次定义到处复用,持续迭代优化 |
用 Prompt 的方式补充单元测试,每次都要写"要用 Jest 框架,要覆盖边界情况,要检查覆盖率……"——容易遗漏,结果不稳定。用 Skill 的方式,只需要说"帮我补充单元测试",Agent 自动加载 test-driven-development Skill,按照里面定义好的流程执行:理解代码 → 设计测试场景 → 编写测试代码 → 验证覆盖率。结果一致,流程稳定。
为什么需要它:三个架构级痛点
从工程架构的角度看,Agent Skills 解决的是三个更深层的问题。
痛点一:巨型提示词灾难
很多团队把所有业务规则、操作流程、边界条件全写进系统提示词。结果是上下文越来越长,几千 Token 变成几万 Token。当提示词超过模型能高质量处理的范围,会出现"注意力丢失(Lost in the Middle)"——中间部分的指令,模型大概率会忽略。越长的 Prompt,指令遵循能力越差。
痛点二:执行能力和专业知识脱节
现在的 Agent 系统通常配了很多工具:能执行代码、能读写文件、能调 API。但拥有工具,不等于知道如何专业地使用工具。给 Agent 一个能执行 SQL 查询的工具,它能查。但它知道针对五百万行的宽表应该怎么写查询吗?知道如何做多步关联验证吗?这些"操作智慧",工具给不了,必须单独注入。
痛点三:企业级可靠性缺失
生产环境有一个基本要求:相同输入,相同输出。但依赖动态生成的提示词,系统行为会有大量随机性。今天跑正确,明天换个措辞就跑歪了。工程化系统需要确定性——把专家的隐性知识,转换成模型可以稳定执行的标准操作流程。
这三个痛点,指向同一个缺失:缺少一种"可插拔的领域专家大脑"机制。Agent Skills 填的就是这个空。
Agent 如何决定调用哪个 Skill?
整个决策流程分五步:

- 识别任务类型:Agent 先判断请求是什么性质的任务——测试相关?文档处理?代码审查?
- 判断是否需要 Skill:不是所有任务都需要 Skill。"Python 是什么语言"这种问题直接回答就好。判断标准是:是否需要结构化的多步骤执行?是否有明确的验证标准?
- 语义匹配:Agent 在所有可用 Skill 的描述(description)里做语义搜索,找到最匹配的那一个
- 注入并执行:把 Skill 的完整内容注入到系统提示词,Agent 按照里面的 Workflow 一步步执行
- 整合输出:Skill 执行完成,结果返回给用户
这背后有一个精妙的设计——渐进式信息披露。系统启动时,只加载所有 Skill 的元数据(名字和描述),每个大约一百个 Token。等到识别到具体任务,才加载完整的 SKILL.md(几千 Token)。如果任务还需要外部参考资料,才在执行过程中按需加载。这种设计让 Agent 能在每一步只获取最小必要信息,从而保证准确性、避免信息过载。
Skill 的代码结构
一个 Skill 目录的标准结构:
my-skill/
├── SKILL.md # 必需:核心文件
├── scripts/ # 可选:可执行脚本
├── references/ # 可选:参考文档
├── assets/ # 可选:静态资产
└── templates/ # 可选:输出模板
只有 SKILL.md 是必须的,其他都是按需添加。
一个典型的 SKILL.md 结构:
---
name: test-driven-development
description: 在实现任何新功能或修复 Bug 时使用,必须在编写实现代码之前调用
---
# 测试驱动开发
## Goal
引导使用 TDD 方法论来实现具体功能。
## Workflow
1. 理解需求:阅读功能描述,识别验收标准
2. 设计测试用例:列举测试场景,按优先级排序
3. 测试先行:用项目指定框架实现测试,确保初始失败
4. 实现代码:编写最小代码使测试通过
5. 重构:在不改变行为的前提下提升代码质量
## Constraints
- 绝对不能在写测试之前写实现代码
- 代码覆盖率最低要求 80%
- 每个测试必须独立、可重复运行
frontmatter 是路由的入口,body 是执行的指南。description 字段尤其关键,它直接决定了这个 Skill 会不会在合适的时机被找到。
根据复杂度不同,Skill 分三种类型:
- 简单型:只有一个 SKILL.md,3-5 步线性流程,比如生成 Git 提交信息
- 多步骤工作流型:仍然只有 SKILL.md,但 Workflow 有分支逻辑,5-10 步,比如 TDD 开发流程
- 资源依赖型:SKILL.md 加上外部资源目录,适合需要参考文档、执行脚本、使用模板的复杂任务
代码落地:两种框架的实现
以"天气查询 Skill"为例,分别用 OpenAI SDK 和 LangChain 两套框架落地。
Skill 定义:
---
name: get-weather
description: 获取指定城市的天气信息。在用户询问天气、气温或出行建议时使用。
---
# 获取天气信息
## Goal
根据用户询问,提供准确的天气信息。
## Workflow
1. 从用户请求中提取城市名称
2. 获取该城市当前天气数据(温度、天气状况、湿度、风速)
3. 以自然对话口吻返回结果
4. 如需对比多城市,分别获取后整合展示
## Constraints
- 默认使用摄氏度
- 只提供当前天气,不做长期预测
- 空气质量差时主动提醒
两套框架共用同一套三层架构:
SkillRegistry(加载所有 Skill)
↓
SkillRouter(根据用户输入选择 Skill)
↓
SkillExecutor(注入 Skill 文档并执行)
OpenAI SDK 版本的核心代码:
class SkillRegistry:
"""扫描目录,加载所有 Skill 文件"""
def _parse_skill_file(self, file_path):
# 提取 YAML frontmatter
# 解析 name 和 description
class SkillRouter:
"""调用 LLM,根据用户输入选择合适的 Skill"""
def route(self, user_input):
# 用 LLM 做语义匹配
class SkillExecutor:
"""加载完整 Skill 文档,注入系统提示词后执行"""
def execute(self, skill_name, user_input):
# 注入 SKILL.md 内容,按 Workflow 执行
LangChain 版本在架构上完全一致,换成 LCEL(LangChain Expression Language)的写法,用 | 操作符串联各组件。如果你的项目里已经在用 LangChain 的生态,直接接入就好;如果是新项目,两种都可以,OpenAI SDK 版本更轻量。
怎么选:Skills、Function Calling、MCP 的边界
先理清各自的定位:
- Function Calling:代码级函数调用。定义函数签名,AI 决定什么时候调用它,调用后你处理结果。执行是确定的,代码写什么就跑什么。
- MCP(Model Context Protocol):协议级能力接入。标准化的接口协议,让 AI 能接入各种外部系统(数据库、文件系统、第三方服务)。解决"如何连接"的问题。
- Agent Skills:语义级能力模块。用 Markdown 描述"做什么、怎么做、不能做什么",AI 按照描述执行。解决"如何专业地完成"的问题。
判断用哪个,看这几个维度:
| 维度 | 推荐方案 |
|---|---|
| 确定性要求高(金融交易、数据库写入) | Function Calling |
| 快速迭代阶段(需求每周变) | Agent Skills(改 Markdown 比改代码快) |
| 非技术人员定义工作流 | Agent Skills(描述清楚流程就能用) |
| 跨平台复用 | MCP(标准化协议价值体现) |
实际项目里,这三个通常是组合使用的:高层工作流用 Skills,底层精确操作用 Function Calling,跨系统集成用 MCP。不是非此即彼,是各司其职。
生产环境最容易踩的四个坑
坑一:路由瘫痪——Skills 互相打架
当 Skill 库积累到几十个,如果各个 Skill 的 description 语义重叠,Agent 就会开始"选择困难"。用户说"处理这个文件",Agent 在 file-processor、document-analyzer、data-extractor 之间反复横跳。
解法:每个 Skill 的 description 要有清晰的边界,而且要加"负向触发器"——明确写出"本 Skill 不处理 X 类任务"。
坑二:上下文隐性膨胀
Skill 里定义了"读取 references/ 目录下的文档",但没有限制读取量。执行时 Agent 把整个目录的内容全加载进来,几万 Token 一下就打满了。
解法:在 SKILL.md 里明确限制:"每次最多读取 5000 Token,使用 grep 过滤后再读取,不要全量加载。"
坑三:description 写成了说明书
新手最常见的错误:把 description 写得很详细,一段话解释背景、功能、使用场景、注意事项。结果适得其反——description 太长太复杂,路由器反而判断不准了。
解法:description 要短、精、关键词密度高。一两句话,清晰说明触发时机和核心能力。
坑四:Skill 过了保质期
Skill 里引用了某个外部接口的格式,接口升级了,Skill 没更新。或者团队的代码规范变了,Skill 里的标准没跟上。这种"静默降级"很隐蔽——系统不报错,但结果越来越偏。
解法:建立定期审计机制。每隔一段时间,人工检查 Skill 的 Workflow 和 Constraints 是否还与实际情况对齐。
总结
Agent Skills 不是什么革命性的新概念。它做的事情很朴素:把专家的知识和流程,结构化地写下来,让 AI 能稳定地照着执行。就像公司有了流程手册,新人上手更快,老员工犯错更少,团队整体输出更稳定。
Prompt 是你告诉 AI"去做这件事"。Skill 是你提前准备好了"这件事怎么做"。区别就在这里。