Skill Simplifier

2432 字
12 分钟
Skill Simplifier
2026-05-21
无标签

agent-team 的时候我反复强调过一条纪律:每段提示词只存在于唯一一个地方。重复就是漂移源——上游措辞变了而下游抄了一份旧版本时,下一次 coordination 就出 bug。但这条纪律没法靠”写的时候多注意点”维持,Claude 自己写 skill 和 CLAUDE.md 时倾向于把它觉得重要的事一股脑全写上,分不清这些事是不是已经被系统提示词、Tool Description、其他 skill 或更上层的 CLAUDE.md 提供了。于是我把这条纪律做成了 skill-simplifier:审一个目标文档,列出每一处与上游重复的内容,自动删那些”无论如何都该删”的,剩下”两侧都由用户拥有”的让用户决定

Fomalhaut647
/
plugins
Waiting for api.github.com...
00K
0K
0K
Waiting...

它解决什么问题#

Claude 写 SKILL.md 和 CLAUDE.md 有一种 kitchen-sink 倾向:只要觉得”这个规则很重要”就写进去,不管这条规则是不是已经由更上游的知识源提供。最常见的几类冤枉重复:

  • SKILL.md 里写”用 Edit 工具不要用 sed”——这是系统提示词里已经有的
  • SKILL.md 里详细解释 TeamCreate 的参数——这是 tool description 已经返回的
  • CLAUDE.md(项目级)写”使用中文回答”——这是用户全局 CLAUDE.md 已经有的
  • skill 的 references/foo.md 里抄一段 superpowers:test-driven-development 的 RED/GREEN/REFACTOR 流程——这是另一个 skill 激活后直接提供的

每条单独看都不冒犯,但堆起来就两件坏事:占 context、稀释目标文档真正独特的价值上游变了之后副本悄悄过时。第二件更要命,因为它是隐式的:你以为 skill 还在按最新规则跑,实际上它依据的是某条 tool description 半年前的措辞

核心判定标准#

判定一段内容是不是冗余的方法很朴素:删掉它,Claude 的行为会不会变? 如果不会,那它就是冗余的,因为同样的约束已经在上游某处提供

两个要点:

  • 语义而非字面:措辞不同也可能是重复。“使用 Read 而非 cat 读文件”和”避免用 shell 拼接读取文件内容,应当调用专用工具” 是同一条规则的两种说法
  • 字面相同也可能不是重复:如果目标补上了上游缺失的”为什么 / 例子 / 取舍”,那它在做独立的工作。例如系统提示词只说”破坏性操作前先确认”,而某个 CLAUDE.md 补一句”过去 force push 删过 main 历史,所以这条规则在我们这特别严”——保留有上下文的那一侧

四类上游知识源#

每一处重复都会归到下面四类之一。skill-simplifier 在 Stage 1 按顺序排查,分类要做准,因为 Stage 4 的处理规则按类不同

1. 系统提示词(隐式上游)#

这是最容易漏的一类,因为 Claude 没法 Read 系统提示词,它就在 context 里。需要逐项扫的重灾区:

  • 用专用 tool 而非 cat / echo / sed
  • 独立的 tool 调用并行执行
  • file_path:line_number 引用约定
  • git commit / PR 工作流
  • sandbox 与安全规则
  • 破坏性操作先确认

只要目标把这些规则之一重新陈述了一遍,就是在重复系统提示词

2. Tool Description#

每个 tool 自带一段 description。这里有个反直觉点:

  • 内置 tool(Read、Edit、Bash、Skill 等)的 description 在 context 里,直接看
  • Deferred toolTeamCreate / SendMessage / WebFetch / Monitor 等)的 schema 不在 context 里——只在 <system-reminder> 块里以名字出现。要查它们的 description 必须先用 ToolSearch 配合 select:Name1,Name2,... 把 schema 拉进来

agent-team 这个 skill 反复出现 “the descriptions returned are the authoritative reference” 这句话的原因正是为此:与其在 SKILL.md 里抄一份 TeamCreate 参数表(必然过时),不如强制 agent 每次激活时去拉 live schema

3. 其他 Skill#

Available Skills 列表在 <system-reminder> 里。扫一遍,挑出名字或一句话描述和目标领域重叠的 skill。读其他 skill 的内容必须用 Skill(name) 调用它,而不是用 Read 去读 SKILL.md 文件——plugin cache 的路径不稳定(带版本号、可能因 plugin 更新而变),靠 Read 拼路径是脆弱的

如果目标重述了一条”另一个 skill 一旦激活就会提供”的指令,就是在重复 Skill

4. 其他 CLAUDE.md#

CLAUDE.md 是 cascade 的,上游链按目标类型不同:

  • CLAUDE.md 目标:从 ~/.claude/CLAUDE.md 一路读到目标父目录的每一个 CLAUDE.md
  • Skill 目标~/.claude/CLAUDE.md 加上 skill 预期将运行其中的项目根 CLAUDE.md

如果目标重述了一条更上游 CLAUDE.md 已经提供的规则,就是在重复 CLAUDE.md

报告先于改动:Stage 4 闸门#

skill-simplifier 最重要的设计是强制在改动前先输出完整报告,等用户对部分条目做决定再执行 Edit。这条约束在 skill 里直接列为红线:“不要在用户给出 Zone B 和 Zone C 决定之前进入 Stage 5”

