第五章 从 Tool 到 Skill:认知复用如何发生

第五章 从 Tool 到 Skill:认知复用如何发生

上一章讨论的是连续性:系统怎样把一次任务里的局部结果、上下文和状态接起来,避免每一轮都从零开始。连续工作一旦真的出现,新的压力很快也会跟着出现。memory 能保存这次发生过什么,却不能自动回答下一次该怎样做。它更像库存,保存的是结果、线索和局部经验;可当同一类任务反复出现时,系统真正想复用的已经不只是某条结论,而是到达结论的方法。

系统能不能不再每次都从工具原语临时拼路,而是把一条已经反复证明有效的处理路径直接拿来复用?

Skill 正是为这一层而出现。它不是工具列表上再包一层名字,也不是把提示词写得更长、更细、更像模板,而是一段已经被任务压力反复筛过、值得外置出来的处理协议。在很多框架里,Skill 本身就是作为一种特殊的工具(Tool)暴露给系统的,比如通过 /skill 命令或 use_skill 接口调用。工具和 Skill 的分工因此可以压成一句话:工具压缩动作,Skill 压缩路径;前者让系统可以做,后者让系统知道在这类事情里应当怎样推进。

如果借用程序员更熟悉的类比,这件事并不神秘。公开函数把一段局部实现藏在函数名之后,模块导出把一组内部 helper 藏在 API 之后;调用者只需要知道入口、参数和返回值,不必每次重新展开函数体。Skill 做的其实是同一件事在任务层的延伸:对外暴露的是稳定入口和触发条件,对内封装的是阶段顺序、检查点、门禁与验证。Skill 不是对 Tool 的简单叠加,而是把"怎样组织这些 Tool 才可靠"也一起抽象到了边界之后。

1. 工具为什么不够,全局 Prompt 为什么不行

如果只站在工具层,系统拿到的是一组动作原语:读文件、搜代码、运行测试、发请求、写文档、调用子代理。这些动作当然重要,但它们并不自带方法。给系统 ReadGrepEditRun,它仍然可能把同一件事做得很差,因为复杂任务真正难的,往往不是"有没有这个动作",而是"动作该怎样排布""哪些步骤必须先确认""什么情况下必须停下来""什么时候该验证,什么时候只该继续收集证据"。工具回答的是能力问题,复杂任务要求的却是组织问题。

既然工具不管组织,一个最直觉的解法就是把所有的组织规程都写进 System Prompt 里。在早期的 Agent 尝试中,开发者常常试图把所有常见任务的 SOP(标准作业程序)全部塞进全局提示词。但这种做法很快就会撞上一个极其现实的物理约束:Token 经济学与注意力稀释

这不只是算力成本问题,更是模型表现的致命伤。过长的全局指令会严重稀释模型的注意力,导致它在真正执行某项任务时,反而容易遗漏眼前的检查点或产生幻觉。你不能让一个系统在修 bug 时,脑子里还被迫装着写文档、做审查、发邮件的完整规程。真正的能力组织,必须是"局部动态加载"的。

所以不能把 Skill 简单理解成"更强的工具集合"或"更长的提示词模板"。把一组工具打成一个别名还没跨过本质边界;把指令变长则只会加重上下文负担。让 Skill 真正成立的,是它把"全局静态约束"变成了"按需注入和渐进展开"。什么时候触发,按什么顺序推进,哪些检查点不能跳,什么叫完成,失败后回到哪里------这些协议只在触发条件满足时才进入上下文,并随着任务推进按阶段逐层显影。这种渐进加载既保住了模型对当前任务的高浓度注意力,也免去了让模型每一轮都带着冗余规程陪跑的开销。工具提供原语,Skill 提供按需加载的协议;没有这层按需协议,系统要么在工具海里迷失,要么被全局 Prompt 压垮。

这里还要拆掉一个误解:Skill 的必要性并不来自"模型还不够强"。即使模型足够强,复杂任务也不会因此变成每次都值得重新搜索的空白问题。第三章已经讨论过,复杂软件更像一个不可压缩的搜索空间,里面同时有代码、环境、历史约束、用户偏好和失败代价;可行路径通常很多,真正困难的并不是找不到一条路,而是几乎不可能在每次任务里重新搜索出全局最优路。工程里大多数时候也没有唯一的"最优",只有在当前约束下足够合适、足够满意、能够被验证和复用的路径。Skill 的意义正落在这里:它把已经被多次判定为可行的路径沉淀成工具化的协议和约束,让系统不必每次都从原语开始重新摸索。

