Skill(或称 Agent 指令包、Prompt Pack)是给大模型的"职业说明书"。但在生产实践中,写得最详细的 Skill 往往最不被遵守。本文从一系列真实事故出发,提炼出七条具有普适性的设计原则——不论你用的是 Claude Code、Cursor、Cline,还是自研 Agent 框架,这些坑都长得一模一样。


写在前面:Skill 的本质矛盾

Skill 的核心机制是:用自然语言文档约束长上下文 LLM 的行为。

这里有个根本性的张力:

文档侧 LLM 侧
时态 静态、有序、确定性 动态、概率性、有遗忘
生命周期 写一次永远在那里 每次生成都重新"理解"
规则形态 显式的 执行是隐式的

理解这个张力是写好 Skill 的起点。Skill 不是说明书,而是约束系统。


原则一:规则必须落到「检查门」上,而不是只写在文档里

失败模式

你在 style-guide.md 里写:

单个段落不超过 100 字,超出即拆分。

然后 LLM 写出一个 300 字的段落。你问它:"你看过 style-guide 吗?"它说:"看过。"问它:"那为什么超长?"它说:“抱歉,我下次注意。”

——下次依然超长。

根本原因

声明式规则(declarative rule)和执行式检查(imperative check)是两件事。文档里写"不超过 100 字"是声明,但如果检查清单里没有"统计每段字数"这一条,规则就不会被执行。

设计要点

每条硬性规则必须满足三件套

规则定义(在哪声明)→ 检查清单条目(如何验证)→ 阻断条件(不过怎么办)
弱设计 ❌ 强设计 ✅
“段落不超过 100 字” “统计最长段落字数 X,X > 100 必须拆分”
“避免重复用词” “列出本文出现 ≥3 次的非功能词”
“保持风格一致” “对照 3 条具体风格指标逐条勾选”

核心:规则的执行力 = 检查门的强制力。任何无法被某个 checklist 项验证的规则,等同于没写。


原则二:在「加载时」解析资源路径,不在「运行时」让 AI 拼接

失败模式

Skill 里写:

配置文件位于项目根目录的 config/ 下,请读取后执行。

LLM 开始猜测项目根目录在哪,从 /home 开始 find,甚至凭空编造一个路径。

根本原因

LLM 不是 shell,它不会自动解析你的环境变量、模板占位符、相对路径。它看到什么字符串就理解成什么字符串——或者更糟,它会"合理推测"一个错误答案。

设计要点

凡是涉及绝对路径、API endpoint、版本号、运行时配置的内容,都应该在 Skill 装载阶段就替换为具体值,而不是依赖 LLM 在运行时拼接。

反模式 ❌ 正确做法 ✅
prompt 中放占位符 种子代码做模板替换
“路径在项目的 config/ 下” “路径在 /home/user/project/config/app.yaml
LLM 运行时拼接 系统装载时硬编码进 prompt

更广义地说:任何 LLM 不需要推理的工程细节,都不要让它推理。 它的注意力是稀缺资源。


原则三:用「主动指令」,不用「能力陈述」

失败模式

可以使用 Bash 工具执行脚本来获取数据。

LLM 阅读后内心 OS:「好的,我了解我有这个能力了。」然后继续不调用 Bash,凭印象编造结果。

根本原因

LLM 对「能力描述」的默认反应是确认能力的存在,不是触发能力的使用。「能做」和「该做」在文本中是两个完全不同的语义场。

设计要点

能力陈述(弱)❌ 主动指令(强)✅
可以使用 X 工具 必须调用 X 工具
建议查阅 Y 文档 加载 Y 文档,逐条对照
注意避免 Z 出现 Z 时立即替换
你有 W 权限 现在执行 W,不要只描述

写 Skill 的时候默念一句话:

「我希望 AI 现在做什么动作?」——不是希望它具备什么能力,而是希望它产生什么具体动作。然后用动词写出来。


原则四:长上下文会稀释规则,必须设置中途检查点

失败模式

你在 Skill 开头加载了 5 条约束:

  • 生成前 500 字时全部遵守 ✓
  • 生成到 2000 字时违反 1 条 ⚠️
  • 生成到 4000 字时违反 3 条 ✗

这不是 LLM 在偷懒,而是注意力机制的物理特性:随着新 token 涌入,早期约束在工作记忆中的相对权重持续衰减。

设计要点

对于长生成任务,单点约束(开头加载)不够,需要前置 + 中途 + 后置三层防御:

[前置:加载约束] → 生成中 → [中途自检 ×N] → 生成中 → [后置:终点强制门]
层级 触发方式 作用
前置 开篇加载 建立约束意识
中途 每 N 字 / 每 N 步 防止规则漂移
后置 终点强制清单 最后一道闸

关键:中途检查点用具体数字触发(“每 1000 字暂停自检”),而不是"适时检查"——后者等于没检查。


原则五:显式区分「内部思考」与「输出内容」

失败模式

LLM 输出里出现:

他走向门口——等等,应该说他冲向门口,因为情境更紧张。他冲向门口。

LLM 把内部修订过程当作正常输出写了出来。

根本原因

