인터페이스는 현지화되어 있으며, Skill 소개와 설명 문서는 선택한 언어로 AI가 자동 번역합니다. 코드·명령어·경로·전문 용어는 원문을 유지하며 원작자 문서가 우선합니다.
Skills 둘러보기
문서 및 사무 · SKILL.md

ppt-generate

ppt-generate

从一句话/大纲/文档生成原生可编辑的 PPT(.pptx)。项目制逐页生成:先定大纲与专属 design system,再每页独立构思版式/内容/衔接,渲染为 python-pptx 原生矢量元素——文本、形状、图表、表格、公式全部可在 PowerPoint/WPS 里二次编辑。当用户说「做PPT」「生成幻灯片」「写个汇报PPT」「把这份文档做成演示文稿」「pptx」「slides」「presentation」「课件」时触发。

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill 문서

GitHub

name: ppt-generate description: "从一句话/大纲/文档生成原生可编辑的 PPT(.pptx)。项目制逐页生成:先定大纲与专属 design system,再每页独立构思版式/内容/衔接,渲染为 python-pptx 原生矢量元素——文本、形状、图表、表格、公式全部可在 PowerPoint/WPS 里二次编辑。当用户说「做PPT」「生成幻灯片」「写个汇报PPT」「把这份文档做成演示文稿」「pptx」「slides」「presentation」「课件」时触发。" trigger: "PPT|ppt|pptx|幻灯片|演示文稿|slides|presentation|deck|做PPT|生成PPT|汇报PPT|课件|keynote" version: 2.1.0 display_name: PPT 生成器 platforms: [macos, linux, windows] metadata: openclaw: requires: bins: - python3

PPT 生成器(项目制逐页生成 · PPTist schema · python-pptx 渲染)

把自然语言需求变成原生可编辑的 pptx:不是图片拼贴,每个文本框、形状、图表、表格、公式都是 PPT 原生元素,用户打开就能改。

好 deck 不是一次写出来的,是逐页设计出来的:先定全局(大纲 + 专属 design system),再每页单独构思版式、内容、和前后页的衔接,最后逐页复审返修。本技能的工作流就按这个节奏组织。

工作流(严格按顺序)

需求 → ①大纲(含衔接设计) → ②design system → ③建项目目录 → ④逐页生成
     → ⑤gen_image.py 填图 → ⑥--check 校验 → ⑦渲染 → ⑧逐页复审/单页返修
     → ⑨deliver_file 可视化交付(强制,缺此步即视为任务失败)

⑨ 不是可选的收尾动作,是本技能的终止条件:没有调用 deliver_file,这次 PPT 生成就没有完成。

Step 1:规划大纲(含衔接设计)

  • 先输出大纲给用户(除非用户说直接生成):每页定 slideType(cover/contents/transition/content/end)和核心内容。
  • 叙事按金字塔原理:全 deck 一个核心结论(写进封面副标题),每章一个分结论,每页一个 action title(完整观点句,带数字或机制名,不是名词短语)。动机页用 SCQA(情境-冲突-问题-答案)。
  • 整体↔细节结构:机制/架构类主题必须有「总览页」——全景图 + 编号圆圈 ①②③④;后续细节页带同编号锚点,细节讲完放「回扣页」闭环(总-分-总)。
  • 衔接设计(逐页生成质量的源头):大纲里每页除了 action title、2-4 个支撑要点(含具体数字/机制)、页面角色(总览/细节①/对比/结论)、锚点编号,还要写一条衔接备注:
    • 承上:本页回收/回答上页留下的什么钩子;
    • 启下:本页给后面哪页埋什么钩子(如「先记住这个公式,第 9 页我们亲手算一遍」)。 前后页的显式引用(页码、章节名)会让 deck 读起来是一个整体而不是一摞单页。
  • 只给主题、没给素材时:大纲内容来自模型自身知识;若主题涉及最新资讯/实时数据/具体数字(如「2026 年行业趋势」「某公司最新财报」),先用 web_search 检索再写大纲,并在交付时说明哪些内容来自检索。
  • 页数:默认 6-10 页;用户没说要目录/过渡页就不加。

Step 2:定制本 deck 的 design system

