<!-- title: 用assets目录造品牌化输出技能 -->

# 用 `assets/` 目录造一个品牌化输出技能

## 概述

本教程聚焦 Claude Code 技能体系里最被低估的一个原语——`assets/` 目录。学完之后，你能造出一个"自带品牌资产"的技能：把 Logo、字体、HTML/PPTX 模板、代码脚手架等文件随技能分发，让 Claude 在**输出**里直接复用这些文件，而不是每次都用文字重新"理解"再画一遍。适用人群：已经能写出基本 `SKILL.md`、想让团队输出在视觉与结构上高度一致的开发者。

## 前置条件

- 已安装 Claude Code（CLI 或桌面端均可），版本支持 `SKILL.md`、`${CLAUDE_SKILL_DIR}` 变量与 `!`cmd`` 注入语法
- 能手写一份带 YAML frontmatter 的 `SKILL.md`（不熟悉可先看官方 skill-development 技能）
- 准备一份本地"品牌素材"：一张 Logo 图、一个想固定下来的输出模板（HTML / Markdown / PPTX 任选）
- 一台装了 `cp`/`mkdir` 的终端（Windows 用 PowerShell 时在 frontmatter 设 `shell: powershell`）

## 一、先理清三种 bundled 资源的边界

很多人写技能时，把所有附带文件一股脑塞进技能目录，却不区分它们的"加载方式"。官方 skill-development 规范明确把附带资源分成三类，它们进入模型的方式完全不同：

| 目录 | 进入上下文的方式 | 典型内容 | 适用场景 |
|------|------------------|----------|----------|
| `scripts/` | **不读入**上下文，直接执行 | `rotate_pdf.py`、`validate.sh` | 需要"确定性可靠"或反复重写的逻辑 |
| `references/` | **按需读入**上下文 | `schema.md`、`policies.md`、`api_docs.md` | Claude 需要阅读理解后再行动的资料 |
| `assets/` | **既不读入也不执行**，只用于输出 | `logo.png`、`slides.pptx`、`template.html`、`font.ttf` | 直接被复制/嵌入到最终产物里的素材 |

关键洞察：**`assets/` 永远不会进入上下文窗口。** Claude 不会"看"Logo 的像素，也不会"读"HTML 模板的内容——它只是把这些文件原样搬到输出里。这意味着品牌的视觉一致性来自资产文件本身，而不是来自你在 `SKILL.md` 里写的一大段"我们的主色是 #1a73e8，圆角 8px……"。后者是典型的反模式：用文字描述让模型重绘，必然漂移；前者是模板化，确定性极高。

> 一句话判断标准：想让 Claude **读懂**它→放 `references/`；想让 Claude **执行**它→放 `scripts/`；想让 Claude **搬运/嵌入**它→放 `assets/`。三者互不替代。

## 二、为什么 `assets/` 几乎没人讲

翻一遍社区教程，"渐进式披露""触发词优化""脚本内嵌""权限白名单"都是热门话题，但 `assets/` 几乎隐形。原因有二：

1. 它不进上下文，所以不会直接影响"触发准确率""token 成本"这些被反复度量的事，存在感弱。
2. 它的价值在**产物**而非**过程**——只有当你真正在乎"每份报告的页眉都带同一个 Logo、每张幻灯片都用同一套字体"时，才会发现它不可替代。

本教程要做的，就是把这个隐形原语放到聚光灯下，并用一个完整可跑的例子证明它的价值。

## 三、动手：造一个品牌化 HTML 周报技能

目标：输入一周的数据（CSV/JSON 或直接在对话里给），输出一份**带 Logo、品牌字体、固定版式**的独立 HTML 周报。无论谁、无论哪一周调用，产物风格都一致。

### Step 1：建目录骨架

技能可以放在用户级 `~/.claude/skills/` 或项目级 `.claude/skills/`。这里用项目级，方便随仓库分发：

```bash
mkdir -p .claude/skills/brand-report/{assets/font,references}
touch .claude/skills/brand-report/SKILL.md
```

得到的结构（对照官方规范）：

```
brand-report/
├── SKILL.md          # 必需：导航与流程
├── assets/           # 本教程主角：用于输出的素材
│   ├── report-template.html
│   ├── brand.css
│   ├── logo.png
│   └── font/
└── references/       # 按需读入的补充文档
    └── tokens.md
```

### Step 2：准备 `assets/`（技能的核心资产）

把品牌文件放进 `assets/`。这一步的质量直接决定输出质量。先放 HTML 模板，里面用 `{{TOKEN}}` 占位，把"需要模型填的"和"必须保持原样的"彻底分开：