LLM 默认不区分「这是给用户看的」和「这是我的思考过程」。在它的视角里,所有 token 都是同等的输出。如果你不显式告诉它"思考停留在脑内",它会把推理痕迹直接写进交付物。

设计要点

凡是涉及生成产物(代码、文章、报告、JSON)的 Skill,都应该有一条明确的边界声明:

内部纠错、自我修订、规则核对——这些过程都发生在你的工作记忆中。
最终输出只包含修订后的终稿,不包含任何自我纠正痕迹。

禁止出现:"等等"、"不对"、"修改为"、"(删除)"、"重新写"等修订语。

同样适用于:

  • 代码生成:不要把「我先尝试 A,再改成 B」写成注释
  • JSON 输出:不要包含 // 这里我犹豫了一下
  • 报告写作:不要出现「上面那段说得不对,应该是……」

原则六:Skill 中的引用文档要强制加载,而不是「可选参考」

失败模式

你写:

写复杂逻辑时可以参考 complex-patterns.md

LLM 永远不会主动去读这个文件。除非你说"必须读",并且给出判断条件 + 加载动作 + 验收标准。

设计要点

引用文档分三种,处理方式不同:

类型 特征 处理方式
常用参考 高频、轻量 直接 inline 在 Skill 主体里
关键专题 触发条件明确 强制加载 + 检查清单
长尾参考 偶尔需要 列入索引,按需加载

对于「关键专题」,标准模板是:

**当 [明确触发条件] 时,必须执行:**
1. 加载 [文档名]
2. 对照其中的 [清单名] 逐条勾选
3. 全部通过后再继续,否则返回修改

三个要素缺一不可:触发条件、加载动作、验收门。少一个就会失效。


原则七:依赖外部世界状态时,强制实时验证

失败模式

用户问:「这个库的最新版本支持哪些功能?」LLM 凭训练数据回答——而训练截止已经是一年前。

或者:「市场上有没有类似产品?」LLM 自信地说"没有"——实际有 50 个。

根本原因

LLM 的世界知识有截止日期,且对自己的不确定性识别能力很差。它会用一个过时但流畅的答案掩盖一个真实但模糊的状态。

设计要点

凡是涉及以下类型的判断,Skill 中必须强制嵌入实时查询步骤:

  • 版本/API 现状:库的最新版本、API 是否变更、deprecation 状态
  • 市场/竞品状态:有没有类似产品、谁在做什么
  • 政策/规范状态:法规、标准、平台规则
  • 数据/价格状态:实时报价、库存、可用性

标准模板:

当任务涉及 [外部世界状态] 时:
1. 必须调用 [搜索/API 工具] 验证当前情况
2. 不得仅依据训练数据作答
3. 若工具不可用,明确告知用户「无法验证,以下基于历史数据」

最后一条很关键——让 LLM 学会暴露自己的不确定性,而不是用流畅性掩盖它。


设计模式总结

将七条原则反向归纳,得到五个可复用的设计模式:

模式 A:约束三件套

规则声明 + 检查清单条目 + 阻断条件

任何硬性规则必须三件齐全。

模式 B:装载时解析

工程细节 → 装载阶段消化 → LLM 看到的是终态

不让 LLM 处理它本不该处理的占位符、模板、配置。

模式 C:前中后三层防御

前置加载 → 中途检查点 → 后置强制门

对抗长生成中的规则漂移。

模式 D:动作语态

"必须做 X" > "应该做 X" > "可以做 X" > "你有做 X 的能力"

强度从左到右递减。生产 Skill 用左两个,避免右两个。

模式 E:思考与输出分离

所有自我修订发生在工作记忆中 → 最终输出只包含终稿

显式声明,不能默认 LLM 知道。


设计自检清单

每写完一份 Skill,过一遍:

  • 每条硬性规则是否在某个 checklist 中有对应验证项?
  • 是否有任何未解析的占位符/模板变量出现在 prompt 中?
  • 关键动作的措辞是「必须」还是「可以」?
  • 长生成任务是否有中途检查点(不只是终点检查)?
  • 是否显式声明了「内部思考不写入输出」?
  • 关键参考文档是否有「触发条件 + 加载动作 + 验收门」三要素?
  • 涉及外部世界状态的判断是否强制实时验证?
  • 检查清单的每一项是否都包含具体可观测的产物(数字、列表、勾选状态)?

结语:从「写文档」到「造约束系统」

很多人写 Skill 的方式像写 README——把功能、用法、注意事项都列清楚,期望 AI 看完就照做。但 LLM 不是工程师,它不会因为某条规则写得清楚就更愿意遵守。

真正有效的 Skill 不依赖 LLM 的善意,而是通过结构性的约束设计让违规成本高于遵守成本:

朴素思维 系统思维
告诉它怎么做 让它不得不那样做
罗列规则 设计检查门
期待理解 强制验证
写一遍生效 多层冗余
信任 LLM 不信任 LLM,设计兜底

Skill Engineering 的本质,是用有限的、确定性的文档结构,为无限的、概率性的 LLM 输出搭建一套护栏。

护栏不在文字的优美,而在拐点的设置。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