ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

什么是SKILL?从作业指导书到Agent工程化的核心实践

什么是SKILL?从作业指导书到Agent工程化的核心实践

很多人第一次听到"SKILL"这个概念时,都会下意识把它当作某种"高级工具函数"或"插件包"。但实际上,Anthropic官方对SKILL的定位要更深刻——它本质上是给Agent的一份"作业指导书",而不仅仅是给它多一把扳手。这也是为什么我们在实际做Agent工程时,经常发现:接入再多MCP工具,模型在真实场景里依然会"手忙脚乱",而一份写得好的SKILL,却能让模型瞬间进入"熟练工"状态。

这篇内容我结合Anthropic官方最佳实践文档、社区里大量的SKILL实现案例,以及我自己在项目里手写SKILL和调试Agent行为的经验,把"什么是SKILL"和"怎么写一个优秀SKILL"这两件事彻底拆开讲清楚。无论你是刚开始接触Agent开发,还是已经在用Claude Code、Codex这类工具,这篇对你都会有实际帮助。

1. 先搞清楚SKILL到底是什么:它不是"工具",而是"作业指导书"

1.1 一句话定义与核心机制

SKILL在Anthropic的Agent体系里,是一个可复用的行为封装单元。它用Markdown文件(SKILL.md)来告诉模型:"在遇到某类任务时,你应当遵循怎样的思考路径、调用哪些工具、按什么顺序执行、最终产出什么格式的结果。"

关键点在于:SKILL不是让模型"多一个能力",而是让模型"知道怎么正确地干活"。举个生活化的类比——你给一个实习生一台单反相机(这是工具/MCP),他拿到手也不一定拍得出好照片;但你给他一份《室内人像拍摄SOP》,告诉他光圈优先模式、对焦在人眼、用窗户光做主光源、先拍20张再选片——他照着做,出片质量立刻不一样。SKILL就是这份SOP。

从技术实现角度看,SKILL的核心机制是:当你把SKILL.md文件放进Agent的skills目录后,系统会把该文件的内容注入到模型的上下文里(或者在Agent初始化时暴露给它),模型在运行过程中如果判断当前任务命中某个SKILL的适用范围,就会主动"照着流程走"。官方文档里反复强调一个词:progressive disclosure(渐进式披露)——也就是说,SKILL.md文件不要一次性把所有细节都堆给模型,而是只给摘要和关键路径,细节放在模型需要时才去读取的辅助文件里,这样既能保证模型"知道有这个技能",又不会占用太多上下文窗口。

1.2 SKILL、MCP、Prompt三者到底什么关系

这三个概念经常被放在一起比较,我直接说结论:

  • Prompt(提示词):是"一次性口述要求"。你跟模型说"帮我写份周报,要包含数据对比和下周计划",模型听完就干,完事就忘。它灵活但不可复用,每次都得从头说。
  • MCP(工具接入层):是"给Agent装上手和脚"。MCP Server暴露一堆工具(查数据库、发邮件、读文件),解决的问题是"Agent能操作哪些外部系统"。但它不负责告诉模型"什么时候用、怎么组合、产出什么样",工具列表一多,模型经常选择困难甚至调错参数。
  • SKILL(技能封装层):是"把一件事的完整做法固化下来"。它把"识别任务类型 → 拆解子步骤 → 调用哪些工具 → 如何处理结果 → 输出什么格式"这一整套流程写成文档。特别重要的一点是:SKILL本身不是工具,它不直接执行任何操作,操作还是要靠MCP工具或Agent内置能力去完成。

所以真正的工程化结构是:MCP解决"能力边界",SKILL解决"行为质量"。如果只接MCP,Agent像个有手有脚但没受过培训的新员工;加上SKILL之后,它才变成熟手。还有一层关系容易忽略——SKILL是对Prompt的结构化管理。你可以把SKILL理解为一套有目录、有分工、有边界的"工程化Prompt套装",但它比普通Prompt强在三个方面:可复用(一个SKILL文件多处引用)、可版本管理(Git管理)、可渐进加载(只注入摘要,细节按需读取)。

1.3 SKILL在Agent工程中的真实价值

