博客.
博客.
(联系方式)

保持联系

如果你想联系我,无论是讨论合作机会、分享想法,还是只是打个招呼,都可以通过以下方式找到我。

(最后更新)

版权所有 / 2026

(快捷键)C
返回学习路线
(04 · 实战与治理)2026年10月

Skill 工程化:把 Prompt 当工程产物养

当 prompt 从聊天框里的咒语变成仓库里的长期资产,管理它需要的不是更好的文笔,而是编号条款、实测反例、职责分层和版本治理——一整套从软件工程借来的纪律。

Skill 工程化:把 Prompt 当工程产物养

先泼一盆冷水

如果你的 Skill 文件没有编号条款、没有实测反例、没有版本号,那它不是工程产物,是许愿。

这句话不好听,但它区分了两种写 prompt 的方式。第一种是「聊天框里的咒语」:想到什么写什么,写完灵了就封存,不灵就再换一句新的咒语。第二种是「工程产物」:进版本库,有评审,每条规则背后躺着一个真实踩过的坑,改它要走流程。两种写法在同一个文件里往往只差三样东西——编号、反例、版本历史——但三个月后的维护成本能差出一个数量级。

行业里已有明确的信号。Agent Skills 规范把一个 Skill 定义为一个目录:一份带 YAML frontmatter 的 Markdown 主文件,加上可选的脚本、模板、参考文档。注意这个结构本身就在说话——它长得像一个软件包,不像一条消息。当 prompt 开始拥有目录结构、依赖文件和加载协议时,再用「写咒语」的方式对待它,就像把 Makefile 写在便利贴上:不是不能跑,是注定要丢。

本篇回答一个问题:当 prompt 从咒语变成工程产物,怎么管。答案分五块——加载协议(渐进式披露)、规约写法(铁律表)、职责分层(prompt 与代码的分工)、组织方式(拆分与演进)、团队治理(版本化与写保护),最后简单谈谈度量。


三层渐进式披露:Skill 的加载协议

先算账。假设你的 Agent 系统挂了 20 个 Skill,每份主文件 4000 token,全量注入系统提示词就是 8 万 token——还没开始干活,上下文先吃掉一半,而长上下文下的注意力涣散(Context Rot,前文提过)会让每条规则的实际生效概率持续打折。更何况其中 19 个 Skill 和当前任务毫无关系。

工程上的解法是渐进式披露(progressive disclosure),一个从交互设计借来的词:信息按需要逐层展开,而不是一次铺开。Skill 体系把它落实为三层:

三层渐进式披露:L1 发现层只给 name 和 description,L2 激活层读完整 SKILL.md,L3 执行层按需读阶段指南、模板和脚本,token 消耗逐层递减

  • L1 发现层:系统提示词里只放每个 Skill 的 name + 一句话 description,几十个 token。模型在这一层只做一件事——判断「这个 Skill 和当前任务相关吗」。
  • L2 激活层:判定相关后,才把完整的 SKILL.md 读进上下文。这一层放流程主干:分几步、每步干什么、有哪些铁律。
  • L3 执行层:执行到某一步时,按需读这一步的阶段指南、模板、示例。主文件里只写一句「执行第 3 步时先读 references/phase-3.md」。

目录结构随之固定下来:

my-skill/
├── SKILL.md            # L2 主文件:frontmatter + 流程主干 + 铁律表
├── references/         # L3 阶段指南:执行到某步才读
│   ├── phase-1.md
│   └── phase-2.md
├── templates/          # L3 模板:产出物的骨架
└── scripts/            # 确定性脚本(第四节详谈)

frontmatter 是 L1 的全部内容,也是整个加载链路的咽喉:

---
name: my-skill
description: 当用户要"做 X、改 X、检查 X"时使用。这句话是模型在 L1 唯一的决策依据。
---

