← All Articles

guizang-ppt-skill 精读:一个杂志风 PPT skill 的工程拆解

歸藏 (op7418) · Original

Layer 1 — 这个 skill 实际是怎么实现的

歸藏开源的 guizang-ppt-skill 表面看是个”做 PPT 的 Claude Skill”,拆开看其实是一份把杂志排版语言压缩成 token-efficient 文档的 skill 工程范本。整个 repo 总共就 8 个文件、约 1500 行内容,但 SKILL.md / layouts.md / checklist.md / themes.md / components.md 五份文档之间的分工、和单一 template.html 种子文件的耦合方式,是这个 skill 真正值得抄的部分。

作者从开篇就把一个反 SaaS 的设计哲学钉死了——产物是单文件 HTML,不是 React 组件、不是 npm 包、不是云服务。整个 deck 双击 index.html 就能在浏览器里跑,发给别人也只是一个文件。这条决定让所有后续设计都简化了:CSS 变量驱动主题、相对路径引图片、Motion One 本地+CDN 兜底(断网也可读),全部围绕”单文件可移植”展开。

“产物是一个单文件 HTML,双击浏览器就能看,发给别人也只是一个文件,不用担心字体和动画在别人电脑上乱掉。”

第一层结构性巧思在 template.html 是 skill 的”种子”,5 份 references 是它的”使用手册”。SKILL.md 里反复强调:“template.html 是唯一的类名来源——不要发明新类名”(Step 3.0)。layouts.md 顶部写”如果某个类缺失,在 template.html 的 <style> 里补上,不要在每个 slide 里 inline 重写”。这条约束把 LLM 在生成时的最大失败模式(自由发挥写新类名导致 fallback 到默认样式、视觉全垮)从源头堵死——layouts.md 里所有骨架的类名都和 template.html 的 <style> 一一对应,校验关系是一对多但单向。

生成 PPT 前,必须先 Read assets/template.html——这是类名的唯一来源,缺类会导致整页样式崩”

第二层是 配置面被砍到只有 6 个 CSS 变量themes.md 里 5 套主题(墨水经典 / 靛蓝瓷 / 森林墨 / 牛皮纸 / 沙丘)每套就是 6 个变量的不同取值——--ink / --ink-rgb / --paper / --paper-rgb / --paper-tint / --ink-tint。template.html 里所有散落的 rgba(...) 都走 var(--ink-rgb) / var(--paper-rgb),所以换主题只改 :root 一处。最关键的是作者明确写在 SKILL.md 里:“不允许用户自定义 hex 值——委婉拒绝并展示 5 套让选”。这是 skill 工程化里很少有人敢做的硬约束。

“约束越严,风格越稳。保护美学,比给用户自由更重要。”

第三层是 主题节奏作为强制规划步骤,写进了 layouts.md 的”Pre-flight”(生成前必读)段。每页 <section> 必须带 light / dark / hero light / hero dark 之一,JS 的 go(n) 函数从 classList 推断主题然后切 body 的 light-bg 类,从而切换两张 WebGL canvas 的 opacity(bg-light / bg-dark)。如果忘记标主题色,body 永远不加 light-bg 类、canvas#bg-dark 一直在上面,视觉直接灰蒙蒙——作者在 checklist.md 的 P0 里把这个失败模式(“亮页面配暗 WebGL”)单独写成一条踩坑案例。硬规则更狠:连续 3 页同主题 = 不允许8 页以上必须有 ≥1 hero dark + ≥1 hero light整个 deck 不能只有 light 正文页。生成后还有自检命令 grep 'class="slide' index.html

第四层是 图片处理被压成两条命令式规则object-fit:cover; object-position:top center.frame-img 里固定写死,所以图片永远只裁底部不裁顶/左/右——作者明确说”图片的核心身份信息区在顶部和左右”。配套规则:网格里的图必须用 height:Nvh 固定,不能用 aspect-ratio(aspect-ratio 在父容器空间不足时会撑破网格);不能给图片加 align-self:end(在非 grid 容器里完全失效,图片会掉到文档流末尾被浏览器底栏遮挡);不准用原图奇葩比例如 2592/1798,必须从模板提供的 .r-16x10 / .r-4x3 / .r-3x2 / .r-1x1 / .r-3x4 / .r-16x9 6 个标准比例类里选。这套规则每一条都对应一个具体踩坑案例,写进了 checklist.md 的 P0 段。