这几年做Agent工程化,最大的痛点不是模型能力不够,而是模型行为不稳定。同一个任务,今天它知道先查资料再写答案,明天可能直接就凭记忆胡编了;这个会话它按你想要的格式输出,换个会话又自作主张改了结构。SKILL就是用来解决这种"行为漂移"的。

我自己实践下来,SKILL带来的具体价值有这么几个:

  • 把专家经验沉淀进Agent:不用每次重复叮嘱模型"你要注意这里""别忘记先做那一步",一份写好的SKILL会把完整流程固化下来。团队里新来的成员,不用从头教Agent的脾气和习惯,看SKILL文件就全明白了。
  • 大幅降低上下文损耗:官方推荐的"渐进式披露"设计,让Agent在大多数场景下只需要读取SKILL.md的摘要部分(很短),真正遇到复杂细节时才去读附加文档,相比把一整套操作手册塞进System Prompt,上下文占用可以少一个数量级。
  • 让调试和复盘变得可操作:模型行为出了问题,你不需要对着几百行的Prompt猜原因,直接打开对应的SKILL.md,检查是哪一步写得不清楚、哪个边界没定义好。改一行描述,再跑测试,这种"可定位、可修复"的体验,Prompt根本给不了。

2. SKILL的标准结构与目录规划:一个小文件加一个配套文件夹

2.1 一个完整SKILL的物理构成

按照Anthropic官方的推荐,一个SKILL在项目里通常是这样组织的:

your-project/ ├── skills/ │ ├── document-review/ # SKILL目录名,简短清晰 │ │ ├── SKILL.md # 技能主文件,必须存在 │ │ ├── scripts/ # 可选:辅助脚本目录 │ │ │ └── extract_key_points.py │ │ └── assets/ # 可选:参考文档、模板等 │ │ └── review_template.md │ └── meeting-summary/ │ └── SKILL.md

目录名用短横线连接的小写单词(kebab-case),比如document-review、code-review、meeting-summary。SKILL.md是每个SKILL的灵魂文件,除它以外的目录都是可选的。

之所以推荐"SKILL.md + scripts + assets"这种结构,核心考量就是"渐进式披露"。SKILL.md里只写摘要、何时使用、关键步骤; scripts目录放可执行脚本,用于把机械化的数据处理从模型那里接管过来(模型只负责判断和编排,计算交给脚本,准确率明显更高);assets目录放模板、参考文档、示例输出,模型需要时再读取。

2.2 SKILL.md的YAML头信息怎么填才有价值

SKILL.md的头部有一段YAML格式的frontmatter,它决定了Agent在什么情况下能"认出"这个技能。拿Anthropic官方最佳实践的推荐写法来看,一个合格的头部信息长这样:

--- name: document-review description: 文档审校技能。在用户提供文章、报告、技术文档并要求检查错误、优化表达、统一风格时使用。适用于中文和英文文档,重点关注逻辑连贯性、事实一致性、格式规范性和可读性。 ---

写description是这里最有讲究的部分。官方文档和社区的共识是:description不要只写"这是什么",要写清楚"何时触发"和"能力边界"。我见过太多人只写一句"文档审校",结果模型在用户让它翻译一段文字时都误触发了——因为"审校"和"翻译"的边界没写明白。

我推荐一个高可靠性的description模板,四个要素缺一不可:

  • 能力名称:这个技能叫什么,一句话说清。
  • 触发场景:哪些情况应该调用这个技能,写具体,不要用模糊词。
  • 明确排除:哪些情况不该调用这个技能,把容易混淆的相邻场景点出来。
  • 地理/语言适用范围:如果有语言或领域限制,明确写出来。

2.3 正文部分:主文件只写流程骨架

SKILL.md的正文部分,官方推荐的是"从宏观到微观"的写作逻辑,而不是事无巨细地罗列所有知识。我实践的写法是:

第一部分:概述(1-2句话)——这个技能做什么、在什么场景发挥作用。这部分要简短,模型读得快。

第二部分:何时使用(When to Use)——把"应该用"和"不应该用"的场景分列出来。这部分是把双刃剑:写太粗,模型容易乱触发;写太细,占用上下文。我的习惯是:列举最常见的3-5个触发场景,再加2-3个明确的"不适用"场景。

