1. 从“skills”这个热词说起:它到底是什么
最近半年,不管是在技术社区、开发者群聊,还是各种工具链的讨论帖里,“skills”这个词出现的频率高得离谱。很多人第一次看到“skills”这个词,脑子里浮现的是招聘网站上的“技能要求”,但在当下的语境里,它指的是一套完全不同的东西——Agent Skills,也就是给 AI 智能体(AI agents)装载的“技能包”。
你可以把它理解成给一个通用大脑安装的“专业插件”。一个裸的 AI agent,就像一个刚毕业的高材生,脑子好使,但具体到某个垂直场景——比如帮你做前端代码审查、自动生成测试用例、按规范写论文、甚至做分镜脚本——它未必知道你们团队的最佳实践是什么。而 skills 就是把这些最佳实践、操作流程、工具调用方式,打包成一份结构化的说明文件,让 agent 在需要的时候自动加载并执行。
这个概念的爆发,和几个平台的动作直接相关。Google Cloud 在 agent 生态上推了一套技能注册与发现机制,npx 作为 Node 生态里最顺手的包执行器,成了安装和分发 skills 的主流通道。Claude 的 agent skills 体系、Codex 的 skills 扩展、GitHub 上各种开源的 skills 仓库,把这件事从“极客玩具”推向了“日常工具”。
那它到底解决了什么问题?核心就一个:把“提示词工程”从一次性对话,升级成了可复用、可版本管理、可组合的工程资产。以前你写一段复杂的 prompt 让 AI 帮你做代码审查,下次换个会话就得重新写一遍,还得担心模型理解偏差。现在你把这段逻辑写成一个 skill,放进项目目录,agent 每次遇到相关任务就自动读取,行为一致、可追溯、可迭代。
适合谁来了解这个内容?三类人最该关注:一是日常和 AI 编码工具打交道的开发者,二是需要把 AI 能力嵌入到产品流程里的工程师,三是想把自己领域经验“固化”成 AI 可执行资产的知识工作者。哪怕你只是刚听说“skills”这个词,跟着下面的拆解走一遍,也能明白它为什么被叫做“打开新世界”。
2. Agent Skills 的整体设计与核心思路拆解
2.1 为什么是“技能包”而不是“更大的提示词”
很多人第一反应是:我直接把要求写长一点不就行了?为什么要搞个 skills 体系?这里面的设计考量其实很实在。
第一,上下文窗口是有限资源。你把所有场景的指令都塞进系统提示里,agent 每次对话都要背着这一大坨文本跑,既浪费 token,又容易让模型在无关任务上分心。skills 的思路是“按需加载”——平时只保留一个技能索引,agent 判断当前任务需要哪个技能,再去读取对应的详细说明。这就像你电脑里装了几十个软件,但不会同时全部打开,用哪个点哪个。
第二,可维护性。一段写在对话里的提示词,改了就改了,没有版本记录,没法回滚,团队里也没法共享。而 skill 通常是一个目录下的 Markdown 文件加若干辅助脚本,可以进 Git、可以 code review、可以打 tag。这从“手工作坊”变成了“流水线”。
第三,可组合性。一个复杂的任务往往需要多个技能协作。比如“帮我修这个 bug”,可能先触发“代码定位”技能,再触发“测试生成”技能,最后触发“提交信息规范”技能。每个技能各司其职,组合起来完成大任务。这种模块化设计,是单条长提示词很难做到的。
2.2 一个 skill 的典型结构长什么样
虽然不同平台的具体规范有差异,但一个标准的 agent skill 通常包含这几个部分:
- 元信息(metadata):技能名称、描述、触发条件、适用场景。这部分决定了 agent 什么时候会想起你。
- 指令正文(instructions):具体要做什么、按什么步骤做、输出格式是什么。这是技能的核心逻辑。
- 辅助资源(resources):可能包括参考文档、模板文件、示例输入输出。
- 可执行脚本(scripts):有些技能需要调用外部工具,比如跑一个 lint、执行一次测试、调用某个 API,这部分就是胶水代码。
我见过不少人把 skill 写成一个几百行的巨型 Markdown,结果 agent 读起来反而抓不住重点。经验是:一个 skill 只解决一类问题,指令正文控制在能让 agent 一口气读完并理解的长度。如果逻辑太复杂,就拆成多个 skill,用组合的方式解决。
2.3 触发机制:agent 怎么知道该用哪个 skill
这是整个体系里最容易被低估的部分。skill 写得再好,agent 在该用的时候没想起来,等于白写。
常见的触发方式有三种。一种是描述匹配,agent 读取所有技能的描述,根据当前用户请求的语义相似度来决定加载哪个。这种方式灵活但不够精确,描述写得含糊就容易漏触发。另一种是显式调用,用户在对话里直接点名某个技能,比如“用代码审查技能看一下这个文件”。这种方式确定性强,但需要用户知道有哪些技能。还有一种是规则触发,比如检测到文件后缀是.test.ts就自动加载测试相关技能。
实操中,最稳的做法是描述匹配为主,显式调用兜底。描述里要把触发关键词写清楚,比如“当用户提到代码审查、review、检查代码质量时使用本技能”。别指望 agent 能读懂你的言外之意,把触发条件写得直白一点,命中率会高很多。
3. 核心细节解析与实操要点
3.1 技能描述怎么写才能被准确触发
描述是 skill 的“广告语”,它的唯一任务就是让 agent 在正确的时候选中你。我踩过的坑是:一开始把描述写得很“高级”,用了很多抽象词汇,结果 agent 根本不触发。后来改成大白话加关键词堆叠,命中率立刻上来了。
一个可参考的描述模板是这样的:
本技能用于[具体场景]。当用户提到[关键词1]、[关键词2]、[关键词3],或需要[具体动作]时使用。不适用于[排除场景]。
比如一个前端代码审查技能的描述:
本技能用于审查前端代码质量。当用户提到代码审查、review、检查代码、看看这段代码有没有问题,或提交了
.tsx、.vue、.jsx文件需要检查时使用。不适用于后端接口审查和数据库查询优化。
这里的关键是把用户可能说的各种说法都列进去。用户不会按你的规范说话,他可能说“帮我看看这段代码”,也可能说“review 一下”,还可能说“这写得有没有毛病”。描述里覆盖的表达越多,触发越稳。
3.2 指令正文的写法:步骤化、可执行、有边界
指令正文最忌讳写成一篇散文。agent 需要的是清晰的操作序列,不是文学欣赏。我的经验是遵循“三段式”:输入说明、操作步骤、输出规范。
输入说明告诉 agent 这个技能需要什么前置信息。比如“本技能需要用户提供待审查的文件路径,或直接粘贴代码内容”。操作步骤是核心,用有序列表写清楚每一步做什么。输出规范定义结果长什么样,是 Markdown 表格、JSON、还是纯文本。
这里有个细节很多人忽略:要写清楚“什么时候停下来”。比如审查技能里要说明“如果代码文件不存在,直接告知用户并结束,不要尝试猜测文件内容”。不写边界,agent 可能会自由发挥,做出你意想不到的操作。
另外,指令里涉及工具调用的部分,要把工具名称和参数格式写死。比如“使用read_file工具读取文件,参数为path”。别让 agent 自己去猜该用什么工具,猜错了整个流程就断了。
3.3 辅助资源与脚本的组织方式
一个成熟的 skill 目录通常长这样:
skills/ code-review/ SKILL.md # 主指令文件 references/ style-guide.md # 团队代码规范参考 checklist.md # 审查清单 scripts/ run-lint.sh # 调用 lint 工具的脚本 examples/ input.md # 示例输入 output.md # 示例输出这种结构的价值在于关注点分离。主指令文件保持精简,详细参考资料放在references里,agent 需要时才去读。脚本放在scripts里,方便本地调试和复用。示例放在examples里,既是文档也是测试用例。
我特别建议把示例输入输出当成必选项。因为 agent 对“格式”的理解,看一遍示例比读十遍文字描述都管用。你写“输出一个 Markdown 表格”,它可能给你整出五花八门的列名;你给一个示例,它就能照着葫芦画瓢。
3.4 安装与分发:npx 为什么成了主流
skills 的安装分发,目前最顺手的通道是npx。原因很简单:Node 生态覆盖面广,npx不需要全局安装就能执行包,一条命令就能把技能包拉下来放到指定目录。
典型的安装命令形态是:
npx skills-installer add code-review --dir ./.agent/skills这条命令背后做的事情是:从注册源拉取技能包,解压到目标目录,可能还会校验版本和依赖。不同平台的命令参数有差异,但核心逻辑一致。
注意:执行安装命令前,先确认目标目录是否已存在同名技能,避免覆盖掉你本地改过的版本。我一般会先
ls一下目标目录,确认没有冲突再执行。
分发方面,GitHub 仓库是最常见的载体。你可以把团队内部的 skills 放在一个私有仓库里,用 git submodule 或者安装脚本同步到各个项目。公开的 skills 市场也在逐渐成型,但质量参差不齐,建议优先用官方或社区验证过的技能,自己写核心业务相关的。
4. 实操过程与核心环节实现
4.1 从零写一个“提交信息规范”技能
拿一个最实用的场景练手:让 agent 帮你生成符合团队规范的 Git 提交信息。这个技能足够简单,又能体现完整流程。
第一步,创建目录结构:
mkdir -p .agent/skills/commit-message/{references,examples}第二步,写主指令文件.agent/skills/commit-message/SKILL.md:
--- name: commit-message description: 生成符合团队规范的 Git 提交信息。当用户提到提交信息、commit message、写 commit、提交代码时使用。 --- # 提交信息生成技能 ## 输入 用户提供的变更内容描述,或当前暂存区的 diff。 ## 步骤 1. 读取用户提供的变更描述,或使用 `git diff --staged` 获取暂存区变更。 2. 判断变更类型:feat(新功能)、fix(修复)、docs(文档)、refactor(重构)、test(测试)、chore(杂项)。 3. 按格式生成提交信息:`<type>(<scope>): <subject>`。 4. subject 使用中文,不超过 50 个字符,不以句号结尾。 5. 如有必要,在 body 中补充变更原因和影响范围。 ## 输出 仅输出提交信息文本,不要附加解释。第三步,在references/下放一份团队规范文档,在examples/下放两三个输入输出示例。
第四步,测试。在对话里说“帮我写个提交信息,我改了登录页的按钮样式”,看 agent 是否触发技能并输出类似fix(login): 调整登录页按钮样式间距的结果。
这个流程走一遍,你就理解了 skill 的基本骨架。后面复杂的技能,无非是步骤更多、资源更丰富、脚本更复杂。
4.2 技能加载的调试方法
技能写完不触发,是最常见的问题。排查思路按这个顺序来:
先确认技能文件放对了位置。不同 agent 工具扫描的目录不一样,有的找.agent/skills,有的找.claude/skills,有的找项目根目录下的skills。查一下你所用工具的文档,确认路径。
再确认文件格式正确。元信息部分的name和description是必须的,缺了任何一个都可能导致技能被忽略。YAML frontmatter 的缩进和分隔符也要检查,---必须独占一行。
然后检查描述里的触发词。把你实际会说的那句话,和描述里的关键词对一下。如果描述里只写了“代码审查”,而你实际说的是“帮我看看这代码”,那大概率触发不了。把口语化表达补进去。
最后看 agent 的日志。很多工具会输出“加载了哪些技能”“为什么没加载某个技能”的调试信息。打开详细日志,比盲目猜测高效得多。
4.3 多技能协作的编排
单个技能跑通后,真正的威力在于组合。举个例子:一个“修复 bug”的完整流程,可以拆成三个技能——bug-locate(定位问题代码)、fix-generate(生成修复方案)、test-verify(生成验证测试)。
编排方式有两种。一种是链式触发,agent 完成第一个技能后,根据输出内容自动判断需要下一个技能。这种方式对描述的要求很高,要写清楚“本技能完成后,如果涉及测试验证,请加载 test-verify 技能”。另一种是显式编排,用一个总控技能,在步骤里写明“依次调用 A、B、C 技能”。这种方式可控性强,适合流程固定的场景。
我个人的偏好是:核心流程用显式编排,边缘场景用链式触发。核心流程要的是稳定和可预测,边缘场景要的是灵活。
4.4 版本管理与团队协作
skills 进了 Git 之后,就要按代码资产来管理。几个实操建议:
- 每个技能独立目录,目录名和技能
name保持一致。 - 修改技能时,在提交信息里写清楚改了什么、为什么改。
- 重大变更打 tag,方便回滚。
- 团队共享的技能放在独立仓库,用安装脚本同步到各项目,而不是直接复制粘贴。
提示:如果多个项目共用一套技能,建议把技能仓库作为 git submodule 引入,或者写一个
sync-skills.sh脚本统一拉取。手动复制迟早会出现版本不一致的问题。
5. 常见问题与排查技巧实录
5.1 技能不触发的原因速查
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 完全没反应 | 技能目录路径不对 | 查工具文档确认扫描路径 |
| 偶尔触发偶尔不触发 | 描述关键词覆盖不全 | 补充口语化触发词 |
| 触发了但行为不对 | 指令步骤有歧义 | 检查步骤是否可执行、有无边界 |
| 加载了错误的技能 | 多个技能描述重叠 | 明确各技能的适用范围和排除条件 |
| 技能读取失败 | 文件编码或格式问题 | 确认 UTF-8 编码,检查 frontmatter |
5.2 指令被“过度解读”怎么办
agent 有时候会“太聪明”,你让它审查代码,它顺手把代码重构了。这种情况通常是因为指令里没有写清楚操作边界。
解决办法是在指令里加一条“禁止事项”。比如:
本技能仅做审查和问题标注,不直接修改代码。如需修改,必须等待用户明确确认。
把“不做什么”写清楚,和“做什么”同样重要。我现在的习惯是每个技能都带一个“边界”小节,列出禁止操作。
5.3 技能之间的冲突处理
当两个技能的触发条件重叠时,agent 可能随机选一个,或者两个都加载导致指令打架。处理原则是:在描述里显式排除。
比如code-review技能描述里写“不适用于安全审计”,security-audit技能描述里写“不适用于常规代码风格审查”。这样 agent 在判断时就有了明确的区分依据。
如果冲突实在难以用描述区分,就合并成一个技能,在内部用条件分支处理。宁可一个技能内部复杂一点,也不要两个技能互相抢触发。
5.4 性能与上下文占用的平衡
技能多了之后,agent 每次对话都要扫描所有技能描述,这会占用上下文。我的经验是:常用技能控制在 10 个以内,冷门技能按需手动加载。
另外,主指令文件不要写太长。把详细内容放到references里,主文件只保留核心步骤和触发逻辑。agent 读完主文件就能干活,需要细节时再去读参考文档。这样既保证了执行效率,又不丢失信息。
5.5 跨平台兼容的注意事项
不同 agent 工具对 skills 的支持程度不一样。有的支持完整的目录结构和脚本调用,有的只支持单文件 Markdown。如果你需要跨平台复用,建议:
- 核心逻辑写在 Markdown 里,保证纯文本可读。
- 脚本调用做成可选,没有脚本时降级为纯指令执行。
- 元信息字段尽量用通用命名,避免平台特有字段。
- 在 README 里注明各平台的适配情况。
6. 技能生态的扩展方向与个人实践体会
skills 这套东西真正有意思的地方,是它把“个人经验”变成了“可分发资产”。你在这个行业干了十年,脑子里有一套排查线上问题的流程,以前只能靠带徒弟口口相传,现在可以写成一个 skill,让 agent 按你的思路去执行。这是知识沉淀方式的一次升级。
从扩展方向看,几个趋势已经比较明显。一是技能市场会逐渐规范化,出现类似包管理器的版本管理和依赖解析。二是技能组合会催生更复杂的 agent 工作流,单个技能是积木,组合起来能搭出完整的自动化流水线。三是领域技能会越来越垂直,通用技能大家都能写,真正有价值的是懂某个行业、某个团队特定实践的技能。
我自己在实际操作中的体会是:别一上来就追求大而全的技能。先从一个你每天都要重复做的小事开始,把它写成 skill,跑通触发、执行、输出整个链路。哪怕只是“按固定格式整理会议纪要”这种小事,跑通之后你对整套机制的理解会完全不一样。然后再逐步扩展,把相邻的环节也技能化,最后串成流程。
还有一个容易被忽略的点:技能是需要迭代的。第一版写出来能用,但肯定不完美。每次用完之后,花两分钟想想哪里可以改进——是触发词不够准,还是步骤有歧义,还是输出格式不理想。把这些改进记下来,定期更新技能文件。用上一个月,你的技能库就会变成真正顺手的工具集。
最后分享一个小技巧:给每个技能写一个“变更日志”小节,记录每次修改的原因和效果。过段时间回头看,你会感谢自己留下了这些记录。