2. Skill 是怎么长出来的

Skill 不是被先验设计出来的,它通常是被重复任务逼出来的。处理一类新任务时,系统最开始往往只能把目标、上下文和工具放在一起,临时推一条路出来。这在低频任务里完全合理,因为过早固化常常只会制造僵化。一旦某类任务持续出现,系统就会越来越清楚地看到,哪些步骤其实每次都要做,哪些错误几乎每次都会重犯,哪些检查点一旦省略就很容易把任务带偏,哪些输入输出值得固定下来,免得每一轮都重新解释。到这一步,复用的对象就开始变化了。

最初被复用的,往往只是结论。系统把稳定事实、用户偏好、项目约定写回 memory,这样下一轮不必彻底失忆;把某次任务里的命令、失败日志和阶段进展留在可搜索的历史会话里,等需要时再召回。随着任务加深,系统会开始复用局部表达:常见提醒、固定模板、约束语句、参数结构会被单独拿出来,减少重新拼写的成本。真正让 Skill 成立的,不是这两层,而是第三层:系统开始发现,值得固定下来的已经不是某个句子,而是一整段处理路径。此时被外置出来的,便不再只是知识点,而是一个任务级单元。它知道自己是为哪类问题准备的,知道开始前要不要先澄清,知道中途允许哪些动作,知道什么证据必须收集,知道结束前必须经过哪些验证。

Hermes 把这个边界拆得很清楚。它的沉淀机制不是把所有东西都塞进一个"长期记忆"桶里,而是按用途分流:用户偏好进 USER,稳定环境事实进 MEMORY,一次性历史细节交给 session_search,可复用方法沉淀成 Skill,外部画像再交给可选的 memory provider。prompt_builder.py#L150-L185 里明确写着:task progress、completed-work logs 和 temporary TODO 不要进 memory;如果发现了新的做法、解决了以后可能还会遇到的问题,就保存成 skill;procedures and workflows belong in skills, not memory。工具层也重复了这条边界:memory_tool.py#L512-L535 把 memory 限定为 durable information,skill_manager_tool.py#L797-L823 则直接把 skill 定义成 procedural memory,也就是 recurring task types 的可复用处理方法。

这套分流的关键在于:Skill 不是 memory 的附属品,而是把 memory 里最容易污染上下文的"过程知识"单独抽出来。事实适合默认注入,因为它短、稳定、长期有效;历史细节适合搜索,因为它长、具体、容易过期;流程方法适合 Skill,因为它既不该每轮都占据上下文,又不能丢在历史 transcript 里等模型临时翻找。Skill 因此成为一种独立的沉淀手段:它保存的不是"发生过什么",而是"下次遇到同类事情应该怎样做"。

这延续了软件工程一直在做的事。过去,人把反复出现的有效路径沉淀成函数、库、命令行工具、平台和软件;一旦路径被代码化,后续使用者就不必重新理解每个细节,只要调用被封装好的入口。Agent 出现之后,沉淀的介质多了一层:有些路径不一定马上写成可执行软件,而可以先写成模型能够直接消费的 token 协议。Skill 就处在这个位置。它不是替代软件和工具,而是把"怎样使用这些软件和工具、按什么顺序推进、哪些约束不能破坏"也沉淀下来。过去主要是用代码沉淀动作,现在还可以用 token 沉淀方法;无论是软件、工具还是 Skill,本质上都是把已经有效的复杂性收束成后续可复用的结构。

