zcbot/skills/ppt/SKILL.md

196 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: ppt
description: 生成 PowerPoint 演示文稿 (.pptx) 文件。✅ 触发:用户明确点名 PPT / 幻灯片 / 演示文稿 / .pptx / slide / deck 之一。⛔ 不触发:用户明确说要"报告 / 文档 / 纪要"等指向纯文档形式的产物。⚠️ 歧义先反问:用户说"汇报 / 方案 / 材料"等产物形态不明的词、且没说成品形式时,不要直接 load 本 skill 也不要假定走文档,先反问一句"这份要做成 PPT 演示稿,还是 Word/Markdown 文档?" 用户确认 PPT 后再 load。
---
# PPT
把材料变成可演示的 .pptx。**先定调(spec + 逐页大纲),再出稿(一个脚本建整 deck),再验收(quality_check)** —— 方向在大纲阶段对齐,不在逐页阶段反复来回。
进度展示建议:多页 deck 任务用 `task_progress` 标记「摄取素材 / 八条对齐 + 逐页大纲 / 图标预取 / 脚本建 deck / 质量检查 / 交付」等关键阶段;不要把每一页的内部写入都作为进度步骤。
## 资源
- `scripts/pptx_helpers.py` —— **版式工具箱模块**:配色/字体常量 + `new_presentation`/`load`/`add_slide`/`set_palette` + `add_textbox`/`add_rect`/`add_dot`/`add_badge`/`page_title`/`apply_brand` 等 helper。每页 `import pptx_helpers as P` 调用,**不要把 helper 源码默写进 run_python**
- `references/design_principles.md` —— 画布尺寸 + 字号/配色/留白/字数预算等硬规则
- `references/layouts.md` —— 9 种版式的调用示例(基于 `pptx_helpers`)+ helper API 速查 + 安全区/越界保护 + `apply_brand` 品牌条
- `references/icons.md` —— 业务图标两层:Iconify (在线/本地缓存) / unicode 字形兜底
- `assets/icons/` —— **只读**种子图标库 (skill 自带的商务红 tabler 集,见 `INDEX.md`;docker 沙盒里 skills 是只读挂载。新拉的图标写 `<task_dir>/assets/icons/`)
- 素材摄取: 用 `markitdown` CLI 把 PDF/DOCX/PPTX/XLSX/HTML/URL 转干净 Markdown,统一落到 `<task_dir>/source/<name>.md`(同 working_dir 多 task 共享 source 池)
- `scripts/fetch_icon.py` —— 从 Iconify CDN 拉 SVG/PNG (染主题色,缓存到 `<task_dir>/assets/icons/`)
- `scripts/render_icon.py` —— unicode 字形 → 透明 PNG (Iconify 没有时兜底)
- `scripts/quality_check.py` —— 产物 .pptx 验收 (越界 / 文本溢出 / 颜色一致)
## 默认主题 — 商务红 (硬约束)
**主色 `#C00000` / 辅色 `#E15554` / 强调色 `#FFC107`。**
**不允许擅自换色**。除非满足以下任一条件,否则 spec 必须填这套红色:
- 用户在请求里**明确**点名其它配色 (例:"做成蓝色"、"用我们公司的紫色")
- 用户提供素材里有明确的 brand guideline / 配色卡
**禁止的自我合理化**(都属违规):
- "这个场景蓝色更专业" / "学术汇报红色不合适" / "财务用蓝更稳重"
- "我觉得 XX 主题更适合"
要换色,**先问用户**,不要在 spec 里塞自己的偏好。其它备选见 `design_principles.md §2`
## 两阶段工作流
### 阶段一: 策略 (Strategist) — 八条对齐
产物:**task 级 spec 文件** —— 整个 deck 的"宪法",阶段二每页前都要重读。文件路径按 system prompt 的《task 级「宪法」文件命名约定》:
<task_dir>/<today>-<task_short_id>-<task_name>.spec.md
`<today>` / `<task_short_id>` / `<task_name>` 用 system prompt 注入的实际值替换。
**0. 先检测已有 spec**:
```
glob <task_dir>/*-<task_short_id>-*.spec.md → 按文件名字典序排,取最大者作 current
```
(按 short_id 主锚,name 部分不参与匹配 — 用户改过 task name 时旧文件仍能定位)
- 有 current(当前 task 已有 spec) → 展示给用户,问「**沿用进阶段二** / **重定调**(以 today 写新版,旧版保留)」,⛔ BLOCKING 等用户决定
- 仅有其它 task 的(`*-<别的 short_id>-*.spec.md`)→ 不当 current 用,继续走下面流程
- 完全没有 → 直接走下面流程
按下表**一次性给出推荐方案**,然后 ⛔ **BLOCKING:等用户确认/修改后才能进阶段二**。不要一条一条问。
| # | 项 | 默认值 |
|---|----|-------|
| 1 | 画布 | **16:9** (13.33×7.5 in) |
| 2 | 页数 | **封面 + 5-8 页正文 + 尾页(Q&A)** = 共 7-10 页。**封面 / 尾页强制必有**,不在 5-8 页预算里 |
| 3 | 受众 | 看材料推断:领导汇报 / 同行评审 / 客户 pitch |
| 4 | 风格 | **现代简约** (白底 + 细线 + 留白) |
| 5 | 配色 | **商务红** `#C00000` `#E15554` `#FFC107` (见上"默认主题") |
| 6 | 字体 | **微软雅黑 + Arial** |
| 7 | 图标 | **Iconify `tabler` 集** (描边商务图标,主色染色;`fetch_icon.py` 拉到 `<task_dir>/assets/icons/`) |
| 8 | 图表 | 数据 ≥ 3 个点的页用 matplotlib 配图 |
把这 8 项写进上面那个 task 级 spec 文件,以表格形式给用户预览,问一句"按这个开干?"。**spec 写定后不再改**(要改就走 §0 的「重定调」分支,以 today 为前缀写新版,旧版保留)。
**8 项之外,spec 还要含一张「逐页大纲」表** —— 这是阶段二一个脚本建整 deck 的输入,也是替代"逐页确认"的前置 checkpoint(改一行文字大纲,比建完一页 slide 再推翻便宜得多):
| 页 | 版式 | 标题 | 核心信息 / 要点(≤5) | 图标 / 图表 |
|---|---|---|---|---|
| 1 | L1 封面 | <主标题> | <副标题 / 定位> | — |
| 2 | L4 三栏 | <标题> | <要点 1 / 2 / 3> | `target` / `cpu` / `chart-bar` |
| … | … | … | … | … |
| N | L9 尾页 | Q&A / 致谢 | <联系方式> | — |
大纲连同 8 项一起给用户预览,**BLOCKING 等用户确认整份结构**(页数、每页讲什么、用什么版式/图标)后再进阶段二。用户在这一步推翻方向 = 改表格文字,零 slide 返工。
### 阶段二: 执行 (Executor) — 一个脚本建整 deck
方向已在阶段一的「逐页大纲」里跟用户对齐过,执行阶段就是把大纲机械落成 slide。**不逐页 run_python**(每页一轮来回烧轮数/token);整 deck 在一个脚本、一个进程内构建,坐标天然一致(`pptx_helpers` 已把画布常量统一,漂移问题已解决)。
流程:
1. **读 current spec**(按 §0 的 glob 规则拿字典序最大那份),含 8 项 + 逐页大纲;只用里面定的颜色/字体/图标/页结构,**不凭记忆发挥**。
2. **图标批量预取(全 deck 一次,不逐页)**: 把大纲里所有页需要的图标概念汇总,`glob` 两处看现成 —— 种子库 `<skill_dir>/assets/icons/`(只读)+ 本 task `<task_dir>/assets/icons/`;缺的在**一个 `run_python` 里批量** `fetch_icon.py <name> --set tabler --color C00000 --size 128 -o <task_dir>/assets/icons/...` 拉齐。**几何形状(圆点/徽章/装饰线)不算图标,走 layouts.md helper**。
3. **写 `build_deck.py` 到 `<task_dir>`,一次建整 deck**: 顶部 `import pptx_helpers as P`(`sys.path` 指到 `<skill_dir>/scripts`)→ `prs = P.new_presentation(...)``P.set_palette(spec_path=...)`**按大纲循环每页**(`P.add_slide` + 各 helper,每页一个小函数 `page_1(prs)`…清晰)→ 末尾一次 `prs.save(...)`。**helper 一律 `P.xxx`,不默写源码**。起手见 `layouts.md §通用起手(整 deck 单脚本)`。先 `write` 脚本文件再 `run_python(script_path=...)` 跑(避免大段源码进对话历史)。
4. **quality_check 一次**(见阶段三)→ 按报告**改 `build_deck.py` 重跑**(不要逐页 edit 成品 .pptx —— 改源脚本可复现、可再跑)。
5. 报整份 deck:页数、各页版式、用到的图标;问用户要不要改。
6. 用户确认了**实质改动**(改版式 / 换图标 / 改文案要点 / 增删页 / 调主色)后,追加一行到 `<task_dir>/REVISIONS.md` —— 见 §修订日志。
**风格探针(可选,降视觉返工险)**: 用户对观感没底、或这是全新风格时,可先只建**封面 + 1 内页**给用户看一眼,确认后把 `build_deck.py` 的页范围放开重跑补齐其余页 —— 仍是改一个脚本,不退回逐页。用户要快("直接全做")就跳过探针,整 deck 一把出。
**为什么不再逐页?** 逐页的两个理由都已消解:① 防坐标漂移 → `pptx_helpers` 模块化已解决;② 早发现方向问题 → 前移到阶段一「逐页大纲」确认(改文字比改 slide 便宜),视觉观感由可选探针 + 整 deck 后批改兜底。代价是放弃"逐页即时纠错",换来 N 页从 ~2N 轮降到 ~3-4 轮。
### 阶段三: 验收
```bash
python <skill_dir>/scripts/quality_check.py <task_dir>/<output.pptx> --spec <task_dir>/<today>-<task_short_id>-<task_name>.spec.md
```
不通过的项,**改 `build_deck.py` 重跑**(改源脚本可复现;不要直接 edit 成品 .pptx)。
## 设计原则 (硬规则速查)
- **每页一个核心信息**: 一页讲一件事,塞两件就拆页
- **bullet ≤ 5 条**: 超过就拆页或改成图表/双栏
- **正文不写完整段落**: 列要点;长句留给演讲者口述
- **数据 ≥ 3 个点应有图表**: 用 matplotlib 生成 .png 嵌入
- **中文标题 ≤ 30 字**
- **配色三色封顶**: 主 + 辅 + 强调,其他用灰阶
- **少用大色块,多用细线 + 图标 + 留白**
- **图标走 MSO_SHAPE**: 矢量、可编辑;复杂图标走 `render_icon.py`
- **Shape 不能越界**: `layouts.md` 起手代码用 `assert_inside` 在生成时即报错
- **字数按预算来**: 写 bullet 前查 `design_principles.md §4.1` 字数预算表
- 详细规则见 `references/design_principles.md`
## 工作目录约定
下文 `<task_dir>` = system prompt 里「task_dir」给的**绝对路径**(host 下形如 `…/workspace/users/<uid>/<wd>/`,docker 沙盒里是 `/workspace/<wd>/`)。**所有产物都写到 task_dir 下**,不要写到 cwd / `skills/` / repo 根;图标分两处:skill 自带的**只读种子库**走 `<skill_dir>/assets/icons/`(docker 沙盒里 skills 只读,只读不写),`fetch_icon.py` 新拉的图标写 `<task_dir>/assets/icons/`(详见 references/icons.md §A)。
```
<task_dir>/
├── source/ # markitdown 转出的素材(同 working_dir 多 task 共享;用 markitdown -o <task_dir>/source/<name>.md)
├── <today>-<task_short_id>-<task_name>.spec.md # 八条对齐落定,task 级宪法;命名见 system prompt 约定;按 short_id 主锚,重定调时写新日期,旧版保留
├── slides/ # 各页用到的图片素材 (chart_p3.png 等),多 task 时文件名前缀区分
├── build_deck.py # 整 deck 构建脚本(一次建完所有页);改稿/修 quality_check 项都改它重跑
├── REVISIONS.md # 修订日志:每次卡点用户确认的实质改动,见 §修订日志
└── <topic>.pptx # 最终产物 (按主题命名,多 task 时主题必须不同)
```
## 修订日志 (REVISIONS.md)
`<task_dir>/REVISIONS.md` 是产物迭代过程的紧凑可读 changelog。**spec 是宪法(定调一次),REVISIONS 是实施日志(每次卡点累加)** —— 两份独立但互参,后期 review / 复盘 / 跨周回看"上周这页为啥改成这样"靠这份。
### 何时记 / 何时不记
| 情形 | 记? |
|---|---|
| 用户确认改**版式 / 主色 / 字体方向** | ✅ 必记 |
| 用户确认换 / 增 / 删**页 / 关键图标 / 数据图表** | ✅ 必记 |
| 用户确认改**文案要点 / 核心信息 / 受众定位** | ✅ 必记 |
| 自查阶段发现版式越界 / 颜色不一致后的修正 | ✅ 必记(说明触发 quality_check 项) |
| 页首次起草(从 0 加出来) | ❌ 不记(初稿不是改动) |
| 字号 / 间距 / 对齐微调 | ❌ 不记 |
| 模型自己改改撤撤、用户没明确确认 | ❌ 不记 |
> 拿不准 → 倾向不记。`REVISIONS.md` 是"用户与 LLM 共同沉淀的实质决策",不是流水账(那是对话历史的事)。
### 格式
文件首次创建时写头(只写一次):
```markdown
# 修订日志
> 产物迭代过程中每次用户确认的实质改动,按时间倒序追加(最新在上)。spec 是宪法定调,本文件是实施日志。
```
每次记一笔追加在头注释之后、最新一笔的顶部(一行 = 一次改动):
```
- `<YYYY-MM-DD HH:MM>` | <第 N 页 / spec §X> | <一句话改了什么> — <为什么>
```
### 实例
```
- `2026-03-12 16:20` | 第 5 页 | 版式从 layouts.md "两栏文+图"改为"单栏图占主体" — 用户反馈原版式右侧文字太挤,核心数据需放大
- `2026-03-12 14:05` | 第 3 页 | 删 chart 图,换成 3 个 KPI 数字块 — 数据点只有 3 个,bar chart 浪费版面
- `2026-03-11 10:30` | spec §5 配色 | 主色 `#C00000` → `#1F4E79` — 用户给的品牌指南要求蓝色,商务红默认被覆盖
```
### 操作
每次卡点用户确认后,用 `edit` 在头注释之后插入新一行(不要 append 到文件末尾 —— 倒序读才能秒看最新)。文件不存在就 `write` 创建带头注释的新文件。
## 反模式
- 用户没给材料就开始硬编内容
- 八条没对齐就跑 python-pptx
- **基于"场景判断"自行换配色**(见上"默认主题"违规清单)
- **缺封面 / 缺尾页(Q&A)** —— 两端都是强制项,不算在正文页数预算内
- **裸白纸版式** —— 所有版式起手都必须 `apply_brand(slide, kind)`,见 layouts.md
- **业务概念页只用几何形状** —— 比如"战略目标"页只摆圆点 bullet 没有 `target` 图标,视觉太单薄;按 §阶段二第 2 步先拉 Iconify 图标再做页
- **逐页 run_python 建 deck**(每页一轮来回烧轮数;改用一个 `build_deck.py` 整建,方向风险靠阶段一大纲 + 可选探针兜)
- **没经阶段一大纲对齐就直接整建** —— 大纲是替代逐页确认的 checkpoint,跳过它整建才会"改方向全推翻"
- 跑完不做 `quality_check.py` 就交付
- 起名 `output.pptx` / `untitled.pptx` —— 务必按主题给文件名
## 输出
完成后告诉用户:文件路径、页数、用到的版式列表、是否有未满足的 spec 项。问一句要不要再改。