---
name: GPT Image 2 PPT
slug: gpt-image-2-ppt
category: AI Engineering
description: "GPT Image 2 PPT generates slide images with OpenAI's gpt-image-2 from a markdown outline and a style or a .pptx template, then packages them into a 16:9 PowerPoint file. Use it for presentations, pitch decks, and courseware."
github: "https://github.com/JuneYaooo/gpt-image2-ppt-skills"
language: Python
stars: 1190
forks: 69
install: "npx degit https://github.com/JuneYaooo/gpt-image2-ppt-skills ~/.claude/skills/gpt-image2-ppt-skills"
installs_to: ~/.claude/skills/gpt-image2-ppt-skills
source_path: SKILL.md
collection_size: 1
category_size: 2451
added: 2026-08-20T07:55:33.545Z
last_synced: 2026-08-20T07:55:33.545Z
canonical_url: "https://dirskills.com/skills/gpt-image-2-ppt"
---

# GPT Image 2 PPT

GPT Image 2 PPT generates slide images with OpenAI's gpt-image-2 from a markdown outline and a style or a .pptx template, then packages them into a 16:9 PowerPoint file. Use it for presentations, pitch decks, and courseware.

**Install:**

```bash
npx degit https://github.com/JuneYaooo/gpt-image2-ppt-skills ~/.claude/skills/gpt-image2-ppt-skills
```

## README

# gpt-image2-ppt -- 用 gpt-image-2 生成 PPT

把一份 markdown 大纲（或 `slides_plan.json`）+ 一种视觉风格，直接喂给 OpenAI 官方 Images API（`gpt-image-2`），逐页出图，最后打包成 16:9 .pptx。

## 可用风格

| 风格 ID | 一句话定位 | 适用场景 |
| --- | --- | --- |
| `gradient-glass` | Apple Vision OS / Spatial Glass | AI 产品发布、技术分享、创意提案 |
| `clean-tech-blue` | Stripe / Linear 级蓝白 | 融资路演、商业计划书、企业战略 |
| `vector-illustration` | 复古矢量插画 + 黑描边 | 教育培训、品牌故事、社区分享 |
| `editorial-mono` | Kinfolk / Monocle 编辑设计 | 品牌发布、文化访谈、读书分享 |
| `dark-aurora` | Linear / Vercel 深色霓虹 | AI 产品、开发者工具、技术分享 |
| `risograph` | Riso 双套色印刷 + 网点纹理 | 创意工作室、文创品牌、独立 zine |
| `japanese-wabi` | 无印 / 原研哉式侘寂 | 茶道、生活方式、奢侈品、文化讲座 |
| `swiss-grid` | Bauhaus / Vignelli 国际主义网格 | 学术报告、博物馆展陈、严肃汇报 |
| `hand-sketch` | Sketchnote / 白板手绘 | 工作坊、产品 brainstorming、培训 |
| `y2k-chrome` | Y2K 千禧液态金属 + 蝴蝶贴纸 | 潮牌、文娱、品牌联名、Z 世代营销 |
| `abstract-art-showcase` | 黑白极简、艺术展览感、超大字体和抽象画面并置 | 艺术策展、作品集、品牌调性展示 |
| `coal-industry-business-company-profile` | 工业棕黑、粗重标题、结构线和硬朗图标 | 能源、制造业、重资产公司介绍 |
| `college-candy-aesthetics-infographics` | 糖果色、校园感、圆润信息图和轻快装饰 | 教育、校园活动、轻量数据科普 |
| `creative-agency` | 创意机构气质、强视觉拼贴、鲜明版式节奏 | Agency 提案、品牌方案、创意汇报 |
| `culinary-innovation` | 餐饮创新感、食材摄影、暖色块和杂志式排版 | 餐饮品牌、食品创新、菜单/新品发布 |
| `data-science-consulting` | 数据咨询蓝灰、模块化布局、图表和技术感信息层级 | 数据分析、AI 咨询、企业数字化 |
| `mindfulness-in-the-classroom-breathing-techniques` | 柔和心理健康配色、留白、圆角块和安静插画感 | 心理健康、课堂活动、呼吸训练课程 |
| `mind-maps-workshop-professional` | 专业工作坊风、思维导图节点、清晰流程结构 | 培训工作坊、方法论、团队共创 |
| `meeting-agenda` | 会议议程感、干净网格、强信息分组和商务标题 | 例会、项目同步、管理层汇报 |
| `investment-company-business-plan` | 投资机构质感、深浅对比、稳重商务版式 | 投资计划、基金介绍、商业计划书 |
| `indigenous-cultures` | 文化纹样、自然色、手工质感和叙事型构图 | 文化课程、历史主题、公益教育 |
| `health-disparities-and-social-determinants-of-health-doctor-of-philosophy-phd-in-health-behavior-and-health-education` | 公共健康学术风、理性网格、柔和医疗色和论文感层级 | 医学论文答辩、公共健康报告、教育研究 |
| `geometric-duotone-thesis` | 双色几何、论文答辩感、斜切图形和强标题 | 学术答辩、研究报告、章节型内容 |
| `geometric-clinical-case` | 几何医疗风、冷静配色、病例卡片和清晰分栏 | 临床病例、医疗培训、诊疗汇报 |
| `geometric-business` | 商务几何块、稳健蓝绿调、简洁图表语言 | 商业计划、团队汇报、产品策略 |
| `formal-lavender-portfolio` | 淡紫正式感、作品集留白、优雅细线和柔和版式 | 个人作品集、设计简历、专业展示 |
| `flowery` | 花卉装饰、柔和色块、浪漫但有秩序的排版 | 生活方式、女性品牌、活动介绍 |
| `first-impressions` | 第一印象主题、强封面视觉、人物/标题的戏剧化关系 | 面试培训、个人品牌、沟通课程 |
| `final-year-project-thesis-defense` | 毕业设计答辩、学院派网格、清晰章节与数据页 | 毕业答辩、项目结题、研究展示 |
| `fashion-business-consulting-toolkit-aesthetic` | 时尚咨询感、高级拼贴、杂志排版和中性色 | 时尚商业、品牌咨询、趋势报告 |
| `economic-impact-of-coronavirus` | 经济影响报告风、严肃信息图、冷静色彩和数据叙事 | 宏观经济、政策分析、风险报告 |
| `eco-green-business-plan` | 鼠尾草绿、自然材质摄影、环保商务与极简分屏 | 可持续商业、环保品牌、健康生活方式 |