画成一张图,这条演进的形状是:
#mermaid-svg-zfdjSQooPiZGHrWp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zfdjSQooPiZGHrWp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zfdjSQooPiZGHrWp .error-icon{fill:#552222;}#mermaid-svg-zfdjSQooPiZGHrWp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zfdjSQooPiZGHrWp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zfdjSQooPiZGHrWp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zfdjSQooPiZGHrWp .marker.cross{stroke:#333333;}#mermaid-svg-zfdjSQooPiZGHrWp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zfdjSQooPiZGHrWp p{margin:0;}#mermaid-svg-zfdjSQooPiZGHrWp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zfdjSQooPiZGHrWp .cluster-label text{fill:#333;}#mermaid-svg-zfdjSQooPiZGHrWp .cluster-label span{color:#333;}#mermaid-svg-zfdjSQooPiZGHrWp .cluster-label span p{background-color:transparent;}#mermaid-svg-zfdjSQooPiZGHrWp .label text,#mermaid-svg-zfdjSQooPiZGHrWp span{fill:#333;color:#333;}#mermaid-svg-zfdjSQooPiZGHrWp .node rect,#mermaid-svg-zfdjSQooPiZGHrWp .node circle,#mermaid-svg-zfdjSQooPiZGHrWp .node ellipse,#mermaid-svg-zfdjSQooPiZGHrWp .node polygon,#mermaid-svg-zfdjSQooPiZGHrWp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zfdjSQooPiZGHrWp .rough-node .label text,#mermaid-svg-zfdjSQooPiZGHrWp .node .label text,#mermaid-svg-zfdjSQooPiZGHrWp .image-shape .label,#mermaid-svg-zfdjSQooPiZGHrWp .icon-shape .label{text-anchor:middle;}#mermaid-svg-zfdjSQooPiZGHrWp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zfdjSQooPiZGHrWp .rough-node .label,#mermaid-svg-zfdjSQooPiZGHrWp .node .label,#mermaid-svg-zfdjSQooPiZGHrWp .image-shape .label,#mermaid-svg-zfdjSQooPiZGHrWp .icon-shape .label{text-align:center;}#mermaid-svg-zfdjSQooPiZGHrWp .node.clickable{cursor:pointer;}#mermaid-svg-zfdjSQooPiZGHrWp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zfdjSQooPiZGHrWp .arrowheadPath{fill:#333333;}#mermaid-svg-zfdjSQooPiZGHrWp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zfdjSQooPiZGHrWp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zfdjSQooPiZGHrWp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zfdjSQooPiZGHrWp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zfdjSQooPiZGHrWp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zfdjSQooPiZGHrWp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zfdjSQooPiZGHrWp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zfdjSQooPiZGHrWp .cluster text{fill:#333;}#mermaid-svg-zfdjSQooPiZGHrWp .cluster span{color:#333;}#mermaid-svg-zfdjSQooPiZGHrWp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zfdjSQooPiZGHrWp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zfdjSQooPiZGHrWp rect.text{fill:none;stroke-width:0;}#mermaid-svg-zfdjSQooPiZGHrWp .icon-shape,#mermaid-svg-zfdjSQooPiZGHrWp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zfdjSQooPiZGHrWp .icon-shape p,#mermaid-svg-zfdjSQooPiZGHrWp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zfdjSQooPiZGHrWp .icon-shape .label rect,#mermaid-svg-zfdjSQooPiZGHrWp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zfdjSQooPiZGHrWp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zfdjSQooPiZGHrWp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zfdjSQooPiZGHrWp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 反复出现的任务压力
收束
Tool Primitives
Temporary Path
Repeated Task Pressure
Stable Checkpoints and Order
Skill

这张图里真正关键的,不是 tool,而是中间那层 stable checkpoints and order。Skill 的本质,不在于它调用了哪些工具,而在于它把一类任务的处理顺序和检查点固定下来了。Skill 和 Prompt、Tool、Memory 不在同一层。Prompt 更像入口约束,决定这轮对话如何理解任务、如何组织表达、如何前置禁令;Tool 更像动作边界,把外部世界收束成可调用接口;Memory 保存长期有效的事实和偏好;Session Search 负责召回历史细节;Skill 则站在这些东西之上,把一类任务组织成稳定的行为单元。它会引用 Prompt,会调用 Tool,也会读取 Memory 和历史会话,但它本身不等于其中任何一层。更具体地说,Skill 和公开 API 的关系很像:名字、触发条件和描述相当于对外可见的入口,真正决定行为质量的阶段顺序、红线和验证要求,则更接近被封装在后面的"私有实现"。

从运行时角度看,这件事可以写得更直白:

text 复制代码
if trigger(task, context):
    protocol = load_skill(skill_name)
    context = inject(protocol.rules, protocol.checkpoints, context)
    tools = narrow(protocol.allowed_tools, tools)
    output = run_with_protocol(context, tools)

这里真正新增的,不是某种神秘能力,而是 protocol。Skill 本质上就是把一类任务的处理协议外置出来:触发条件、行为规则、工具作用域、阶段顺序、验证要求、完成条件,都会被写进这份协议。系统复用的因此不再只是答案,而是达到答案的方法。

3. Superpowers 在证明什么

如果想看这种协议被写成工程结构之后是什么样子,Superpowers 是最直接的证据。它的价值不在于"技能很多",而在于它把一场原本容易失控的开发对话,改造成了一条有入口纪律、有阶段切换、有验证闭环、还有回归测试的运行链。只盯着某一个 skill,很容易把这件事看小;更准确的说法是,Superpowers 不是给 Agent 额外挂了几段说明,而是在重写 Agent 默认怎样工作。