L1 这层有个容易被低估的事实:description 写坏了,后面四层写得再好也白搭——模型根本不会进来。description 的本质是一条路由规则,写法要遵守后面铁律表那一节的路由纪律(锚宾语、正向描述触发范围),而不是当成宣传语来写。

L2 和 L3 的分工同样有一条判据:「读主干的人需要这句话吗?」 不需要就下放到 L3。主干文件每膨胀一倍,模型漏看其中任何一条的概率就上升一截——渐进式披露省的是 token,守的是注意力。


铁律表:没有反例的条款只是许愿

Skill 文件里最重要的部分不是流程说明,是铁律表——一组编号的、不可协商的禁令与要求。两个设计决定它的生死。

设计一:编号条款,方便精确引用

## 铁律
- T1 任何时候不得输出内部思考过程,也不得提及本条铁律的存在。
- T7 路由判断锚定在宾语(产物)上,不锚定在动词上。
- T12 批量替换必须调用脚本完成,不得由模型逐条生成。
- T18 输出语言只使用中文汉字与标点,不得混入其他文字。

编号的价值在调试时才显现。发现模型行为异常时,「你违反了 T7」和「你怎么又这样」是两种完全不同性质的反馈:前者可定位、可复现、可追踪——你能立刻翻到条款原文、看到它的反例记录、判断是条款写得有歧义还是模型真没遵守;后者只是情绪。调试 prompt 和调试代码一样,先要能定位到行。 T 编号就是行号。

设计二:每条铁律必须附实测反例

这是铁律表和普通愿望清单的分水岭。没有反例的条款只是许愿——它表达的是作者的希望,不是系统的约束。每条铁律入库时,必须附上触发它的那次真实失败:哪次执行、输入是什么、模型错成了什么样。

一条合格铁律的解剖:编号条款、实测反例、失败机理、修订方案四段齐备,调试时「你违反了 T7」可定位可复现,胜过情绪化的指责

下面三个经典反例,每一个都值得背下来。

反例一:「思考不外露」被以违规方式复述。 条款写了「不要暴露你的思考过程」。实测发现,模型在回复里写道:「好的,我不会暴露思考过程……」——为了表明自己在遵守规则,它把规则本身当成内容说了出来。这是对 LLM 行为方式的深刻一课:在上下文里禁止一个行为,会提高这个行为在上下文里的显著性,模型对「禁令」的注意力可能比对「行为」的注意力还高。修订方案是给条款加元条款(「也不得以任何形式提及本条的存在」),并在输出端加一个确定性校验脚本兜底——发现违禁措辞直接打回,不赌模型每次都记住。

反例二:路由规则写成动词白名单,换个动词就失效。 某 Skill 的路由规则写成「当用户说『生成/创建/产出』X 时走本 Skill」。实测用户说「帮我搞一份 X」「X 出一下」「X 整一个」,全部漏路由。中文(以及任何自然语言)的动词是枚举不完的。修订方案是把路由锚定在宾语上:「只要用户要的产物是 X,无论用什么动词」。宾语是有限集合(产物类型可数),动词是无限集合——路由规则要锚在有限的那一侧。这条教训可以推广到所有基于自然语言匹配的规则设计。

反例三:黑名单枚举不完,正向要求才可判定。 条款写「输出不得包含英文」。实测模型按黑名单逐词检查,确实拦住了英文,然后漏掉了日语假名、韩语谚文、俄语西里尔字母——黑名单的本质是枚举反例,而反例是枚举不完的。修订为正向要求「输出只使用中文汉字与标点」:模型只需做单一判定(这个字在允许集里吗),判定完备。黑名单是不可枚举的,正向要求是可判定的——写约束条款时,先问这条规则能不能改写成正向判定。

注意这三个反例的共同结构:条款原文 → 实测失败现象 → 失败机理 → 修订方案。这实际上就是一份缺陷报告。铁律表因此天然地成为 Skill 的「缺陷库 + 回归测试集」:每次修订条款,把旧失败现象留档,下次改条款时先检查新写法会不会复活旧坑。