所有可用风格都统一放在 `styles/` 下并按来源分组，使用方式完全相同：`initial/` 收录初始 10 套，`featured/` 收录精选 22 套，`xiamulingzi/` 收录设计师 @夏目玲子 提供的 233 套。目录索引见 `styles/README.md`；精选风格封面展示见 `docs/distilled-styles.md`。

> 风格选择原则：先根据内容场景在 `styles/` 里选择最贴近的一套。技术类可优先看 `dark-aurora` / `gradient-glass` / `data-science-consulting`，商务类可优先看 `clean-tech-blue` / `editorial-mono` / `eco-green-business-plan` / `investment-company-business-plan`，文化生活类可优先看 `japanese-wabi` / `vector-illustration` / `culinary-innovation` / `flowery`，学术类可优先看 `swiss-grid` / `geometric-duotone-thesis` / `final-year-project-thesis-defense`，工作坊与培训类可优先看 `hand-sketch` / `mind-maps-workshop-professional` / `mindfulness-in-the-classroom-breathing-techniques`。

## 场景 recipes（可选起步模板）

`examples/` 不是新的 skill，也不是运行时必须输入；它是当前 skill 的场景起步模板库，用来在用户只给出模糊需求时，帮助 agent 更快写出第一版 `slides_plan.md`。

触发规则：

- 用户已经提供完整大纲 / 完整 `slides_plan.md` / 完整 `slides_plan.json` 时，不要套 recipe，直接按用户内容走生成流程。
- 用户只说“做一份产品发布 PPT / 融资路演 / 周报 / 课程课件 / 论文答辩 / 读书分享”等常见场景，且没有给清晰页结构时，先查看 `examples/` 是否有匹配 recipe。
- recipe 只作为结构参考：读取 `examples/<id>/recipe.md` 了解场景、推荐风格和注意事项，再参考 `examples/<id>/slides_plan.md` 的页序结构，改写成用户自己的主题与内容。
- 不要把示例里的虚构产品、公司、项目、数据直接当成用户成品；必须替换为用户提供的信息，或明确标注为占位内容并等待用户确认。
- 如果用户给了真实图片、logo、截图、论文图表或产品 UI，仍按“外部真实图片贴入”规则处理；recipe 只负责内容结构，不替代素材保真流程。

当前内置 recipes：

