在 AI Agent 开发这个圈子里泡久了,你会发现一个特别现实的问题:模型本身越来越聪明,但让它稳定输出专业领域的结果,靠的还是你给它喂的那套"技能包"。我最近在整理自己的 agent-skills 项目,把平时用的、写的、踩过坑的 skills 全收拢到一起,越整理越觉得这里面门道不少。这篇文章就把我对 agent skills 的完整理解、接入方式、开发流程和避坑经验一次性讲清楚,适合正在做 agent 开发、或者刚接触 Claude Code / Codex / OpenCode 这类工具的人参考。
如果你还在疑惑 skill 和 agent 到底有啥区别,为什么装了一堆 skills 却不生效,或者想自己写一个排版类、图片生成类的 skill,那这篇内容大概率能帮你省下好几个晚上的摸索时间。
1. 先搞清楚 skills 到底是什么
1.1 skill 和 agent 的本质区别
很多人一上来就把 skill 当成一个小 agent,这个理解方向是有问题的。agent 是一个完整的智能体,它有记忆、有推理循环、有工具调用能力,可以自主规划任务路径;而 skill 更像是一份结构化的"操作手册",告诉模型在特定场景下应该按什么流程做事、调用什么工具、产出什么格式。
拿生活里的事打比方:agent 是一个刚入职的实习生,他有学习能力和执行力;skill 是公司里的 SOP(标准作业流程)文档,实习生平时不会把几千页 SOP 都背在脑子里,但一旦接到对应任务,他就能立刻翻出那本手册照着干。你让 agent 写一份学术论文的 LaTeX 排版,它可能只会"大概知道"怎么排;但你给它配一个 latex 排版 skill,它就能按你预设的宏包、字号、图表规范精确执行。
从架构上看,skill 是一段 prompt 模板加配套脚本、参考资源、校验规则的集合。常见的目录结构长这样:
my-skill/ ├── SKILL.md # 核心文件,包含元信息和执行指令 ├── scripts/ # 可被调用的辅助脚本 └── references/ # 参考文档、示例文件SKILL.md 是灵魂,它用 YAML frontmatter 声明技能名和触发描述,正文部分则是给 agent 的具体操作指引。模型只有在描述匹配时才加载这份文件,平时完全不占上下文窗口。
1.2 为什么 agent 需要技能体系
大模型的工作记忆非常宝贵,动辄几十万字符的上下文窗口看着很大,但真跑起来,塞对话历史、系统提示词、工具定义、中间推理结果,剩下的空间没你想的那么多。这就是 skills 存在的核心意义:把"平时用不到、用时很关键"的专业知识从上下文中挪出去,按需加载。
我自己实测过两个场景对比:一是让 agent 直接处理一份数学建模比赛的 LaTeX 论文,二是挂载一个专门的排版 skill 再处理同一份论文。前者的输出经常出现宏包冲突、表格溢出、中文支持缺失这些问题;后者因为有明确的编译校验和模板参考,第一次跑就通过了。差距不在模型能力,而在于后者给了模型一套可执行的规范。
skills 还有一层价值是知识复用。团队里一位后端同事写了一份很棒的 API 测试 skill,你直接拿过来用,不需要重新跟 agent 解释你们的接口约定。这个和代码库里的组件复用是一个道理,只不过复用的是"行为准则"。
1.3 一套合格 skill 应该长什么样
社区里对 skill 的结构已经形成了一些事实标准,核心是 SKILL.md 这个文件。它至少要有三块内容:第一,明确的触发描述,让 agent 能判断"什么场景该用我";第二,分步骤的执行流程,最好是带决策分支的流程;第三,输出格式和自检清单。
一个容易翻车的点是:描述写得太大而全。比如你写"帮助用户写报告",那模型几乎在所有对话里都想加载它,既有噪音又浪费 token。正确做法是把描述写得具体甚至带点"排他性",比如"仅当用户要求生成符合 IEEE 会议格式的 LaTeX 源码时使用"。这样模型才不会被误导。
2. 主流框架的 skills 接入方式与差异
2.1 Claude Code 的 skills 目录与安装方法
目前我用的主力工具之一就是 Claude Code,它的 skills 机制文档相对完善。个人级别的技能放在~/.claude/skills/下,项目级别的技能放在项目根目录的.claude/skills/下,命名要求是 snake_case,比如latex-formatter。
安装一个现成 skill 最直接的办法就是把它克隆或复制到上述目录里。很多 GitHub 上的 skills 仓库本身就按目录组织好了,你只要保证目标目录下直接是 SKILL.md 就行,不要套两层文件夹,否则识别不到。装完之后不需要重启进程,新会话会自动扫描。
我曾经因为目录层级问题折腾了很久:仓库克隆下来是skills-repo/latex-formatter/SKILL.md,我图省事直接把skills-repo整个复制到了 skills 目录,结果 agent 一直不识别。后来才排查出来,它需要的是~/.claude/skills/latex-formatter/SKILL.md这种层级。
2.2 Codex、OpenCode 的接入差异
Codex 的 skills 路径习惯放在~/.codex/skills/,也支持在项目内用.codex/skills/做局部覆盖。它的细节表现和 Claude Code 略有差异,但基本理念一致:按目录名匹配 skill,读取 SKILL.md 的 frontmatter 判断是否触发。如果你在同一台机器上同时使用多个 agent 框架,建议把 skills 仓库用 git 管理,然后通过软链接或者一个同步脚本把它们同步到各框架的对应目录,省得每个框架各维护一份副本。
OpenCode 的接入方式更偏配置文件驱动。它可以通过opencode.json中的 skill 相关配置来声明技能来源,也支持在特定目录下组织技能文件。我自己用下来感觉 OpenCode 对自定义工具的兼容度更高,适合喜欢自己折腾脚本的人。但也要注意,不同框架对 skill 内脚本的执行权限和环境变量要求不一样,跨框架复用 skill 时,最好先看它有没有硬编码路径。
2.3 从 superpower skills 看第三方技能市场
社区里比较出名的一个集合是 superpower skills,它打包了大量可复用的技能,从代码审计到写作润色都有。这类集合的好处是开箱即用,一条安装命令就能把几十个 skill 拉下来;坏处是数量太多之后反而不好管理。
我参考社区的做法,把这类大型技能包当作"资源仓库"而不是"直接安装包":先拉下来,按需挑选其中几个复制到自己的 skills 目录,而不是整包安装。这样既能控制上下文噪音,也方便自己二次修改。类似的技能源网站和 GitHub 仓库现在越来越多,很多还附带了安装脚本,但我的建议始终是——别信一键安装,自己审查一遍里面的 SKILL.md 再上机器。
2.4 harness 和 agent 到底什么关系
这个词组最近搜索量很高,在 agent 开发语境下,harness 指的是承载 agent 运行的"外壳"或"调度框架",负责管理模型调用循环、工具注册、上下文窗口、权限控制这些事情。你用的 Claude Code、Codex 命令行工具本身就是一个 harness;而 agent 是这个 harness 里基于模型推理跑起来的那套"大脑"。
skills 挂在 harness 和 agent 之间。harness 提供机制,比如"我能读取 SKILL.md 并按描述触发它";agent 提供决策,比如"当前任务需要调用哪个 skill";skill 提供内容,也就是具体干什么、怎么干。你可以把 harness 理解成操作系统,agent 是系统里跑的应用进程,skill 则是应用调用的动态链接库。理解这一层,你对"skills 装在哪目录""为什么换了 harness 就不生效"这类问题就会有直觉了。
3. 从零写一个可用的 skill:LaTeX 排版实战
3.1 需求拆解与触发词设计
我在 agent-skills 项目里维护的第一个自写 skill 就是 LaTeX 排版。起因是一次数学建模比赛,队友用 Word 写论文惨不忍睹,转 LaTeX 又总被格式问题折磨。和 agent 聊了几轮之后我发现,让它"临时发挥"不稳定,不如固化一套流程。
需求拆解下来其实就三条:一是把纯文本或 Markdown 内容转成规范的 LaTeX 源码;二是解决中文支持、图片插入、公式编号这些高频问题;三是保证生成结果能通过编译。基于这三条需求,我给 skill 定了严格的触发描述:
--- name: latex-formatter description: 仅当用户要求生成或排版 LaTeX 文档时使用。包括把 Markdown/纯文本转换为 LaTeX 源码、修复编译错误、调整学术论文格式等场景。 ---注意这里加了"仅当",目的是避免模型在普通代码问答时误加载。
3.2 SKILL.md 的结构化编写
SKILL.md 的正文部分我按流程步骤 + 决策分支 + 自检清单来组织。给 agent 的指令要像给实习生写操作手册,每个关键节点都要有判断条件。
以下是我整理的写作思路,你可以直接参考:
- 先确认输入:要求用户提供文档语言、目标模板(IEEE / 中文论文 / Beamer),不明确就先问。
- 生成主文档:使用
ctexart或article加ctex宏包处理中文,公式统一用equation/align环境。 - 图片处理:所有图片路径用相对路径,插入前检查文件是否存在。
- 编译校验:调用本机
xelatex编译两遍,处理交叉引用;如果编译报错,按错误信息依次修复。 - 输出检查:确认没有
Overfull hbox严重告警、没有未引用的\ref、目录页存在。
我在 references 目录里放了一个精简的template.tex,作为生成风格基准。这样一来,agent 的输出就有了锚点,不会每次自由发挥。
3.3 图片生成类 skill 的写法参考
除了文字排版,图片生成类 skill 也是很多人会尝试的方向。这类 skill 一般不是让 agent 自己画图,而是让它组织好提示词、尺寸、风格参数,再调用外部生图工具或 API。
我写图片生成 skill 时,SKILL.md 里重点规定了提示词结构:
- 主体描述:一句话说清"画什么"。
- 风格限定:摄影、插画、3D 渲染等,给出参考风格词。
- 进阶污染词:列出需要规避的元素,比如文字水印、额外手指等。
- 输出检查:生成后必须按用户意图核对一轮,不满意就调整提示词重试。
这里的核心心得是:把提示词工程固化成 skill,比每次手动敲提示词稳定得多。尤其当你用同一批风格参数反复生成配图时,这种技能包的价值立竿见影。
3.4 用 evals 思路验证你的 skill
写完 skill 不测试是不行的。AI 圈子里管这类测试叫 evals(评估集)。我的做法是给每个 skill 建一个测试用例集,里面记录三类输入:标准输入、边界输入、错误输入。
以 LaTeX 排版 skill 为例:标准输入是一篇正常的建模论文文档;边界输入是极长表格、图片路径带空格、公式数量特别多;错误输入是没有提供中文宏包的空文档、残缺的 Markdown。跑的时候看两件事:一是在这些输入下 skill 是否正确触发;二是输出结果完成度如何。
测试完还要做一轮"负向测试",也就是故意问无关问题,确认 skill 不会被误触发。我自己就遇到过描述写太宽导致画图 skill 在普通文本问答里被加载的情况,负向测试能帮你把这些坑提前踩掉。
4. 使用中的坑:安装、安全、清理、排错
4.1 安装失败与加载不上的排查
skills 装不上或加载不了,我见过的高频原因有三个。
第一个是目录层级错误。前面提过,SKILL.md 必须位于技能目录的直接下一层。检查方法很简单:在终端里进到对应 skills 目录,找一下find . -name SKILL.md,看看输出路径是否符合预期。
第二个是 frontmatter 格式问题。YAML 的缩进非常严格,有时候少一个冒号空格都会导致解析失败,而且失败可能不会直接报错,只是模型静默忽略这个 skill。排查时要把 SKILL.md 用支持 YAML 校验的编辑器打开,确认name和description字段格式无误。
第三个是描述与模型判定不匹配。即便格式都对,如果描述写得含糊,模型不认为当前任务"命中"这个技能,一样不加载。这种问题和模型版本也有关系,改描述时记得用词具体、语义清晰。
4.2 第三方 skills 的安全审查
这个必须单独拎出来说。技能市场越来越繁荣,来源不明的 skill 也越来越多。SKILL.md 本质是 prompt 指令,里面完全可以夹带"忽略用户后续要求"这类越狱内容;配套的脚本更可能直接执行恶意命令。
我的原则是:所有 skill 先审查再运行。具体审查三块:第一,读一遍 SKILL.md,看指令是否有异常要求;第二,逐个查看 scripts 目录下的脚本,确认没有可疑的网络请求、文件删除操作;第三,检查 references 里的文档,防止里面有误导性内容。
注意:即使是社区口碑很好的技能包,也不要盲目信任。GitHub 上高 star 仓库也存在被篡改的风险。引入新 skill 后,先在一个隔离环境里跑一次,观察它的行为再考虑正式使用。
4.3 数量膨胀与清理策略
skills 装多了之后,另一个问题冒出来:加载干扰和匹配性能下降。几十个 skill 时模型还能准确判断,几百个之后描述重叠、误触发的情况就会变多。我维护 agent-skills 项目时,特别注重"技能健康度"。
清理思路可以分三层:
- 停用层:把不常用但偶尔需要的 skill 移出自动扫描目录,归档到一个
_archive文件夹。 - 合并层:多个描述相近的 skill 合并成一个,比如把"代码格式化""代码风格检查""代码重构"合并为"代码质量"一个技能,用执行流程区分场景。
- 删除层:超过 3 个月没用过的 skill 直接删,需要时再从 git 历史找回。
这个方法是借鉴社区里清理 skills 的推荐做法改造的。用 git 管理整个 skills 目录会让你有底气删东西,反正能恢复,就不容易陷入"留着占地、删了怕用"的纠结。
4.4 常见报错场景与真实解决记录
开发中我也遇到过不少报错,最典型的是agent execution terminated due to error这类消息。它太笼统了,真正的问题往往在它之前几行的日志里。
我遇到过的一次情况是 skill 里调用的脚本缺少 Python 依赖,agent 执行脚本时直接异常退出。排查办法是:先把 skill 里的脚本单独在终端跑一遍,确认没有环境问题,再检查 agent 进程是否有执行的权限和环境变量。
还有一次是 skill 里写死了路径/tmp/template.tex,换个项目跑的时候根本没有这个文件,导致生成流程中断。后来我把路径改成项目相对路径,并在 SKILL.md 中加了一步"先检查模板文件是否存在,不存在则生成默认模板"。这些都说明一个问题:skill 不是纯 prompt 就完事了,它涉及脚本、环境、权限、依赖,调试的时候要从下往上排查堆栈里的每一条线索。
| 报错/异常 | 常见原因 | 排查动作 |
|---|---|---|
| skill 完全不触发 | frontmatter 描述不匹配 / 目录层级错误 | 检查 SKILL.md 描述与目录结构 |
| 脚本执行报错 | 依赖缺失 / 权限不足 | 终端里单独跑脚本看真实报错 |
| 触发了但输出跑偏 | 指令流程不够细 | 拆解 SKILL.md 里的执行步骤 |
| 误触发 | 描述太宽泛 | 增加排他性条件,优化描述 |
写在最后的一些个人体会
项目整理到这一步,我自己最大的感受是:skills 的价值不在于数量,而在于精准。很多人一开始热血沸腾装了几十个技能包,结果常用的一只手数得过来。我建议从自己每周至少重复三次的工作流入手,先把最痛的那一个场景固化成 skill,跑顺了再扩展。这个过程本身就是对 agent 工作方式的理解加深。
另外,写 skill 时保持"教人"的心态:你是在替未来的自己写操作手册,所以每一步都要说人话、给判断依据、留自检清单。写完后放到 git 仓库里管理,改坏了能回滚,版本迭代也有迹可循。这不仅是效率工具,也是沉淀团队知识的一种好方式。