技能被选中靠两条通道:人明确点名,或者模型自己读描述做判断。 后者是常态,所以描述写得好不好,直接决定技能存不存在。 描述要写三段:做什么、什么时候用、什么时候不要用。第三段最容易被漏,也最能防过触发。
上一节说清了三级的付费时机,这一节讲第一级那个判断是怎么做出的。 这一节是全章的核心:三级披露的前提是「一行描述够判断」,而能不能判断,取决于描述怎么写。
一、两条通道:点名与自选
第一条通道是人点名:打斜杠命令,或者直接说「用 deploy-check 跑一遍」。 这条通道不依赖描述,技能叫什么就用什么。 第二条通道是模型自选:用户说了句普通的话(「发版前帮我查一下」),模型在常驻的那一堆描述里找, 觉得哪个合适就调哪个。 第二条是常态。真实使用里很少人会记得技能名,多数时候就是正常说话。
所以「技能能不能用上」这件事,实际上由描述决定,而不是由内容决定。 内容决定的是「用上之后干得好不好」。两件事分清楚,才知道该往哪使劲。
二、description 是灵魂
模型看到的只有一行描述:它得从这一行里判断出「这次的任务是不是归它管」。 这是个分类问题,而分类的准确率取决于两件事:描述里有没有这次场景的词, 以及不同技能之间的描述能不能分开。 演示里造了十二个技能、八个请求。三组描述:全都写得很泛、都写准、都只写几个关键词。
写得泛那组,八个请求命中了三个,其实等于全错——十二个技能的描述一模一样,分值也一样, 排序只能退到按名字排。 所以「适用面很广」这几个字,在分类问题里等于「什么都能干」,也就等于「什么都别找我」。
三、过触发与欠触发
过触发是「不该用它的时候用了」。 典型症状:描述里全是行业大词,「代码」「数据」「分析」都沾边,于是任何请求都能被它接住。 欠触发是「该用它的时候没用」。典型症状:描述里写的是内部术语,用户说的是人话,两边词对不上。 两种错的方向相反,修法也相反:过触发要加排除条件,欠触发要加场景词。
演示里写得泛那组就是过触发:八个请求里七个被送给了同一个技能。不是它更合适,是它的名字字典序靠前。 写得窄那组反过来:只写「代码审查」四个字,于是 code-review、sql-explain、perf-profile 三个都沾边, 分不开。 注意窄不等于准。窄是「词少」,准是「词对得上场景」。词少到分不开,准确率一样会掉。
四、参考型与任务型:两种哲学
参考型技能的目标是「被正确的人在正确的时候查到」。 它不怕没人用,怕的是被不该用的人用上,所以描述宁可窄一点。 任务型技能的目标是「该触发的时候一定触发」。它怕漏,所以描述要把用户可能说的各种说法都写进去。 两种哲学的差别落在描述上:参考型多写「什么时候不要用」,任务型多写「用户说……时使用」。
还有一个差别在正文:参考型正文薄、重量在 refs;任务型正文就是全部,不需要 refs。 这条在 3.5 节和 3.9 节会各自展开。 判断自己的技能属于哪一类,问一句:它被误用一次,代价大,还是漏用一次,代价大?
五、描述的三段写法
第一段写做什么:一句话说清动作和产出。比如「审查代码改动,输出问题清单」。 第二段写什么时候用:把用户可能说的词列进去,用「用户说……时使用」这种句式。 这一段是给分类器喂关键词的。 第三段写什么时候不用:把最容易混淆的邻居场景点出来。「只是解释代码怎么跑时,不要用这个技能」。
三段里第三段最值钱。 正向描述告诉模型什么时候用它,反向描述告诉它什么时候别用。只写前者,等于只给了一半信息。 演示第 ④ 段打了一份完整的描述:三行,六十字出头。 这个长度既够判定,又不会在二十个技能的时候把常驻预算吃穿。
六、为什么这件事只能靠试
描述的写法没有标准答案,因为它面对的是一个语义判断,不是规则匹配。 同一句话,在只有三个技能的时候够用,装到二十个就可能分不开——因为邻居变多了。 所以调描述的办法只能是:备一批带标准答案的请求,改一版跑一遍,看错的是哪一类。
这套流程在 3.11 节会完整跑一遍。 这一节只需要记住一件事:描述是可以被测的,而没测过的描述只是「看起来还行」。
七、动手 Demo:同一批技能,描述写宽、写准、写窄,命中率差多少
十二个技能、八个请求,每个请求都有唯一正确答案。 三组描述:全都写得很泛、都写准、都只写一两个关键词。 这里用字面重合度代替模型的判断——真机上是模型读描述做语义匹配,本沙箱没有模型, 所以只能比【排序对不对】,不能比【分值准不准】。
for q, want in REQS:
got = pick(q, lib, top=1)[0][1] # 按字面重合度取第一名
ok = (got == want)
print(q[:16], u"→", got, u"对" if ok else u"错(该是 %s)" % want)
实跑输出:
--------------------------------------------------------------------
同一批技能,描述写宽、写准、写窄,命中率差多少
--------------------------------------------------------------------
十二个技能、八个请求,每个请求都有唯一正确答案。
三组描述:全都写得很泛、都写准、都只写一两个关键词。
这里用字面重合度代替模型的判断——真机上是模型读描述做语义匹配,本沙箱没有模型,
所以只能比【排序对不对】,不能比【分值准不准】。
| 描述写法 | 首名命中 |
|---|---:|
| 写得泛 | 1/8 |
| 写得准 | 7/8 |
| 写得窄 | 5/8 |
① 写得泛:全都一样,等于没写
--------------------------------------------------------------------
帮我把这次发版前该查的东西过 → api-design(该是 deploy-check)
这份结算单金额对不上,帮我核 → api-design(该是 invoice-format)
昨天那次故障写个复盘 → api-design(该是 incident-report)
十二个描述一模一样,算出来的分也一模一样,排序只能退到按名字排。
所以八个请求里有七个都被送给了同一个技能——不是它更合适,是它的名字字典序靠前。
! 过触发不是模型贪心,是描述没给它排除的依据。
「适用面很广」这几个字,意思是「什么都能干」,也就等于「什么都别找我」。
② 写得准:场景词对齐了才命中
--------------------------------------------------------------------
帮我把这次发版前该查的东西过 → deploy-check 对
这份结算单金额对不上,帮我核 → invoice-format 对
昨天那次故障写个复盘 → incident-report 对
看看这个 PR 有没有问题 → code-review 对
八个请求里第一次就对了 7 个。
错的那一个:这张表重复行太多,洗一下 → api-design(该是 data-clean)
对的那几个有个共同点:请求里的词跟描述里的词对得上——「发版」对「发版」,「结算单」对「结算单」。
③ 写得窄:命中了,但误判也多
--------------------------------------------------------------------
只写关键词,命中率 5/8。看着还行,但那是因为这八个请求都用到了核心词。
错:帮我把这次发版前该查的东西过 → api-design(该是 deploy-check)
错:看看这个 PR 有没有问题 → api-design(该是 code-review)
错:这张表重复行太多,洗一下 → api-design(该是 data-clean)
! 窄描述的问题不在漏,在【分不开】。
只写「代码审查」四个字,code-review、sql-explain、perf-profile 三个都沾边,排序全靠字面撞运气。
④ 描述该怎么写
--------------------------------------------------------------------
三段:做什么、什么时候用、什么时候不用。第三段最容易被漏,也最能防过触发。
[description 原样 · 本沙箱只比字面排序]
| description: 审查代码改动:看边界条件、错误处理、测试覆盖,输出问题清单。
| 用户说审查、看看这个 PR、有没有问题时使用。
| 只是解释代码怎么跑、或者问某个函数什么意思时,不要用这个技能。
第三行是排除条件。有了它,模型在「解释代码」的场景就不会误调审查技能。
①写得泛那组:一个都没对。 十二个描述一模一样,算出来的分也一样, 排序只能退到按名字排——所以八个请求里有七个被送给了同一个技能。 不是它更合适,是它的名字字典序靠前。这就是过触发的典型样子:描述没给模型任何排除的依据。 ②写得准那组:八个里对了七个。 对的那几个有个共同点——请求里的词跟描述里的词对得上,「发版」对「发版」,「结算单」对「结算单」。 错的那一个是「这张表重复行太多,洗一下」,被判给了 api-design,该是 data-clean。 原因是「表」这个字在两个描述的邻域里都出现过。 ③写得窄那组:五个对。看着还行,但那是因为这八个请求都用了核心词; 错的三个全是「分不开」——只写「代码审查」四个字,三个技能都沾边。 窄描述的问题不在漏,在分不开。词少不等于准,词少到无法区分,准确率一样掉。 ④最后打了一份三段式描述:做什么、什么时候用、什么时候不用。第三行是排除条件。 有了它,模型在「解释代码」的场景就不会误调审查技能——这一句是整段描述里最值钱的。
30 秒实验
- 把「写得泛」那组的描述改成各写一句不同的,重跑第 ① 步。命中率能到多少? 这说明过触发的根子是「描述相同」还是「描述太长」?
- 把请求里加一个生僻词(比如「帮我洗一下这张宽表」),重跑第二组。「写得准」那组的命中率会掉吗? 为什么?
- 把第三组的关键词从两个词扩到四个词,看能否把「分不开」修掉。扩词之后常驻预算涨了多少?
常见误区
- 以为技能能不能用上取决于内容质量。取决于描述——内容是「用上之后」才起作用的东西。
- 把描述写成产品介绍:「功能强大、适用多种场景、提升效率」。这类词在分类时提供不了任何区分度。
- 只写正向描述,不写排除条件。过触发的根子就在这里——模型没有「不该用」的依据。
- 以为描述越窄越准。窄是词少,准是词对得上;词少到分不开,准确率一样掉。
- 凭感觉判断描述写好了。没有带标准答案的请求集,任何描述都只是「看起来还行」。
自测三问(点开对答案)
1. 技能被触发有哪两条通道?哪条是常态? —— 人明确点名(斜杠命令或直接说技能名),以及模型自己读描述做判断。 后者是常态,因为真实使用里多数人只是正常说话。 2. 过触发和欠触发的修法有什么不同? —— 过触发要加排除条件(什么时候不要用),欠触发要加场景词(用户会怎么说)。方向相反。 3. 为什么描述要写第三段「什么时候不用」? —— 因为正向描述只说明「能用」,不说明「别用」。相邻技能最容易混,一段排除条件就能把边界钉住。描述决定它被不被选中,下一节讲选中之后那一段正文该写成什么形状。
- ☐ (本篇完,下一篇 3.5 SKILL.md 正文:是路由器,不是仓库)
相关笔记
- 渐进式披露:三级里最便宜也最关键的一级
- 正文的形状:正文是路由器
- Claude Code 橙皮书 · 索引
- 🐎 Claude Code 实战 · 索引