扫码打开虎嗅APP

搜索历史
删除
完成
全部删除
热搜词
本文拆解Skill的底层逻辑,指出Skill七成是提示词,额外三成的外部封装才是其核心价值,同时分享了实操经验。 ## 从模型视角看:Skill本质就是带位置优势的提示词 Skill被加载时,只是一串token被放入模型的context window,大模型本身没有专门的Skill执行引擎。 Skill能生效是因为RLHF训练让模型养成了遵循context开头系统格式指令的pattern,它通过占据context前段位置,靠self-attention持续影响后续token生成概率。 ## Skill的作用机制:设计偏移生成概率的「引力场」 Skill没有被模型「执行」,只是通过自身token在attention计算中拉拽后续生成token的概率分布,让输出向期望方向偏移,写Skill本质是设计引力场的形状和强度。 Transformer生成token分为四步:第一步tokenization,Skill的token会直接挤占模型工作记忆,臃肿Skill会降低效果,例如398行的Skill约占2000-3000个token;第二步位置编码,RoPE特性让靠前的Skill指令随着对话变长影响力逐渐稀释,导致长对话后期人设丢失;第三步self-attention计算,只有和当前任务语义高度相关、信息密度高的Skill内容能获得高attention权重,空泛描述等于白写;第四步输出概率分布,纯否定指令会反而激活目标token,效果通常很差。 ## 真正的差异:Skill比纯提示词多了模型外的可管理性封装 Skill有很多内容不会进入模型context window,是给Agent运行时处理的,类似npm包的package.json给npm生态而非V8引擎看。 Skill比纯提示词多了触发路由机制、权限边界声明、模块化子结构、可索引分享的元数据,这些外部能力解决了Skill的可管理问题,能让工作流更可控。 ## 写好Skill的实操要点 信息密度是唯一核心指标,每个token都消耗context预算,要替换空泛描述为具体可校验的指令,一个好示例的效果远胜十段抽象描述。 Markdown结构本身就是指令,关键规则用##标注、枚举用列表、示例用引用块,能借助预训练先验获得更高遵循率。 首次触发语是调性锚点,自回归模型首个输出token会强力影响后续所有内容,触发语的调性会被模型全程自我强化。 否定规则要搭配正面表述,先给正面指令,再加否定约束,最后补充正确示例,效果远胜单独的否定要求。 大型Skill要做子模块懒加载,例如首席蒸馏官Skill将全量3000token的占用降到1000token,省出空间给用户内容和模型思考。
2026-05-19 20:45

Skill的本质不就是提示词?吹什么?

本文来自微信公众号: 碳基智 ,作者:碳基智


最近沉迷于写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左右,省出来的空间全是留给用户原料和模型思考的。

本内容来源于网络 原文链接,观点仅代表作者本人,不代表虎嗅立场。
如涉及版权问题请联系 hezuo@huxiu.com,我们将及时核实并处理。

支持一下

赞赏

0人已赞赏

大 家 都 在 搜

好的内容,值得赞赏

您的赞赏金额会直接进入作者的虎嗅账号

    自定义
    支付: