Anthropic Agent Skills实战:从SKILL.md到最佳实践 1. SKILL到底是什么先把这个概念从高级Prompt模板里摘出来聊到Anthropic的Agent Skills官方文档里统称SKILL第一次接触的人十有八九会把它当成高级一点的Prompt模板。我第一次看到这个概念的时候也是这么想的——直到真的在Claude Code里把一个SKILL文件夹丢给模型去跑让它自己决定什么时候加载、怎么用我才意识到这完全不是一个东西。SKILL的官方定义很简洁一组打包好的指令和相关资源让Claude在需要时自动调用从而获得某一项专业能力。它可以是分析财报的技能、生成SVG图标的技能、填写PDF表格的技能也可以是复制某个品牌设计风格的技能。关键在于按需加载这四个字——它不是每轮对话都塞进上下文的固定指令而是一个放在旁边、等任务匹配时才被读取的专业手册。在SKILL出现之前想让Claude稳定输出某种特定格式或者具备某种专业行为通常只有两条路要么把几千行的领域规则硬塞进System Prompt结果上下文被占满普通对话的质量肉眼可见地下降要么专门写一个MCP服务器用代码把工具和数据接进来成本高、维护也重。SKILL正好补上了中间地带它不需要长驻上下文也不需要写代码只需要一份高质量的Markdown指令文件外加可选的脚本和静态资源。对我来说理解SKILL最好的切入点是把Claude想象成一个新入职的顾问。System Prompt是这个人的性格底色和工作原则MCP是他能调用的数据库和外部系统而SKILL则是他办公桌上那一摞遇到XX任务时先翻这一本的操作手册。手册平时不摊开等真接到对应任务他才会翻开按照流程执行。理解了这层关系后面很多写作规范就顺理成章了。另外一个容易忽略的点是SKILL的适用范围。它并不只是Claude Code的专属功能API、Claude桌面端和网页版都支持。在API里通过skills参数传入在Claude Code里放进skill目录在Claude应用中通过设置上传。同一个SKILL文件夹换不同入口都能被识别这也是它适合团队成员之间共享复用的原因。2. 拆开一个标准的SKILL目录每个文件都是干什么的一个SKILL本质上就是一个目录目录里最重要的文件叫SKILL.md。官方推荐的目录结构大概是这样的my-skill/ ├── SKILL.md ├── SKILL.py ├── assets/ │ ├── report-template.xlsx │ └── brand-colors.md └── requirements.txt2.1 SKILL.md的三层结构SKILL.md是整个技能的主控制器。它由三部分组成开头的YAML frontmatter元信息区、正文指令区以及可选的示例区。--- name: meeting-notes description: When to use this skill to extract meeting minutes and action items from a transcript. --- # Meeting Notes Skill ## Instructions Extract the following from the transcript: - Key decisions - Action items, each with owner and deadline ...frontmatter里有两个必填字段name和description。name要求小写字母、数字和连字符的组合最好控制在40个字符以内这个值会作为技能的唯一标识。description则直接决定Claude会不会在合适的时机调用这个技能——它需要清晰地说明什么场景下使用这个技能以及这个技能能做什么一般1到2句话就够了。正文部分才是技能的真正内容。官方推荐的做法是SKILL.md整体控制在500行以内极限不要超过2000行。如果超过多半是你把太多细节塞进了主文件而不是通过渐进式披露progressive disclosure把深度知识放到被引用的附属文件里。2.2 附属资源文件SKILL.py、assets和依赖清单SKILL.py是一个可选文件。当你希望技能具备计算或自动化能力时可以在这里放Python代码。Claude会在需要时调用它并读取执行结果。相比在指令里让模型手算或用bash跑一堆命令把逻辑放进Python脚本显然更可靠、更可复现。assets目录用来存放模板、参考文档、图片等静态资源。比如做一个Excel报表生成的SKILL就可以把带格式的模板文件放在assets里指令里用相对路径引用它。requirements.txt则声明技能依赖的Python包Claude环境会自动处理安装。2.3 技能应该放在哪里在Claude Code里技能可以放在用户级目录~/.claude/skills/也可以放在项目级目录.claude/skills/下。放用户级意味着所有项目都能用放项目级则只对当前项目生效。Claude app则是在设置-技能里上传或添加。有一点要注意技能目录名需要和SKILL.md里的name保持一致否则识别会出现问题。我自己习惯把所有技能用git管理。每个技能一个仓库目录改动有记录团队里其他人直接clone过来就能用。这比反复复制粘贴文件靠谱得多。3. 官方最佳实践拆解怎么写出一份真正好用的SKILL.mdAnthropic官方文档里有一些非常具体的写作建议我把它们翻译、消化之后结合自己的实测经验整理成下面这几条。每一条都会配上错误示范和正确做法的对比方便对照。3.1 description是唯一的入口闸门值得单独打磨Claude不会提前读你的SKILL.md正文它只会在每轮对话开始前快速扫描各个技能的描述。所以description写得好不好直接决定它会不会在正确的时机打开这个技能。错误示范是宽泛、模糊的描述比如A skill for data analysis。这种描述会让Claude拿不准什么时候该用结果就是该触发时不触发或者不该触发时频繁触发。正确做法是把触发条件写完全description: When the user asks to analyze sales data from CRM exports, use this skill to build a monthly summary report with YoY comparison and anomaly flags.这个描述同时包含了触发场景CRM导出、销售数据和产出形态月度摘要、同比对比、异常标记。Claude只需要扫一眼就能做判断。3.2 指令要写怎么做而不是只写做什么这是官方明确强调的一条好的SKILL不是描述结果而是解释过程。直接写Resolve the users issue的问题是模型的自由度太高输出风格和结构都不可控。正确的方式是给出步骤化指令。比如做一个日志排查技能不要只写Analyze the logs and identify the error而要拆解成1. Read the log file and extract the first 20 lines of context around each ERROR entry. 2. Classify each error into: authentication, rate limiting, infrastructure, or application logic. 3. For each class, list the top 3 most likely causes based on the surrounding log lines. 4. Propose a fix, ordered by implementation effort.每一步都是可验证的动作输出才有稳定的结构。这背后其实是一种思维你把分析日志这件事从一个模糊目标拆成了模型可以逐步执行的子任务。3.3 渐进式披露用500行原则保持上下文干净渐进式披露是SKILL设计里最核心的思想。它的意思是SKILL.md里只放高信号、高频使用的核心指令把低频但重要的细节放在附属文件里等模型真正需要时再去读取。我见过不少失败的SKILL都是把整个领域的知识百科全塞进一个文件结果上下文被大量低概率信息占据模型反而抓不住重点。官方推荐的500行以内像一个强制约束逼着你做取舍。那放不下的细节怎么办放在references.md或者assets目录里然后在正文中用一句话引用If you need the detailed data dictionary, read assets/data-dictionary.md first.这和我日常写代码的习惯很像主函数保持短小复杂的实现抽到工具类里按需import。SKILL.md就是主函数附属文件就是工具类。3.4 示例的价值超乎想象尤其是坏输入示例光说要做什么还不够模型需要看到做出来的东西长什么样。官方最佳实践里有一条用示例展示期望的输出格式效果远好于大段文字说明。更进阶的用法是给边界示例。比如日期解析技能示例里不只是常规的2025-01-15还要有last Friday、Q3、FY26这类模糊表达怎么处理。把容易出错的输入类型写进示例等于给模型打了一针预防疫苗实测下来能显著减少边界情况的翻车。3.5 重要规则要放在显眼位置固定措辞直接引用如果某项规则特别关键比如所有的金额都必须四舍五入到两位小数所有报告必须包含免责声明不要把它淹没在长段落中间而是要单独成节放在Instructions的顶部或者专门的Critical Rules部分。模型对上下文头尾的注意力天然高于中间部分重要规则放在头部比放在尾部稳定得多。另外有一种特殊场景——品牌合规或内容安全。当技能需要强制输出某些固定句子时不要把意思转述给模型直接把原文放进代码块里引用并要求逐字复制。这样比换种说法也可以要稳得多。3.6 时间感知的写法用相对时间而不是硬编码日期技能会在任意时间点被调用如果指令里写死2025年第一季度。这个技能半年后就过时了。官方建议使用相对时间表达比如use the current date and refer to today、this quarter——让模型基于系统时间现场推算。我曾经写过一个做季度汇报的技能就因为没有强调以系统当前时间为准导致模型在4月份生成报告时仍然引用上一个季度的数据口径。后来在指令里加了一句All date references must be based on the current system date, never assume a fixed date.这个问题再没出现过。3.7 反面清单什么样的SKILL一定会翻车官方文档里也列举了一些反面案例我照着踩过坑之后深有体会问题具体表现我的建议追求大而全一个技能想覆盖所有场景拆成多个单一职责的小技能用形容词描述风格make it beautiful/polished给出具体标准色值、字号、结构塞入大量通用知识把百科内容复制进技能只保留流程性、步骤性知识引用外部登录资源指令里让模型去读需要鉴权的链接把内容直接放进assets里盲目堆砌长指令2000行以上还想让模型全记住坚持渐进式披露4. SKILL、MCP、System Prompt、插件四者的边界与选型很多人混淆SKILL和MCP这不能怪大家因为两者确实都是在扩展Claude能力这个目标下工作。但它们解决的问题完全不同选错方案的代价也不小。MCPModel Context Protocol的本质是给模型提供工具和数据访问能力。它让Claude可以查询数据库、调用REST API、操作外部系统而且通常需要你维护一个服务端。SKILL的本质是给模型提供专业指令和领域知识它不需要任何服务端纯粹是一份怎么做这件事的说明书。打个比方MCP是给顾问接通了公司内部的ERP系统他可以直接查数据SKILL是给他一本《如何做月度经营分析》的方法论文档让他知道查哪些数据、怎么算、怎么呈现。一个解决能不能访问一个解决会不会做。System Prompt则是另一回事。它每轮对话都全程加载适合放全局性的行为规则、身份设定和价值观约束。而SKILL是条件加载的适合放局部的专业任务指令。如果某个规则必须任何时候都生效比如永远用简体中文回复那它属于System Prompt如果只是在做数据分析时才需要遵守的规则则更适合做成SKILL。插件Plugin在Claude Code生态里是更上层的概念它可以把SKILL、MCP服务器、命令、子代理打包在一起分发。你可以把插件理解成一个全家桶安装包而SKILL是其中一个独立的模块。选型时我的判断依据很简单需要连接外部系统、读写数据 → MCP需要专业技能、领域流程、格式模板 → SKILL全局必守的规则 → System Prompt你要打包发给团队协作、组合多能力 → 插件还有一个常见误区有人想用SKILL来做通用知识问答增强把一堆百科条目放进技能里。这是对SKILL的误解。技能不是知识库它是如何执行任务的程序化说明。通用知识应该靠模型自身能力或RAG方案解决塞进SKILL只会造成上下文浪费和触发不确定性。5. 实战从零写一个会议纪要与行动项抽取SKILL理论说再多不如实际走一遍。我以最近常用的一个技能为例把从需求定义到测试迭代的完整过程记录下来。5.1 第一步界定输入输出做任何技能前先回答三个问题输入是什么输出是什么什么场景触发我当时的答案输入一段会议录音转文字文本可能夹杂无关闲聊输出结构化会议纪要包含会议主题、关键决策、行动项每个行动项含负责人和截止日期触发场景用户提供会议transcript并要求整理这三个问题不搞清楚后面怎么写都不对。很多人写SKILL翻车第一步就栽在连自己的技能边界都没想明白。5.2 第二步编写SKILL.md--- name: meeting-minutes description: When the user provides a meeting transcript (or asks to summarize meeting notes), use this skill to produce structured minutes with key decisions and action items. Output as Markdown. --- # Meeting Minutes Skill ## Instructions Follow these steps when processing a meeting transcript: 1. Read the full transcript first. Do not skip sections. 2. Extract and state the meeting topic in one sentence, based on the dominant agenda. 3. Identify the participants, only if explicitly named. 4. Summarize key decisions as bullet points. Each decision must have a Decision: prefix. 5. Extract action items, one per bullet, using this format: - Owner: [person or unassigned] - Task: [specific deliverable] - Due: [date if mentioned, otherwise no deadline] 6. Ignore small talk, repeated points, and unrelated tangents. 7. If the transcript is ambiguous, note it in an Open Questions section instead of guessing. ## Example Output # Meeting Summary **Topic:** Q3 OKR planning **Participants:** Alice, Bob, Carol **Key Decisions:** - Decision: Focus on retention metrics over acquisition this quarter. - Decision: Launch the mobile beta by the end of Q3. **Action Items:** - Owner: Alice | Task: Write the retention dashboard spec | Due: 2025-06-20 - Owner: Bob | Task: Draft beta launch checklist | Due: no deadline **Open Questions:** - Who owns the migration plan for legacy users?这个SKILL.md不到50行大部分是步骤和示例。注意第5步给出的行动项格式它直接告诉模型列出字段值而不是一句抽象的提取行动项。示例区的作用是让模型有一个可以复制的输出骨架实际测试中模型几乎不会偏离这个格式。5.3 第三步测试与迭代写好之后我把一份真实的工作会议纪要约3000字作为测试输入跑了一遍。第一版的问题很明显行动项的责任人被识别错了一次因为原文里有个人名因为被前面大量Alice说干扰模型把the PM team识别成了Alice。这说明第5步的Owner解析规则不够明确。我的修正是在步骤5里加了一句Owner必须是在原文中被明确指派任务的人或团队如果只是参与讨论但未被指派不要列为Owner。再次测试识别准确率明显提升。反复跑5到10组不同风格的输入有的啰嗦、有的跳跃、有的中英混杂直到输出稳定这个技能才算能用。5.4 第四步通过调试命令验证在Claude Code里可以用/skills命令查看当前项目可用的技能列表并手动激活某个技能方便单独测试。也可以启动一个带技能但不会真正执行的dry-run模式做快速回归。我会把测试用的transcript样本存成一个固定的测试文件每次改完技能先跑一遍dry-run再跑一次真实对话保证改动没有破坏既有能力。5.5 注意别踩的坑这个技能从初期版本到稳定我踩过几个值得说说的坑一是description写得太泛。最初我写的是Use this skill to summarize meetings结果Claude在用户只是闲聊两句会议话题时也去加载技能白白浪费上下文。改成when the user provides a meeting transcript之后触发准确率高了很多。二是指令里有歧义词。我最初写的是summarize the decisions模型有时候输出Alice decided to这种过程性描述而不是决策本身。后来要求每个决策都用Decision:前缀强制格式统一彻底解决了歧义。三是没有处理信息不足的情况。真实纪要里经常有人名缺失、日期缺失以前模型会自己编一个。加上第7步的Open Questions机制后它学会了诚实标注未知项这份能力远比编造正确答案重要。6. 实用技巧与维护心得让技能长期稳定地工作技能写出来只是开始维护才是大头。以下几条是我在实际使用中总结出来的经验不一定都在官方文档里但非常实用。6.1 坚持单一职责一个技能只做一件事做到极致。我早期写过一个综合助手技能既管翻译又管排版还管数据提取结果每次调用上下文里都充斥着大量无关指令模型经常在翻译任务里突然开始排表格。拆成三个独立技能之后每个都更短更精准触发也更稳定。官方说的more skills is not always better前提是每个技能都足够聚焦。6.2 用git管理技能并维护版本记录技能是会演化的。我通常在description里不带版本号避免干扰触发但在SKILL.md首段保留一行变更记录。例如## Changelog - 2025-06-01: Strict owner detection rules. - 2025-05-20: Initial version.这样既不影响模型判断又方便人类追踪。6.3 别在技能里放敏感信息这个坑比较隐蔽。技能文件因为是共享的经常会被同步到团队的公共仓库或者发给外部协作者。如果你的技能里包含了内部系统的绝对路径、数据库表名、API密钥一旦分发出去就是安全事故。我的原则是技能里只放方法和模板凡是涉及内部信息的都改用占位符真正的内容通过环境变量或配置文件在运行时注入。6.4 定期用真实数据回归技能不是写一次就一劳永逸。模型升级、办公流程调整、输入数据格式变化都可能让一个原本正常的技能逐渐失效。我给自己定了一个习惯每两周用固定的测试样本集把核心技能跑一遍发现漂移就微调指令。这有点像给代码库做回归测试工作很机械但能避免突然某天技能就不好使了的尴尬。6.5 与其他技能共用规则时优先抽取公共模块如果你的多个技能都涉及输出内容必须严格按Markdown格式货币数值保留两位小数这类共性规则不要在每个SKILL.md里复制一遍。复制会导致改一处忘一处最后几个技能行为不一致。更合理的做法是把公共规则写进System Prompt技能里只保留自己特有的部分。如果非要放在技能层也做成一个公共技能并在其他技能开头引用它。回到最初的问题什么是SKILL我的理解是它把教Claude做专业事这件事工程化了让它从文本框里的固定话术变成可管理、可共享、可迭代的代码资产。怎么写一个优秀的SKILL遵守官方那条最核心的建议就够了——为模型而写不要为给人看而写指令要像给同事的交接文档那样清晰示例要像测试用例那样覆盖边界结构要像好代码那样简单到不需要注释。按照这个标准写出来的技能即使过半年回头看你依然能一眼看懂它当时的设计意图而Claude也依然能稳定地交出符合预期的结果。