数据截至 (上游 commit 0a64e398ec6b)
Skill 设计套路
本章讲什么: 把仓库 17 个 skill 横着看,抽出反复出现、可直接抄的设计模式。每个模式都先白话点出「妙在哪」,再钉到真实文件。这是你写自己 skill 时最实用的一章。
0. 全家福(它们各管什 么)
四类(按用途归类;技能成员见 README.md 与 .claude-plugin/marketplace.json):
| 类别 | skill | 一句话 |
|---|---|---|
| 文档处理 | docx pdf pptx xlsx | 读/改/造 Office 与 PDF(source-available) |
| 开发技术 | mcp-builder webapp-testing web-artifacts-builder claude-api skill-creator | 造 MCP、测网页、搭 artifact、写 Claude 应用、造 skill |
| 创意设计 | algorithmic-art canvas-design frontend-design theme-factory slack-gif-creator | 生成艺术/版式/前端/主题/GIF |
| 企业沟通 | brand-guidelines internal-comms doc-coauthoring | 品牌排版、内部沟通、文档协作 |
1. 模式 A:脚本当黑盒(省上下文)
妙在哪。 大脚本若被读进上下文会吃掉宝贵窗口。所以把它们设计成只调用、不阅读的黑盒:先 --help 看用法,直接跑。
webapp-testing 把这条说得最直白:
「Always run scripts with
--helpfirst. DO NOT read the source until you try running the script first and find that a customized solution is absolutely necessary. These scripts can be very large and thus pollute your context window.」
来源:skills/webapp-testing/SKILL.md:11-14、「Best Practices」(约 85 行)。它的 scripts/with_server.py 就是个黑盒——管理服务器生命周期,你只管 python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py(:39-50)。
这正是 01 章 L3「脚本可只执行、不读入」的落地。
2. 模式 B:用决策树替代一长串 if
妙在哪。 「该走哪条路」用 ASCII 决策树画出来,比一段散文清楚得多,模型照着走不容易跑偏。
webapp-testing 开篇就是一棵树:
User task → Is it static HTML?
├─ Yes → 直接读 HTML 找 selector
│ └─ 不行 → 当成动态(走下面)
└─ No(动态) → 服务器起了吗?
├─ 否 → 跑 with_server.py --help,再写精简 Playwright 脚本
└─ 是 → 侦察后行动:导航→等 networkidle→截图/查 DOM→用发现的 selector 执行
来源:skills/webapp-testing/SKILL.md:16-33(「Decision Tree」)。docx 也用「Quick Reference」小表做同样的事:读/造/改各走不同路(skills/docx/SKILL.md:14-19)。
3. 模式 C:reference 按域拆 + 正文只放总纲
妙在哪。 跨多语言/多框架的 skill,若把所有方言塞进正文会爆 500 行;按域拆成 reference,正文只放工作流和『读哪份』的指针,模型只读相关那份。
mcp-builder 是范本:正文是 Phase 1-4 的工作流骨架,Python/TypeScript 的真正写法分别在 reference/python_mcp_server.md、reference/node_mcp_server.md,正文用一行链接挂出来:
For TypeScript: [⚡ TypeScript Guide](./reference/node_mcp_server.md)
For Python: [🐍 Python Guide](./reference/python_mcp_server.md)
来源:skills/mcp-builder/SKILL.md:60-66。它的 reference/ 目录里 4 份文档(evaluation.md/mcp_best_practices.md/node_mcp_server.md/python_mcp_server.md)分别在不同 Phase 才被读入。claude-api 更进一步,按语言开了 python/ typescript/ go/ java/ php/ ruby/ csharp/ curl/ shared/ 子目录。
4. 模式 D:推式触发描述(claude-api 是极致)
妙在哪。 description 是触发器(index §3)。claude-api 把它写成了一套带 TRIGGER/SKIP 双向规则的小决策器,专治漏触发:
- TRIGGER:prompt 里出现 Claude/Anthropic 任意形态(
claude-*、@anthropic-ai…)、问到 LLM(定价/选型/限流)、或任务是「LLM 形状」但没说提供商时——都要在打开目标文件前先读本 skill。 - SKIP(压过所有 TRIGGER):已在做别的提供商(OpenAI/GPT/Gemini…),或
grep到openai|langchain_openai|…命中时——先跑这个 grep,别凭空读文件。
来源:skills/claude-api/SKILL.md 的 frontmatter description(多行块,约 3-7 行)。
这把 skill-creator 那条「description 要 pushy、所有『何时用』都进 description」(skills/skill-creator/SKILL.md:67)用到了极限——连「什么时候别用」都写进去了,这是减少误触发的高级招。
5. 模式 E:把易漂移的知识做成对照表
妙在哪。 模型训练有截止日,某些 API 形状会变;与其让它凭记忆,不如在 skill 里摆一张「旧记忆 vs 现行」对照表,显式纠偏。
claude-api 有一张「API Drift」表,例如:
| 领域 | 旧记忆(可能已过期) | 现行 API |
|---|---|---|
| extended thinking | thinking: {type:"enabled", budget_tokens:N} | 4.6+ 用 thinking: {type:"adaptive"};新模型上 budget_tokens 被 400 拒 |
来源:skills/claude-api/SKILL.md「⚠️ API Drift」表(约「Extended thinking」行)。配套还有一句明确的优先级:skill 里的 {lang}/ 文件权威于你回忆的模式(同节)。这是「用 skill 给模型打补丁」的典型用法——把会变的事实从模型权重里『外置』到可更新的 skill 文件里。
6. 模式 F:共享库 + ZIP-of-XML 编辑哲学(office 四件套)
妙在哪。 docx/pptx/xlsx 都要操作「本质是 ZIP 包着 XML」的 Office 文件,于是它们共享同一套 office/ 工具库——2026 年中的瘦身之后,库里只剩两件主器:validate.py(XSD 校验 + --auto-repair)和 soffice.py(调 LibreOffice 做格式转换与渲染验证),外加 helpers/、schemas/、validators/。
经核对,docx 与 xlsx、docx 与 pptx 的 scripts/office/ 目录逐文件无差异(diff -rq 无输出)——是同一份库被各 skill 复用。
编辑哲学(以 docx 为例)是一套反直觉的「裸手」流程(skills/docx/SKILL.md:51-58):
unzip -q doc.docx -d unpacked/ # 1 解包:就用系统 unzip,不美化不重排
find unpacked -type l -delete # 顺手删掉 symlink 条目——外部来的 docx 不可信
merge_runs.py unpacked/ # 2 合并碎片 run(Word 把一句话拆成一堆 <w:r>,
# 不合并不然正文里搜不到整句)
用 Edit 原地改 word/document.xml # 3 编辑:明确禁止 reformat/pretty-print——
# 重排空白在 docx 里是破坏性的
zip -Xr ../out.docx . # 4 回包:裸 zip
validate.py out.docx --original doc.docx # 5 校验:XSD;--auto-repair 修常见问题
为什么「不要美化 XML」反而是智慧: 上一版工具链有 unpack.py/pack.py 负责美化与回包,现在全删了——docx 的 XML 里空白和 run 边界都带语义,美化工具本身就是 bug 源头。流程退到「系统 unzip + 原地编辑 + 裸 zip + 独立校验器」,把「编辑」和「校验」解耦成两步,反而更可靠(merge_runs.py 的动机注释,skills/docx/SKILL.md:61)。
值得带走的细节——tracked changes 的诚实边界: 红线(redlining)模式下 validate.py --author "<名字>" 会报告「改了文字却没包 <w:ins>/<w:del>」的编辑;而接受修订时,「被删段落的段落标记」意味着「并入下一段」——accept_changes.py 和 pandoc 都处理不完美这个边角,SKILL.md 把两种失败形态直接写出来(skills/docx/SKILL.md:63-72)。这是「工具能力边界要诚实划清」的教科书写法。
7. 模式 G:把「全是坑」的领域写成 gotcha 清单
妙在哪。 有些库默认值反直觉(docx-js 默认 A4 不是 Letter),错一个就渲染崩。docx 用一节「gotchas」把这些坑一次列清,每条都点出后果而非空喊规则(skills/docx/SKILL.md:21-33):
- 「Tables need dual widths」——
columnWidths和每个 cell 的width都要设且要相等,否则某些平台渲染错位(skills/docx/SKILL.md:25)。 - 「Table shading: use
ShadingType.CLEAR,neverSOLID」——否则表格出现黑底(:26)。 - 「Never use unicode bullets」——要用
LevelFormat.BULLET的 numbering 配置(:27)。
这与 skill-creator「解释 why、少用全大写 MUST」的建议略有张力——但这里每条都带了后果解释,属于「值得喊」的那种。
8. 边界与局限(诚实)
- 本章对
mcp-builder、claude-api的reference/、{lang}/子目录只读到 SKILL.md 层的指针与目录布局,未逐份核读其内部全文;引用均限于 SKILL.md 明示与目录事实。 office/的「逐文件无差异」基于diff -rq的目录比对结论;未逐行比对每个文件内容。- 创意类 skill(
algorithmic-art/canvas-design/theme-factory等)未逐一展开,模式 A-G 已覆盖其共性套路。
9. 代码地图
| 模式 | 文件路径 | 符号 / 锚点 |
|---|---|---|
| A 脚本黑盒 | skills/webapp-testing/SKILL.md | 「Helper Scripts」「Best Practices」 |
| A 黑盒脚本本体 | skills/webapp-testing/scripts/with_server.py | —(--help) |
| B 决策树 | skills/webapp-testing/SKILL.md | 「Decision Tree」 |
| C reference 分域 | skills/mcp-builder/SKILL.md | 「Documentation Library」 |
| C 多语言子目录 | skills/claude-api/ | python/,typescript/,shared/ |
| D 推式触发 + SKIP | skills/claude-api/SKILL.md | frontmatter description |
| E API 漂移表 | skills/claude-api/SKILL.md | 「⚠️ API Drift」表 |
| F 共享 office 库 | skills/docx/scripts/office/ | validate.py,soffice.py(瘦身版) |
| F 编辑五步 + 边界 | skills/docx/SKILL.md | 「Editing existing documents」:51-72 |
| G gotcha 清单 | skills/docx/SKILL.md | 「Creating with docx-js — gotchas」:21-33 |