为什么你的 AI Skill 总是不生效?从 Anthropic 内部实践看 Skill 设计的三个层次
AI Agent Skill 写了不调用、调用了效果差?拆解 Anthropic 工程团队的 9 条 Skill 设计实践,从内容层、结构层到高级技术层,解决 Skill 不生效的根本问题。
这个行业里有一种很普遍的情绪:花两小时写了个 Skill,AI 从来不调用;好不容易调用了,执行起来又僵化得像个 shell 脚本。然后有人提出了一个很尖锐的问题——"我让 AI 帮我写 Skill 不就行了,为什么还要自己写?"
这个问题背后藏着一个更深的困惑:Skill 到底是什么?它和我们以前写的工作流编排、自动化脚本有什么本质区别?还是说,这只是换了个名字的老东西?
我在 AI 工具链这个方向做了一段时间,从 prompt engineering 到 Agent 工作流设计都有涉猎。我的判断是:Skill 确实是工作流编排的延续,但设计逻辑发生了根本性的变化。以前的工作流是给机器执行的确定性脚本,现在的 Skill 是给一个"有判断力的 Agent"提供的能力模块。这个区别决定了你该怎么写它。
最近读到 Anthropic 工程师 Thariq 分享的 Claude Code 内部 Skill 构建经验,他总结了 9 条最佳实践。今天不是翻译文档,是结合我自己踩过的坑,把这套方法论拆成三个层次来讲。
第一层:你没让 AI "看见"你的 Skill
大多数人写 Skill 的 Description 字段时,会写成功能说明:"这是一个监控 PR 状态的工具"、"这是一个代码格式化 Skill"。
看起来没问题,但 AI 不是这么工作的。
Agent 启动会话时,会扫描所有可用 Skill 的 Description,然后做一个判断:用户当前的请求,有没有对应的 Skill 可以用?它需要的不是"这个 Skill 能做什么"的说明书,而是"什么时候该用它"的触发条件。
换句话说,Description 是写给模型看的调度信号,不是写给人看的功能介绍。
正确的写法应该是:"当用户说 watch CI、babysit this PR、make sure this lands 时触发"。你得用 AI 能匹配到的自然语言模式来描述触发场景。这一点在 Anthropic 官方的 Skill 编写指南中也有明确说明——Description 决定的是 Skill 何时被激活,而非它能做什么。
这是 Skill 能不能被调用的第一道门槛,很多人卡在这里都不知道。
第二个常见错误:在 Skill 里写了一堆 AI 本来就知道的东西。
Anthropic 内部有个真实案例。他们的 frontend design skill 一开始写了大量 React 组件规范、样式指南。后来发现完全没必要——AI 本来就会写 React。真正的问题是 AI 生成的界面总是用 Inter 字体配紫色渐变,看起来很"AI 味",客户反馈说不喜欢。
最终这个 Skill 被精简到只做一件事:告诉 AI "别用 Inter 和紫色渐变,客户不喜欢这种风格"。
Skill 的价值在于补充 AI 默认不知道的上下文——你们团队的偏好、踩过的坑、特殊约定。通用知识它都会,你要告诉它的是"我们这里不一样"的部分。
第三个实践是构建 Gotchas 部分。Anthropic 发现,任何 Skill 里信号最强的内容不是教程,而是"坑"。比如:
- 不要在循环里调用这个 API,会慢一百倍
- 记得清理临时资源,我们生产环境因为这个磁盘满过
教程 AI 自己能找到,但你们团队独有的坑,只有写进 Skill 它才知道。而且这个部分应该随时间持续更新——每踩一个新坑,就加一条。
第二层:结构决定了 Skill 能不能复用
内容写对了,Skill 能被调用了,但很多人会发现换个项目、换个场景就不好使了。这是结构层的问题。
最常见的错误是把 Skill 写成一个巨大的 Markdown 文件,所有内容都塞在里面。但 Skill 是文件夹,不是文件。你可以放脚本、模板、数据文件、配置。主文件只写核心逻辑,详细文档放在 references.md 里,告诉 AI "需要的时候自己去读"。
这种设计在 AI 领域有个专门的名字叫 Progressive Disclosure(渐进式披露)——先给最少的信息让 Agent 能行动,需要更多细节时再按需加载。AI 的上下文窗口是有限资源,你把所有内容一次性塞进去,反而会稀释关键信息的权重。Anthropic 在官方文档中也明确提到:"Claude reads SKILL.md only when the Skill becomes relevant, and reads additional files only as needed."
另一个结构问题是过度约束。很多人会写"先运行 test,再运行 lint,最后运行 build"。这样写太死了。换个项目,test 和 lint 的顺序可能要反过来;有些项目根本没有 lint 步骤。
更好的写法是:约束目标,而不是约束路径。"在部署前确保代码通过测试、规范检查和构建,根据项目情况调整顺序。"
我在和做工程效率的朋友聊这个问题时,他说了一句很到位的话:"这就是从 if-else 编程到让 AI 理解意图的转变。"以前我们写工作流是硬编码每一步,现在写 Skill 应该是声明目标,让 AI 自己规划路径。
但这里有个现实问题——我自己也遇到过"约束了路径,换一个项目就不稳定"的情况。这恰恰说明约束路径本身就是不稳定的根源。路径是具体的、场景相关的,目标才是可迁移的。
第三层:让 Skill 从脚本变成有记忆的助手
前两层解决了"能用"和"好用",第三层解决的是"越用越好用"。
默认情况下,Skill 每次运行都是全新的,不记得上次做了什么。Anthropic 的解决方案是让 Skill 写日志——每次运行后追加一条记录,下次运行时先读取日志,只报告新的变化。
这让 Skill 从无状态的脚本变成了有记忆的助手。比如一个监控 CI 的 Skill,第一次运行报告"3 个测试失败",第二次运行只报告"新增 1 个失败,之前的 2 个已修复"。
第二个高级技巧是存储可调用的代码。别让 AI 每次都从头写样板代码,把稳定的能力封装成脚本和辅助函数,让 AI 负责组合,而不是重造轮子。给 AI 最好的工具不是更多文档,而是可以直接 import 的代码。
第三个是按需 Hooks。有些规则太严格,你不想一直开启,但特定场景下又需要。Anthropic 有个 careful skill,调用后会注册一个 Hook,阻止 rm -rf、drop table 这类危险命令。关键是——这个 Hook 只在当前会话有效,会话结束自动失效。
这种"临时护栏"的设计思路很值得借鉴。不是所有安全规则都要全局生效,有些只在高风险操作时才需要激活。
反面:Skill 真的不是换了名字的工作流编排吗?
说到这里,必须正面回应一个质疑:这套东西和传统的工作流编排(Workflow Orchestration)到底有什么区别?
公平地说,相似性是存在的。Description 对应的是触发条件(Trigger),Gotchas 对应的是异常处理(Error Handling),Progressive Disclosure 对应的是懒加载(Lazy Loading)。如果你把 Skill 的每个组件拆开看,都能在传统工作流引擎里找到对应物。
但关键区别在于执行者变了。
传统工作流的执行者是确定性引擎——你写 if-else,它就走 if-else,没有任何"理解"可言。Skill 的执行者是一个有推理能力的 Agent——你给它目标和约束,它自己决定路径。这意味着:
- 传统工作流需要穷举所有分支,Skill 只需要声明边界
- 传统工作流的复用靠参数化,Skill 的复用靠 Agent 的泛化能力
- 传统工作流出错了你得改代码,Skill 出错了你可能只需要加一条 Gotcha
所以我的判断是:Skill 是工作流编排在 Agent 时代的进化形态,不是简单的改名。但如果你用写传统工作流的思路来写 Skill——穷举步骤、硬编码路径——那它确实会退化成一个笨拙的脚本。
还有一个元问题:让 AI 写 Skill 靠谱吗?
既然 AI 能写代码,让它自己写控制自己的 Skill 不是更高效?
我试过。结论是:初稿可以让 AI 生成,但打磨必须人工介入。
原因很简单——Skill 里最有价值的部分是 Gotchas,而 Gotchas 来自你们团队真实踩过的坑。AI 没有你的生产环境经验,它不知道"这个 API 在循环里调用会慢一百倍",因为这是你们的特殊情况,不是通用知识。
用 AI 生成 Skill 的合理工作流是:让 AI 搭骨架(结构、Description 模板、基本逻辑),然后你来填肉(Gotchas、团队偏好、真实案例)。对于工作流级别的复杂 Skill,从创建到稳定,两小时不一定搞得定——这不是 AI 能不能写的问题,是你的领域知识需要时间沉淀的问题。
我的判断和行动建议
Skill 不是 Prompt。 这是这篇文章最核心的一句话。
Prompt 是一次性的指令,你告诉 AI 每一步做什么。Skill 是可复用的能力模块,你给 AI 的是组合的能力和判断的依据,让它在执行时自己决定怎么做。写 Prompt 的人倾向于事无巨细地规定流程;设计 Skill 的人倾向于定义边界和目标,把路径选择权交给 AI。
如果你现在的 Skill 效果不好,按这个优先级排查:
- 先查 Description——写的是触发场景还是功能说明?改成"当用户说 XX 时触发"的格式
- 再删冗余——内容里有多少是 AI 本来就知道的?大胆删,只留团队特有的信息
- 加 Gotchas——把最近踩的坑写进去,这是 Skill 里 ROI 最高的部分
- 松绑路径——把"先做 A 再做 B"改成"确保 A 和 B 都完成"
- 拆文件夹——主文件只放核心逻辑,详细内容让 AI 按需读取
如果你还没开始用 Skill,建议从一个小场景切入:找一个你每次都要重复给 AI 说的指令(比如"代码风格用 XX"、"测试覆盖率要达到 XX"),把它写成 Skill。先跑通"被调用"这一关,再逐步优化结构和状态管理。
说到底,AI Agent 的能力上限不取决于模型本身有多强,而取决于你给它的"工具箱"设计得有多好。Skill 就是这个工具箱里最重要的组件——设计好了,AI 能自主完成复杂工作流;设计差了,它就是个需要你手把手带的实习生。
你在用 AI 工具的过程中,有没有遇到过"明明配置了但就是不生效"的问题?最后是怎么解决的?