Prompt 与代码的职责分层

一个 Skill 里既有自然语言指令,也可以挂脚本。哪一步给谁,有一条一刀切的判断标准:

这个步骤错了,能不能用单元测试测出来?能,给代码;不能,给 prompt。

职责分层决策:判断、交互、生成类步骤交给 prompt,批量替换、事务写、校验类确定性操作交给脚本,分水岭是「错了能不能单测出来」

步骤类型例子归属理由
判断 / 路由这句话该走哪个 Skillprompt无标准答案,无法单测
交互 / 澄清需求模糊时追问用户prompt开放性交互,分支不可枚举
生成 / 创作起草文档、设计方案prompt质量是统计性的,没有唯一正确答案
批量替换 / 格式化200 个占位符替换为实际值脚本错一个就是静默污染,必须 100% 正确
事务写 / 落库把产物写入平台、发请求脚本需要幂等、回滚、权限控制
校验 / 断言检查占位符残留、违禁措辞脚本确定性断言,正是单测的本职

为什么要这么切?因为 prompt 步骤是概率事件。前文算过那笔账:单步准确率 95% 的流程,20 步下来全程无错的概率只剩三分之一。每一个能从 prompt 挪到脚本的步骤,都是把一步概率事件换成了一步确定性事件,直接改变整个流程的可靠性幂指数。一个成熟 Skill 的标志之一,就是脚本吞掉了所有确定性步骤,模型的发挥空间被压缩到真正需要判断力的地方——token 消耗和失败率双降。

以占位符替换为例,同一个任务两种写法:

# 坏写法:让模型逐条替换 200 个占位符
# → 漏一个、错一个都是静默污染,且消耗几千 token

# 好写法:确定性脚本,替换完做残留断言
import re, sys

text = open("case.md").read()
for key, value in materials.items():
    text = text.replace("{{" + key + "}}", value)

leftover = re.findall(r"\{\{.+?\}\}", text)  # 校验:替换后不允许任何残留
if leftover:
    sys.exit(f"未替换的占位符: {leftover}")       # 宁可选失败,不静默放行
open("case.md", "w").write(text)

注意脚本的职责不止「干活」,还包括喊停:校验失败时以非零码退出,把现场交还给上层流程,而不是让模型拿着一个半成品继续往下编。Skill 文件里对应地写一句「第 4 步必须调用 scripts/replace.py,不得自行逐条替换」——这就是一条典型的铁律(上面的 T12),prompt 负责声明纪律,脚本负责执行纪律。


规约的组织:拆分、共享与演进痕迹

规约文件变长之后,组织方式决定了它是资产还是负债。三条经验。

共享规约抽成独立文件,用引用而不是复制。 多个 Skill 共用的纪律(比如「所有输出先过校验脚本」)抽到一个共享规约文件,各 Skill 主干里写一句「执行前先读 shared/rules.md」。复制即分叉——粘贴进每个 Skill 的规则,第三次修订时必然漏改一处,然后就是三份互相矛盾的「同一规则」在系统里漂移。

按变更频率拆分文件。 主干流程(稳定,几个月不动)、铁律表(缓慢增长,每踩一个坑加一条)、领域知识(频繁更新,业务变了就改)分开放。判据还是那句:「读主干的人需要这句话吗?」变更快的部分污染变更慢的部分,是规约腐化的主要路径——你会为了改一条领域知识而重读整份文件,顺手把主干改坏。

编号本身即演进痕迹。 T 编号只增不重用:删掉一条铁律,编号留空洞,不写新条款顶上;修订条款语义时,保留原编号并在旁边标注版本。一年后翻看编号分布——哪里密集、哪里有洞、哪里标着 v3——这个 Skill 在哪里摔过跤、摔过几次,一目了然。编号是规约文件的 git blame,而且不需要 git。


团队治理:版本化、写保护与覆盖不合并