第三部分:核心流程(Key Steps)——这是技能的主体。按顺序告诉模型完成任务需要经历哪些步骤,每一步要关注什么。这里只写"骨架"——做什么、产出什么,不写"怎么做"的细节。细节留给脚本或assets里的参考文档。

第四部分:输出规范(Output Format)——明确产出物的格式标准。这一步经常被忽略,但恰恰是最影响实用性的:模型输出格式乱七八糟,后面接手的程序就崩。

2.4 scripts和assets的补充角色

scripts目录:凡是可以用代码精确完成的事情,不要指望模型用自己的"推理"去算。比如统计文档字数、提取关键词、生成格式化JSON、批量重命名文件——这些在脚本里几十行代码就能做得完美,让模型写代码再执行反而容易出错。一个重要的心得是:让Agent调用MCP工具或执行脚本时,一定要在SKILL.md里把"传什么参数、期望什么返回格式"写清楚,否则模型会自由发挥,传参不规范,脚本根本跑不起来。

assets目录:放那些"模型需要时才应该读"的深度材料。比如更完整的示例、风格指南、历史优秀案例、原始参考文档。这样主文件SKILL.md体积可以控制在几百行以内,模型绝大多数情况下只需要轻量读取主文件,真正遇到特殊场景时才去翻assets——上下文占用率显著下降,对API场景来说还能省钱。

3. 怎么写一个优秀SKILL:从白纸到可复用技能包的七个关键步骤

3.1 第一步:明确技能边界,先定义"不做什么"

动手写SKILL.md之前,先做"边界定义"练习。拿我最近帮团队写的"会议纪要生成SKILL"举例,动笔之前先列了三个问题:

  • 这个技能解决什么任务?将会议语音转录稿整理为结构化会议纪要。
  • 它不该处理什么?不负责安排会议、不发会议邀请、不自动生成待办事项的提醒通知。
  • 它的输入是什么、产出是什么?输入是语音转文字后的文本或笔记草稿;产出是包含"会议主题/时间/参与人/讨论要点/决议/待办事项"六个部分的纪要文档。

把这三个边界问题回答清楚,后面写description和正文的时候,笔头就有方向了。很多SKILL写得差,不是文笔问题,是边界没想清楚——什么都想做,结果模型遇到任何任务都模模糊糊想触发,误用率高得吓人。

3.2 第二步:设计description,让模型一眼认出"这就是我要找的"

description直接决定Agent的"召回率"和"准确率"。我的经验是,写description时把自己当成产品经理在写功能入口文案,要兼顾召回和去重:

从"召回"角度——必须包含任务领域的高频词。比如"文档审校"技能,description里必须有"检查错误""优化表达""语法""格式""风格统一"这类词,模型在上下文中做语义匹配时,这些词是命中的关键信号。

从"去重"角度——必须写清"不在这里使用的场景"。比如同样一个文档审校技能,如果团队里还有专门的"翻译审校SKILL",那这个description里必须明确:"如果任务是对外文内容进行翻译并审校译文,请勿使用本技能,请使用translation-review技能。"

3.3 第三步:画核心流程,用步骤编号强迫模型按顺序执行

在SKILL.md的Key Steps部分,我强烈建议用有序列表来组织流程。Anthropic官方推荐的做法也是步骤化的,因为模型对"第一步""第二步"这种显式的序号极其敏感,按顺序执行的服从率远高于整段描述。

以"文档审校SKILL"为例,核心流程写出来大概是:

  1. 读取用户提供的文档全文,理解主题和用途。
  2. 通读全文,标记明显的错别字、语法错误、标点问题——这一轮只做"机械错误"检查,不做深层次修改。
  3. 逐段检查逻辑连贯性:段内论证是否完整、段落之间是否有断裂、结论是否有依据支撑。
  4. 检查事实一致性:人名、时间、数据、引用来源是否前后矛盾。
  5. 统一风格和格式:对照assets中的风格指南,检查标题层级、术语用词、编号格式、引用格式。
  6. 汇总修改意见,按严重程度分类(必改/建议/可选),输出审校报告。