| 用户场景 | recipe 目录 | 推荐风格 |
| --- | --- | --- |
| 产品发布、新功能发布、AI 产品介绍 | `examples/product-launch/` | `gradient-glass` |
| 融资路演、商业计划书、投资人汇报 | `examples/investor-pitch/` | `clean-tech-blue` |
| 项目周报、月报、例会同步 | `examples/weekly-report/` | `meeting-agenda` |
| 课程课件、培训、知识科普 | `examples/courseware/` | `vector-illustration` |
| 论文答辩、毕设答辩、结题展示 | `examples/thesis-defense/` | `final-year-project-thesis-defense` |
| 读书分享、文化访谈、观点分享 | `examples/book-sharing/` | `editorial-mono` |

使用方式：

1. 判断用户需求是否命中某个 recipe。
2. 读取对应 `recipe.md` 和 `slides_plan.md`。
3. 基于用户主题改写一份新的 `slides_plan.md`，不要直接改 recipe 源文件。
4. 与用户确认页数、每页标题和关键内容。
5. 用户确认后再执行 `md_to_plan.py` 转 json，并继续下面的指定风格或模板克隆流程。
### 内置风格的 layout bank sidecar（唯一运行格式）

内置风格采用“MD 给人看，JSON 给机器用”的双文件结构：

```text
styles/<collection>/<style-id>.md            # 风格说明、设计令牌、基础提示词
styles/<collection>/<style-id>.layouts.json  # 必需；每页 layout bank，供自动分配页面形态
```

`generate_ppt.py` 会把同名 `.layouts.json` 作为无 reference image 的 RuntimeProfile 使用：通过 `assign_layouts()` 分配不同 layout，把 `visual_signature` / `content_capacity` / `best_for` / `avoid_for` / `variation_tags` 写入 prompt，并把命中的 layout 精简信息写入 `metadata.json`。

当前所有 `styles/**/*.md` 都必须配套同目录、同名的 `.layouts.json`。只有 Markdown、缺少 sidecar 的旧风格会在出图前直接报错，不再静默走旧 Prompt；先把它迁移为配对格式。以后蒸馏公开模板或新增内置风格时，必须同时产出 JSON sidecar；不要把多页 layout 只压缩进单个 MD 的“布局系统”文字段落。

### 统一 RuntimeProfile 运行内核

严格模板克隆和结构化 style sidecar 都先编译成同一种 RuntimeProfile，再统一经过 `assign_layouts()`、页面 Profile 附着、prompt 编译和 metadata 记录。入口适配器只保留必要差异：

- `template-clone`：来自 `--template-profile` 或模板 vision 分析；layout 可携带 `reference_image`，只有 `--template-strict` 才实际传入生图。
- `distilled-style`：来自 `<style>.md` + `<style>.layouts.json`；使用内容路由和多布局，不依赖原模板图片。

RuntimeProfile 统一记录 `source_kind`、固定的 `prompt_strategy=layout-fields`、`layouts` 和 `capabilities`（routing / evidence / reference / portability）。优先级固定为：有效模板 Profile > style RuntimeProfile；模板分析没有 layouts 时必须真正回退到结构化 style，而不是只打印提示。运行时不再包含 `legacy-freeform` 或 synthetic layout 分支。

## 模板克隆模式

直接给 skill 一个 .pptx 模板，后续所有页都仿这个模板。

```bash
# 一行：自动渲染 + 模板分析 + 出图。需本机有可用 PPTX 渲染后端
python3 scripts/generate_ppt.py \
  --plan slides_plan.json \
  --template-pptx ./company-template.pptx \
  --template-strict
```

`--template-strict` 表示每页都把模板对应页作为 image reference 喂给 gpt-image-2，仿真度最高。

### 模板渲染：本机不需要操作 PowerPoint

skill 自带 `render_template.py`，把 .pptx 自动渲染成每页 PNG，存到 `<cwd>/template_renders/<stem>/page-NN.png`。

### Agent 前置检查（模板克隆时必须做）

**在跑任何 --template-pptx 命令之前，你必须先检查本机是否有可用 PPTX 渲染后端。**

检查方式：

- 首选：在 skill 目录运行 `python3 scripts/render_template.py --check`。它会验证后端是否真的可执行，而不是只看路径是否存在。
- macOS：优先检查 `/Applications/Keynote.app` 且 AppleScript 可执行；否则检查 `libreoffice --version || soffice --version`
- Windows：优先检查本机 PowerPoint COM 可启动；否则检查 `libreoffice --version` / `soffice --version`
- Linux / 兼容层：检查 `libreoffice --version || soffice --version`，不要只用 `which`

注意：鸿蒙 / Termux / 容器 / 特殊架构环境可能看起来像 Linux，但不能假设 Linux aarch64 的 LibreOffice 二进制可运行；必须以 `render_template.py --check` 或 `soffice --version` 的实际执行结果为准。不要把 `aspose-slides` 当默认兜底，它在很多移动/特殊 Python 环境没有可安装 wheel。