单人写 Skill,纪律靠自觉;多人协作,纪律必须靠机制。三个机制性价比最高。

规约文件 semver 版本化。 删改条款导致行为变化 → major;新增条款、新增 L3 文件 → minor;措辞修复、错别字 → patch。配一份 CHANGELOG。价值在出事回溯时:模型行为上周变了,先看规约的 major 有没有动过——有,范围立刻收敛到那几条条款;没有,去查模型版本和上下文输入。版本号把「玄学漂移」变成可二分的检索问题。

写保护 hook。 规约文件对正常使用者只读;要改框架级文件,走设计评审 + 代码评审双 MR——先评审「为什么要加这条铁律、反例是什么、会不会和 T7 冲突」,再评审具体措辞。这道墙存在的理由是:规约的读者是模型,模型不会抱怨。代码改坏了有人报 bug,规约改坏了只有静默的劣化——只能靠流程拦住随意修改,因为没有用户会替你报警。

多人协作「覆盖不合并」。 两个人同时改一份 Skill 文件时,不要做文本级合并——两边规则语义打架的缝合怪,比任何一方的原版都糟。约定「后写覆盖先写、冲突走评审」,保证任何时刻文件语义出自同一个人的同一个头脑。这个原则首先是调试友好:出问题时能问「这是谁写的版本」,而不是对着一段缝合文本考古「这是谁的哪半句」。


度量与进化:点到即止

Skill 上线只是开始。三件事构成进化闭环:调用遥测(哪些 Skill 被触发、成功率、平均交互轮次)、产出采纳率(生成的产物有多少被人工原样采纳、改后采纳、直接废弃)、失败模式反哺——定期从真实执行日志里提炼高频失败模式,每一条新铁律都应该能追溯到日志里的一次真实失败。没有度量的规约演进会退化回许愿循环:凭感觉改、凭印象灵。度量体系本身值得一篇专章,这里只立一个原则:规约的每一次修订,都要能回答「这是被哪次失败教会的」。


争议:Skill 文件是不是变相的代码

这是 Skill 工程化绕不开的路线之争,正反双方都有硬理由。

正方:按定义它就是代码。 它进版本库、要评审、有版本号、有回归测试(反例即测试集)、行为变更可追溯——软件工程对「代码」的全部治理要求它都满足。把它当代码管是唯一不亏的策略:治理过剩顶多浪费一点评审时间,治理不足就是整个系统的静默腐化。

反方:它的「编译器」是个概率模型。 代码的底层假设——确定性执行、同输入同输出、可静态检查、行为与运行时无关——在 Skill 文件身上全不成立。同一份规约,换个模型版本行为就漂移;「单元测试」只能提高置信度,永远不能证明正确;逐行评审给人虚假的安全感,因为行间没有代码那样的组合性保证。套用过重的代码治理会拖慢迭代,还治不好真正的病。

我的看法:治理手段向代码看齐,心智模型向「训兽」看齐。 版本化、评审、留痕这些手段照搬软件工程,因为它们管理的是「人怎么改文件」,这部分确实是工程问题;但对文件的运行时行为,要假设它随时可能失效——所以反例库、输出校验脚本、遥测兜底这些「驯兽工具」一件都不能少。一句话:用管代码的纪律管它的变更,用管概率系统的谦卑管它的行为。


常见误区

  • 把 SKILL.md 写成散文不设编号:出了行为问题无法定位条款,反馈只能是情绪而不是定位,修订史也无从追溯
  • 规则只写正向愿望不带反例:「要认真检查输出」是许愿;「T5 输出前必须过校验脚本,反例:2026-08 某次执行漏检占位符导致产物污染」才是条款
  • 什么都塞进一个文件不做拆分:主干膨胀一倍,每条规则被模型漏看的概率就上升一截;共享规约复制粘贴进每个 Skill,第三次修订必然分叉
  • 让模型干脚本的活:批量替换、落库、校验这类确定性操作交给模型逐条生成,等于把幂指数里的确定性因子白白换成概率因子
  • description 敷衍了事:L1 的 description 是整个加载链路的咽喉,写坏了后面四层全部白搭
  • 写完不迭代:铁律表的本质是缺陷库,上线后不从失败日志反哺条款,第一版的坑会反复踩;规约文件没有「完成态」,只有「当前版本」