每一步都要给"关注什么、产出什么",但不要给"具体怎么改"。因为模型的语言能力很强,你给它框架它就能发挥;你反而去逐字教它怎么写,既占空间又限制了它的灵活性。

3.4 第四步:把机械操作写成脚本,模型只做判断和编排

这是很多SKILL作者忽略的一步。举个实际例子,我见过一个"周报汇总SKILL",作者让模型直接阅读10个团队成员的周报文本,然后自己总结。结果模型经常漏掉某些人的重要进展,或者把不同人的数据混在一起。

正确做法是:在SKILL目录里放一个scripts/extract_updates.py脚本,它的职责是先把所有周报里的"本周进展""风险项""下周计划"三个字段提取出来并结构化;模型只需调用脚本获得结构化数据,再基于数据做概括和优先级排序。这样做的最大优势是:错误率大幅下降,脚本处理结构化数据是100%准确的,模型只做它擅长的高层判断。

我在SKILL.md里推荐这么写脚本调用部分:

使用 scripts/extract_updates.py <周报目录> 提取团队成员周报中的关键更新。脚本会输出JSON格式的汇总对象,包含每个成员的名字、进展摘要、风险项、下周计划。拿到JSON数据后,基于它撰写汇总报告,不要再直接引用原始周报文本。

这样模型看到的是一个"步骤5:运行该脚本 → 读取Json输出 → 基于输出撰写报告",而不是"读10份周报并提炼要点"。准确率天差地别。

3.5 第五步:给出输出范例,比描述一百句都管用

对模型来说,一个完整的输入输出示例,胜过你对格式做的十句文字描述。在assets目录里放一个example_output.md,给一个完整的输出样例,让模型照着学。这个操作非常朴素,但效果立竿见影——模型是Few-shot学习者,给它一个完整范例,格式服从率从60%提升到95%以上。

拿文档审校SKILL来说,示例里应该包含:一份"修改前"的段落、对应的"修改后"段落、审校报告里怎么分类标注问题(必改/建议/可选)、用什么符号标示修改位置。模型看到这种一对一的对照,马上就知道自己要产出的东西长什么样。

3.6 第六步:明确"注意事项"小节,防止模型自由发挥

在SKILL.md末尾,我习惯加一个"关键注意点/边界限制"小节。内容通常是:

  • 不要做的事(比如"不要改变原文的核心观点""不要对数据准确性做主观臆断")
  • 需要谨慎处理的场景(比如"如果原文有引用外部数据,标出'需要人工核实引用来源'")
  • 当遇到异常情况的兜底方案(比如"文档编码无法解析时,报告错误并请求重新提供文件")

这个部分本质上是给模型画"红线"。模型在自由发挥时经常会做出"看起来合理但实际越权"的操作——你加了注意点,它跑偏的概率会显著下降。

3.7 第七步:设计测试用例,验证触发条件和输出质量

SKILL写完不是结束,测试才是真正的工作量所在。我的测试清单一般包含三类:

  • 触发测试:给一段看似相关但实际不适用(或者反之)的任务文本,看模型是否正确触发或正确不触发。这一步测的是description写得好不好。
  • 流程测试:给一个标准任务输入,看模型是否严格按SKILL.md里的步骤走完了流程,有没有跳步、有没有多余动作。
  • 输出测试:检查产出质量。格式对不对、内容全不全、有没有幻觉。这里建议找两三个人同时看同一份输出,每个人对"质量"的判断不太一样,收集足够反馈再迭代。

官方文档里也推荐建立一个"评测集"(eval set),把你期望Agent在触发、执行、输出三个环节达到的标准写成一组测试样例,每次修改SKILL之后跑一遍评测集,确保没有引入回归。

4. 我踩过的坑:SKILL最容易犯的五个错误

4.1 把SKILL当成万能说明书,塞太多内容

第一次写SKILL的时候,我犯的最严重的错误就是恨不得把所有业务规则、行业知识、历史经验全部塞进SKILL.md。结果是文件写了上千行,模型读一次就要消耗大量上下文,而且细节越多,模型在关键路径上的注意力越分散——经常陷入某个旁支细节,忘了主线流程。