最前面的一层,甚至还不是具体任务 skill,而是注入机制。Superpowers 通过 session-start hook,在会话启动、清空和 compact 这些节点把 using-superpowers 直接注入上下文,要求系统在任何响应前先检查 skill 是否适用。hooks.json#L1-L16 定义了触发点,session-start#L17-L55 则把 using-superpowers 的正文直接塞进启动上下文。这里的关键不在"能不能调用 skill",而在"skill 是否已经被前置成默认纪律"。系统不是先自由发挥,再偶尔想起某个 skill;它是一开始就被放进了"必须先判断 skill 是否适用"的工作模式。

进入具体任务之后,Superpowers 真正关心的,也不是某个局部技巧,而是一条受控的阶段链。README 里给出的顺序很清楚:先 brainstorming 把模糊需求收束成可确认设计,再由 writing-plans 把设计拆成可执行计划,随后进入 subagent-driven-developmentexecuting-plans 两种执行分流,在真正宣称完成前经过 verification-before-completion,最后由 finishing-a-development-branch 处理合并、保留、丢弃等收尾决策。using-git-worktrees 当然也重要,但它更准确的位置是常见的隔离策略,而不是所有任务都必须经过的唯一路径。这条顺序在 README.md#L119-L167using-git-worktrees#L209-L218executing-plans#L65-L70 里都能对上。

Superpowers 的主干画成图,更接近这样:
#mermaid-svg-ZiqhAbEDV3CeNoKC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZiqhAbEDV3CeNoKC .error-icon{fill:#552222;}#mermaid-svg-ZiqhAbEDV3CeNoKC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZiqhAbEDV3CeNoKC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .marker.cross{stroke:#333333;}#mermaid-svg-ZiqhAbEDV3CeNoKC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZiqhAbEDV3CeNoKC p{margin:0;}#mermaid-svg-ZiqhAbEDV3CeNoKC .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .cluster-label text{fill:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .cluster-label span{color:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .cluster-label span p{background-color:transparent;}#mermaid-svg-ZiqhAbEDV3CeNoKC .label text,#mermaid-svg-ZiqhAbEDV3CeNoKC span{fill:#333;color:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .node rect,#mermaid-svg-ZiqhAbEDV3CeNoKC .node circle,#mermaid-svg-ZiqhAbEDV3CeNoKC .node ellipse,#mermaid-svg-ZiqhAbEDV3CeNoKC .node polygon,#mermaid-svg-ZiqhAbEDV3CeNoKC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .rough-node .label text,#mermaid-svg-ZiqhAbEDV3CeNoKC .node .label text,#mermaid-svg-ZiqhAbEDV3CeNoKC .image-shape .label,#mermaid-svg-ZiqhAbEDV3CeNoKC .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZiqhAbEDV3CeNoKC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .rough-node .label,#mermaid-svg-ZiqhAbEDV3CeNoKC .node .label,#mermaid-svg-ZiqhAbEDV3CeNoKC .image-shape .label,#mermaid-svg-ZiqhAbEDV3CeNoKC .icon-shape .label{text-align:center;}#mermaid-svg-ZiqhAbEDV3CeNoKC .node.clickable{cursor:pointer;}#mermaid-svg-ZiqhAbEDV3CeNoKC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .arrowheadPath{fill:#333333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZiqhAbEDV3CeNoKC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZiqhAbEDV3CeNoKC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZiqhAbEDV3CeNoKC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZiqhAbEDV3CeNoKC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .cluster text{fill:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC .cluster span{color:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZiqhAbEDV3CeNoKC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZiqhAbEDV3CeNoKC rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZiqhAbEDV3CeNoKC .icon-shape,#mermaid-svg-ZiqhAbEDV3CeNoKC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZiqhAbEDV3CeNoKC .icon-shape p,#mermaid-svg-ZiqhAbEDV3CeNoKC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZiqhAbEDV3CeNoKC .icon-shape .label rect,#mermaid-svg-ZiqhAbEDV3CeNoKC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZiqhAbEDV3CeNoKC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZiqhAbEDV3CeNoKC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZiqhAbEDV3CeNoKC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 验证与收尾
执行与分流
规划与设计
前置注入
no
yes
yes
no
session-start hook
using-superpowers
brainstorming
design approved?
writing-plans
need isolated workspace?
using-git-worktrees
subagent-driven-development
executing-plans
verification-before-completion
finishing-a-development-branch