如果都没有可用后端，先告知用户模板渲染需要安装可执行的 LibreOffice，或让用户在桌面端手动把模板每页导出为 `page-01.png`、`page-02.png` 后通过 `--template-images` 传入。可选安装命令：

| 平台 | 安装命令 |
| --- | --- |
| Windows | `winget install LibreOffice.LibreOffice` |
| macOS | `brew install --cask libreoffice` |
| Linux (Debian/Ubuntu) | `sudo apt-get install -y libreoffice` |
| Linux (Fedora/RHEL) | `sudo dnf install -y libreoffice` |
| Linux (Arch) | `sudo pacman -S --noconfirm libreoffice-fresh` |

装完再次检查，确认存在可用渲染后端再继续后续流程。

> 注意：Windows 上 `winget` 是 Win10/11 自带，会弹 UAC 确认框，需要用户点确认；macOS 上 `brew` 需要先安装 Homebrew。

`render_template.py` 的渲染后端按优先级自动挑：
1. **Windows**：PowerPoint COM（本机有 Office 时优先，直出 PNG，跳过 PDF 步骤）> LibreOffice
2. **macOS**：Keynote AppleScript（本机有 Keynote 时优先，直出 PNG）> LibreOffice
3. **Linux / 兼容层**：通过 `--version` 探测确认可运行的 LibreOffice / soffice 命令
4. PDF -> PNG 走 `pymupdf`（已在 requirements）；没装就用 `pdf2image` + poppler

跑 `generate_ppt.py --template-pptx ...` 时如果省略 `--template-images` 会自动调一次渲染；也可以手动先跑一次：

```bash
python3 scripts/render_template.py company-template.pptx
# -> <cwd>/template_renders/company_template/page-01.png ... page-NN.png
```

### 仿模板的两层缓存

| 资料 | 路径 | 用途 |
| --- | --- | --- |
| 模板每页 PNG | `<cwd>/template_renders/<stem>/page-NN.png` | 本机渲染后端一次渲染长期复用 |
| 模板风格分析 | `<cwd>/template_cache/<sha256>.json` 或手写 `template_profile.json` | 多模态 agent 自己看图生成；纯文本 agent 才需要外挂 vision |
| 生成产物 | `<cwd>/outputs/<timestamp>/` | 每次新跑都新目录 |

三者都在调用者 cwd 下，与项目自然同进退；建议把 `template_renders/`、`template_cache/`、`outputs/` 加进项目的 `.gitignore`。

**模板看图分析（让 agent 自己判断要不要配 `VISION_*`）**：

- **当前 code agent 本身是多模态模型**（例如 Claude Code 的多模态 Claude、Codex 的多模态 GPT）：不需要额外配置 `VISION_*`。agent 直接读取 `template_renders/<stem>/page-*.png`，按 `template_analyzer.py` 的 `TemplateProfile` 结构生成 `template_profile.json`，再用 `--template-profile template_profile.json` 传给 `generate_ppt.py`。如果要配合 `--template-strict`，每个 layout 里要写 `reference_image`（模板 PNG 的绝对路径或可访问路径）。
- **当前 code agent 是纯文本模型**（例如只接入 DeepSeek 文本模型）：它看不了模板截图，需要额外配置 `VISION_BASE_URL` / `VISION_API_KEY` / `VISION_MODEL_NAME`，让 `template_analyzer.py` 调一个独立的 OpenAI 兼容多模态端点做模板分析。

vision 分析与图片生成的 `gpt-image-2` 永远解耦——换 vision provider 不影响出图路径。

## 安装

```bash
git clone git@github.com:JuneYaooo/gpt-image2-ppt-skills.git
cd gpt-image2-ppt-skills
bash install_as_skill.sh --target claude   # Claude Code
# 或
bash install_as_skill.sh --target codex    # Codex
# API 直连所需密钥优先通过 agent 配置 / 系统环境变量注入
```

## 环境变量注入（API 直连时）

不要把本 skill 的密钥写进调用者业务项目根目录的 `.env`，也不要为了出图去读取用户项目里的通用 `.env`。环境变量建议按 agent 框架的标准方式注入：

- **通用 / CI / 服务器**：用系统环境变量、Docker Compose `environment` / `env_file`、Kubernetes Secret、CI Secret 等注入。
- **Claude Code**：用用户级 `~/.claude/settings.json` 或项目级 `.claude/settings.local.json` 注入环境变量；命令行环境变量优先级最高。
- **OpenClaw / 自定义 Agent**：用框架配置里的 `apiKey` / env reference 引用系统环境变量，避免把 key 明文写进项目配置。
- **本地 standalone CLI fallback**：可以设置 `GPT_IMAGE2_PPT_ENV=/path/to/private.env`，或使用 skill 安装目录下的 `.env`；这只是备用方式，不是业务项目 `.env`。

