碳基智2026年05月13日预计 7 分钟最近沉迷于写 Skill,正好刷到了某乎上有这样的问题讨论,于是想来聊聊我的理解。
结论先摆在最前面:说 Skill 本质是提示词,对了七成。
但剩下的三成,反而是 Skill 之所以重要的关键。
1 先从模型本身视角来看,其实它压根不知道什么叫 Skill。
这是理解这个问题最重要的前置认知。以我前两天写的「首席蒸馏官 Skill」为例:398 行 Markdown,里面写了身份设定、工作流、品控守则、调性规范。
但当这个 Skill 被加载的时候,发生的事情其实非常朴素:这 398 行文本被塞进了一个叫 context window 的东西里,变成了一串 token 序列。
然后,就没有然后了。大模型本身并没有一个 Skill 执行引擎,它不会说「哦我现在加载了蒸馏官模式,让我切换到蒸馏逻辑」。
它只是看到了一堆 token,跟它看到你打的「帮我写个总结」这句话的方式完全一样。
对 Transformer 来说,这些 token 没有标签,没有优先级,没有所谓系统指令优先的标记。
模型会按照 Skill 逻辑执行的原因是训练。在 RLHF 阶段,模型被大量训练了一个 pattern:当 context 开头出现类似 system prompt 格式的文本时,后续生成应该遵循这些指令。
你把同样的文本用 system prompt 格式发送,还是用 user message 格式发送,模型的遵循程度是有差别的,因为训练数据里这两种位置的指令遵循率不同。
当然,你要是 token 自由,你直接把这些 prompt 发对话框里,效果也差不到哪儿去。
所以第一个技术事实很明确:从模型推理的角度,Skill 就是一段提示词。
它通过占据 context window 中的前段位置,利用 self-attention 机制持续影响后续每一个 token 的生成概率。
2 那么,一段 Skill 文本到底是通过什么机制控制模型输出的呢?
Transformer 生成每一个新 token 的时候,做的事情可以简化成四步:第一步,把 context window 里所有已有文本切成 token(tokenization)。
中文大概是 1-2 个字对应一个 token,英文大概是一个单词或半个单词。
我的 首席蒸馏官 Skill 398 行大概会被切成 2000-3000 个 token,这些 token 直接占据模型的工作记忆容量。
这里有个坑是很多人都会踩的,最开始都想着把 Skill 写丰满,想到什么都往里加,最后模型输出效果反而越来越差,于是又开始做减法。
一个臃肿的 Skill 会挤占用户对话和模型思考的空间,写多了是有代价的。
第二步,给每个 token 打上位置编码(positional encoding)。
现在主流用的 RoPE(旋转位置编码)有一个特性:距离当前生成位置越近的 token,在计算 attention 时天然有更高的关联权重。
Skill 文本在序列的最前面,当对话越来越长,Skill 里的指令跟当前生成位置的距离就越远,影响力会被稀释。
这就是为什么长对话到后面模型会逐渐丢掉你给它设的人设,而我在这个问题上最近已经被搞得没脾气了。
第三步,self-attention 计算,核心中的核心。
每个待生成的 token 会计算一个 query 向量,然后拿这个 query 去跟前面所有 token 的 key 向量做点积,得到 attention 分数,再 softmax 归一化,最后用这些分数加权求和所有 token 的 value 向量。
翻译成人话就是:模型在生成下一个字的时候,会回头看前面所有的字,但有选择地重点关注某些字。
Skill 里哪些字会被重点关注?那些跟当前生成任务语义高度相关的、信息密度高的 token。
写「请产出高质量内容」这种话,跟任何具体任务的语义相关度都很低,所以 attention 权重分不到它头上,等于白写。
第四步,输出概率分布。最后一层 Transformer 输出一个巨大的 logits 向量(比如 10 万维,对应词表里 10 万个可能的 token),softmax 之后变成概率分布,模型从中采样下一个 token。
Skill 里写"不使用感叹号"会发生什么?训练时模型学过否定指令的目标 token 应该被抑制,所以"!
"这个 token 对应的 logit 会被压低。
但这里有个反直觉的点:为了理解"不使用感叹号",模型需要先 attend to 感叹号这三个字,这反而会在某种程度上激活"!
"的相关表征。这就是为什么纯否定式指令效果差,你说"别写感叹号"反而提醒了模型感叹号的存在,AI 犟种就这样炼成了。
这四步串起来看,会得出一个关键性的洞察:Skill 其实没有被「执行」,它起到的是一个引力场的作用。
它通过自己的 token 在 attention 计算中持续拉拽后续生成 token 的概率分布,让输出向你期望的方向偏移。
写 Skill 的本质是在设计引力场的形状和强度。
3 如果只看进入模型的部分,Skill 和提示词确实没区别,真正的区别在模型外部。
还是拿首席蒸馏官 Skill 为例:打开 SKILL.md 文件,它的 YAML frontmatter 长这样:name: "首席蒸馏官"version: "2.0.0"triggers: ["蒸馏", "CDO", "帮我蒸馏"]allowed-tools: [Read, Write, WebFetch, Edit, Bash]这些东西不会进入 context window。
它们是给 Agent 的运行时看的,负责的是:什么时候加载这个 Skill(trigger 匹配)、加载后模型能用哪些工具(权限白名单)、怎么管理版本和更新(version)。
这就像你写了一段 JavaScript 代码能跑,但你把它打包成 npm 包之后,多出来的 package.json、入口声明、依赖管理、版本号这些东西不是给 V8 引擎看的,是给 npm 生态看的。
V8 引擎只认 JavaScript(就像大模型只认 token)。
Skill 比纯提示词多出来的东西,拆开看:一个触发路由机制,按需加载,不干占着 context。
一个权限边界声明,限制加载后模型能调用哪些工具,防止一个写内容的 Skill 去执行危险的系统命令。
一个模块化结构,大型 Skill 可以只加载当前需要的子模块。
一套元数据(名字、版本、标签),让 Skill 可以被索引、被发现、被分享、被版本管理。
这些东西的共同特点是:它们在模型外面运行,解决的是可管理性的问题。
模型本身不会因为这些封装变聪明,但你的工作流会因此变得可控。
4 所以,写好 Skill 到底要注意什么?搞清楚了底层原理,实操层面的 know-how 就很自然了,以下是我的几点经验总结:信息密度是唯一重要的指标。
每个 token 都在烧 context 预算。
写"你是一个专业的、认真的、高质量的内容生产者"等于浪费了 20 个 token 说了一句模型完全无法理解的废话。
什么叫专业?什么叫高质量?模型不知道。你需要换成这种格式:## 标题 + 3-5 条核心要点 + 来源标注。
这是具体的、可校验的、模型知道下一步该生成什么 token 的指令。
一个好的示例比十段抽象描述有效得多,因为示例直接提供了模型可以延续的 pattern。
Markdown 结构本身就是指令。 模型在预训练时见过海量 Markdown 文档,## 标题后面跟重要内容这个 pattern 已经被深度编码进了参数里。
你用 ## 标注的内容,在 attention 计算时天然会获得更高的权重,因为模型学过标题后的内容需要被更多后续 token 关注。
利用这个训练先验:关键规则用 ## 标注,枚举用列表,示例用 \> 引用块。
这比写一坨纯文本段落的遵循率高得多。首次触发语是调性锚点。
自回归模型有一个特性:第一个输出 token 的选择会极强地影响后续所有 token。
模型在生成第一句话的时候,Skill 里的首次触发文本是它最近的参考。
首席蒸馏官的首次触发语是"👋 我是首席蒸馏官,碳基智开源的知识蒸馏工具",这句话锚定的是:冷静、专业、克制。
如果你把它写成"嗨嗨嗨!超开心见到你!有什么我能帮忙的吗?
",后续整场对话都会被拉向浮夸,因为模型的第一句输出就定了调,后面它会自我强化这个调性。
否定规则要搭配正面表述。 前面讲过,"不要用感叹号"会让模型先 attend to 感叹号这个概念。
更有效的写法是先给正面指令(句末用句号收束),再给否定约束(禁止使用感叹号),最后给一个正确示例。
三层信息互相加强,比单独一个"不要"强三倍。子模块懒加载是大 Skill 的命门。
一个 400 行的 Skill 全量加载进 context,在 128K 窗口里占 3000 多 token,看起来不多。
但如果你同时还有 system prompt、对话历史、用户上传的长文档,context 很快就满了。
首席蒸馏官的做法是主文件只放 80 行路由逻辑 + 通用守则,具体的蒸馏流程放在子文件里按需 Read。
这样实际 context 占用从 3000 token 降到 1000 token 左右,省出来的空间全是留给用户原料和模型思考的。大家如果还有其他经验,欢迎交流分享。
Skill的本质不就是提示词?吹什么?