这张图把 Skill 从"局部技巧"提升成了"阶段控制结构"。brainstorming 解决的是不经设计直接开工的问题,writing-plans 解决的是任务颗粒度过粗、实现者容易乱做的问题,subagent-driven-developmentexecuting-plans 解决的是执行阶段怎样按计划推进的问题,verification-before-completion 则把"没有证据就宣称完成"这种高频错误直接封死,finishing-a-development-branch 负责把最后的分支命运也收进固定流程里。这里沉淀下来的已经不再是知识点,而是一整条围绕失败模式反向设计出来的任务协议。Superpowers 展示的是一种成熟的业务型 Skill:它不只是暴露能力,而是在接管任务推进本身。

Superpowers 还有一个容易被忽略的特点:它不只定义运行链,还验证这条运行链有没有真的生效。docs/testing.mdtests/claude-code 下的测试,并不是简单检查某段文本是否存在,而是直接跑真实的 Claude Code 会话,解析 transcript,确认 skill 是否被触发、subagent 是否真的派发、评审顺序是否正确、测试是否真的执行、实现结果是否真的产生。testing.md#L3-L18testing.md#L40-L64 说得很清楚,README.md#L7-L8 也明确了这是在验证 Claude 是否真的按 skill 行为执行。这个细节说明 Skill 在这里不是写给模型看的信条,而是会被持续评测、持续回归的行为工程单元。

Superpowers 真正证明的并不是"skill 可以复用",而是更强的一句:当一类任务的阶段、检查点、隔离要求和失败模式已经足够稳定时,系统最终会把它们写成可前置、可执行、可验证、可回归的协议。到这一步,被沉淀下来的就不再是"这次怎么答",而是"以后都按什么结构做"。这正是 Skill 本质。

4. Skill 的工程形态与边界

只停留在前面的判断,Skill 仍然会显得有些抽象。更实用的问题是:当系统里已经有一堆工具,也已经积累了不少成功经验时,什么时候这些经验值得提升成 Skill,又该怎样理解它们的工程形态?

并不是所有 Skill 都长得像 Superpowers。同样叫 Skill,有的读起来像流程规程,有的却更像能力手册。差别不在文风,而在它们各自压缩的对象不同。更贴近工程现实的看法是,Skill 至少常见两种形态。工具型 Skill 靠近能力暴露层,主要解决的是接入问题:系统这里到底提供了什么能力,入口怎么写,参数怎么带,边界在哪里,常见误用是什么。这类 Skill 压缩的不是完整任务路径,而是能力接入成本,让模型不必在接口层反复试错。

业务型 Skill 靠近任务组织层,主要解决的则是推进问题:为了完成一类事情,什么时候该先澄清,什么时候必须停下来验证,哪几步不能跳,失败后应当回到哪里。这类 Skill 压缩的不是接口记忆成本,而是任务组织成本。前面之所以反复展开 Superpowers,正因为它最能说明这一类 Skill 的本体:重点不在告诉模型"这里有哪些功能可用",而在规定"做这类事时要按什么协议推进"。把这层区分立住,很多看上去差异很大的 Skill 就容易落回同一张图里了。资料索引、命令说明、参数规范,通常更偏工具型;纪律约束、方法迁移、阶段推进,通常更偏业务型。两者并不互斥,很多 Skill 会同时带有两面,但主导面通常很清楚。

这里还需要澄清一个边界:Skill 并不一定只是静态文本。一个工程化程度更高的 Skill,完全可以配套脚本、CLI 命令、浏览器跳转、状态文件和验证规则。比如某个内部 Skill 可以先调用脚本发起 SSO challenge,再引导用户完成授权,把 token 或 credential 路径保存到本地,随后继续执行后续任务。从使用者视角看,这像是 Skill 自己完成了鉴权;但从系统边界看,Skill 真正做的是组织这条流程,实际执行 SSO 的仍然是脚本、CLI、浏览器、MCP 工具或宿主 runtime。

Skill 的边界不在于"有没有调用外部动作",而在于它压缩的对象是什么。如果它主要回答"这类任务应该按什么顺序推进、什么时候鉴权、鉴权结果放在哪里、失败后如何恢复、完成后如何验证",它仍然是任务协议。如果它开始承担权限签发、身份校验、服务发现和审计记录,那些能力就已经进入了 CLI、MCP、Gateway 或平台服务的范围。两者可以被打包在同一个 Skill 目录里,但概念上不能混在一起。