API 直连需要这些变量：

```bash
OPENAI_BASE_URL=https://api.openai.com    # 或任意 OpenAI 兼容中转站
OPENAI_API_KEY=sk-...
GPT_IMAGE_MODEL_NAME=gpt-image-2
GPT_IMAGE_QUALITY=high                     # low / medium / high / auto

# 可选：模板克隆模式的 vision 分析 backend。
# 多模态 agent / 原生 Codex 可自己看图生成 --template-profile，不需要下面这组。
# 只有纯文本 agent（如 DeepSeek 文本模型）才需要外挂下面这组。
# 不内置默认 endpoint，请填你自己信任的服务，否则就别填。
# VISION_BASE_URL=https://your-openai-compatible-relay.example.com/v1
# VISION_API_KEY=sk-...
# VISION_MODEL_NAME=gemini-3.1-pro-preview   # 或 gpt-4o / claude-3.5-sonnet 等任意多模态 SKU
```

> **安全提示**：脚本只读取当前进程环境、平台注入的 `gpt-image2-ppt_*` 变量、显式 `GPT_IMAGE2_PPT_ENV`，以及 skill 安装目录下的 `.env` fallback。脚本**不会**向上递归读取调用者项目目录里的 `.env`，避免误吃业务项目密钥。

## 如果你就是 Codex agent（原生 image_generation 出图 — 推荐）

**如果你自己就是 Codex**（正在运行本 skill 的 agent 就是 Codex CLI / Codex TUI），并且当前环境提供 `image_generation` tool 和 ChatGPT 登录态，此时**不要用 `generate_ppt.py` 或 `--backend codex` 负责出图**，直接用原生工具生成图片，最后只复用本仓库的 md 转换 / PPTX 打包逻辑即可。

关键边界：Python 脚本运行在子进程里，拿不到当前 agent 会话里的原生 tool。`generate_ppt.py --backend codex` 能做的只有再启动一个 `codex exec` 子进程，让另一个 Codex 去出图；它不是“复用当前 Codex 的 image_generation tool”。所以当前 agent 已经能原生出图时，出图动作必须由 agent 本身完成，而不是交给 `generate_ppt.py`。

### 如何判断

你能访问 `image_generation` tool，并且不需要手动配 `OPENAI_API_KEY` 就能出图——满足这两个条件就走原生路径。若当前 Codex 会话没有这个 tool，就按普通 agent 处理：走 API 直连、`--backend codex` 备用后端，或让用户补齐环境。

### 出图流程（Codex 原生路径）

**1. 准备 slides 数据**

如果还没有 `slides_plan.json`，先按下面「生成流程」第 2-3 步写 `slides_plan.md` → `python3 scripts/md_to_plan.py ...` 转 json。

**2. 用统一运行时准备 prompt**

不要手工复刻 `generate_prompt()`。运行 `--prepare-only`，让 API 直连和 Codex 原生路径共享同一个 RuntimeProfile、layout routing 和 prompt compiler：

```bash
python3 scripts/generate_ppt.py \
  --plan slides_plan.json \
  --style styles/<collection>/<id>.md \
  --prepare-only \
  --output outputs/<timestamp>
```

该命令不调用图片 API，也不打包 PPTX；它会生成 `prompts.json`、逐页 prompt 文本和 `metadata.json`。只做单页冒烟时同时传 `--slides 1`。

**3. 读取每页编译结果**

从 `outputs/<timestamp>/prompts.json` 读取每页 `prompt`、`reference_image`、`asset_reference_image` 和 `layout_id`。不要根据 Markdown 重新拼一份 Prompt，否则会绕过结构化 layout bank。

**4. 调 image_generation tool 出图**

对每页调你的 `image_generation` tool：

- `prompt`: `prompts.json` 中该页已经编译好的完整 prompt
- `output_format`: `png`
- 如果记录了 `reference_image` / `asset_reference_image`，按原顺序作为图片 reference 传入
- 将返回的图片保存到 `outputs/<timestamp>/images/slide-NN.png`（NN 为两位页码）

可以并发（建议 ≤4 并发，避免限流）。

**5. 打包 PPTX**

