本技能是一份关于如何编写与编辑技能(skill)的参考指南,目标是让技能变得可预测。它的基本立场是:技能存在的意义是从随机(stochastic)系统中压榨出确定性;可预测性——智能体每次运行走同一套流程,而不是产出相同的结果——是根本美德,下文所有手段都服务于它。文中加粗的术语在 GLOSSARY.md 中有定义,可前往查阅完整含义。
一、调用方式
有两种选择,代价不同。
模型调用(model-invoked)的技能保留 description,因此智能体可以自主触发它,其他技能也能触达它(你同样可以手打它的名字)。它会带来上下文负载(context load)——description 每一轮都占据上下文窗口。机制:不要设置 disable-model-invocation,并写一个面向模型的 description,包含丰富的触发措辞(如“Use when the user wants…, mentions…”)。
用户调用(user-invoked)的技能把 description 从智能体可及的范围内剥离:只有你手打它的名字才能调用,其他技能也无法调用。上下文负载为零,但消耗认知负载:你自己就是那个必须记住它存在的索引。机制:设置 disable-model-invocation: true;description 转为面向人——一句话摘要,触发词列表去掉。
只有当智能体必须自行触达该技能、或另一个技能必须触达它时,才选择模型调用。如果它只会被手动触发,就做成用户调用,不付上下文负载。当用户调用的技能多到你记不住时,堆积的认知负载可用路由器技能(router skill)来化解:一个用户调用的技能,列出其余技能以及各自何时使用。
二、撰写 description
模型调用的 description 干两件事——说明技能是什么,以及列出应该触发它的各个分支。每个词都会增加上下文负载,所以 description 比正文更需要下狠手精简:
把技能的引领词(leading word)前置——description 正是引领词发挥调用作用的地方。
每个分支一条触发词。给同一个分支改名的同义词就是重复——“build features using TDD … asks for test-first development”是同一个分支写了两遍。把它们合并,只保留真正不同的分支。
砍掉正文里已有的身份说明。description 只保留触发条件,外加任何“当另一个技能需要……”的触达子句。
三、信息层级
技能由两类内容构成——步骤(steps)与参考(reference)——二者可自由混用:技能可以全是步骤、全是参考,或两者兼有。核心决策是用哪一种,以及各自处在信息层级(information hierarchy)的哪一级。信息层级是按智能体对该材料的即时需要程度排序的阶梯:
技能内步骤(in-skill step)——SKILL.md 中一条有序动作,属于首要层级:智能体做什么,按顺序。每个步骤以一个完成判据(completion criterion)收尾,即告诉智能体工作已完成的那个条件。让判据可检验(智能体能分辨完成与未完成吗?),在重要之处还要穷尽(“每一个被修改的模型都已交代”,而不是“产出一份变更清单”)——含糊的判据会招致过早完成。
技能内参考(in-skill reference)——SKILL.md 中的一个定义、规则或事实,按需查阅。它常常是一组合法的扁平同级项(一次评审的每条规则都在同一级)——这是合理的安排,不是坏味道。本技能全部是参考。
外部参考(external reference)——被推出 SKILL.md 到单独文件中的参考,通过上下文指针(context pointer)触达,只在指针触发时才加载。(范围从披露的参考——如 GLOSSARY.md 这类仍属于技能一部分的兄弟文件——一直到完全存在于技能系统之外、任何技能都可指向的外部参考。)
严苛的完成判据会驱动充分的功课(legwork)——智能体在工作中所做的深挖——无论技能有没有步骤,因为“每条规则都已应用”对扁平参考的约束,正如“每一步都已完成”对序列的约束。
往下推得太少,顶部会臃肿;推得太多,又会藏起智能体真正需要的材料。这一张力就是全部决策所在。
渐进式披露(progressive disclosure)就是在阶梯上下移——走出 SKILL.md 进入一个链接文件——以保持顶部清晰可读。机制:技能文件夹中一个链接的 .md 文件,按其内容命名(本技能把完整定义披露到 GLOSSARY.md)。有些技能以不止一种方式被使用,每一种不同方式就是一个分支(branch)——不同运行在技能中走不同路径。分支是检验披露的最干净标准:每个分支都需要的就内联,只有部分分支会用到的就推到指针之后。决定智能体何时、以多可靠的程度触达该材料的,是上下文指针的措辞,而不是它的目标。
阶梯决定一个内容该放多深,共置(co-location)则决定它一旦放下后旁边挨着什么:把一个概念的定义、规则和注意事项放在同一个标题下,而不是分散各处,这样读到一部分就会把邻近部分一并带出。
四、何时拆分
粒度(granularity)是你把技能切得多细,每一刀都要花掉两种负载之一,所以只有切得值时才切。有两种切法:
按调用拆——当你有一个独特的引领词应当独自触发它、或另一个技能必须触达它时,就拆出一个模型调用的技能。你要为这个新的、始终加载的 description 付上下文负载,所以这种独立触达必须值得。
按序列拆——当仍在前头的步骤(某步骤的完成后续步骤)会诱使智能体赶工眼前这一步(过早完成)时,就把一串步骤拆开。让它们不在视野内,会鼓励智能体对当前任务做更多功课。
五、精简
让每个含义只有一个事实来源(single source of truth):一个权威之处,改行为只需改一处。
逐行检查相关性:它是否仍然切合该技能所做的事?
然后逐句、而不只是逐行地揪无操作(no-op):对每句话单独跑无操作测试,一旦不过,就删掉整句,而不是从中修词。要下狠手——大多数不过关的散文应当删除,而不是改写。
六、引领词
引领词(leading word)是一个紧凑概念,它已存在于模型的预训练中,智能体在运行技能时用它来思考(例如 lesson、fog of war、tracer bullets)。它在全文中反复出现(但未必——一个强有力的引领词也许只需出现一次),积累出一种分布式定义,以最少的 token 锚定一整片行为区域,靠的是调用模型既有的先验。
它两次服务于可预测性。在正文中它锚定执行:每次这个词出现,智能体都伸手去够同一行为。在 description 中它锚定调用:当同一个词也活在你的提示词、文档和代码里时,智能体就把这种共享语言与技能联系起来,更可靠地触发它。
寻找机会把技能重构为使用引领词。一个三处铺陈的三元组(重复),一句 description 花一整句话去比划一个想法——每一处都是 begging 要塌缩成单个 token 的段落。例如:
“fast, deterministic, low-overhead” -> tight——把跨越一个阶段反复陈述的一种品质,收进一个预训练词(tight loop)。
“a loop you believe in” -> red——把一个模糊的门槛转成二元的可观察状态(循环在 bug 上变红,或者不变红)。
你会双赢:更少的 token,以及一个更锋利的钩子供智能体挂住它的思考。假设每个技能都带着可被引领词退休的重复陈述——去找出来。
七、失败模式
用这些来诊断用户可能遇到的技能问题。
过早完成(premature completion)——在一步真正完成之前就结束它,注意力滑向了“已完成”。防御,按序:先磨利完成判据(便宜、局部);只有当它无可再减地模糊且你确实观察到赶工,才通过拆分(按序列拆)隐藏完成后续的步骤。
重复(duplication)——同一含义出现在不止一处。代价是维护与 token,并把一个含义在阶梯上的显著度抬到高于其真实级别。
沉积(sediment)——陈旧层沉积下来,因为加东西感觉安全、删东西感觉有风险。任何没有精简纪律的技能的默认命运。
蔓延(sprawl)——技能单纯太长,即便每一行都鲜活且独一无二。伤害可读性与可维护性,浪费 token。解药是阶梯:把参考披露到指针之后,按分支或序列拆开,使每条路径只携带它需要的东西。
无操作(no-op)——模型默认已经遵守的一行,你白付负载却什么也没说。测试:相比默认,它改变行为了吗?一个弱引领词(当智能体本来就够彻底时让它“be thorough”)就是无操作;修法是换一个更强的词(relentless),而不是换一种技术。
否定(negation)——靠禁令来引导会适得其反:别想大象会说出大象,让它更可得,而不是更不可得。用正面措辞——陈述目标行为,让被禁的那种从不被说出口;只有在无法正面表述的硬护栏里才保留禁令,即便如此也要配上该做什么取而代之。