mattpocock-skills:标准化跨 Skill 调用术语——"Call the Skill tool" 约定及其双 Harness 实践
【免费下载链接】skillsSkills for Real Engineers. Straight from my .agents directory.项目地址: https://gitcode.com/GitHub_Trending/skills13/skills
这篇指南基于仓库中的 changeset 文档 .changeset/skill-tool-invocation-terminology.md 展开,讲解 mattpocock-skills 如何把各 Skill 之间"调用另一个 Skill"的指令,从裸写的/skill风格散文统一为显式的 "Call the Skill tool" 表述。读完后你能理解:为什么"在文字里提到另一个 Skill 名字"并不可靠、如何书写多 Skill 步骤、以及该约定在 Claude Code 与 Codex 双 Harness 下如何保持中立,并掌握在.agents/invocation.md中沉淀的完整书写规范。
变更背景:这是一个什么改动
该文件是一个 changeset(变更描述片),frontmatter 中声明了对mattpocock-skills包的 patch 级修改:
"mattpocock-skills": patchchangeset 主体一句话概括了改动范围:在code-review、diagnosing-bugs、grill-with-docs、grill-me、improve-codebase-architecture、tdd、to-spec、to-tickets、triage和wayfinder这 10 个 Skill 中,把跨 Skill 调用统一为显式的 "call the Skill tool" 指令,替代原来裸写的/skill风格散文。
仓库使用.changeset/目录按"一个文件一个变更"的方式记录每次 patch/minor 修改,由工具汇总进 CHANGELOG.md。这个 changeset 与另一个 changeset user-invoked-skill-invocation.md 是同一批工作的两部分:前者建立"怎么调"的术语标准,后者修复"什么不能调"的边界违规。
问题根源:散文里提到 Skill 名字,不等于调用了它
changeset 第一条给出了改动的技术动机,原文明确承认了旧写法是一个"有文档记录的粗糙边缘":
A skill that names another skill in prose ("run the
/grillingskill") does not reliably cause it to load. This is the documented rough edge behindgrill-with-docs's most-reported problem.
也就是说,一个 Skill 若在正文里只写"运行/grillingskill",并不保证该 Skill 真正被加载——这正是grill-with-docs用户反馈最多的问题根源。grill-with-docs的整个实现就是委托给两个底层 Skill,一旦委托失败,用户看到的就是一次空转的面试流程。
其底层原因在于:大多数 harness(agent 运行框架)把 Skill 调用暴露为一个工具,模型必须真正去 call 这个工具才能触发加载。把/name当作普通文字丢进散文里,是在"希望"模型把它读成命令——命中率不稳定。而直接点名工具(Call the Skill tool with "grilling")把意图写得没有歧义,changeset 原话是 "is intended to raise the hit rate"(旨在提高命中率)。
约定本体:显式点名 Skill 工具
改动落地的写法是:让 Skill 的正文用"指令句式"直接命名 Skill 工具,而不是使用 slash-command 风格的名字。仓库中改动后的真实用例如下:
grill-me/SKILL.md 全文正文只有一行:
Call the Skill tool with "grilling".grill-with-docs/SKILL.md 的正文:
Call the Skill tool twice, for "grilling" and "domain-modeling".wayfinder/SKILL.md 的第一步("命名目的地"):
Call the Skill tool twice, for "grilling" and "domain-modeling", to pin down what this map is finding its way to: the spec, decision, or change.
improve-codebase-architecture/SKILL.md 中出现了两处调用,一处是获取架构词汇表(module、interface、depth、seam、adapter、leverage、locality),另一处是指向 "design-it-twice" 的并行子代理模式:
Call the Skill tool with "codebase-design" for the architecture vocabulary ...
Want to explore alternative interfaces for the deepened module?Call the Skill tool with "codebase-design" and use its design-it-twice parallel sub-agent pattern.
retro/SKILL.md 的第一步:
Call the Skill tool with
writing-for-agentsfor the writing style guide.
这些例子展示了约定的三个要点:
- 句式固定:"Call the Skill tool with ..." 是一个可被模型无歧义执行的操作性指令,而非描述性文字;
- Skill 名字放在引号中作为参数,与 slash-command 语法解耦;
- 调用发生在 Skill 自身的步骤里,即 changeset 所指的 "operative instructions"(操作性指令)——Skill 的步骤正告诉 agent "现在就去运行另一个 Skill"。
去掉前导斜杠:harness 中立而非降低要求
changeset 第二条值得单独展开:
Dropping the leading
/also makes the instruction harness-neutral rather than less: it no longer assumes Claude Code's trigger syntax.
这是一个容易被误读的设计决策。表面上,从/grilling到"grilling"像是丢掉了信息;实际上恰恰相反——/name这种前缀假设了 Claude Code 的触发语法,而 mattpocock-skills 同时支持多个 harness。从仓库结构看,每个 Skill 都带有一份 agents/openai.yaml(Codex 侧的元数据),与 Claude Code 的 frontmatter 并行存在;CHANGELOG.md 中 1.2.0 版本记录了这个双 harness 设计:每个 user-invoked Skill 在 Claude Code 侧用disable-model-invocation: true(frontmatter),在 Codex 侧用policy.allow_implicit_invocation: false(agents/openai.yaml)标记,两侧语义必须保持同步。
既然 Skill 集合要在两种(及未来更多)harness 上运行,正文里的指令就不能绑定任何一方的触发语法。裸 Skill 名字本身不携带 harness 假设,这就是 changeset 里 "harness-neutralrather than less" 的含义:中立性不是信息的减少,而是信息密度的提升。同一批变更中还有同类动作的佐证——CHANGELOG.md 1.2.3 版本记录了"从子代理分派指令中移除 Claude Code 专属的工具名和 agent 类型名,使步骤在 Codex 等其他 harness 上同样可执行"。
多 Skill 步骤:一次调用只带一个名字
changeset 第三条规定了组合调用的写法:
A step needing more than one skill now says so as multiple calls ("Call the Skill tool twice, for
grillinganddomain-modeling"), not one call carrying two names.
规范文档.agents/invocation.md对此给出了原理性解释:Skill 工具一次调用只接收一个 Skill。需要两个 Skill 的步骤必须写成两次调用。原因很实际——措辞会引导模型的解析:"call it with X and Y" 读起来像"一次调用携带两个名字",而Call the Skill tool twice, for "grilling" and "domain-modeling"在字面上就是一次动作发生两次,模型没有歧义可犯。
grill-with-docs是这个规则最典型的受益者:它作为 user-invoked 的"带文档版面试",其全部行为就是依次加载grilling(面试原语)和domain-modeling(领域建模纪律)两个 model-invoked Skill,并把产出沉淀为CONTEXT.md和 ADR。一行正文、两次显式调用,委托链完全可预期。
边界:该约定只适用于 model-invoked 的 Skill
写跨 Skill 调用指令时最容易被忽略的是"被调方是否可达"。.agents/invocation.md把 Skill 按"谁能触达"分成两类:
- User-invoked:只有人能触发。Claude Code 侧在 frontmatter 中设
disable-model-invocation: true,Codex 侧在agents/openai.yaml中设policy.allow_implicit_invocation: false; - Model-invoked:模型和人都能触达,是默认状态。
description保留丰富的触发短语("Use when the user wants…, mentions…, asks for…")以便自动触发。
不变式是:任何 Skill 都永远无法触达另一个 user-invoked Skill——每个 harness 都会把 user-invoked Skill 排除在模型触达范围之外。因此Call the Skill tool with "name"约定只在被点名 Skill 是 model-invoked 时成立。
这条边界在仓库中留下了真实的历史教训,见配套 changeset user-invoked-skill-invocation.md:PR #878 引入本约定时,曾把to-spec、wayfinder、to-tickets、triage、code-review五个 Skill 中"如果没有配置,运行/setup-matt-pocock-skills"的前置条件,机械地改写成了字面的Call the Skill tool with "setup-matt-pocock-skills"指令——但setup-matt-pocock-skills是 user-invoked 的,这种调用必然失败;其中diagnosing-bugs的失败更危险,因为它发生在无人值守的自主修 bug 流程里。修复方式是把这些前置条件全部改写成"告知人类去运行"的指令,例如 to-spec/SKILL.md 与 code-review/SKILL.md 中的:
The issue tracker should have been provided to you. If not, tell the user to run
/setup-matt-pocock-skills.
注意这里的/setup-matt-pocock-skills保留了前导斜杠:因为它不是操作性调用指令,而是给人类看的、在终端里要实际敲出的 slash command。.agents/invocation.md对两者的区分写得很清楚:
When a step's precondition is a user-invoked skill (e.g.
setup-matt-pocock-skills), phrase it as an instruction for the human to act on: "tell the user to run/setup-matt-pocock-skills", never as a Skill tool call.
相应地,该文档也在 "Dependencies between them" 一节补充了 carve-out(豁免)段落,声明 Skill 工具约定仅适用于 model-invoked Skill。该 changeset 还点出了教训的另一层:规范文档与八行之外的不变式没有对齐,正是这个 bug 扩散到六处调用点而非一处的主因。
约定文档化:.agents/invocation.md的完整规则
changeset 的最后一项是把整套约定写入.agents/invocation.md,供后续新 Skill 遵循。除前文引用的四条(点名工具、多调用写法、user-invoked 豁免、harness 中立)外,该文档还有两条与"何时该调用、何时不该调用"相关的细则,值得纳入写作规范:
- 操作性指令 vs 路由性文字:只有 Skill 自身步骤中"现在就让我去运行另一个 Skill"的指令才使用 Skill 工具句式;而给人类做选择的导航文字(如 ask-matt/SKILL.md 和各桶 README)只是把 Skill 名字当标签列出,保留
/skill风格即可,它们不构成调用; - 被动阅读 vs 主动建模:仅仅是"读一下
CONTEXT.md查词汇"只是一行散文指引,不等于调用domain-modeling。只有主动的构建/打磨纪律——质疑术语、用边界场景压测、写 ADR、内联更新CONTEXT.md——才算domain-modeling的调用。这防止了"因为提到了某个词就顺手调了重型 Skill"的过度触发。
小结:把"希望模型看懂"变成"模型只能这样执行"
这个 patch 级的术语变更没有新增任何 Skill,改的只是一批SKILL.md正文的措辞,但它确立的是一条可复制的写作原则,适用于任何由多个 Skill/命令/工具协作组成的 agent 技能库:
- 委托必须点名机制本身("Call the Skill tool with X"),而不是描述性散文("run the
/grillingskill"); - 一次调用一个名字,多 Skill 步骤显式写成多次调用;
- 名字不携带 harness 假设,去掉与特定框架绑定的前缀语法;
- 写之前先核对调用边界:user-invoked 的能力只能转化为"告知人类去做"的指令,永远不能写成工具调用。
配套的验收标准也很直接:在仓库内全文检索Call the Skill tool,应当只命中操作性调用点,且每一处被点名的 Skill 都是 model-invoked——这一条可以在.agents/invocation.md的不变式对照下逐条核验。
【免费下载链接】skillsSkills for Real Engineers. Straight from my .agents directory.项目地址: https://gitcode.com/GitHub_Trending/skills13/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考