如果本 deck 没有外部真实图片对象，可以用下面的简易整页 PNG 打包。**如果任一页有 `external_image` / `image_overlay` / `external_image_placeholder` 且指向真实图片，不能用这个简易打包片段**，否则真实图片会被合进整页背景 PNG，用户无法在 PowerPoint 里单独选中拖动。此时必须走 `generate_ppt.py` 的标准打包逻辑，或在已有 session 中调用 `generate_pptx(..., metadata=metadata)`，让真实图片作为独立 picture object 叠在背景上。

```bash
python3 -c "
from pptx import Presentation
from pptx.util import Inches
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
import os, glob
for p in sorted(glob.glob('outputs/<timestamp>/images/slide-*.png')):
    slide = prs.slides.add_slide(blank)
    slide.shapes.add_picture(p, 0, 0, width=prs.slide_width, height=prs.slide_height)
prs.save('outputs/<timestamp>/<title>.pptx')
print('done')
"
```

外部真实图片页的正确 PPTX 结构应是：

- 第 1 层：`images/slide-XX.png` 作为整页背景图（包含模型生成的背景和文字）。
- 第 2 层：`source` 指向的真实图片作为独立 PPT picture object，按 `slide_spec` 坐标贴在背景上，可在 PowerPoint 里选中、拖动、缩放。

### 模板克隆模式（Codex 原生路径）

你自己就是多模态 agent——直接 `Read` 模板每页 PNG 抽取视觉风格，写成 `template_profile.json`（schema 见 `template_analyzer.py` 里的 `TemplateProfile`，每个 layout 写上 `reference_image`），再用 `--template-profile template_profile.json --template-strict --prepare-only` 编译每页 Prompt 和 reference；不要手工选择另一套 Prompt 拼接逻辑。

**不需要配 `VISION_*`**——你就是 vision。

### 与下面「--backend codex」的区别

| | 原生路径（本节） | --backend codex |
|---|---|---|
| 适用场景 | **你就是** Codex agent | 你是 Claude Code / 其他 agent，借用本机 codex CLI |
| 调用方式 | 直接调 `image_generation` tool | spawn `codex exec --full-auto` 子进程 |
| 出图层数 | 1 层 | 2 层（agent → python → codex exec） |
| 速度 | 几秒/张 | 30-60s/张 |
| 可靠性 | tool 参数精确 | 自然语言 relay，偶发失败 |
| 需要 API Key | 不需要 | 不需要 |

---

## 可选：走 codex CLI 出图（--backend codex，非 Codex caller 用）

> **如果你就是 Codex agent，不要走这条路——用上一节的「原生路径」代替。**

当你用 Claude Code / OpenClaw / 其他 agent 运行本 skill，但本机装了 codex CLI 且已登录（`codex login`），可以借用它的凭据出图，省掉配 `OPENAI_API_KEY`：

```bash
python3 scripts/generate_ppt.py --plan slides_plan.json --style styles/initial/editorial-mono.md --backend codex
```

默认后端仍是 `openai`（直调 API，快、并发稳、每页 3-10s）。`--backend codex` 是逃生口，适合"只跑 1-2 张图试水、不想配 key"的场景。

**Tradeoffs**：
- ✅ 不需要在本 skill 配 `OPENAI_API_KEY`
- ⚠️ 慢：每页多一层 agent loop，单页 30-60s+，10 页可能 5-10 分钟
- ⚠️ 计费不变：gpt-image-2 是按图计费，不在 ChatGPT 订阅内，codex 只是代你刷额度
- ⚠️ 可控性差：aspect_ratio / quality / reference_image 靠自然语言指令让 codex 转发，偶发失败

相关 env（都可选）：

```bash
CODEX_CMD="codex exec --full-auto"   # 覆盖 codex 调用方式（默认这串）
CODEX_IMAGE_MODEL=gpt-image-2        # 传给 codex 的目标模型
CODEX_TIMEOUT_SECS=900               # 单页超时
GPT_IMAGE_BACKEND=codex              # 不想每次敲 --backend 就设这个
```

模板克隆的 vision 分析同理——当 caller agent 自己是多模态时（Claude Code / 多模态 codex），可以直接 `Read` 模板 PNG 抽取风格，不用配 `VISION_*`；只有 caller agent 是纯文本模型时才需要外挂 vision provider。

## 生成流程（指定风格）

**先 md 后 json**：md 给人看、方便 diff / review / 改文案；json 由 md 派生，喂给 `generate_ppt.py`，标为 generated，不手改。

