--- name: gpt-image2-ppt description: Generate visually striking PPT slides via OpenAI's gpt-image-2 -- use any style in styles/.md or mimic a user-supplied .pptx template; outputs high-res slide PNGs and a 16:9 .pptx. Use when the user asks to make a presentation, slides, deck, pitch deck, investor PPT, magazine-style PPT, or 做一份 PPT / 生成幻灯片 / 用 gpt-image 生成 PPT / 按这个模板生成 PPT. --- # 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/` 下,使用方式完全相同。需要查看风格封面展示时,读取 `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//recipe.md` 了解场景、推荐风格和注意事项,再参考 `examples//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/.md # 风格说明、设计令牌、基础提示词 styles/.layouts.json # 可选;每页 layout bank,供自动分配页面形态 ``` 当 `--style styles/.md` 存在同名 `.layouts.json` 时,`generate_ppt.py` 会自动把它作为无 reference image 的 TemplateProfile 使用:优先通过 `assign_layouts()` 分配不同 layout,把 `visual_signature` / `content_capacity` / `best_for` / `avoid_for` / `variation_tags` 写入 prompt,并把命中的 layout 精简信息写入 `metadata.json`。 当前所有内置 `styles/*.md` 都应配套同名 `.layouts.json`。以后蒸馏公开模板或内置风格时,优先补这个 JSON sidecar;不要把多页 layout 只压缩进单个 MD 的“布局系统”文字段落。 ## 模板克隆模式 直接给 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,存到 `/template_renders//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 # -> /template_renders/company_template/page-01.png ... page-NN.png ``` ### 仿模板的两层缓存 | 资料 | 路径 | 用途 | | --- | --- | --- | | 模板每页 PNG | `/template_renders//page-NN.png` | 本机渲染后端一次渲染长期复用 | | 模板风格分析 | `/template_cache/.json` 或手写 `template_profile.json` | 多模态 agent 自己看图生成;纯文本 agent 才需要外挂 vision | | 生成产物 | `/outputs//` | 每次新跑都新目录 | 三者都在调用者 cwd 下,与项目自然同进退;建议把 `template_renders/`、`template_cache/`、`outputs/` 加进项目的 `.gitignore`。 **模板看图分析(让 agent 自己判断要不要配 `VISION_*`)**: - **当前 code agent 本身是多模态模型**(例如 Claude Code 的多模态 Claude、Codex 的多模态 GPT):不需要额外配置 `VISION_*`。agent 直接读取 `template_renders//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. 读风格模板** 读 `styles/.md`,取 `## 基础提示词模板` section 作为 base prompt。 **3. 构造每页 prompt** 参考 `generate_ppt.py` 的 `generate_prompt()` 逻辑,核心规则: - 封面(cover/slide 1):标题/副标题为视觉焦点 - 数据页(data/最后一页):突出关键数字、对比或结论 - 内容页(content/其余页):按层级、对齐、留白结构化呈现 - **所有文字必须简体中文**,字体用思源黑体/苹方,严禁草书/艺术字 - **16:9 横版宽屏**(landscape, widescreen),prompt 里明确说"宽度明显大于高度、绝对不要方图" ```text {style 基础提示词模板} --- 现在请生成本组中的【{封面页/内容页/数据页}】,{对应 hint} 本页要呈现的内容如下(请按本风格美学重新设计版式): {slide content} 【强制语言与字体要求】 1. 所有文字必须使用简体中文,严禁英文(专有名词除外) 2. 中文字体使用思源黑体或苹方,严禁草书、艺术字 3. 标题粗体,正文常规,字号对比清晰 【画面比例 — 强制】16:9 横版宽屏 (landscape, widescreen),宽度明显大于高度,绝对不要方图或竖图。 ``` **4. 调 image_generation tool 出图** 对每页调你的 `image_generation` tool: - `prompt`: 上面拼好的完整 prompt - `output_format`: `png` - 将返回的图片保存到 `outputs//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//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//.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`),然后按上面流程出图时把对应模板页作为 reference image 传给 `image_generation` tool。 **不需要配 `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/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/` 里挑一个,对应 `styles/<id>.md`;如果使用了 recipe,优先采用 `recipe.md` / frontmatter 里的 `recommended_style`,需要视觉预览时先看 `docs/distilled-styles.md` 5. **构造 slide_spec**(Agent 步骤):读 `styles/<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/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/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` 记录原因。Case 05 的毛绒角色、白色冰淇淋与水彩云混合,A1/A2 边缘不稳定,因此使用 B 生成单色键背景的组合素材,再本地去背景。 ### Clean plate 与页面类型 - 保存 `visual-master.png`,不要覆盖原始成品页。 - 文字和独立图片对象必须从 `clean-plate.png` 中移除;移动对象后不能露出第二份相同对象。 - API edit 只能在显式 repair mask 内合成,mask 外像素必须锁定。 - 简单渐变、霓虹光带、纯色卡片可使用确定性插值;出现幽灵字、色块、暗圆或明显补丁时必须拒绝。 - 数据页把标题、标签和数字分别建立 `native_text`,不要把整张数据卡当成不可编辑截图。 - 架构图、流程图和规则信息图优先重建为 `native_shape` + `native_text` + `connector`,不要仅在截图上覆盖文字。 ### 交付门槛 每页至少保留: ```text editable/slide-XX/ ├── visual-master.png ├── clean-plate.png ├── repair-mask.png # 使用局部修复时 ├── layers/*.png ├── edge-check-white.png # 有透明图片层时 ├── edge-check-black.png └── quality-report.json ``` 交付前必须检查:scene schema、PPTX 对象名称与数量、mask 外像素变化、黑/白底边缘、文字修改、图片移动、`editable_renders/page-XX.png` 以及人工视觉效果。初始报告状态为 `rendered_pending_manual_review`;只有多模态 agent 或用户逐页目测后才能判定通过。 向用户报告普通 PPTX、`-editable.pptx`、输出目录和 `editable_renders/` 路径,并说明哪些视觉仍作为独立图片层存在。 ## 外部真实图片贴入(推荐精确流程) 默认规则:用户提供真实图时,优先按原图保真后贴,不要让 `gpt-image-2` 重画这张图。使用 `slide_spec` 声明外部图片槽位: 这套流程只在元素声明了 `type: "external_image"` / `image_overlay` / `external_image_placeholder` 且 `source` 能解析到真实本地图片文件时启用。没有真实图片 source 的普通生成、模板克隆、纯占位布局和老的自由风格生成不受影响。 如果用户明确说“更重视画面融合效果,不需要一定贴原图 / 可以重绘 / 可以图生图”,可以走参考图模式:把图片作为 generation reference 输入给模型,而不是最终独立后贴。此时版面通常更融合,但不保证像素级保真,PPT 里也不会有可单独选中的原图对象。 参考图模式可用 `type: "image_reference"`,或在 `external_image` 上显式写 `render_mode: "reference"` / `preserve_original: false`: ```json { "elements": { "mood_reference": { "type": "image_reference", "source": "/absolute/path/to/photo.png", "purpose": "只作为视觉参考,允许模型融合重绘,不作为独立 PPT 图片对象后贴" } } } ``` 不要对高精度素材使用参考图重绘:医疗影像、病理图、诊断依据、实验/工程读数、财务表格、论文图表、法律证据截图、产品 UI 精确截图等都应默认走 `external_image` 保真后贴,并在交付前提示用户核对。 ```json { "elements": { "hero_photo": { "type": "external_image", "source": "/absolute/path/to/photo.png", "layout_intent": "auto", "tailor_to_asset": true, "slot_strategy": "fit-within", "fit": "contain", "slot": { "padding": 0.012, "bleed": 0, "fill": "#F7F7F5", "mask_placeholder": false, "sanitize_background": false, "draw_frame": false, "outline_width": 0, "skeleton_canvas_fill": "transparent", "skeleton_fill": "transparent", "skeleton_shape": "corners", "skeleton_outline": "#000000", "skeleton_outline_width": 2, "skeleton_ticks": false } } } } ``` 生成时脚本会自动做四件事: 1. **先规划槽位,再生成 skeleton**。脚本会优先读取模板 profile 里的 `external_image_slots`,或根据模板摘要推断“左图右文 / 右图左文 / 底部图表 / 中央主视觉”等候选区域;然后结合本页文字量、标题长度、真实图片数量、真实图片宽高比和素材分类(照片 / 图表 / 文档 / 架构图等)打分选位,先产出 `position` / `computed_bbox` / `auto_layout_reason` / `layout_planning_profile`。skeleton 只是把这个规划结果画给模型看,不负责临时想位置。 2. 读取 `source` 真实图片尺寸。如果声明了 `tailor_to_asset: true` 或 `slot_strategy: "fit-within"`,脚本会把 `position` 当作“可用区域”,按真实图片宽高比在其中计算 `computed_bbox`;这个 bbox 会同时用于 prompt、骨架参考图和最终 PPTX 贴图。这样不是生成后再临时缩放,而是在 `gpt-image-2` 出图前就量体裁衣。 3. 在 `outputs/<timestamp>/references/slide-XX-asset-skeleton.png` 生成一张透明画布的角标骨架参考图,把最终真实图会覆盖的 `final_image_rect_px` 标出来,并作为 reference image 传给 `gpt-image-2`。这只用于引导模型不要把关键信息放进该区域;**每页只调用一次 `gpt-image-2`,不是先生成一张再用骨架二次重生。** 4. 打包 PPTX 时,按同一个 bbox 用 `python-pptx` 把 `source` 指向的真实图片作为独立图片对象贴入。默认不画额外框,也不铺遮罩;也不会默认清理 `gpt-image-2` 生成图。真实图片不应被合成进 `images/slide-XX.png`,否则用户无法在 PPT 里单独拖动。 如果生成后发现真实图片槽位压到大面积文字或图形,优先按下面两种方式处理: 1. **预生成前微调槽位**:改 `slide_spec.elements.<id>.position`(或 `anchor` / `padding`),让真实素材移动到更干净的区域,再重新生成该页。只要槽位位置变了,就必须重新生成背景;不要只在 PPTX 里移动最终图片,否则背景内容仍可能压住新位置。 2. **二次版式修复**:当第一页整体风格已经满意,只是局部内容压入槽位时,用 `--edit SLIDE --external-slot-repair`。该模式会同时把当前页和新的 `asset-skeleton` 作为 reference image 传入,要求模型保持原风格但重排文字/图形,让槽位空出来。 示例:把真实图区域右移并重排当前页: ```bash python3 scripts/generate_ppt.py \ --session outputs/20260529_120000 \ --edit 3 \ --external-slot-repair \ --element-updates '{"hero_photo":{"position":[0.60,0.16,0.32,0.60],"anchor":"center"}}' ``` 同时,每个包含外部真实图片的页面都会在 `outputs/<timestamp>/external_image_trace/slide-XX/` 记录完整中间链路: - `step1-real-on-blank.png`:把真实图片按最终坐标和大小先贴到空白页上,用来确认“真实图最终应该出现在这里”。 - `step2-reference-outline-blank.png`:去掉真实图片,只保留给 `gpt-image-2` 的角标定位参考图;默认透明画布,不铺白底。定位区域使用 `final_image_rect_px`,也就是最终真实图实际会覆盖的像素矩形,而不是外层 slot。这张图同时会复制到 `references/slide-XX-asset-skeleton.png` 并作为 image reference 输入。 - `step3-generated-background.png`:`gpt-image-2` 根据 step2 reference 生成的背景图,尚未贴入真实图片。 - `step3-image2-raw.png` / `step3-sanitized-background.png`:只有显式设置 `sanitize_background: true` 时才会出现,用于兜底清理模型已经画出的占位块;默认不启用。 - `step4-final-overlay-preview.png`:在 step3 上按 step1 同一坐标贴回真实图片的预览图,用来和 PPTX 最终效果对照。 - `manifest.json`:记录每个外部图片的 `source`、`slot_bbox_norm`、`inner_rect_norm`、`reference_rect_px`、`final_image_rect_px`、padding、bleed、素材尺寸和比例。 关键原则: - reference skeleton 负责“告诉模型哪里不要放关键信息”,不是要求模型画白色空框。 - 模板克隆 / `--template-strict` 与外部真实图片槽位同时存在时,生成阶段会同时传入两张 reference:模板页用于学习风格,`asset-skeleton` 用于标记后贴图片覆盖区;不要二选一,否则模型只看模板页时不会知道最终图片位置。 - 外部真实图片页不能简单堆叠“模板照片/图片区 prompt”和“留空 prompt”。构造 prompt 前必须先消解冲突:模板只提供配色、字体、网格、节奏和装饰语言;模板里的照片区、图片框、全幅图、裁切图等都视为已被真实图片槽位替代。 - 构造 `slide_spec` 时,`position` 不能随便选,也不要默认固定右侧。模板克隆模式下,优先让模板 profile 提供 `external_image_slots`,或从模板布局摘要推断候选图片区,再根据本页文字量、真实图片数量、真实图片比例和页面类型打分:文字多时优先保证标题/正文阅读区;图片多或比例极端时优先用模板原有分栏/上下布局;无法共存时减少装饰和假视觉主体,而不是让真实图压内容。 - 推荐先写 `layout_intent: "auto"`,不手写 `position`。脚本会读取模板候选槽位、真实图尺寸、文字量、图片数量和比例来选择位置,写入 `position` / `computed_bbox` / `auto_layout_reason`;只有自动规划不理想时才用人工 `position` 覆盖。 - 使用 `layout_intent: "auto"` 时,`slide_spec.layout` 尽量写清图片区方向和结构,例如"左文右图 / right image / right landscape photo / 底部图片 / portrait rail"。自动规划会优先从这些方向性描述和模板候选槽位推断真实图区域;描述过泛时,重文本页可能退化到保守的小图槽位。 - `position` 默认可作为“允许使用的区域”;`computed_bbox` 才是脚本算出的最终真实图片槽位。 - 如果你想完全固定坐标,不要量体裁衣,直接写 `bbox`,或设置 `slot_strategy: "exact"` / `tailor_to_asset: false`。 - 最终精度由 `python-pptx` 坐标保证,不由模型画框保证。 - `skeleton_outline_width` 只控制给模型看的骨架参考图;`outline_width` / `draw_frame` 才控制最终 PPT 里是否出现可见框。 - prompt 中不写归一化坐标;位置通过透明角标 reference 图控制,避免模型错误解释数值坐标,也避免闭合框被理解成真实图片框。 - `skeleton_canvas_fill` / `skeleton_fill` / `skeleton_outline` / `skeleton_outline_width` / `skeleton_shape` 只影响参考骨架图。默认 `skeleton_canvas_fill: "transparent"` 且 `skeleton_shape: "corners"`,只在 `final_image_rect_px` 四角画短角标,不画闭合矩形、不铺白底,避免模型把 reference 理解成真实图片框或白色占位块。需要旧行为时显式设 `skeleton_shape: "outline"`。 - `sanitize_background` / `mask_placeholder` 不是推荐路径;它们只适合清掉极轻微的占位痕迹,不适合解决文字或图形大面积压住槽位的问题。遇到压内容,按“微调槽位并重生”或“二次版式修复”处理。 - 默认最终不画外框、不插入任何底色矩形,只贴真实图片;`mask_placeholder` 会被忽略,避免在真实图下方产生可拖动白底。只有显式设置 `draw_frame: true` 且 `outline_width > 0` 时,才会额外画无填充边框。 - 推荐默认:`tailor_to_asset: true` + `slot_strategy: "fit-within"` + `fit: "contain"` + 少量 `padding`。这会完整保留原图,并让骨架图从一开始就是按素材比例预留的。 - `fit: "contain"` 保留完整图片;`fit: "cover"` 会居中裁剪图片来铺满槽位。 - 如果要“严丝合缝”无白边,使用 `fit: "cover"`、`padding: 0`、`outline_width: 0`,并设置很小的 `bleed`(例如 `0.0015`-`0.003`)让图片比槽位多铺出约 1-3px,抵消 PowerPoint / Quick Look 渲染取整和抗锯齿缝隙。 - 如果想“预留一点但不要莫名空隙”,不要靠后期 `contain` 硬塞进一个比例不匹配的大框;应使用 `fit-within` 先算好比例匹配的槽位,再用很小的 `padding` 做设计留白。 - 交付前必须抽查 `external_image_trace/slide-XX/manifest.json`:重点看 `final_image_rect_px` 是否符合视觉预期,`auto_layout_reason` 是否选中了正确的左右/上下区域。若横图被算成小缩略图、竖图过窄或位置压内容,先补清楚 `slide_spec.layout` 的方向意图,或显式设置 `position`,再重新生成该页背景并重新打包 PPTX。 整体原理图保存于 `docs/external_image_overlay_logic.txt`;修改外部真实图片链路时,先对照这张图确认顺序仍是“模板/页面/素材画像 -> 候选槽位打分 -> 透明 skeleton -> 背景生成 -> 后贴真实图 -> 质检/有限修复”。 ## 生成流程(模板克隆) 1. **拿到模板 .pptx**(用户提供 / 内部模板库 / 网络下载) 2. **(可选)先单独渲染并人工挑选**----大模板(>15 页)建议先 `python3 scripts/render_template.py xxx.pptx`,再从 `template_renders/<stem>/` 里挑 8-12 张代表页复制到 `template_renders/<stem>_curated/`,供 vision 分析。页数越精,layout 命中越准 3. **生成 slides_plan.md → 转 slides_plan.json**(见指定风格流程第 2-3 步)。每页 `slide_number` / `page_type` (`cover` / `agenda` / `section` / `content` / `data` / `quote` / `closing` / `other`) / `content`;想精准对位时在 h2 里加 `layout=layout-NN`(NN = 模板第 N 页 / 你期望对应的模板页编号) 4. **出图冒烟**。API 直连 / 非 Codex 原生路径跑 `generate_ppt.py`: ```bash python3 scripts/generate_ppt.py \ --plan slides_plan.json \ --template-pptx xxx.pptx \ --template-images template_renders/xxx_curated \ --template-strict --slides 1 ``` 如果当前 agent 自己是多模态模型,也可以先看模板 PNG 写出 `template_profile.json`,再这样跑,完全不需要 `VISION_*`: ```bash python3 scripts/generate_ppt.py \ --plan slides_plan.json \ --template-profile template_profile.json \ --template-strict --slides 1 ``` 先 `--slides 1` 出封面冒烟,效果 OK 再跑全量。 如果当前 agent 就是带原生出图能力的 Codex,不要用上面的 `generate_ppt.py` 命令负责出图;先生成 / 读取 `template_profile.json`,再按“Codex 原生路径”直接调当前会话的图片生成 tool 输出第 1 页 PNG,用户确认后再生成全量页面并打包。 5. **告知用户产物路径** ### 模板页面挑选 / 复用原则 **核心原则:尽量做到 1 page : 1 layout**----同一份 deck 里每个 slide 用不同的模板页作 reference,观众会觉得每页都是新内容;如果同一个独特 layout 出现 2-3 次,观众下意识会想"为什么又是这页"。 vision 分析时会给每个 layout 标 `reuse_friendly`: TemplateProfile 每个 layout 除了 `id` / `page_type` / `summary` / `json_schema` / `reference_image`,还会尽量保存: - `visual_signature`:这页最明显的视觉差异点,例如"右图左文"、"编号时间线"、"三卡片网格"。 - `content_capacity`:适合承载的信息密度,避免把长文塞进强视觉页。 - `best_for` / `avoid_for`:适合或不适合的内容结构。 - `variation_tags`:英文短标签,用来帮助比较和错开 layout 形态。 生成时会用 `assign_layouts()` 优先分配未使用 layout;即使 plan 没有手写 `slide_spec`,命中的模板 layout 也会以精简版 `template_layout_profile` 写进 `metadata.json`,便于后续编辑、贴图槽位规划和复盘。 | reuse_friendly | 典型 layout | 多次使用的代价 | | --- | --- | --- | | `false`(不可复用,(!) 强警告) | 封面、3 个具名角色插画页、独特场景图(雪山/广播塔/复古收音机)、5 步骤 zigzag 各步独有图标、novelty 数据中央装置 | 视觉重复非常明显,观众会困惑 | | `true`(可复用,但仍建议错开,(i) 弱提示) | 纯文字、卡片网格、通用列表、章节小节标题 | 不致命,但平白浪费模板里的其它好版式 | Agent 在搭 plan 时的执行策略: 1. **优先把模板里 N 个不同 layout 分配给 N 页 slide**(N 不够就在 SKILL 里看 reuse_friendly=true 的部分挑能复用的) 2. **如果 plan 里某页内容结构非常相似(比如多个"5 步骤流程"),先尝试改写内容用不同 layout 表达**(4 步骤 + 5 步骤分别用不同流程页),而不是同一个 zigzag 用两次 3. **冒烟跑完后,看 `Layout 复用检测` 那段输出**:(!) 必须改,(i) 看情况改;改 plan 里相应 slide 的 `layout_id` 即可 4. **看完 profile JSON 选 layout**:`cat <cwd>/template_cache/<sha256>.json | jq '.layouts[] | {id, page_type, reuse_friendly, visual_signature, content_capacity, summary}'`;如果是多模态 agent 自己生成的 `template_profile.json`,就读取那个文件。 `generate_ppt.py` 在派发任务前会自动跑一次复用检测,把警告打到终端,不阻塞执行。 ## Skill 调用规范 当用户说"做一份 PPT" / "生成幻灯片"时: 1. **先问三件事**(不要直接动手): - 内容 / 页数 / 观众是谁? - 风格偏好?按 `styles/` 和 `docs/distilled-styles.md` 的场景类目映射推荐 1-2 个;**或者用户上传自己的 .pptx 模板**(走 `--template-pptx`,自动渲染) - 是否需要单页测试一张图先看效果(API 直连用 `--slides 1`;Codex 原生路径直接生成第 1 页 PNG) 2. **先写 slides_plan.md** 给用户确认文案(md 是 source of truth,人审阅友好) 3. **转 slides_plan.json**:`python3 scripts/md_to_plan.py slides_plan.md -o slides_plan.json`(json 标为 generated,不手改;要改文案回到 md 改再转) 4. **构造 slide_spec**(Agent 步骤):读 `styles/<id>.md` 了解视觉规范,然后为 `slides_plan.json` 每页构造 `slide_spec`,写入每页的 `slide_spec` 字段(格式见"指哪改哪"章节)。这一步让后续修改能精确到每个元素 5. **出图冒烟**: - API 直连 / 非 Codex 原生路径:跑 `generate_ppt.py --slides 1` 出封面冒烟,效果 OK 再跑全量 - 当前 agent 就是带原生出图能力的 Codex:按上方“Codex 原生路径”直接调当前会话的 `image_generation` tool 生成 `outputs/<timestamp>/images/slide-01.png`;不要用 `generate_ppt.py --backend codex` 6. **告知用户产物路径**,产物在 `outputs/<timestamp>/`,`<title>.pptx` 可直接打开 ### 面向用户的表达规范 对普通用户汇报时,默认不要解释 `slide_spec`、`metadata.json`、`element-updates`、JSON Schema、pytest 命令等内部实现,除非用户明确问技术细节。 用户最关心的是: 1. 做出来的 PPT 是否好看、能不能直接用。 2. 哪些场景稳定,哪些场景需要人工验收。 3. 是否只改了指定页 / 指定内容。 4. 最终输出目录和 PPTX 文件在哪里。 5. 当前不足是什么,例如背景/文字仍是整页图片、数字小字需复核;真实 logo/产品图需提供素材,才能作为独立图片对象放入。 如果需要介绍修改能力,优先引用 `docs/edit_guide.md` 的场景分级、before / after 案例和当前不足,不要把实现链路放在用户前面。 当用户说"改第 X 页的 XX"时: 1. **找到 session**:先用 `--list-sessions` 列出现有 session,确定要编辑的是哪个 2. **读 metadata.json**:查看对应 slide 的 slide_spec,找到目标元素 3. **确认修改内容**:告知用户当前内容,询问新内容 4. **构造编辑指令**:用 `--element-updates` 指定要改的元素和新内容 5. **执行 --edit**:`python3 scripts/generate_ppt.py --edit X --session <ts> --element-updates '{"elem_id": {"content": "new"}}'` 6. **告知结果**:新版本已生成,PPTX 已更新 ## 仅生成部分页 ```bash python3 scripts/generate_ppt.py --plan my_plan.json --style styles/dark-aurora.md --slides 1,3,5 ``` 跑过的页有同名 PNG 时会自动跳过,方便逐页迭代。 ## "指哪改哪" PPT 编辑工作流 本节只保留 agent 执行所需信息;完整结构、版本链和数据安全细节见 `docs/workflow.md`。向普通用户解释能力时看 `docs/edit_guide.md`。 ### 生成时的结构化要求 生成新 PPT 时,agent 应为每页写入简洁的 `slide_spec`,方便后续按标题、副标题、卡片、指标等元素精确修改。最低要求: - `layout`: 一句话描述版式 - `elements`: 语义化元素字典 - 常用元素 ID:`title`、`subtitle`、`card_1`、`card_2`、`metric_1`、`date_line`、`footer` - 元素字段优先写 `type`、`content` 或 `heading/body`、`position`、`style`、`color` 不要为了追求完整而写很长的 spec;能让后续定位和编辑即可。 ### 修改已有幻灯片 1. 用 `--list-sessions` 找到目标 session。 2. 读目标 session 的 `metadata.json`,定位页号和元素 ID。 3. 如果用户没给新内容,先问一句“当前是 X,要改成什么?” 4. 用 `--element-updates` 描述修改;需要更强约束时加 `--edit-instruction`,明确“其他内容、布局、配色不要动”。 5. 执行 `--edit` 后检查目标页图片,重建后的 PPTX 会同步更新。 常用命令: ```bash python3 scripts/generate_ppt.py \ --edit 3 \ --session 20240523_143052 \ --element-updates '{"subtitle": {"content": "医疗数据碎片化"}}' \ --edit-instruction "将副标题从'健康管理的两类割裂'改为'医疗数据碎片化'" python3 scripts/generate_ppt.py \ --edit 3 \ --session 20240523_143052 \ --edit-prompt "在参考图基础上,只修改标题下方副标题的文字,从'健康管理的两类割裂'改为'医疗数据碎片化',保持位置、字体、颜色、大小完全不变。" \ --element-updates '{"subtitle": {"content": "医疗数据碎片化"}}' ``` ### 外部 PPTX 摄取后修改 外部 PPTX 可先摄取为图片 session,再由多模态 agent 看图补齐每页的 `slide_spec`。没有补 spec 前,不要承诺“精确改某个对象”。 ```bash python3 scripts/generate_ppt.py --ingest-pptx path/to/deck.pptx python3 scripts/generate_ppt.py --ingest-pptx path/to/deck.pptx --session my_deck_2024 ``` ### 回滚和 session 列表 ```bash python3 scripts/generate_ppt.py \ --rollback 3 \ --to-version 1 \ --session 20240523_143052 python3 scripts/generate_ppt.py --list-sessions ``` ## 文件结构 ``` gpt-image2-ppt-skills/ |---- SKILL.md # 本文件(Claude Code skill 入口) |---- AGENTS.md # codex / aider / cursor 等 agent 的薄索引,指向本文件 |---- README.md # 项目说明 |---- scripts/ # 所有 Python 脚本 | |---- generate_ppt.py # 主入口(CLI) | |---- md_to_plan.py # slides_plan.md -> slides_plan.json 转换器(CLI) | |---- render_template.py # PPTX -> 每页 PNG 的辅助脚本(CLI + library) | |---- image_generator.py # gpt-image-2 wrapper(支持 reference image,openai backend) | |---- codex_backend.py # 可选:走 codex CLI 出图(--backend codex) | \---- template_analyzer.py # PPT 模板剖析器(vision + 缓存) |---- styles/ # 所有可用风格,每个 .md 对应一个 style id | |---- gradient-glass.md dark-aurora.md | |---- clean-tech-blue.md risograph.md | |---- vector-illustration.md japanese-wabi.md | |---- editorial-mono.md swiss-grid.md | |---- hand-sketch.md y2k-chrome.md |---- examples/ # 场景 recipes:常见 PPT 的 slides_plan.md 起步模板 | |---- product-launch/ investor-pitch/ | |---- weekly-report/ courseware/ | |---- thesis-defense/ book-sharing/ |---- docs/README.en.md # 英文 README |---- install_as_skill.sh # 一键安装到 agent skills 目录 |---- requirements.txt # requests + python-dotenv + python-pptx + jsonschema + pymupdf \---- .env.example ``` 调用时产生的运行时目录都在 `<cwd>` 下: ``` <your-project>/ |---- template_renders/<stem>/page-NN.png # PPTX 渲染(render_template.py) |---- template_cache/<sha256>.json # 外挂 vision 风格分析缓存(纯文本 agent 路径) |---- template_profile.json # 多模态 agent 可手写/生成的模板 profile(可选) \---- outputs/<timestamp>/ # 每次生成产物 ``` ## License Apache License 2.0.