```html
<!-- .claude/skills/brand-report/assets/report-template.html -->
<!doctype html>
<html lang="zh">
<head>
  <meta charset="utf-8">
  <title>{{TITLE}}</title>
  <link rel="stylesheet" href="brand.css">
</head>
<body>
  <header>
    <img src="logo.png" alt="logo" height="40">
    <h1>{{TITLE}}</h1>
  </header>
  <section class="period">报告周期：{{PERIOD}}</section>
  <section class="metrics">{{METRICS}}</section>
  <section class="highlights">{{HIGHLIGHTS}}</section>
  <footer>© 2026 · 内部使用</footer>
</body>
</html>
```

再放品牌样式 `brand.css`（这里只示意，真实团队应直接用设计规范稿）：

```css
:root { --primary:#0b5fff; --ink:#1f2330; --muted:#6b7280; }
body{font-family:'BrandSans',system-ui,sans-serif;color:var(--ink);max-width:880px;margin:40px auto;padding:0 24px}
header{display:flex;align-items:center;gap:16px;border-bottom:3px solid var(--primary);padding-bottom:12px}
h1{font-size:22px;margin:0}
.period{color:var(--muted);margin:16px 0;font-size:14px}
.metrics table{border-collapse:collapse;width:100%}
.metrics th,.metrics td{border:1px solid #e5e7eb;padding:8px 12px;text-align:left}
.metrics th{background:#f8fafc}
footer{margin-top:40px;color:var(--muted);font-size:12px;border-top:1px solid #eee;padding-top:12px}
```

最后把 `logo.png` 和品牌字体文件放进 `assets/`。注意：**这些二进制文件 Claude 永远不会读进上下文**——它只会 `cp` 它们，所以放心放，不用担心 token 成本。

### Step 3：写 `SKILL.md`（精简、祈使句、引用资产）

按官方规范三条铁律写：① description 用第三人称并塞进真实触发短语；② 正文用祈使句（verb-first），不用第二人称；③ 保持精简（目标 1500–2000 字），细节挪到 `references/`。

```markdown
---
name: brand-report
description: This skill should be used when the user asks to "generate a weekly report", "create a branded report", "生成品牌周报", "导出带 Logo 的 HTML 报告", or needs on-brand standalone HTML output. Uses bundled brand assets (logo, fonts, CSS, HTML template) so every report stays visually consistent without re-deriving the style from prose.
allowed-tools: Read Write Bash(cp *) Bash(mkdir *) Bash(cp -r *)
---

# 品牌化 HTML 周报生成

Generate a standalone, on-brand HTML weekly report. Brand fidelity comes from the bundled asset files, not from re-styling in the prompt.

## Bundled assets

All brand files live under `${CLAUDE_SKILL_DIR}/assets/` and are **used in output, not loaded into context**:

- `assets/report-template.html` — full scaffold with header, footer, and token placeholders
- `assets/brand.css` — brand palette, typography, spacing
- `assets/logo.png` — company logo, copied next to the report
- `assets/font/` — brand web fonts referenced by `brand.css`

## Procedure

1. Determine the reporting period from `$ARGUMENTS` (e.g. `2026-W26`). If absent, use the current ISO week.
2. Read the data source (a CSV/JSON path, or values given in the prompt).
3. Scaffold the output deterministically by copying assets:
   ```!
   OUT="./out/report-$1.html"
   mkdir -p ./out
   cp "${CLAUDE_SKILL_DIR}/assets/report-template.html" "$OUT"
   cp "${CLAUDE_SKILL_DIR}/assets/logo.png"      ./out/logo.png
   cp "${CLAUDE_SKILL_DIR}/assets/brand.css"     ./out/brand.css
   cp -r "${CLAUDE_SKILL_DIR}/assets/font"       ./out/font
   ```
4. Fill tokens `{{TITLE}}` `{{PERIOD}}` `{{METRICS}}` `{{HIGHLIGHTS}}` in `$OUT` with real values. Preserve all brand markup; only replace token text.
5. For a self-contained file, inline `logo.png` as a base64 data URI and inline `brand.css` into a `<style>` block.
6. Reply with the output path and a one-line metric summary.

## Style rules

- Never re-derive palette or fonts from prose; always copy from `assets/`.
- Keep the template section order; do not reorder header/metrics/highlights/footer.
- If a token has no data, replace it with an em dash `—`; never delete the section.

## Additional resources

- For the full token list and edge cases, see `references/tokens.md`.
```

这里有几个设计要点值得展开：

**`${CLAUDE_SKILL_DIR}` 是资产型技能的生命线。** 它在运行时被替换成 `SKILL.md` 所在目录的绝对路径，与当前工作目录无关。如果你写成相对路径 `./assets/logo.png`，一旦 Claude 的 cwd 不在技能目录（几乎总是不在），复制就会失败。官方文档把它列为少数几个可用的内置变量之一，与 `$ARGUMENTS`、`${CLAUDE_SESSION_ID}` 并列。