1. 用户给一份大纲 / 已有的 slides_plan.json；如果用户只给常见场景和主题，先按上方“场景 recipes”选择一个 `examples/<id>/` 作为结构参考
2. Agent 按下面 md 规范写一份新的 `slides_plan.md`，与用户确认文案：
   ````markdown
   ---
   title: MediWise Health Suite 商业计划书
   ---

   ## 1. [cover] MediWise Health Suite
   副标题：家庭健康管理智能平台
   年份：2026

   ## 2. [content] 市场痛点：健康管理的两类割裂
   痛点一：高频无深度
   ...

   ## 6. [data] 效率对比：使用 MediWise 前后
   ...
   ````
   - h2 格式：`## N. [page_type, layout=layout-05] 本页标题行`
   - `N.` 可省（按出现顺序自动编号）；`[page_type]` 可省（默认 `content`）；`layout=` 只在模板克隆模式需要
   - `page_type`: `cover` / `agenda` / `section` / `content` / `data` / `quote` / `closing` / `other`
   - h2 标题行 → json 里 `content` 的第一行；下面的正文 → 正文
3. 用户 OK 后，转 json：
   ```bash
   python3 scripts/md_to_plan.py slides_plan.md -o slides_plan.json
   ```
4. 选风格：从 `styles/initial/`、`styles/featured/` 或 `styles/xiamulingzi/` 里挑一个，对应 `styles/<collection>/<id>.md`；如果使用了 recipe，优先采用 `recipe.md` / frontmatter 里的 `recommended_style`，需要视觉预览时先看 `docs/distilled-styles.md`
5. **构造 slide_spec**（Agent 步骤）：读 `styles/<collection>/<id>.md` 的视觉规范，为 `slides_plan.json` 每页构造 `slide_spec`（每个元素的 type、content、position、style），写入每页的 `slide_spec` 字段。格式见下方"指哪改哪"章节
6. 调脚本：
   ```bash
   python3 scripts/generate_ppt.py --plan slides_plan.json --style styles/initial/editorial-mono.md
   ```
7. 产物在 `<cwd>/outputs/<timestamp>/`：
   - `images/slide-XX.png` -- 每页 PNG（16:9，1536x864）
   - `prompts.json` -- 每页用到的完整 prompt（便于复盘 / 二次微调）
   - `metadata.json` -- slide_spec 版本历史（支持精确编辑和回滚）
   - `<title>.pptx` -- 16:9 PPTX；默认背景与文字是整页图片，通过 `external_image` 放入的真实图片会作为独立 PPT 图片对象叠加

## 可编辑模式（默认关闭）

普通模式仍优先保证 gpt-image-2 的整页审美，输出背景和文字为整页图片。只有用户明确要求“可编辑 PPTX / 文字可以改 / 元素可拆 / 图片可移动 / 原生形状”时，才启用可编辑模式；不要根据内容类型自行默认开启。

### 核心原则

**不要禁止 gpt-image-2 在初始视觉稿中生成标题、正文、数字、表格、Logo 或关键图表。** 模型仍先生成完整成品页，以保留整体构图、材质、光效和文字与视觉之间的关系；可编辑模式是生成后的重建步骤。

### 效果优先与轮次控制

可编辑模式以最终视觉效果和对象级可编辑质量为首要目标，不强制单轮完成；但必须区分低成本检查轮次与高成本生成轮次：

- **检查轮次可以多轮**：scene schema、字体可用性、文字溢出、对象越界、图片比例、黑白底边缘、对象移动、PPTX 回渲染和人工看图都可以重复执行，不因追求少轮而跳过。
- **生成轮次逐级升级**：优先调整字体、坐标、裁切、圆角、层级等确定性参数；其次走 A1 原像素提取和 A2 遮挡补全；再只对失败的复杂素材做 B AI 分离/重生成；只有整体构图、视觉层级或风格明显不合格时，才允许重生整页。
- **局部问题只修局部**：一个图层、一个文本框或一个槽位失败时，不得默认重新生成已经通过检查的其它内容。
- **每轮保留当前最佳版本**：在 `quality-report.json` 记录本轮问题、修复范围、所用路由和结果；新版本没有带来可见提升时停止，不要为了“多试一次”让版式随机漂移。
- **真实素材仍以保真为先**：Logo、产品 UI、医学影像、论文图表、财务数据和证据截图不得为了减少轮次而改走 AI 重绘。

推荐顺序：

```text
完整视觉稿 / 用户参考图
  -> 一次性 scene 规划与对象分层
  -> 原生对象重建 + A1/A2 素材处理
  -> 多轮低成本预检与回渲染
  -> 仅对失败范围做局部修复或 B 路由
  -> 只有结构性失败才重生整页
  -> 选择历史最佳版本交付
```