pi-mono 提供的是另一种更克制、也更偏工具型的写法。它的 skill 体系并没有把自己做成系统能力的中心,运行时真正的重心仍然落在 tool registry、slash command、extension loader 和 session/runtime 这些层上;skill 更像一层按需暴露的流程说明。/skill:name 触发时,宿主做的不是执行一个隐藏子程序,而是把 SKILL.md 读出来,包成协议文本,再送回当前上下文。Skill 因此不是替代 runtime 的执行器,而是 runtime 在合适时机注入给模型的工作方法。

这里真正被宿主承认的,不是"这段文本说了什么",而是"这份协议来自哪里"。Skill 之所以不像一段普通 user message 那样容易滑成提示词攻击,不是因为它天然拥有更高权限,而是因为宿主先通过可见技能索引、文件位置和按需读取这几层机制承认了它的来源。它把过去只能通过代码、文档和人工经验散落保存的方法,收束成一份可被模型即时读取的 token 化中间结构;正因为是按需注入而非常驻,它才成为对 Token 成本和注意力最友好的方法载体。

判断一段路径是否值得 Skill 化,可以拢回到四个条件:它是否高频重复,是否已经长出了稳定的顺序和检查点,失败成本是否足够高,以及输入输出边界是否已经清楚。一次性的偶发任务被立刻做成 Skill,系统很容易过度抽象;如果每次做法都完全不同,只能靠临场探索,那更适合把经验留在 memory 或案例里;如果失败代价并不高,或者"什么时候触发""成功算什么""失败回到哪一步"仍然说不清,那也说明这条路径还没有收束成稳定单元。

只有在这些条件逐渐满足之后,Skill 才会真正长出工程形态。一个像样的 Skill,至少要把五件事写清楚:什么时候触发,它到底要解决什么问题,内部顺序和分支怎样推进,这一阶段允许看见和调用哪些工具,以及在什么条件下算完成、什么时候必须停下或返工。把这些层次写清楚之后,Skill 就不再只是经验总结,而会变成一个真正可触发、可执行、可验证、可迭代的行为单元。也正是在这里,它和普通 Prompt 的差异才被真正拉开。Prompt 可以很强,但它通常还停留在对当前一轮行为的约束;Skill 则开始跨越多轮,直接塑造系统在一类任务里的默认工作方法。更重要的是,这套工作方法在运行时也不必一次性完整摊平,而可以随着任务进入不同阶段逐层展开;因此它压缩的不只是记忆成本,也压缩了当前轮不必要的上下文负担。

把这种工程形态抽象成最小骨架:

markdown 复制代码
---
name: skill-name
description: Use when [真实用户会怎么触发这个 skill,只写入口,不写流程]
---

# Skill Name

## Overview
这个 skill 属于哪个阶段,负责把什么输入推进到什么状态。

## When to Use
什么时候应该加载。这里写正向入口,不展开具体步骤。

## When NOT to Use
哪些相邻场景不该加载,应该交给哪个上游或下游 skill。

## Required Inputs
进入这个 skill 前必须已有的文档、计划、diff、环境、用户决策或验证结果。

## Hard Gate
未满足哪些输入不得进入下一步;允许做什么,禁止做什么;越界后回到哪里。

## Red Flags
Agent 最容易用来跳步、猜上下文、绕过验证或提前宣布完成的真实借口。

## Steps
按什么顺序推进;每一步负责什么,为什么必须在这里做。

## Done When
什么产物或证据已经出现;下一步交给哪个 skill,或者明确停止。

这个骨架把 Skill 和普通提示词分开了:frontmatter 里的触发入口,OverviewRequired Inputs 明确阶段与上游依赖,Hard GateRed Flags 前置失败模式,Done When 把完成条件落到证据和下一步。Skill 不是"把一段要求写长一点",而是把一类任务拆成 trigger -> boundary -> protocol -> gate -> evidence 这样一套完整结构。若借用前面的公开/私有函数类比,frontmatter 和入口描述更像对外暴露的调用面,真正决定这次调用怎样展开的 Required InputsHard GateRed FlagsStepsDone When,则更像被封装在后的实现细节。Superpowers 里很多 skill 虽然细节各不相同,但骨架都绕不开这几层:frontmatter 负责被系统发现,When to UseWhen NOT to Use 负责收缩触发边界,阶段步骤负责定义协议,HARD-GATEIron LawRed Flags 这类段落负责把失败模式显式前置,最后再用 checklist、re-test 或 approval gate 把验证闭环补上。