**`!`cmd`` 注入负责"搬运资产"。** `cp` 这些命令在内容发给模型之前就执行完毕，输出替换占位符。也就是说，模板与 Logo 的复制是**预处理**，不是模型"决定要不要做"——这正是确定性的来源。注意 inline 形式只在一行开头或空白后识别；多行用 ` ```! ` 围栏。

**`allowed-tools` 不是白名单。** 官方文档明确：它只是"在技能激活期间免去这些工具的授权弹窗"，并不禁止其它工具。真正要禁用某工具用 `disallowed-tools`。这里允许 `cp`/`mkdir` 是为了资产复制不被反复打断。

### Step 4：配置触发方式（可选但重要）

如果想让它**只能手动 `/brand-report` 调用**（比如避免 Claude 自作主张生成报告），加一行：

```yaml
disable-model-invocation: true
```

如果想让它**只在处理数据文件时自动激活**，用 `paths` 限定：

```yaml
paths: "**/*.{csv,json}", "**/weekly-data/**"
```

两种字段可以并存：`paths` 管"什么时候触发"，`disable-model-invocation` 管"模型能不能自动触发"。

### Step 5：验证

```bash
# 在项目根目录启动
claude
# 对话里输入：
生成 2026-W26 的品牌周报，数据见 ./data/week26.csv
```

预期结果：Claude 先执行 `!`cmd`` 段，把模板、CSS、Logo、字体复制到 `./out/`；接着读取 CSV 填充 `{{METRICS}}`；最后给出 `./out/report-2026-W26.html` 路径。打开该文件，页眉是固定 Logo，标题/周期/指标表/页脚结构完全一致。

常见问题速查：

| 现象 | 原因 | 解决 |
|------|------|------|
| `cp: assets/report-template.html: No such file` | 用了相对路径 | 改用 `${CLAUDE_SKILL_DIR}/assets/...` |
| 报告出来了但没 Logo | 在 SKILL.md 里用文字描述让模型"画"Logo | 改成 cp 资产 + `<img src="logo.png">` |
| 每次颜色/字体都略不同 | 样式写在 prompt 里而非 `brand.css` | 把样式全部沉淀进 `assets/brand.css` |
| 技能不被触发 | description 缺真实触发短语 | 按"生成品牌周报"等真实说法补触发词 |
| 修改了 assets 但产物没变 | 改的是 `references/` 误以为是 `assets/` | 确认文件确实在 `assets/` 且 cp 命令引用正确 |

## 四、完整工作流：技能加载与资产搬运

下面两张图分别说明"渐进披露的三层加载"和"一次调用的资产流动"。

```mermaid
flowchart TD
    A[技能目录 brand-report/] --> B[第1层: 元数据]
    A --> C[第2层: SKILL.md 正文]
    A --> D[第3层: 附属资源]
    B --> B1["name + description<br/>始终在上下文, ~100词/截断1536字符"]
    C --> C1["技能触发时加载<br/>目标 1500-2000 词"]
    D --> D1["scripts/ → 执行, 不读入"]
    D --> D2["references/ → 按需读入上下文"]
    D --> D3["assets/ → 既不读入也不执行<br/>★本教程主角★"]
    style D3 fill:#ffe4b5,stroke:#d97706,stroke-width:2px