### 可编辑模式的回渲染前置检查（必须）

可编辑 PPTX 必须能被重新渲染成图片，供多模态 agent 逐页读取并人工验收；要求与模板克隆模式相同。**在跑任何 `--editable` 命令之前，必须先检查本机是否有可执行的 PPTX 渲染后端：**

```bash
python3 scripts/render_template.py --check
```

- Windows：PowerPoint COM > LibreOffice
- macOS：Keynote AppleScript > LibreOffice
- Linux / 兼容层：实际可执行的 LibreOffice / `soffice`

不能只检查文件路径或安装包是否存在，必须以 `--check`、PowerPoint COM 启动、Keynote AppleScript 探测或 `libreoffice --version` 的实际结果为准。鸿蒙、Termux、容器和特殊架构同样不得假设 LibreOffice 可运行。

如果没有可用后端，停止可编辑模式并告知用户安装 PowerPoint、Keynote 或 LibreOffice；不得生成一个未经回渲染检查的 `-editable.pptx` 并声称成功。安装方式与上方“模板克隆模式”的渲染后端说明相同。

`generate_ppt.py --editable` 会在开始生成前执行同等预检；构建完成后自动把 `-editable.pptx` 回渲染到 `<session>/editable_renders/page-XX.png`。agent 必须逐页读取这些 PNG，检查字体替换、换行、对象错位、边缘和视觉差异。纯文本 agent 无法完成这一步时，必须明确要求用户或另一个多模态 agent 看图验收，不能把自动报告当作人工验收。

用户明确要求可编辑时，agent 必须：

1. 先运行 `python3 scripts/render_template.py --check`，确认回渲染后端真实可用；
2. 正常完成 `slides_plan.md` → `slides_plan.json` 和单页视觉冒烟；
3. 保存每页完整视觉稿为 `visual-master`；
4. 为每页建立 `slide-XX.scene.json`、clean plate、独立素材和质检证据；
5. 调用显式的 `--editable` 模式；
6. 读取 `<session>/editable_renders/page-XX.png` 逐页人工检查，不能只看自动报告。

```bash
python3 scripts/generate_ppt.py \
  --plan slides_plan.json \
  --style styles/initial/dark-aurora.md \
  --editable \
  --editable-scenes editable_scenes/
```

- `--editable` 默认关闭；未传时，现有生成、编辑、回滚和普通 PPTX 打包行为不变。
- `--editable-scenes` 指向包含 `slide-01.scene.json`、`slide-02.scene.json` 等文件的目录。
- 省略 `--editable-scenes` 时，会尝试 `<session>/editable_scenes/`。
- CLI 会在生成前拒绝不可用的回渲染环境，并在构建后自动生成 `<session>/editable_renders/page-XX.png`。
- scene 缺页、素材丢失或格式错误时，**不得静默**退化成整页图片并声称可编辑；应保留普通 PPTX 和中间证据，然后明确失败。
- 成功时同时保留 `<title>.pptx` 和 `<title>-editable.pptx`。

### Scene 元素

每个 scene 使用真实像素画布坐标，至少声明 `slide_number`、`canvas`、`clean_plate` 和按 `z_index` 排序的 `elements`。支持：

| type | 用途 |
| --- | --- |
| `native_text` | 标题、正文、日期、数字、标签、徽章文字；输出 PowerPoint 原生文本框 |
| `image_layer` | 照片、主视觉、插画、复杂纹理和无法合理转成 shape 的对象；输出独立图片层 |
| `native_shape` | 矩形、圆角矩形、圆、五角星和线条；输出原生 PowerPoint shape |
| `connector` | 架构图、流程图的直线连接线和箭头 |

scene 中的路径优先写相对于 scene JSON 的相对路径，便于示例和 session 整体移动。完整示例见 `examples/editable-pptx/case05-summer-poster/slide-01.scene.json`。

### 重叠素材的 A1 → A2 → B 路由

1. **A1 原像素直接提取（默认）**：轮廓完整、遮挡少、边缘干净时直接从完整视觉稿提取。多个彼此重叠的素材默认作为一个连接组合层提取，不强行拆成残缺对象。
2. **A2 原像素 + 遮挡补全**：保留可见原像素，对对象背面或对象移走后暴露的 clean plate 做补全。
3. **B AI 分离或重生成**：仅当 A1/A2 的毛发、毛绒、半透明、玻璃、白色主体、复杂水彩边缘或遮挡补全效果不合格，或用户明确要求设计模式时启用。

不要因为 B 更方便就跳过 A1。每次升级必须在 `quality-report.json` 记录原因。Ca