不要直接从预设主题里挑一个了事——每个值得认真做的 deck 都该有一套为它定制的视觉语言:

  1. 读 references/fonts.md:按 deck 气质(学术/商务/科技/营销)和交付平台选定中西文字体配对(中文 ea 字体 + 西文 latin 字体分离设置)。
  2. 给这套设计语言起个名字、定一组规则,在大纲确认时一并告知用户,例如「地图策略:纸白底 + 深海军蓝主色 + 灰调皇家蓝强调 + 朱红警示 + 路线/坐标装饰语法」。规则至少包括:
    • 主色 / 强调色(≤1 个)/ 语义色(如「Encoder 蓝、Decoder 粉」全 deck 一致)——主色往灰调一档更雅致(如灰调皇家蓝 #4A5FA8,不用高饱和纯钴蓝);
    • 装饰语法:编号圆圈、章节导航点、分隔线、卡片形态(圆角?描边?投影?)——全 deck 统一;
    • 字体配对与字号阶梯(标题/正文/注释)。
  3. 落成内联 theme 对象写进项目 deck.json(结构见 schema.md 的 SlideTheme,typography 按 textType 给默认值)。预设主题(business-blue / dark-tech / fresh-green / vibrant-orange)只作为快速兜底或定制起点,可在其基础上改色改字体。

⚠️ 质量红线(强制):

  1. 必须有主题色:禁止纯白背景 + 黑色文字的"默认"样式。每页必须有背景色/渐变 + 主题色点缀。
  2. 必须从预设主题起步:至少从 business-blue / dark-tech / fresh-green / vibrant-orange 中选一个作为定制起点,禁止完全自创配色(除非用户明确指定)。
  3. 禁止空页面:每页必须有标题 + 正文内容,不允许只有标题无内容的空白页。
  4. 标题必须是 action title:完整句子,表达结论或观点,不能是"概述""背景"等名词短语。

Step 3:建项目目录

<输出目录>/<项目名>/
  deck.json        # version / canvas / theme(Step 2 的内联主题),不含 slides
  pages/           # 每页一个 JSON,Step 4 逐页写入
  • 默认输出目录钉在 ~/.ethan/output/(即 $HOME/.ethan/output/<项目名>/),除非用户明确指定别的位置。这一步不能用 cwd 相对路径:ethan 可能从 home 外的目录启动,相对路径建的目录渲染虽成功,但 Step 9 的 deliver_file 会因「路径必须在用户主目录或 /tmp 下」而报错,整份 deck 得挪目录重渲一遍。钉到 ~/.ethan/output/ 从源头避免这轮返工。
  • 项目名用人类可读命名(如 Transformer详解课件/),最终项目目录形如 ~/.ethan/output/Transformer详解课件/。
  • deck.json 骨架:{"version": 1, "canvas": {"width": 1000, "height": 562.5}, "theme": {...内联主题...}}。
  • ≤5 页的小 deck 可以走旧的单文件模式(一个含 slides 的 deck.json),但逐页生成 + 复审的效果更好,默认用项目制。

Step 4:逐页生成(本工作流的核心)

一次只写一页:pages/NN_slug.json(NN 两位序号保证排序,如 01_cover.json、05_attention_intro.json),文件内容是单个 Slide 对象({"id","type","background"?,"remark"?,"elements":[...]})。

每写一页之前,显式过四遍再落笔(可以在回复里用一两句话说明设计意图):

  1. 版式:本页从 layout-guide 版式库选哪个骨架?为什么适合这段内容?(三卡片 / 左右论点-证据 / 图表页 / 公式页 / 流程图页…)
  2. 内容:action title 是不是观点句?2-4 个区块形态是否错开?每条 bullet 有没有数字/机制/对比?密度够不够(构件清单见 layout-guide)?
  3. 高度预算:多行文本按 layout-guide「宽度与行数估算」核一遍——中文字 ≈1 个字号宽(270px 卡片 @14px 每行只装 17 字)、行高 ≈1.36×字号、表格总高 ≈ Σ行 max(cellMinHeight, 行数×13×1.36+8) 且 top+总高 ≤ 540。中文宽约西文 1.8 倍,字符数直觉不可信,必须按容器宽度换算。
  4. 衔接:kicker 与章节导航点对不对?总览锚点编号是否全局一致?本页是否兑现了大纲里的承上/启下钩子(该引用的页码要写进文案)?
  • Schema 全文见 references/schema.md(元素字段、形状名表、主题结构),写之前必读。
  • 排版必读 references/layout-guide.md:咨询式页面骨架、版式库、信息密度标准、衔接与设计语言规则。
  • 画布固定 1000×562.5;文本用结构化 runs,不写 HTML;形状只用预设名,不写 SVG path。
  • 公式页用 latex 元素(默认 OMML 引擎:真根号/真分式,PowerPoint/WPS 可再编辑;Keynote 交付时加 "engine": "runs"),不要画成图片。
  • 图片先用占位符:
    • 照片/配图 → "src": "gen:modern office skyline"(英文搜索词效果更好)
    • 图标 → "src": "icon:mdi:rocket-launch"(Iconify 集合:名称,如 mdi/fa/carbon)
    • 用户提供的图 → 直接写本地路径
  • 演讲者备注写进该页 JSON 的 remark 字段。

Markdown 输入约定(用户给 md 大纲时)

用户可能直接给一份详细的每页规划 md。按以下映射转成逐页 JSON:

# PPT 主题:大模型时代的搜索架构
主题:dark-tech          ← 可选,映射 theme(此时可不做 Step 2 定制)
页数:8                  ← 可选

## 第1页 [封面]
标题:大模型时代的搜索架构
副标题:从倒排索引到向量召回

## 第2页 [目录]
- 检索范式的三次迁移:关键词→语义→生成式
- 向量召回的工程落地:HNSW 与 IVFFlat

## 第3页 [正文] 检索范式对比
版式:三卡片            ← 可选,映射 layout-guide 版式
- 卡片1 icon:mdi:magnify 关键词检索:倒排+BM25,精确强、语义弱
- 卡片2 icon:mdi:vector-point 向量检索:Embedding+ANN,语义强
- 卡片3 icon:mdi:brain 生成式:RAG,成本高

## 第4页 [正文] IVFFlat 原理
公式:\mathrm{Recall@K} = \frac{|S_K \cap S_K^*|}{K}   ← 映射 latex 元素
要点:
- nlist 取 √N 量级
- nprobe 是召回/延迟旋钮
表格:                      ← 映射 table 元素
| nprobe | Recall@10 | P99 |
| 8 | 0.86 | 6ms |
| 64 | 0.97 | 21ms |

## 第5页 [正文] 上线效果
图表:柱状图               ← 映射 chart 元素,数据必须给出
| 月份 | nDCG@10 | 召回率 |
| 1月 | 0.61 | 0.72 |
配图:gen:server room data center   ← 映射 gen: 占位符
备注:强调延迟只涨 8ms        ← 映射 slide.remark

## 第6页 [结尾]
谢谢观看

映射规则:[封面/目录/过渡/正文/结尾]→slideType;公式:→latex;表格:后的 md 表格→table;图表:+数据表→chart;gen:/icon:→图片占位;备注:→remark。用户没写页类型时按内容推断(第 1 页默认封面、最后默认结尾)。md 里没给的细节(精确坐标、字号)按 layout-guide 补齐。

忠实原则:md 里写明的页数、页序、文案、公式、表格/图表数据必须原样进入页面 JSON,不增页、不减页、不改写观点、不编造 md 里没有的数据。可自由发挥的只有视觉层:版式选择、坐标、字号微调、装饰元素、配图选词。md 内容明显有误或遗漏时先问用户,不要擅自扩写。

Step 5:填充图片

python3 ~/.ethan/skills/ppt-generate/scripts/gen_image.py /path/to/<项目目录>
  • 传项目目录即可:自动合并 pages/*.json,解析后逐页原地回写,图片存到项目内 assets/。
  • 瀑布流:Pexels(需 PEXELS_API_KEY)→ Unsplash(需 UNSPLASH_ACCESS_KEY)→ AI 生图(需 ETHAN_IMAGE_GEN_API_KEY)→ 纯色占位图(保底,永不失败)。
  • Iconify 图标无需任何 key。
  • 没有配任何 key 时:改用 ethan 内置 image_search 工具搜图并 download=true,把返回的本地路径直接写进对应页 JSON 的 src,跳过 gen_image.py。
  • --dry-run 可先列出待解析项。

Step 6:校验

python3 ~/.ethan/skills/ppt-generate/scripts/render_pptx.py /path/to/<项目目录> --check
  • 有 error 必须修到 0 个再渲染;warning 尽量修。报错信息里的 slides[i] 对应 pages/ 下排序后的第 i 个文件,回到那一页改。
  • 文字溢出检测(overflow.*)分级:
    • overflow.fixable(warn):渲染时会自动缩字兜底(不小于原字号 80% 且 ≥12px),但建议按报错里的「建议高度/删减字数」改文案——自动缩字会让该页字号与别页不一致。
    • overflow.unfixable / overflow.nofit(error):缩字也救不了,必须删字或加高,error 清零前不许渲染。
    • overflow.table-canvas(error):表格末行会被画布裁掉——删行/降 cellMinHeight/表格上移。
    • overflow.table-grow(warn):表格行会被内容撑高、可能压住下方元素,核对下方留白。
  • 加 --json 可拿到结构化 issues(severity/code/message)供程序化消费。

Step 7:渲染

python3 ~/.ethan/skills/ppt-generate/scripts/render_pptx.py /path/to/<项目目录>
# 默认输出 <项目目录>/<项目名>.pptx;也可 -o 指定;--theme 可临时覆盖主题
  • 首次运行会自动 pip install python-pptx latex2mathml mathml2omml(纯 Python 依赖);用到 icon: 图标时还会自动装 pymupdf(SVG→PNG 光栅化)。

Step 8:逐页复审,单页返修

渲染完不要直接交付。逐页过一遍复审清单,有问题的页只改那一个 page 文件再重新渲染(这就是项目制的意义):

  1. 每页 action title 都是观点句?有没有名词短语漏网?
  2. 密度:每页 2-4 个区块、形态错开?有没有纯文字堆砌页或空洞页(<60 字)?
  3. 衔接:锚点编号全 deck 一致?承上/启下钩子都兑现了?章节导航点逐页正确?
  4. 视觉纪律:无越界/贴边、语义色一致、装饰语法统一?主色是否灰调雅致、大面积填充是否「深色字+浅色底」(白字深底只留给小徽章)?
  5. 数据页有结论栏和来源行?公式符号逐一解释了?
  6. 溢出复查:--check 的 overflow 警告是否都已处理?转图后目检文字有没有触底/压框、表格末行有没有被裁(这三类是最影响观感的缺陷,Step 6 已给过建议值)。
  7. 公式纪律:grep 一遍页面 JSON 里的 _k、√d_、\sqrt 字面量——展示公式都走 latex 元素、行内变量都用 sub/sup run,没有裸文本伪公式?形状内嵌文本(圆圈/步骤条/按钮)都写了 text.align: "middle"?
  • 若本机装了 LibreOffice(soffice),可 soffice --headless --convert-to pdf <pptx> 再 pdftoppm -png 逐页转图,用文件读取工具看图做视觉自检,溢出/重叠/字体替换问题一目了然;没有这些工具就按清单文字审查。
  • 返修只动 pages/ 下的单页文件,改完重跑 Step 7 即可(页少时秒级)。

Step 9:可视化交付(强制 · 违反即失败)

🚫 绝不允许把文件路径当纯文本吐给用户。 像「pptx 路径:/root/.ethan/output/xxx.pptx」这样直接在正文里写一行路径,用户根本点不动、看不了预览——这是失败交付。文件必须以「文件卡片」形态交付。

渲染成功后、报告最终结果前,必须先调用 deliver_file 工具,传入 pptx 的绝对路径:

deliver_file(path="/absolute/path/to/<项目目录>/<项目名>.pptx")

它会在聊天里生成可点击的文件卡片(icon + 文件名 + 页数),用户点击卡片进入逐页预览页,可在线翻页预览并选择下载 PPTX 或 PDF。

正确顺序:

  1. 先调 deliver_file(path="<pptx 绝对路径>") —— 生成文件卡片(这一步不可省)。调用时机是 pptx 已完整落盘之后(Step 7 渲染成功、Step 8 复审通过);若 Step 8 返修后重新渲染,用最终那次渲染的 pptx 再调一次,确保卡片指向最终版本。
  2. 卡片发出后,再用文字补充说明:页数、design system 名称与要点、哪些图是占位图(若有)、项目目录位置(pages/ 下单页 JSON 可改后重新渲染)、所有元素都能在 PPT 里直接二次编辑。
  3. 文字说明里不要再重复粘贴那条绝对路径——路径已经在卡片里,重复只会把 AI 味写回来。

失败必须处理,不能静默跳过:若 deliver_file 返回 Deliver failed: ...,说明路径不合法(必须在用户主目录或 /tmp 下,见 Step 3 的默认落点)、文件不存在或扩展名不支持。此时修正问题后重试——例如把项目输出目录挪到用户主目录下再重新渲染。重试仍失败时,明确告知用户「文件已生成但卡片交付失败」并附上原因和路径,不要假装交付成功。

自检:回复发出前问自己「我调 deliver_file 了吗?」没调就是没交付完,回去补。

预设主题(快速兜底 / 定制起点)

主题风格适用
business-blue(默认)白底商务蓝汇报/总结/通用
dark-tech深色科技AI/技术分享/发布会
fresh-green清新绿教育/环保/健康
vibrant-orange活力橙营销/活动/路演

正式 deck 应在预设基础上走 Step 2 定制(内联 theme 对象覆盖,结构见 schema.md 的 SlideTheme)。

关键约束(违反必然翻车)

  1. 渲染完必须 deliver_file:Step 9 是本技能的终止条件。渲染出 pptx 却只在文字里报路径、没生成文件卡片,视为任务失败——用户在聊天里拿不到可点击的预览/下载入口。工具报错要修正重试,不能静默跳过。
  2. 元素可编辑是底线:禁止把整页渲染成一张大图;禁止 SVG path 形状(用预设形状名);禁止 HTML 文本(用 runs)。
  3. gen:/icon: 占位符必须先跑 gen_image.py,否则渲染器直接报错退出。
  4. 中西文字体:主题 fontName(中文)+ latinFontName(西文)分离设置;配对选择读 references/fonts.md。run 级显式 fontName 会同时覆盖中西文。
    • 渲染机不需要装字体:渲染器只把字体名写入 pptx,字体解析发生在打开文件的机器上。
    • 查看端是 Linux(WPS/LibreOffice)时:雅黑/Verdana 通常都没有,会被替换成默认字体。预先知道的话把主题改成 Linux 常见自带字体:中文 Noto Sans CJK SC / WenQuanYi Micro Hei,西文 DejaVu Sans。
  5. 坐标纪律:元素不越界(右 ≤940、下 ≤540)、不贴边、页边距 60/40;字数按容器宽度核(左栏 430px 一行 ≤29 个中文字,全栏 880px ≤61 字;西文字符按 0.6 个中文字折算),速查表见 layout-guide。
  6. 图表用原生 chart 元素(数据可编辑),不要用 image_search 找图表截图。
  7. 演讲者备注写进该页 JSON 的 remark 字段,不要塞进页面元素。
  8. 项目目录整体交付与保留:deck.json + pages/ + assets/ 别删(用户可能改单页后重新渲染);pptx 默认输出在项目目录内。
  9. 输出目录要落在可交付范围内:deliver_file 只接受用户主目录或 /tmp 下的绝对路径,项目目录别建在别处,否则渲染完无法交付。

参考文档(按需 skill_read 加载)

  • references/schema.md — deck/页 JSON 完整字段定义(写页前必读)
  • references/layout-guide.md — 页面骨架、版式库、信息密度、衔接与设计语言规则
  • references/fonts.md — 中西文字体配对与平台适配(Step 2 必读)
  • examples/demo.json — 覆盖全部元素类型的示例 deck(单文件模式,可当元素写法参考)

故障排查

症状原因处理
deliver_file 报 path must be under the user home directory or /tmp项目目录建在了主目录//tmp 之外把项目目录移到主目录下(如 ~/Downloads/)重新渲染再交付
deliver_file 报 file not foundpptx 还没落盘或路径拼错确认 Step 7 渲染成功、用渲染输出的实际绝对路径
用户说「没看到文件 / 收不到」漏了 Step 9,只在文字里报了路径补调 deliver_file 传 pptx 绝对路径
渲染报「图片占位符未解析」跳过了 Step 5跑 gen_image.py 或把 src 改成本地路径
渲染报「项目目录缺少 deck.json」deck 参数传了目录但没有元信息文件在项目目录补 deck.json(version/canvas/theme)
渲染报「页文件应为单个 Slide 对象」pages/*.json 里写成了数组或包裹层每页文件直接是 {"id","type","elements":[...]}
pip 自动安装失败无网络/权限pip3 install --user python-pptx latex2mathml mathml2omml 后重试
中文变方框/宋体用户机器无该字体换主题 fontName(Windows: 微软雅黑,macOS: PingFang SC),详见 fonts.md
Linux/WPS 打开字体被替换、版式跑偏Linux 无雅黑/Verdana主题改 fontName: Noto Sans CJK SC(或 WenQuanYi Micro Hei)+ latinFontName: DejaVu Sans 后重新渲染
公式变成一行源码文本latex 依赖缺失或语法错看 stderr 的 [warn],检查 LaTeX 语法(latex2mathml 子集)
Pexels 搜不到中文词API 对中文支持差gen: 后用英文搜索词
저장한 Skills