官方推荐的"渐进式披露"是有道理的。主文件保持精简,只保留"骨架"——触发条件、关键步骤、输出规范、红线提醒。真正需要时再去读取assets里更详细的参考资料。这个"主文件几百行、参考文档能多厚就多厚"的比例,是实践下来最舒服的结构。

4.2 description写得太笼统,模型乱触发

"用于文档处理"和"在用户提供中文或英文文档并要求检查语法错误、优化表达、统一格式时使用;如果是纯翻译任务,请不要使用本技能"——这两句话的触发质量天差地别。前者会让模型在用户提"帮我翻译这段"的时候也去打这个技能的主意;后者把边界划得明明白白。

4.3 脚本和SKILL之间缺少"接口说明"

最开始我写的SKILL里让模型去跑脚本,但没在SKILL.md里写清楚脚本的参数和返回格式。模型捣鼓半天,传了个不存在的路径参数进去,脚本抛异常,Agent卡住。后来学乖了——每个脚本的调用说明都写成"运行什么命令、传什么参数、返回什么结构、失败如何处理",模型照着填参数,几乎零障碍。此外,脚本本身要加基本的错误处理:文件不存在的时候返回友好提示而不是直接traceback,模型看到后还能自动换个路径重试,不至于卡死在那儿。

4.4 忽略"输出规范",下游程序全是坑

有的SKILL做完后,下游还要对接自动化流程——比如把会议纪要写入项目管理工具、把审校报告发送到邮件系统。模型输出格式跑偏一个字段名,下游程序就崩。我的解决方案就是在SKILL.md里放一个**"输出JSON结构定义"或"输出Markdown模板"**,并在下一步把示例文件放进assets。然后测试的时候,专门检查模型输出和模板的一致性。

4.5 没有版本管理,改坏了不知道回滚

SKILL是工程产物,理应纳入Git管理。我之前手写改了一版SKILL.md,没提交Git,跑了两天测试发现输出质量反而不如上一版,想回滚却找不回来了。后来所有SKILL目录都进Git仓库,每次改动一个commit,备注里写清楚"改了什么、为什么改”。测试完新的,不满意就checkout回旧版。这种做法也方便团队协作——别人改了你的SKILL,你能在code review里看到改动点,避免"悄悄改了啥"的情况。

5. 从0到1实操:用"代码审查SKILL"演示完整写法

纸上谈兵到此为止,我直接用一个我自己写过的"代码审查SKILL"来做一个从零到一的完整实例,你对照着抄就行。

5.1 目录结构

skills/ ├── code-review/ │ ├── SKILL.md │ ├── scripts/ │ │ ├── detect_secrets.py │ │ └── complexity_analysis.py │ └── assets/ │ ├── code_review_guide.md │ └── review_example.md

5.2 SKILL.md全文

--- name: code-review description: 代码审查技能。在用户提供源代码文件或代码片段,并要求检查代码质量、找出潜在缺陷、评估安全风险时使用。适用于Python、JavaScript、Java、Go等主流编程语言。如果用户要求的是编写新功能而非审查现有代码,请勿使用本技能。 --- # 代码审查技能 对用户提供的源代码进行系统性审查,输出结构化审查报告,帮助开发者在合并代码前发现潜在缺陷。 ## 何时使用 - 当用户要求"审查代码""检查代码质量""看看这段代码有什么问题"时使用。 - 当用户在Pull Request场景下要求"帮我Review代码"时使用。 - **不要**在用户要求"写一个函数""实现某个功能"时使用。 ## 核心流程 1. 读取待审查的代码文件或代码片段。 2. 运行 scripts/detect_secrets.py <文件或目录路径>,检测硬编码密钥、API密钥、密码等敏感信息。脚本输出JSON数组,包含风险类型和位置。 3. 运行 scripts/complexity_analysis.py <文件或目录路径>,计算圈复杂度、代码行数、嵌套深度等指标。脚本输出JSON对象。 4. 人工(模型)逐段阅读代码,从以下维度检查并可对照assets/code_review_guide.md中的详细检查清单: - 逻辑正确性:边界条件、空值处理、条件判断是否符合预期 - 并发安全性:共享状态、竞态条件、锁使用是否正确 - 性能隐患:无意义的重复计算、可避免的O(n^2)复杂度 - 可维护性:命名是否清晰、职责是否单一、是否存在魔法数字 5. 汇总脚本检测结果和人工分析结果,按严重程度分级输出审查报告。 ## 输出规范 按以下Markdown结构输出审查报告: ## 代码审查报告 ### 1. 概要 - 审查文件: <文件名> - 总体评估: <通过/需改进/存在高风险> ### 2. 严重问题(必须修复) - <文件位置>:<行号> - 问题描述与修改建议 ### 3. 建议改进 - <文件位置>:<行号> - 问题描述与修改建议 ### 4. 潜在风险提示 - <脚本检测到的敏感信息或复杂度风险> ## 关键注意点 - 不要修改用户的代码,只输出审查报告。 - 如果用户未提供完整代码,只给了片段,请在报告中注明"仅对提供的片段做审查,不覆盖完整上下文"。 - 发现疑似敏感信息时,不要输出具体密钥内容,只指位置和类型,并提示用户立即更换。安全优先。