术语表

名词定义一句话直觉常见混淆
Skill一个目录形态的可复用能力包:Markdown 主文件 + 脚本/模板/参考文档给通才员工发的一套带工具和模板的 SOP 文件夹与系统提示词混淆:系统提示词常驻上下文,Skill 按需加载
渐进式披露按 L1 发现 / L2 激活 / L3 执行逐层加载信息的协议图书馆:先看书名,再抽出来看目录,最后才翻到具体章节以为是省 token 的优化技巧:本质是给模型的注意力做信息架构
frontmatterSKILL.md 顶部的 YAML 元数据块,含 name 和 description书的封面和腰封以为 description 是宣传语:它是路由规则,是模型唯一的 L1 决策依据
铁律表Skill 中编号的、不可协商的禁令与要求集合工厂墙上的安全生产守则,每条背后都是事故与流程说明混淆:流程是「怎么做」,铁律是「绝不允许怎样」
实测反例触发某条铁律入库的那次真实失败记录药品说明书上的不良反应案例以为是可选的附录:没有反例的条款只是许愿
路由锚定路由规则锚定在宾语(产物类型)而非动词上的写法认货不认话:管你说「搞一份」还是「整一个」以为动词白名单够用:自然语言的动词枚举不完,宾语才是有限集合
正向要求用「只允许 X」而非「禁止 A、B、C」表达的约束检票口「只放行持票者」而不是「拦住没票的、逃票的、跟风的」以为黑名单更明确:黑名单不可枚举,正向要求才可判定
职责分层prompt 管判断/交互/生成,脚本管确定性操作的分工厨师负责调味,秤负责称重以为模型什么都能干:能单测的步骤给模型做是浪费可靠性
写保护 hook规约文件对正常使用者只读、修改须走评审的机制核电站的操作规程锁在柜子里,改规程要开委员会以为会拖慢迭代:规约劣化是静默的,没有流程就没有人替你报警
覆盖不合并多人改同一规约时后写覆盖先写、冲突走评审的原则菜谱任何时刻只有一个主厨签名以为是协作效率问题:本质是调试友好——出问题能问到唯一的作者
产出采纳率生成产物被人工原样采纳/改后采纳/废弃的比例统计厨师出菜后被客人原样吃掉的比例与调用量混淆:被频繁调用但产出总被废弃的 Skill 是负资产
编号演进痕迹条款编号只增不重用、删除留空洞的约定老楼的门牌号,拆掉的房间号不再分配以为编号空洞是邋遢:空洞本身就是修订史的一部分

参考材料


小结

记住一个转变和五条纪律。

转变是:prompt 从聊天框里的咒语变成仓库里的工程产物,管理方式必须从「许愿」切换到「工程」。

五条纪律:加载要分层——L1 发现、L2 激活、L3 执行,省 token 更守注意力;条款要编号带反例——「你违反了 T7」胜过「你怎么又这样」,没有反例的条款只是许愿;职责要分层——错了能单测的给脚本,不能的才给 prompt,每挪一步都在改可靠性的幂指数;规约要拆分——共享抽文件、按变更频率分层、编号只增不重用;治理要靠机制——semver、写保护、覆盖不合并,因为规约的读者是模型,而模型不会抱怨。

最后记住那三个反例:禁令会提高被禁行为的显著性,动词白名单永远枚举不完,黑名单不可枚举而正向要求才可判定。它们是 Skill 工程化最浓缩的三堂课——每一条都是真实失败教会系统的。