第五层是 Motion One 动效系统的 5 个 recipe 抽象。整个动效系统就 5 种:cascade(默认 stagger 淡入)、hero(仪式感更慢)、quote(每行 550ms 揭示)、directional(左进 → 分割 → 右进,用于 Before/After)、pipeline(手动推进,按 → 一步步点亮 step,全部点亮才放行翻页)。前两种自动判断(hero slide 自动用 hero recipe,其他默认 cascade),后三种通过 <section data-animate="quote|directional|pipeline"> 显式指定。HTML 里的元素只需要加 data-anim(可选附值如 left / right / line / step),不需要写一行 JS。最值钱的是兜底逻辑:本地 assets/motion.min.js → CDN jsdelivr → 都失败时把所有 [data-anim] 强制设 opacity:1——动画死了内容永远可读。

第六层是 6 问反问机制写在 Step 1 里作为强制开场。SKILL.md 直接列了 6 个问题:受众与场景 / 时长(15 分钟≈10 页这种映射) / 原始素材 / 图片 / 主题色 / 硬约束。回答完才进入 Step 2 拷贝模板。作者还特意区分了运行环境——Codex 里用普通对话问,Claude Code 里用 ask question 机制。这个分支处理是 cross-platform skill 的细节工程。

收尾的 checklist.md 把整个 skill 的”failure modes”按 P0 / P1 / P2 / P3 分级,每条都是”现象 + 根因 + 做法”的三段式——读起来像一份从 5 轮真实迭代里捞出来的踩坑日志。最末尾 35 项的”最终自检清单”是 LLM 生成完 deck 后逐条勾选的——把 LLM 当作流水线工人来管。

📌 金句摘抄

“约束越严,风格越稳。保护美学,比给用户自由更重要。” (themes.md, SKILL.md Step 2.2)

template.html 是唯一的类名来源——不要发明新类名,如需自定义用 style="..." inline。” (SKILL.md Step 3.0)

生成 PPT 前,必须先 Read assets/template.html,确认 layouts.md 里用到的类都已定义。” (checklist.md P0-0)

“WebGL 背景只在 hero 页透出,普通页几乎看不见。” (SKILL.md 核心设计原则 #1,“克制优于炫技”)

“结构优于装饰 — 不用阴影、不用浮动卡片、不用 padding box,一切信息靠大字号 + 字体对比 + 网格留白。” (SKILL.md 核心设计原则 #2)

“本地 + CDN 双双失败时会兜底把所有 [data-anim] 设为可见,不让动效破坏阅读。” (template.html L686-704)

“如果用户已经给了完整的大纲 + 图片,可以跳过直接进 Step 2。” (SKILL.md Step 1)——反问机制不是教条,有完整 input 时直接放行

Layer 2 — 给 Justin 自己 skill 的三条带走

1. “唯一类名来源”是个非常硬的工程模式,可以直接搬到 html skill 和 sequoia skill。 你的 html skill 现在的”路由 → 主题 → 布局”三层在概念上已经类似,但缺少 guizang 这种”layouts.md 里所有类必须能在 template.html 里 grep 到”的单向校验关系。如果让 LLM 自由发明类名,fallback 到默认样式的视觉灾难基本不可避免——这条事故在他 checklist 的 P0-0 里被列为最重要的一条。可以加一个生成前的 pre-flight check:“Read base template <style> 块,列出 layout 用到的所有类,逐个 grep 确认存在”。失败则补到 template,不在 slide 里 inline 写。

2. “不允许自定义 hex”是一条值得复制的元规则——但要写得足够明确。 你的 sequoia skill 已经锁了红杉绿,apple-ui-design 锁了 SF Pro,本质思路一致。但 guizang 把这条拔高到 SKILL.md 的”不要做的事”明确列项:“不允许用户随便给一个 hex 值——需委婉拒绝并展示 5 套预设让选”。这种”明确说不接受 X,告诉 LLM 怎么 push back”的写法比”建议用 X”有效得多——LLM 在用户压力下很容易让步,必须给它一个明确的拒绝脚本。html skill 的主题层可以加这种硬拒绝条款。

3. checklist.md 的 P0/P1/P2/P3 分级 + “现象-根因-做法”三段式是一份很好的 skill 失败模式编码模板。 你之前的 skill(research / investment / learning hub)有 procedures.md 但没有这种”踩坑驱动的 checklist”。guizang 的 checklist 每条都从一次具体生成事故里来——“AI 把图标写成 emoji”、“图片堆到底被浏览器工具栏遮挡”、“chrome 和 kicker 写同一句话”——读起来像 git blame log。这种格式比抽象的”最佳实践”对 LLM 有约束力,因为它把抽象规则锚定到具体可识别的失败现象。html skill 的部署 spoke、apple-ui-design 的组件层都可以加一份这种 checklist。


📎 相关历史

discussion_added: pending