写一个像样的 Skill 之前,作者首先要把工作流本身想清楚。看上去是在写文本,实际上是在交付自己对一类任务的理解:这件事到底分成几个阶段,哪些动作必须前置,哪些证据必须收集,模块之间怎样切分,每个模块里最容易犯什么错误,跳过哪一步会让后续无法收尾。如果作者自己都说不清这些,写出来的 Skill 只能停留在"尽量做好""注意验证"这种泛泛而谈的层面,最终又把判断权全部交回模型,等于没沉淀。Skill 的密度,恰好等于作者对工作流理解的密度。

参考 superpowers/skills 这一组目录就能看得很清楚:brainstormingwriting-planssubagent-driven-developmentexecuting-plansverification-before-completionfinishing-a-development-branch 各自负责一个阶段,互相之间通过 When NOT to Use 排除误触发;每个 SKILL.md 内部又有自己的小工作流------先要求什么输入、按什么顺序推进、哪些动作算越界、什么时候算完成、下一步交给谁。brainstorming 强调"不进入实现",writing-plans 强调"先把模糊需求拆成可执行计划",verification-before-completion 强调"没有证据不得宣布完成"。这些不是修辞,而是把作者已经踩过的坑直接写成可执行的门禁。

写 Skill 之前先回答五个边界问题------什么时候加载、属于哪个阶段、依赖什么上游、允许做什么、做到哪里停。这五个问题分别对应 descriptionOverviewRequired InputsHard GateDone When。它们的共同点都不是"描述能力",而是"前置约束":description 只写 when 不写 how,Hard Gate 必须是可执行门禁而不是价值观口号,Red Flags 写的是 Agent 用来跳步的真实借口,Done When 必须给出可检查的证据和明确的下一步。这套写法之所以有效,是因为它把作者自己的判断从"凭感觉"逼到了"写得出来"。能写出 Hard Gate,说明你真的知道这个阶段的红线在哪;能写出 Red Flags,说明你真的见过 Agent 在哪些地方偷懒;能写出 Done When,说明你真的清楚什么算完。

所以 Skill 表达的从来不只是流程,还有约束。流程告诉 Agent 应该怎么走,约束告诉 Agent 不能怎么走。两者缺一不可:只有流程没有约束,Skill 会被模型在压力下偷偷绕过;只有约束没有流程,Skill 又退化成几条孤立禁令,无法承接任务推进。Superpowers 之所以读起来既像一组工作流又像一组纪律,正是因为它把这两层一起写进了 Skill。

把视野从 Superpowers 拉开,OpenSpecGSD 也在证明同一件事,只是表达介质不同。Superpowers 本身就是一组显式 Skill:brainstormingwriting-plansverification-before-completion 等目录各自封装一个阶段协议。GSD 采用的是相近的显式 Skill 目录形态:它有 tddverify-before-completereviewhandoff 等多个 skill,每个 skill 内部又用 objectivecontextcore_principleprocessanti_patternssuccess_criteria 这些块,把流程、门禁、反模式和完成证据写清楚。OpenSpec 则不一定把自己表现为一组 SKILL.md,但它用 proposal -> specs -> design -> tasks -> apply -> archive 这样的 artifact graph,把"为什么做、做什么、怎么做、怎样拆任务、什么时候归档"拆成可生成、可检查、可回退的中间产物。它明确反对僵硬阶段,强调 "actions, not phases",但每个 action 仍然有依赖、模板、规则注入和输出位置。

这说明不同系统的 Skill 确实会越来越像。这不是因为大家互相抄模板,而是因为它们面对的是同一组工程失败模式:需求没说清就实现,设计没有边界,任务太大塞不进上下文,验证缺失却宣布完成,阶段之间没有交接物,Agent 用"我大概知道"跳过上下文。只要要解决这些问题,结构就很难逃开几类共同模块:入口条件、阶段归属、上游依赖、允许动作、禁止动作、执行顺序、反模式、完成证据和下一步。标准写法不是审美收敛,而是失败模式倒逼出来的形状收敛。

但这并不意味着开发重新退回瀑布模型。瀑布模型的问题,是把阶段理解成单向、刚性、不可回退的线性通道;这些新的 Skill 和 workflow 更像"带门禁的可迭代协议"。OpenSpec 可以在 proposal、spec、design、tasks 之间反复补充;GSD 把 milestone、slice、task 切成能在一个上下文窗口里完成的工作单元;Superpowers 也允许先 brainstorming,再 writing-plans,再执行和验证,必要时回到前一步。它们收敛的不是"所有项目都必须按同一条线走",而是"任何复杂开发都需要显式中间产物、边界、检查点和证据"。更准确的说法不是瀑布回来了,而是 Agent 时代的开发正在重新长出一套可被模型消费的标准工作协议:它继承了瀑布对阶段和产物的重视,也继承了敏捷对反馈、迭代和小步交付的重视,只是把这些东西写成了 token 化、可加载、可验证的中间结构。