5.3 运行效果与复盘

这个SKILL跑起来后,Agent的行为显著变得更像一个"负责任的代码审查员"了:先跑脚本检测敏感信息和复杂度,再人工逐段分析,最后按标准格式输出报告。不会有以前那种"模型看了三行代码就开始发表长篇大论,漏洞漏一堆"的情况。

复盘这个SKILL的成功要素:第一个是description的触发边界写得很清楚(明确排除"写新功能");第二个是步骤强制了顺序(先脚本后人工);第三个是输出格式固定死了,下游接自动化处理很方便;第四个是资产文件——code_review_guide.md 里有详细的审查维度清单,遇到了具体场景模型会去参考,平时不占上下文。

6. SKILL的适用边界与选型判断:什么时候该写、什么时候别写

最后聊一个非常实际的工程问题:是不是所有场景都值得写SKILL?

我的建议是,以下三种情况适合上SKILL:

  • 任务出现频率高:每周至少有几次同类任务,写一份SKILL能让模型在下一次直接进入状态,省去反复调Prompt的时间。
  • 流程相对固定:任务步骤可以标准化、顺序化。步骤越固定,SKILL的收益越大。
  • 需要多人协作或跨会话复用:团队里多个成员都在让Agent做类似的事,写一份优质SKILL就等于把"最佳实践"沉淀下来,全员共享。

反过来,以下情况不要急着写SKILL:

  • 一次性任务:用完就忘了,写SKILL的投入产出比太低,直接用Prompt约束就好。
  • 高度开放、没有固定流程的任务:比如"帮我头脑风暴几个创意",这类任务没有标准步骤,硬套SKILL反而束缚模型的发散能力。
  • 你还没搞清楚最优流程的任务:先手工调教几轮,确认"什么做法效果好"之后再固化成SKILL。过早把不成熟的流程写进SKILL,会让模型在错误的路线上跑很久。

另外,关于"SKILL会不会被模型忽略/误触发"的问题,我的实测经验是:SKILL的本质是在上下文里注入一段"行为准则"文本——模型是否采用它,是个概率问题。即使你把description写得很精准,也无法做到100%命中,但做得好的SKILL,触发率和流程服从率通常在90%以上。剩下的10%,就得靠测试后的持续迭代补。这也是为什么我一直强调评测集的重要性——要是没有一套固定的测试用例,你到底把触发率从80%提到了85%还是90%,根本说不清。

写到这儿,SKILL这件事基本聊透了。最后给一个我在实践中非常管用的小建议:每写一个SKILL,一定要花时间建立对应的eval set(哪怕只有5-10个测试样例)。因为SKILL这东西,最核心的生态位就在"沉淀工程化能力"上——没有评测反馈的沉淀,等于闭着眼优化一个系统而不是所看方向。等SKILL版本多起来,这个评测集的价值会越来越大。比如模型升级了、API改了、业务规则变了,跑一遍eval set马上就知道哪些SKILL需要调整,比靠肉眼盯输出靠谱得多。要入坑SKILL,就从今天下午写一个"文档审校"或"会议纪要"这种小技能开始吧。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进