```

```mermaid
sequenceDiagram
    participant U as 用户
    participant CC as Claude Code
    participant SH as Shell(!cmd注入)
    participant FS as 文件系统
    U->>CC: 生成 2026-W26 品牌周报
    CC->>CC: 加载 SKILL.md 正文(触发)
    CC->>SH: 执行 cp ${CLAUDE_SKILL_DIR}/assets/* ./out/
    SH->>FS: 复制 模板/Logo/CSS/字体
    SH-->>CC: 占位符替换为复制结果
    CC->>FS: 读取 ./data/week26.csv
    CC->>FS: 填充 {{METRICS}} 等token, 写 report.html
    CC-->>U: 返回 out/report-2026-W26.html
```

第二张图揭示了资产型技能的本质：**Logo 与样式的"注入"发生在模型看到内容之前**，由 Shell 完成；模型只负责读数据、填 token。这与"让模型理解品牌再画一遍"是两条完全不同的路线，前者确定、后者漂移。

## 五、进阶：资产型技能的三种高阶模式

**模式 A：资产 + 动态注入组合。** 资产负责"固定的壳"，`!`cmd`` 注入负责"动态的馅"。例如周报里嵌入本周 git 提交数：

```!
echo "本周提交数: $(git log --since='last monday' --oneline | wc -l)"
```

注入结果再被填进 `{{HIGHLIGHTS}}`。固定版式 + 动态数据，两全其美。

**模式 B：自包含产物（base64 内联）。** 当输出要发邮件、贴 wiki 时，外部依赖的 `logo.png`/`brand.css` 会丢。让模型在填充后把图片转 base64、把 CSS 塞进 `<style>`，得到单文件 HTML。指令写在 SKILL.md 的第 5 步即可，资产仍由 `cp` 提供，只是最终内联。

**模式 C：多模板资产。** 在 `assets/` 放多个模板（`report.html`、`slide-deck.pptx`、`one-pager.html`），用 `$ARGUMENTS[0]` 选模板：

```bash
cp "${CLAUDE_SKILL_DIR}/assets/$1-template.${2:-html}" "$OUT"
```

一套品牌资产，多种产物形态，但视觉语言统一。这正是官方 skill-development 文档里 `brand-guidelines` 技能设想的落地形态——文档原话："实现 brand-guidelines 技能时，用户可能需要提供品牌资产或模板存进 `assets/`。"

## 六、`assets/` vs `references/` 的取舍清单

写技能时最容易在两者间犹豫。给出一个可操作的判别流程：

- 这份文件，Claude 需要**读懂内容才能行动**吗？（如 API 文档、字段 schema、公司政策）→ `references/`
- 这份文件，Claude 只需要**原样放进产物**吗？（如 Logo、字体、PPT 母版、HTML 脚手架）→ `assets/`
- 同一份信息会**既被读又被搬**吗？（如一份"模板说明"既要读又要附带）→ 拆成两份：说明进 `references/`，文件进 `assets/`，避免重复。
- 文件很大（>10k 词）且是参考性质？→ `references/`，并在 SKILL.md 里给出 grep 检索模式，避免整文件读入。

记住：信息要么在 SKILL.md，要么在 references，**不要三处重复**；assets 是素材不是文档。

## 七、安全与治理提醒

资产型技能往往随仓库分发，几个红线：

- `assets/` 里别塞密钥、`.env`、内部凭证——它们会被复制到产物目录，容易泄露。
- 项目级 `.claude/skills/` 的 `allowed-tools` 在你接受工作区信任对话框后才生效，审阅陌生仓库的技能时务必检查它给自己授予了哪些工具。
- `cp` 前确认目标路径不会覆盖用户既有同名文件，建议输出文件名带时间戳或周期参数（本例用 `report-$1.html`）。
- 若技能由不可信来源提供，可在 managed settings 设 `"disableSkillShellExecution": true` 关掉 `!`cmd`` 注入（注意：bundled/managed 技能不受此开关影响）。

## 训练营适用性评估

- **最适合**：企业内部 Claude Code 落地训练营、文档/报表自动化训练营、品牌与市场团队的内容生产工作坊。这类场景的共性是"输出必须长期保持品牌一致"，正是 `assets/` 的主场。
- **预计时长**：讲解 30 分钟 + 动手 60 分钟 + 迭代调优 30 分钟，合计约 2 小时。建议每位学员自带一份真实品牌素材（Logo + 一个模板），结营即带走可用的技能。
- **验收标准**：能独立产出一份带 Logo、固定版式、风格与样例完全一致的输出文件；并能口述 `scripts/references/assets` 三者的边界。
- **进阶衔接**：本主题可与"渐进式披露""脚本内嵌""Skill 发布成插件"组合成半天到一天的技能开发专题。

## 参考来源

1. [Extend Claude with skills — Claude Code Docs](https://code.claude.com/docs/en/skills) — 官方技能文档，含 frontmatter 全字段、`${CLAUDE_SKILL_DIR}`、`!`cmd`` 注入、`paths`/`allowed-tools` 等权威说明
2. [Skill Development SKILL.md — anthropics/claude-code](https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/skill-development/SKILL.md) — 官方技能开发规范，明确 `scripts/references/assets` 三类资源的边界与 progressive disclosure 设计原则
3. [Claude Code Skills 2026 — Progressive Disclosure and How to Standardise Workflow for Engineering Teams](https://anhtu.dev/claude-code-skills-2026-progressive-disclosure-and-how-to-standardise-workflow-for-engineering-teams-1062) — 三层渐进披露、SKILL.md 解剖与 frontmatter 实践
4. [Progressive Disclosure — Agent Skills (claudeskills.link)](https://claudeskills.link/module/core-concepts/lesson/progressive-disclosure) — 渐进披露的设计要点与分层加载示意
5. [Example Claude Code Skill: Development Best Practices (mcpmarket)](https://mcpmarket.com/tools/skills/example-skill) — 展示技能结构与渐进披露实践的可参照样例

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