理由:删除是低成本的操作,但误删(false-positive)是隐性回退——一段被错删的情境化指引不会立刻报错,下一次 Claude 在边界 case 上失去判断依据时才暴露。让用户先看完所有命中条目再做决定,比一次性 batch 删完更安全

报告分两到三区:

Zone A — 自动删#

上游是系统提示词Tool Description。这两个上游用户没法编辑,唯一可动的杠杆就是目标侧。所以 Zone A 默认全删,列出来只是方便用户做合理性核查、对具体某条提出反对

Zone B — 用户决定#

上游是其他 Skill其他 CLAUDE.md。两侧都由用户拥有,所以三选一:删目标侧、删上游侧、或两侧都留并加显式的交叉引用

为什么不能合并条目

明显成组的条目可以合并成一个决定。但不要把上游来源不同的条目合并成同一条——用户可能想对不同上游做不同选择(比如:愿意删项目 CLAUDE.md 的副本,但全局 CLAUDE.md 的那条保留)

Zone C — 内部分层(仅 Skill 目标)#

skill 的 SKILL.md 总是在激活时加载;references/*.md 按需加载。内容在两层都出现就破坏了 progressive disclosure。用 Zone B 同款格式让用户选,因为”哪一层拥有这段内容”是设计决策——是把它放进常驻 context 还是按需加载

几条不能碰的红线#

触发内容神圣不可动#

Skill 的 description: frontmatter 是它被 trigger 的入口,CLAUDE.md 里的”看到 X 时做 Y”短语是它被应用的入口。即便它们和某条上游措辞重叠,也要保留——删掉就破坏了激活路径,整个文档变成沉默资源

不要把临时 query 结果固化进去#

通过 ToolSearch / WebSearch / Read 一次性获取的 schema、版本号、API 字段名等等,绝不能抄进 SKILL.md 或 CLAUDE.md 当”方便的 inline 参考”。上游会变,inline 副本必然过时。让目标在每次调用时重新获取——这正是 deferred tool schema 不进 skill 的同一条原则

保守删除#

拿不准时保留目标内容,加一句 “see X” 的指针即可。多一句话的代价很小;丢掉用户依赖的情境化指引的代价大。漏删在下一次审查时能补救;误删则悄悄回退 Claude 的行为

具体胜过泛化#

如果一份 skill / CLAUDE.md 重述了系统提示词的泛化规则、但补上了具体例子、取舍或为什么,它是在做真实工作。这种张力出现时保留情境化的那一版,只裁掉冗余的泛化前言

一个工作流上的小细节#

skill 在 Stage 2 会激活辅助 skill,但按目标类型分叉

  • 目标是 Skill → 激活 superpowers:writing-skills + skill-creator
  • 目标是 CLAUDE.md → 激活 claude-md-management:claude-md-improver

这两组辅助 skill 提供”好的 skill / 好的 CLAUDE.md 长什么样”的参考,但它们本身不是 skill-simplifier 的替代品——它们关心结构和清晰度,skill-simplifier 单点关心去重。所以辅助 skill 是激活,不是委派

安装#

Terminal window
/plugin marketplace add Fomalhaut647/plugins
/plugin install skill-simplifier@fomalhaut647-plugins

@ 前的 skill-simplifier 是 plugin name,@ 后的 fomalhaut647-plugins 是 marketplace name

怎么用#

最直接的触发短语:“simplify this skill”、“review this CLAUDE.md”、“审查 / 精简 / 去重 / 瘦身 skill”、“是不是有重复”。其实更常见的场景是用户自己写完 skill 后感觉冗长 / 抱怨”这段我好像在别处写过”——这时候哪怕用户没明说 “simplify”,也应该优先调用本 skill。这正是它存在的意义

跑一次完整流程的样子:

  1. 问用户目标是哪个 skill 目录或 CLAUDE.md 文件
  2. 枚举四类上游知识源、读完整目标
  3. 输出两到三区报告(这里停下来
  4. 用户对 Zone B / Zone C 给出决定
  5. Edit 按决定逐条删除或加交叉引用

每次调用只处理一个目标。如果用户有多个 skill 要审,每个文件各跑一次工作流——上游枚举可能因目标而异,混在一起处理会漏判

后记#

skill-simplifier 自己是个反讽:它的 SKILL.md 写得相当瘦,没有重复的”好 skill 长什么样”教学(那是 superpowers:writing-skills 的事)、没有抄 Skill tool description(那是 tool 自带的)、没有解释什么是 cascade(那是 CLAUDE.md 自己的概念)。它只做一件事——审目标里有没有上游已经提供的内容——所以它自己也必须严格遵守这条纪律

仓库:https://github.com/Fomalhaut647/plugins/tree/main/plugins/skill-simplifier,欢迎试用、提 issue

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Skill Simplifier
https://fomalhaut647.com/posts/skill-simplifier/
作者
Fomalhaut
发布于
2026-05-21
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Fomalhaut
Hi, I'm Fomalhaut~
公告
寒舍装修中
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
32
分类
4
标签
0
总字数
45,684
运行时长
0
最后活动
0 天前

目录