Chengshu@skadai · 2026.10.20
RSS
1,500 字 · 332 词 · 约 5 分钟

setup-matt-pocock-skills 精读:为什么不把 issue tracker 写死在技能里

setup-matt-pocock-skills 是每个仓库跑一次的配置技能:它问清三个决定(issue tracker、triage 标签、文档放哪),把答案写进 docs/agents/。本文解释这套『用数据文件换掉硬编码』的做法为什么能让同一批技能跑在 GitHub、GitLab、本地 markdown 或 Jira 上,以及一个配置技能该怎样探索、确认、幂等落盘。

(本文读的是 mattpocock/skills 快照 5beb35b,2026-10-19。引用的原文都能按文中的文件路径回仓库核对。)

一个用来配置其它技能的技能

在 Matt Pocock 的 skills 集合里,/ask-matt 负责告诉你该用哪个技能,而 /setup-matt-pocock-skills 负责在你第一次用其它工程技能之前,把这个仓库配置好。它每个仓库只跑一次。

触发方式是手动输入 /setup-matt-pocock-skills。skills/engineering/setup-matt-pocock-skills/SKILL.md 的 frontmatter 里两行说明了它为什么不能自动被调用:

name: setup-matt-pocock-skills
description: "Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills."
disable-model-invocation: true

docs 页面把这句话讲得更直白:“You invoke this by typing /setup-matt-pocock-skills; the agent won’t reach for it on its own. Its metadata marks it non-invokable on purpose, so no other skill can fire it for you.” 也就是说,它是 ask-matt、setup 这一类里被刻意设成 user-invoked 的成员:只有你能打,别的技能也调不动它。

它怎么工作

它是探索 → 呈现 → 确认 → 写盘四拍,而不是一把梭跑脚本。SKILL.md 自己声明:“This is a prompt-driven skill, not a deterministic script. Explore, present what you found, confirm with the user, then write.”

第一步探索:它先去读这个仓库现在是什么状态,而不是假设。它看 git remote -v(是不是 GitHub、哪个仓库)、根目录有没有 AGENTS.md / CLAUDE.md 以及里面有没有 ## Agent skills 段、GLOSSARY.md / GLOSSARY-MAP.md、docs/adr/、docs/agents/ 是否已存在、有没有 .scratch/(本地 markdown 工单的迹象)、triage 技能装没装、以及有没有 monorepo 信号(pnpm-workspace.yaml、package.json 的 workspaces、有自己 src/ 的 packages/*)。

第二步问三个决定。规则是“One section, one answer, then the next.”——一节问一个,答完再问下一个;每一节都先给出推荐答案,让你能用一个字接受;探索已经解答的整节直接跳过。

  • Section A:issue tracker。 工单存在哪。GitHub(默认,用 gh)、GitLab(用 glab)、本地 markdown(.scratch/<feature>/ 下的文件,不需要 remote),或「其他」(Jira、Linear 等,你描述一段工作流,它把这段散文记下来)。落盘到 docs/agents/issue-tracker.md。
  • Section B:triage 标签词表。 只有装了 triage 技能才问,而且只问一句「要不要保留默认的五个标签」(needs-triage、needs-info、ready-for-agent、ready-for-human、wontfix)。落盘到 docs/agents/triage-labels.md。
  • Section C:域文档。 默认单上下文(根目录一个 GLOSSARY.md + docs/adr/),不问,直接写;只有探索发现 monorepo 信号时,才提供多上下文(一个 GLOSSARY-MAP.md 指向各上下文的 GLOSSARY.md)让你确认。落盘到 docs/agents/domain.md。

第三步把草稿给你看、让你改。第四步才写:往 CLAUDE.md 或 AGENTS.md 加一个 ## Agent skills 块(里面是三条一行的摘要,各指向对应文件),并按模板写出 docs/agents/*.md,需要时用 gh label create / glab label create 补齐缺失的标签。第五步告诉它读这些文件的技能有哪些、以后可以直接手改。

核心设计:把「每个仓库会变的东西」抽出代码

这套东西最值得抄的一点,在 docs 页面里说得非常清楚:

Those files are the only thing that varies between repos. The skills themselves are identical everywhere. They read docs/agents/issue-tracker.md at run time and do what it says. That is why the set is not tied to GitHub, and why you never edit a skill file to point it at another tracker.

换成一句话:技能本体是同构的,仓库之间只有一个数据文件不同。 技能在运行时去读 docs/agents/issue-tracker.md,照着它说的做。所以「用哪个 tracker」不再是技能代码里的一个分支,而是一份仓库内的配置。你要换 tracker,改的是那份 markdown,不是技能。

这也是为什么它支持「其他」这个选项——同一套技能可以接 Jira、Linear、Azure DevOps(甚至社区做的 Gitea 风格 gh)。硬编码的话,每加一个平台就要改技能;抽成数据之后,只需要那段描述工作流的散文。

它和一般技能哪里不一样

  • 它是一个配置技能,工作在「其它技能」这个层面上。 它的产物是别人运行时读取的文件。
  • 它是 prompt 驱动、不是脚本。 因为「这个仓库现在缺什么」本身需要判断:triage 没装就整节跳过、没有 monorepo 信号就直接写单上下文。这些分叉用确定性脚本写起来又长又脆。
  • 配置跟着仓库走,而不是全局。 docs 明确说“There is no user-level or global mode.“没有 ~/.claude 模式,每个仓库都带自己的一份 docs/agents/,于是它可 commit、可 review、可手改。
  • 它懂得幂等。 SKILL.md 规定:## Agent skills 块已存在就原地更新、不追加重复;两个指令文件只有一个存在时绝不去新建另一个(“Never create AGENTS.md when CLAUDE.md already exists”),两个都不存在就问你选哪个、不替你定。

它有意识摒弃了什么

  • 摒弃了把 tracker 写死进技能。 代价是把逻辑从代码挪进了数据文件,换来的是平台无关。
  • 摒弃了确定性脚本。 它不生成一个 .sh 一次跑完,因为它要探索、呈现、确认,再写。
  • 摒弃了全局配置。 没有用户级模式,配置进仓库、能进版本控制。
  • 摒弃了「顺手把副作用也做了」。 docs/agents/triage-labels.md 只是一张映射表:它告诉 /triage 你 tracker 里哪些字符串对应那五个角色,它自己不建标签。docs 里承认用户不止一次把「标签没被创建」当成 bug 报上来——那是刻意的收窄,不是遗漏。wayfinder 要用的标签同理,得你手工先建。
  • 摒弃了把个人偏好塞进来。 有人要求在配置里改 grilling 的节奏、问题格式、语气,答案是「技能保持有主张、不收 per-user 配置;偏好写进你的 CLAUDE.md」。

可迁移结论

  1. 把项目间会变的决定抽成数据文件。 让技能本体保持同构,运行时读配置,而不是把方案写进技能分支里——这就是「不把 tracker 写死」的一般形式。
  2. 配置技能应当探索 → 呈现 → 确认 → 写。 先读现状,再提建议,最后才落盘;不要一上来就改。
  3. 一次问一个问题,每题先给推荐答案,已被探索解答的整节跳过。 大多数运行只需要两次确认,靠的就是这两条。
  4. 配置进仓库、可提交、可手改。 不要做全局模式;让配置能被 review,且出了问题的修复方式就是直接编辑那个文件。
  5. 收窄职责。 配置只写映射,不顺手执行有副作用的动作(建标签、改文件之外的系统);这类边界要在文档里讲清楚,否则会被当成 bug。
  6. 幂等。 重跑时原地更新、不产生重复块、不新建第二个指令文件。

setup-matt-pocock-skills 的启发其实很朴素:当你有一套要在很多项目里复用的技能时,别去写「如果仓库在 GitHub 就……否则如果……」,而是先问清楚「哪些东西每个仓库不一样」,把它们变成一份可读、可改、可提交的配置——技能本体于是不必再关心平台。

讨论

用 GitHub 账号留言;评论保存在公开仓库chengshu-blog-discussions的 Discussions 里。也可通过 RSS 订阅后续文章。