Skill 讲到这里,会自然冒出一个反问:模型越来越强,Skill 会不会越来越不重要?这个判断有一部分对。模型变强之后,那些只是在弥补"不会做"的浅层提示,确实会被模型内部的先验吃掉。比如"按某种风格改写一段文字",直接问模型常常已经能得到看上去不错的结果,因为模型本来就存着大量关于语气、句式和常见写法的模糊印象。问题也正在这里。直接问模型时,系统复用的其实是参数里的平均印象,它能工作,却不总是稳定;一旦给它几段真实样例或一套更明确的协议,结果往往立刻收紧。模型越强,越不需要那些只是为了弥补"不会做"而存在的浅层 Skill;但只要任务里仍然存在顺序、检查点、工具边界、验证要求和失败代价,Skill 就不会消失。它解决的不是"模型知不知道这种风格",也不是"模型能不能临场想出一条路",而是"系统是否要把已经证明可行的路径沉淀下来,避免每次重新搜索、重新解释、重新承担同一种失败风险"。

当然,Skill 也不是越多越好。把路径固化出来,收益很直接:常见任务不必每次从工具原语重新拼装,失败模式更容易被提前堵住,系统行为更一致,验证点也更容易前置。但代价同样明显。一条路径一旦被证明有效,就很容易被重复调用;如果环境已经变化,任务已经变形,系统仍然按旧协议推进,就会出现僵化。过早把一类任务总结成"标准流程",又可能把还没有想清楚的东西写死,结果不是提升复用,而是扩大误用。与此同时,Skill 还会增加触发治理的复杂度:什么时候该触发,什么时候不该触发,多个 Skill 冲突时谁优先,都是工程问题。如果这层没有设计好,Skill 体系反而会变成新的噪音来源。更根本的一点是,Skill 会把原本隐藏在上下文里的方法显式化,这本身就是成本。你必须真的把那条路径讲清、拆清、验证清,它才可能变成可复用单元。

Skill 是任务经验被工程化之后的结果。它出现的前提,不是系统已经拥有很多工具,而是系统已经在同类任务里反复遇到同样的组织问题,并且开始有能力把这些问题的解法写成协议、前置成纪律、固化成入口。它和第三章里的中间结构是同一条逻辑:复杂任务不能每次从完整搜索空间里重新开始,只能把已经被环境判定过、在当前约束下足够满意的路径沉淀下来,作为后续继续推进的稳定支点。memory 把局部经验持续接起来,Skill 则把这些局部经验继续提炼成跨任务可复用的方法。

Skill 让系统第一次把"怎样做一类任务"写成稳定语义,它甚至可以编排脚本、CLI、浏览器和本地状态,完成鉴权、查询、验证和恢复这些跨步骤动作。只要这些动作依赖外部资源,问题就不会停在 Skill 本身:工具怎样暴露,权限怎样校验,credential 怎样保存,内部数据源怎样接入,不同宿主之间怎样共享同一套能力。Skill 解决任务语义复用,能力接入复用则要交给另一层协议。

相关推荐
林小卫很行1 小时前
Obsidian 入门58:用 Remotely Save + 腾讯云 COS 实现多端同步
人工智能·云计算·腾讯云·知识管理·obsidian
继续商行1 小时前
Go并发模型深度剖析:从GPM调度到Channel通信原理的底层实现
人工智能
岳小哥AI1 小时前
一篇标题只有5个单词的论文,改变了整个AI世界,并打开了AI大语言模型时代
ai·ai基础
linge_sun1 小时前
SpringAI SQL 智能助手实战:用自然语言查询数据库
java·人工智能·ai编程
圣殿骑士-Khtangc1 小时前
2026 AI 编程工具终极实战指南:Cursor vs Claude Code vs Copilot,开发者该怎么选?
人工智能·copilot
澹锦汐1 小时前
独立开发者的出海架构:从单一市场到全球化部署
人工智能
lovePaul771 小时前
CSDN 自动发布测试
ai·自动化·csdn
深度学习lover1 小时前
<数据集>yolo航拍视角垃圾识别<目标检测>
人工智能·深度学习·yolo·目标检测·数据集·航拍视角垃圾识别
孟俊宇-MJY1 小时前
CSDN AI数字营销GEO工具测评
人工智能