Ray PPT Generator — PPT 内容引擎 + 可编辑 PPTX 生成
> 定位(v3.6 明确):本 skill 聚焦「内容生成」——把材料/主题变成高质量 PPT 内容与可编辑 PPTX 初稿,并同步产出演讲稿 MD。排版做到"够用"(生成即做好基础版式);需对已有 PPTX 深度美化/换肤/修复时,用 ray-ppt-refine(独立 skill,见文末分工)。
基于 python-pptx 库快速生成专业级可编辑 PPTX 文件。适用于培训课件、安全汇报、流程图解等场景。不依赖 ppt-implement skill,无预览弹窗干扰。
触发条件
当用户要求:
- 基于 PDF/Word/数据生成 PPT
- 制作培训课件 / 汇报 PPT / 流程图 PPT
- 批量生成多页 PPTX
- 输出为可编辑的 PowerPoint 文件
需求确认(动手前必做)
先判断输入模式(v3.5 新增):
| 用户输入 | 走哪个 |
|---|---|
| 给了资料(文档/PDF/报告/视频转写稿),要"总结并做 PPT" | 资料→PPT 模式:见 references/doc-to-ppt.md(理解资料→提炼素材→叙事转化→排版) |
| 给了已有 PPTX,要"扩充/加模块/改部分内容",且保持原格式风格 | 已有 deck 扩充模式:见 references/extend-deck.md(2026-08-27 新增:复用原版式新增页 + 保格式就地改文字 + XML 重排页序) |
| 只给了主题/标题 | 本文件常规模式(下方需求确认 + 内容缺口补充) |
扩充模式 vs 从头生成(决策要点):用户说"以这份 PPT 为底""保持原格式/风格一致""在这个课件基础上加"→ 扩充模式,不要从零重造——重造版式对不上原 deck(字体/色板/装饰细节很难完全复刻),工作量还大。扩充模式核心三件套:①新页复用原 deck 样式常量(先 dump 原 deck 的颜色/字体/版式坐标再动手);②原页改文字用 set_shape_text 保格式替换(坑见 extend-deck.md);③页序用 reorder_slides(重建 sldIdLst)统一收口。
收到主题后,先对齐以下信息(没有提供的用默认值),不要直接开做:
| 信息 | 说明 | 默认值 |
|---|---|---|
| 主题 | PPT 的核心内容 | 必填 |
| 行业 | 商务/教育/科技/医疗/金融/化工等 | 根据主题自动判断 |
| 页数 | 需要几页 | 10 页 |
| 风格 | 简约/商务/科技/学术/化工安全 | 简约商务 |
| 配色 | 6 套通用 PALETTES + 化工安全配色 | 商务深蓝 |
| 语言 | 中文/英文 | 跟用户一致 |
| 用途 | 汇报/培训/答辩/提案 | 汇报 |
风格推荐交互(v3.1 新增):用户不确定风格/配色时,不要盲目默认——按场景推荐 2-3 套候选让用户确认:
| 用户场景 | 推荐配色候选 |
|---|---|
| 商务汇报/年终总结 | 商务深蓝 / 炭灰极简 / 暖陶简约 |
| 技术分享/产品发布 | 科技深空 / 商务深蓝 |
| 培训课件/教学 | 暖陶简约 / 青绿信任 / 化工安全配色 |
| 化工安全/危化品 | 化工安全配色(SAFE_BLUE 系列) |
| 数据报告/ESG | 青绿信任 / 海洋渐变 |
> 判断口诀:"先推荐再确认,别让用户对着 6 套配色表发懵"。用户明确指定则尊重用户选择。
结构对齐:用"叙事弧"快速搭骨架(钩子 1 页 → 定调 1-2 页 → 主体 3-5 页 → 转折 1 页 → 收束 1-2 页),再按主题填页。
> 判断口诀:"先对齐需求再开做,结构定错后期翻修代价最高"。
内容缺口自动补充
如果用户输入内容较少或不完整,必须主动联网检索补充内容,不要用空洞文案硬填。
识别缺口:
- 用户只给了主题 → 检索该主题的市场数据/趋势/案例
- 用户只给了标题 → 补充正文要点和支撑数据
- 用户描述模糊 → 明确行业/场景/受众
检索执行:用 web_search / web_fetch 搜:
- "[主题] + 数据/报告/趋势/案例"
- 优先权威数据源(Gartner、IDC、艾瑞、行业白皮书)
- 优先最近 6 个月的时效性数据
填充原则:
- 每个要点至少补充 2-3 句详细说明
- 添加真实数据、案例、数字支撑(禁止编造数据,无来源数据必须标注"估算")
- 每页正文至少 80-150 字,不空洞
- 化工安全场景优先引用 GB 标准/事故案例数据
核心原则
1. 方案选型:绝不混用 ppt-implement
| 场景 | 方案 | 是否加载 ppt-implement |
|---|---|---|
| 快速生成可编辑 PPTX | python-pptx(本 skill) | 不加载 |
| 需要精美网页预览/动画 | ppt-implement 完整工作流 | 加载,走 5173 预览 |
绝对禁止混用:加载 ppt-implement skill 后使用 python-pptx 生成文件,会触发其 hooks 反复尝试启动 5173 预览服务器,导致黑窗口反复弹出。若已误加载,需手动禁用两个脚本中的 startServer / start_server 函数。
2. 页面尺寸:13.333" × 7.5"(16:9)
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] # 空白布局
3. 颜色常量:先定义再使用
SAFE_BLUE(0x005293) 主色 / ACCENT_ORANGE(0xE67E22) 强调 / DARK_TEXT(0x2C3E50) 正文 / 警示红绿常量。完整常量见 references/code-templates.md 第 0 节。
4. 字体:中文环境统一微软雅黑
def set_font(run, name='Microsoft YaHei', size=Pt(14), bold=False, color=DARK_TEXT):
run.font.name = name
run.font.size = size
run.font.bold = bold
run.font.color.rgb = color
字号参考:标题栏 32pt 粗 / 副标题 16-18pt / 条目标题 18-20pt 粗 / 条目描述 12-14pt / 流程框 11-12pt / 页脚 10pt
文字层次(v3.4 新增):不要只用一种正文色——用五级灰阶拉开层次(常量见 code-templates.md 第 0 节):TEXT_MAIN 正文 / TEXT_SUB 次要 / TEXT_MUTED 弱化(来源、标注)/ TEXT_FAINT 最弱(页标签、深底弱字)。数据/技术页正文可压到 10.5-11pt(配半号字微调),比默认 13pt 更有印刷感;标题仍保持大号对比。
5. 文字排版:自动换行防溢出(核心教训)
每个文本框必须启用 word_wrap = True——否则中文长文本会溢出截断。框尺寸预留 20% 以上余量;两栏布局每栏宽 6.0-6.2",间距 0.3-0.5"。
6. 统一标题栏 + 页脚
add_title_bar() / add_footer() 见 references/code-templates.md 第 0 节。页码框必须左移到 PRS_WIDTH - Inches(3.8) 避免溢出。
页标签(v3.4 新增):add_title_bar(tag=...) 可在标题栏右上角加灰色小字标本页定位/来源/时长(如"条文说明 5.1.4"/"调查报告认定的直接原因"),杂志眉线感,几乎零成本。
数据来源标注(v3.4 新增):数据/技术/学术页必须在底部加来源——add_source_note(slide, "数据来源:GB 51283—2020 条文说明")(9.5pt 弱灰)。这是课件的严谨性体现,引标准/报告/检测数据时不可省。
7. 多脚本拆分策略
单脚本生成 25+ 页容易因代码过长导致维护困难。拆分为 part1.py(生成前半) + part2.py(加载已有 PPTX 追加后半,见 code-templates.md 拆分配方)。
8. 临时文件 → 目标文件(避免权限冲突)
不要直接写入目标目录(可能 Permission denied)。先写入临时目录,再用 shutil.copy2 复制到最终位置。
9. Logo 添加(全页统一)
用 PIL 读尺寸算宽高比,右上角统一位置,遍历全部 slides 添加。代码见 references/code-templates.md。
10. 视觉设计规范
- 一页一主题:标题即观点,内容支撑标题
- 少字多图:超过 50 字的页面要警惕,用列表/框图代替大段文字
- 配色 dominance(v3.3 新增):主色占 60-70% 视觉权重,1-2 个辅助色 + 1 个强调色,绝不平均分配;主题相关配色,不要默认蓝
- 对比:高风险用红底,低风险用绿底,警示用橙/红
- 留白:文字框四周留 0.15" 以上内边距
- 3 秒法则(v3.3 新增):观众 3 秒内理解页面要点,否则内容太密
- AI 痕迹规避(v3.3 新增):标题下不加装饰线(AI 生成标志);全 deck 不重复同一版式;正文左对齐(只有标题居中);不整页纯文字——每页至少一个视觉元素
11. 版式函数调用契约(v3.9 新增,防双页)
> 本 skill 的页面函数(references/code-templates.md 的 add_cover_slide / add_content_slide / add_table_slide / add_vertical_chain_slide / add_stat_panel_slide / add_chart_slide / timeline_deadline_slide / card_matrix_slide / traffic_light_slide / heatmap_table_slide / metro_lines_slide / stair_levels_slide 等全部 2.x 函数)内部自带建页(函数体内调用 prs.slides.add_slide(layout))。
铁律:调用任何页面函数(add_*_slide(...) / *_slide(...))的页面函数内,不得再自己建页——否则产生双页(页面函数建一页 + 版式函数又建一页)。实战踩坑:65 页版多 6 页、90 页版多 13 页,同一错误犯 2 次。
⚠️ v3.20.0 修正:本原则原列举的 chain_slide / card_slide / stat_slide / table_slide / two_col_slide / checklist_slide / section_slide 这 7 个名字在 references/ 里从来没有定义过(历史遗留,全目录 grep def <名>( 零命中)——按名字复制会找不到函数。规则不变,名字以本行上方所列实际函数为准。
写法模板(版式函数页面):
def p46():
steps = [...] # 只写数据
s = add_vertical_chain_slide(prs, '标题', steps, colors, layout, tag='...') # 函数体内已建页
notes(s, '口播稿...')
写法模板(手写布局页面):
def p05():
s = prs.slides.add_slide(prs.slide_layouts[6]) # 自己建页(手写布局)
add_title_bar(s, '标题', '副标题', tag='...')
# ... 手写 rect/txt ...
add_footer(s, 5, total=10, reg_no='文件编号')
判断口诀:"本页用版式函数 → 页函数只写数据;本页手写 → 页函数自己建页。二选一,绝不混用。"
🔍 生成前自查(v3.20.0 由 grep 钩子改脚本,防复发):规则写入不等于自动遵守——v3.9 晋升后实战写新页(y01/y02/y05)依然犯了 3 次。写完全部页面函数、运行脚本前,先跑:
python scripts/qa_ppt.py --dblpage gen_*.py # 双页隐患静态扫描(不读 pptx)
python scripts/qa_ppt.py <生成的.pptx> # 生成后三项体检(见原则 12)
有命中 → 删掉该页函数里多余的自建页行,把页面函数调用改为 s = <页面函数>(...)。自查不过不运行。
> 为什么弃用原 grep 钩子:① Windows/DSH 环境没有 grep 命令,钩子不可执行;② 原正则只覆盖"自建页 + 调版式函数"这一种写法,另两种(只调版式函数 / 纯手写)不触发;③ 原钩子硬编码了 7 个不存在的函数名。
12. 布局行高自适应 + 越界检测(v3.9 新增,防溢出)
- 行高按条目数自适应:表格/事件链/条目页的行高步进要随行数/条目数压缩,防止最后一行溢出页面。已验证公式:竖向事件链
row_h = min(0.98, (5.45 - (n-1)*gap) / n);表格函数加row_h/font_size参数(12 行表用 0.42 行高 + 9.5pt,7 行表用 0.55)。 - 生成后必跑越界检测(QA 第一动作,不能只靠肉眼):用 python-pptx 重读文件,遍历所有 shape,检查
left+width > slide_width或top+height > slide_height(含文本/形状),越界即修。"看着没超"不算数——文本框 word_wrap 后文字可能溢出框体,必须用脚本检测。 - 装饰形状不越页:封面/结束页等装饰性 rect/oval 必须完全在页面边界内(0 ≤ x ≤ 13.333",0 ≤ y ≤ 7.5")——突出页边的"角部装饰"视觉上突兀(用户实测反馈"丑")。
页面类型速查(14 种函数,按需加载)
全部函数代码在 references/code-templates.md,生成时按需复制。选择页面类型的依据:
内容 → 版式映射表(v3.3 新增)
| 内容类型 | 用哪个函数 | 为什么 |
|---|---|---|
| 开头定调 / 总论点 | add_cover_slide |
全屏大字冲击力,不用小字列表 |
| 3-5 个要点 | add_content_slide(左条+右文) |
可扫读,视觉节奏 |
| 6+ 个要点 | 双栏 add_toc_slide 式网格或拆两页 |
避免单页拥挤 |
| 核心数字 / 成果 | add_big_number_page(大字 callout) |
数字是主角,不是正文 |
| 关键数值 / 阈值 / 检测结论(v3.4) | add_stat_callout / add_stat_panel_slide(数字徽章+说明配对) |
数值大字徽章当主角,说明做小字配角 |
| 流程 / 因果链 / 事故还原(v3.4) | add_vertical_chain_slide(竖向事件链) |
编号圆点+标题描述行+行间箭头,比横排能装更长描述 |
| 硬时限 / 里程碑(v3.16) | timeline_deadline_slide(时限时间轴,2.16) |
"立即/1小时/24小时"徽章+轴线+说明卡,制度宣贯首选 |
| 目录 / 职责 / 要点归纳(v3.16) | card_matrix_slide(卡片矩阵,2.17) |
左色条+数字圆点+描述,3+2 / 2×2 / 2×3 三种网格 |
| 行为规范 DO/DON'T(v3.16) | traffic_light_slide(红绿灯对比,2.18) |
左绿右红双卡+中央信号灯隐喻 |
| 梯度考核 / 风险分级表(v3.16) | heatmap_table_slide(热力图表格,2.19) |
整行梯度底色,"颜色越深越重"不言自明 |
| 分级上报 / 双路径审批(v3.16) | metro_lines_slide(双通道地铁图,2.20) |
每通道一条线+站点,表达"路径"概念 |
| 事故分级 / 响应级别(v3.16) | stair_levels_slide(阶梯分级,2.21,注意三坑) |
台阶逐级升高+绿→红梯度 |
| 时间序列 / 项目进程 | add_timeline_slide |
方向感直观 |
| 方案对比 A vs B | add_two_column_slide |
并排凸显差异 |
| 结构化数据 | add_table_slide |
表头底色+隔行变色 |
| 数据图表(趋势/对比/占比,v3.7) | add_chart_slide(原生可编辑图表) |
柱状/折线/饼图用真图表非图片,观众可在 PPT 里改数据 |
| 章节切换 | add_section_slide(大编号) |
节奏提示 |
| 金句 / 引用 | add_quote_slide |
留白强调 |
| 收尾 / 行动号召 | add_summary_slide / add_end_slide |
最后看到的要记住 |
| 团队介绍 | 2x2/3 网格卡片(用 add_content_slide 改造) | 人脸连接感 |
| 联系方式 | add_contact_slide |
居中列表 |
> 判断口诀:"先看内容类型再选版式,不让一页装下所有东西"。数据密集页:极简表头 + 一个主图 + 1-2 个数字 callout。
配色方案库(6 套通用 + 化工安全)
| 方案名 | 主色 | 辅色 | 强调色 | 适合场景 |
|---|---|---|---|---|
| 商务深蓝 | #1E2761 |
#CADCFC |
#FFFFFF |
商务汇报、年终总结 |
| 科技深空 | #0D1117 |
#58A6FF |
#FFFFFF |
技术分享、产品发布 |
| 海洋渐变 | #065A82 |
#1C7293 |
#FFFFFF |
医疗、环保、教育 |
| 青绿信任 | #028090 |
#00A896 |
#02C39A |
可持续发展、ESG |
| 暖陶简约 | #B85042 |
#E7E8D1 |
#A7BEAE |
文化、培训课件 |
| 炭灰极简 | #36454F |
#F2F2F2 |
#212121 |
极简风、设计汇报 |
PALETTES 字典代码(RGB 元组)见 references/code-templates.md 第 1 节。
配图策略(v3.8 新增)
> PPT 做好 = 文字内容 + 合适配图。配图决策是内容规划的一部分——在页面规划表阶段就为每页决定"要不要图、哪类图、从哪来"。本 skill 只做配图决策与编排,不自建生图能力(防漂移:生图能力复用现有 skill,见下)。
配图三类来源(先分类,再定来源)
| 类型 | 典型场景 | 来源 | 理由 |
|---|---|---|---|
| 信息类 | 流程图/事件链/防护分级/对比图 | 自己画(python-pptx 原生形状) | 与内容强耦合,网上找不到完全匹配的;原生形状风格统一且可编辑 |
| 氛围类 | 封面背景/章节页/意境图 | ①免版权图库(Unsplash/Pexels)②AI 生图 | 图库快但化工场景覆盖差(反应釜/HAZOP 会议等几乎无贴切图);AI 可控 |
| 证据类 | 事故现场/设备照片/合规文档截图 | 必须真实照片 | ⚠️ 红线:事故报告/合规文档禁止 AI 生成"现场图"——真实性是证据的生命 |
生图编排(调用外部 skill,不复制能力)
氛围类图需要 AI 生成时,按场景选执行层:
| 需求 | 调用 | 说明 |
|---|---|---|
| 通用 AI 生图 | ImageGen(工具) |
文生图/图生图,默认选项 |
| 独立计费生图 | ray-wuyin-image |
速创 API,ImageGen 不可用时的备选 |
| 手绘风示意图 | sketch-illustration |
流程图/功能说明/PPT 配图(Sketch 极简/水彩等 5 种风格) |
生图 prompt 规范:风格词(如"商务简约、扁平插画")+ 尺寸 16:9 + 无文字(AI 生成文字必乱码,文字一律后期用 python-pptx 加)+ 配色与所选 PALETTE 协调。
免版权工业图获取(v3.12 新增,实战验证 2026-08-17)
氛围类图库路线(无需注册的最快路径 + 可编程 API 方案):
| 路径 | 做法 | 适用 |
|---|---|---|
| Pexels 直链免注册(实战推荐) | WebSearch 搜 pexels photo 主题 → 拿 photo id → 直接 curl "https://images.pexels.com/photos/{id}/pexels-photo-{id}.jpeg?auto=compress&cs=tinysrgb&w=1200" |
一次性找 3-5 张图,最快,无注册无 key |
| Pexels API(可编程) | 注册 https://www.pexels.com/api/ 拿 key → curl -H "Authorization: KEY" "https://api.pexels.com/v1/search?query=industrial" |
批量/动态换关键词 |
| Unsplash API(可编程) | 注册 https://unsplash.com/developers 拿 Access Key(50 次/时)→ curl -G "https://api.unsplash.com/search/photos" -H "Authorization: Client-ID KEY" --data-urlencode "query=industrial factory" |
同上 |
灰度化(统一插图风格):PIL: Image.open(url).convert('L')('L'=灰度);背景用途再加压暗+染主色调(ImageEnhance.Brightness + Image.blend),保证文字可读。页脚标注图片来源(如"图片来源:Pexels,经灰度处理")——免版权可商用,标注是礼貌也是溯源。
⚠️ 网络注意:Wikimedia Commons 国内常不可达;Pexels CDN(images.pexels.com)与 baidu 可达;www.pexels.com 网页有 403 反爬(用 WebSearch 拿 photo id 绕开)。
插入规范(与 ray-ppt-refine 诊断库对齐)
- 等比缩放,不拉伸变形
- 避开页脚区与标题栏
- 图片不遮正文;半透明蒙版上压文字时保证对比度
- 记录图片来源(图库 URL / AI 生成标记),备查
判断口诀
"信息图自己画,氛围图找或生,证据图必真实;生图靠编排,能力不进 skill"。
演讲者备注(Speaker Notes)
python-pptx 原生支持每页备注(slide.notes_slide),生成时务必填写——演示者开「演讲者视图」即可看到逐字稿。函数 add_speaker_notes 见 references/code-templates.md。
逐字稿编写 3 规则:
| # | 规则 | 说明 |
|---|---|---|
| 1 | 不是讲稿,是提示信号 | 加粗核心词 + 过渡句独立成段,帮演讲者抓节奏,不逐字朗读 |
| 2 | 每页 150-300 字 | 对应 2-3 分钟/页;超过则说明内容太满需精简 |
| 3 | 用口语,不用书面语 | "因此"→"所以",听起来像在讲而不是在读 |
> 备注写在 notes 里,不写在页面上——页面只放面向观众的内容。
演讲稿 MD 产出(v3.6 新增)
生成 PPTX 时同步导出一份独立演讲稿 MD——与每页一一对应的口播稿,是演讲者手上的完整脚本(区别于写在 PPTX notes 里的提示信号)。
实现(v3.20.0 补,原仅有要求、没有做法)——单源导出,天然抗漂移:
不要"另写一遍"演讲稿——那是两处真相,改一处必漂移。正解=写完 PPTX 的 notes_slide 后,从 PPTX 回读生成 MD:
python scripts/export_speech.py <生成的.pptx> <演讲稿.md> --titles "封面,结论先行,措施一,措施二,..."
scripts/export_speech.py 逐页读 slide.notes_slide.notes_text_frame.text 成文;页标题用 --titles(或 --titles-file)传入——脚本不猜标题,标题散在 add_title_bar 的文本框里,猜错比留空更坏。改口播稿 = 改 PPTX 备注层 → 重跑导出,MD 永远与 deck 同步。
格式决策(md 权威源 + word 可选):
| 格式 | 角色 | 何时用 |
|---|---|---|
| MD(默认,权威源) | 长期演进的活文档 | 演讲稿跟着 PPT 改;md 轻量、可版本控制、易再加工 |
| Word(可选导出) | 打印 / 分享 / 给非技术人员 | 需要时用 pandoc 或 python-docx 一键转,不做权威源 |
MD 结构:每页一节——## 第 N 页:{标题} + 150-300 字口播稿(沿用上方"逐字稿 3 规则":口语、提示信号、每页 150-300 字)。
同步原则:演讲稿与 PPTX 同源产出、逐页对应,权威源在本 skill。ray-ppt-refine 只动排版、不动内容结构,不另造演讲稿;若 refine 改了页数/标题,由它提示失同步,回本 skill 重新导出。
Win32COM 后处理(需本机 PowerPoint)
当需要修改已生成的文件(批量改字体/颜色/间距)且要保留渐变、阴影等效果时使用。函数见 references/code-templates.md 第 3 节。
要点:
- COM 索引从 1 开始;True = -1;修改前必须备份(*_backup.pptx)
- .RGB 是 BGR 顺序——用 rgb_to_bgr() 转换
- 视觉 QA 利器(v3.3 新增):export_slides_to_images() 用 COM 把每页导出 PNG,再逐页看(见下方 QA)
生成后必做 QA
> 核心原则:"假设第一次渲染是错的,至少做一轮 fix-and-verify 再交付"。
> 代码证明"结构存在",不证明"版式舒服"——必须实际打开检查。
内容 QA
- [ ] 标题即观点,内容支撑标题(一页一主题)
- [ ] 数据准确、无错别字、无占位文字残留("XXX"、"待补充")
- [ ] 每页 ≥ 3-5 个要点,不空洞
叙事完整性
- [ ] 目标一致性:deck 回答了用户的核心问题,重点/结论/语气适合目标受众
- [ ] 逻辑承接:开场→论证/展开→结论/行动,页与页之间连贯过渡,不跳步
- [ ] 每页服务整体:没有重复、断层、空白页或明显不匹配的页面类型
- [ ] 交付完整性:最终文件存在且能打开,页数/格式正确,首尾页非空白
视觉 QA(转图片逐页看,v3.3 升级)
- 生成后必跑
python scripts/qa_ppt.py <文件.pptx>(QA 第一动作,不能只靠肉眼):一次跑三项——① 越界(shape 右下角 ≤ 页面边界,含文本/形状)② 正文区重叠(y∈[1.55,7.05]内文本两两相交 > 0.06 in² 即报)③ 文本溢出(按 CJK em 宽度估算行数 × 行高 vs 框高)。越界即修。 - [ ] 越界检测脚本 0 报错(python-pptx 重读,shape 右下角 ≤ 页面边界)
- [ ] 交叉引用自洽:文案里凡出现"见第 N 页"的,回读第 N 页确认内容确实在该页(实战:写了一处指向并不存在的页内容,脚本查不出)
- [ ] 无孤立标点 / 单字成行(widow):末行只剩一个标点或一两个字 = 文本框偏窄,收窄措辞或加宽框
- [ ] 装饰件不压正文:越界检测只查"出不出画布",查不出"压在文字上"——装饰 rect/oval 必须目检确认未遮盖文本
- [ ] 卡内标题不加装饰线:本 skill 只禁了"页标题下装饰线",卡片内小标题下的短色条同样是 AI 指纹,一并禁
- [ ] 文字无溢出(中文长文本最容易溢出——确认所有 text_frame 都 word_wrap)
- [ ] 无重叠(文本框/形状碰撞)、元素间距 ≥ 0.3"
- [ ] 边距足够(距幻灯片边缘 ≥ 0.5")
- [ ] 配色统一且非默认蓝;对比度足够(正文 ≥ 12pt,深底白字/浅底深字)
- [ ] 无标题下装饰线、无 lorem/占位残留
- [ ] 图片不越界、比例正常、不与页脚碰撞
- [ ] 页脚页码紧贴右下角(left≈12.25"、右边缘≈13.20"),封面/目录等无 title_bar 的页也统一
fix-and-verify 循环(必做一轮):
1. 生成 → 导出图片 → 逐页找问题(找不到问题时,再怀疑一次——假设一定有问题)
2. 列出全部问题 → 修复
3. 重新导出受影响页复验——一个修复常引入新问题
4. 直到完整检查一遍无新问题才交付
技术 QA
- [ ] 文件能正常打开(python-pptx 生成后至少验证一次)
- [ ] 页码连续、页脚正确
- [ ] 若用 Win32COM 后处理,确认备份文件存在
QA 通过标准:上述清单全绿才交付;任一红项 → 修 → 重验 → 再交付。
常见坑与排查
| 问题 | 原因 | 解决 |
|---|---|---|
| 文字溢出框外 | 未启用 word_wrap = True |
所有 text_frame 都要设置 |
| 中文显示为宋体 | 未设置 font.name = 'Microsoft YaHei' |
每个 run 都要设置字体 |
| 页数翻倍(22 页变 28 / 90 页变 103) | 页面函数先建页又调用自带建页的版式函数 | 见核心原则 11「版式函数调用契约」:二选一,绝不混用 |
| 布局越界(最后一行溢出页面) | 表格/事件链/条目页行高未按行数自适应 | 见核心原则 12:行高按条目数压缩 + 生成后必跑越界检测 |
| 装饰形状突出页面(封面角部图案) | rect/oval 坐标超出画布边界 | 装饰形状必须完全在 0-13.333"×0-7.5" 内(见核心原则 12) |
| 页码文字溢出 | 页码框太靠右 | 页码框收窄(宽 0.95")紧贴右下角,右边缘 13.20",距页边 0.13" |
| 流程框文字挤在一起 | 框高度不够 / 字号太大 | 框高 +0.2",描述字号降到 11-12pt |
| Permission denied | 直接写入被占用的文件 | 先写临时目录,再 shutil.copy2 |
| 黑窗口反复弹出 | 误加载了 ppt-implement skill | 不加载 ppt-implement,或禁用其 hooks |
| 多页后脚本过长 | 单文件维护困难 | 拆分为 part1 + part2(公共模块 + load_prs 追加) |
| 扩充已有 deck 时保格式改文字报 IndexError | 原 shape 段落数不足,set_shape_text(para=1) 越界 |
para=0 写标题 → clear_paragraphs(keep=1) → add_para() 追加(见 references/extend-deck.md) |
| 新页插不进指定位置 / move_slide 失败 | 逐页移动依赖 rId 反查,易错 | 新页全部追加尾部 → 顺序表拼最终页序 → reorder_slides 一次重排(见 references/extend-deck.md) |
| 标题下装饰线 / 默认蓝 | AI 生成通病 | 用留白/背景色替代;选主题相关配色 |
快速开始
完整代码模板(公共函数 + 12 种页面函数 + PALETTES + Win32COM)见 references/code-templates.md,复制即用。
快速启动提示词(给用户参考,v3.3 新增):
- 基础版:"生成一个关于[主题]的 PPT,包含[X]页"
- 详细版:主题 + 风格(商务简约/科技感/化工安全)+ 受众 + 页数 + 重点内容(2-3 条)
与 ray-ppt-refine 的分工(正交,可组合不耦合)
| ray-ppt-generator(本 skill) | ray-ppt-refine(独立 skill) | |
|---|---|---|
| 定位 | 内容引擎:从无到有 | 排版美化器:从有到好 |
| 输入 | 材料 / 主题关键词 | 任意已有 PPTX |
| 输出 | PPTX 初稿 + 演讲稿 MD | 美化调整后的 PPTX |
| 排版 | 够用排版(生成即做好基础版式) | 深度美化(验收 + 改造) |
边界:两者独立可用、互不依赖——generator 一步到位产出可交付 PPTX;refine 自包含,能美化任意来源的 PPTX(含非 generator 产出)。需深度美化时,在 generator 之后单独跑 refine。
演进方向:本 skill 聚焦"最强内容生成器"(资料提炼 / 叙事弧 / 演讲稿);refine 聚焦"最强版式美化器"(检测 / 换肤 / 修复)。经验由 ray-self-reflection 回流,高手由 ray-skill-evolve 学习。
实战经验
> 任务复盘经验由 ray-self-reflection 回流到此(一行一条,带 ID)。格式:- YYYY-MM-DD|[LRN-...]|场景:xxx|经验/教训:xxx|死路:xxx|来源:任务名|计数:N|状态:pending
> ⚠️ resolved 条目已归档至 references/experience-archive.md(规则入主流程后毕业删除,此处只留活跃条目)。
-
2026-08-16|[LRN-20260816-011]|场景:课时-页数配比|经验:3 小时培训课 ≈ 90-100 页(每页约 2 分钟),要素类内容按四步闭环但只精选 1-2 个要素做完整闭环示范,其余要素按同一逻辑简要带过——防止课件膨胀超课时|死路:20 要素全做闭环(4×20=80 页要素区,总页超 150 失控)|来源:RBPS培训PPT 页数迭代(用户两次要求 90 左右→90-100)|计数:1|状态:pending
-
2026-08-17|[LRN-20260817-012]|场景:配图轮反向经验(生成-美化分工)|经验:生成 deck 时内容页文字宽度预留侧栏插图位(chain_slide 类公共函数 text_w 参数化,默认让出右侧 ~3")——本次配图是事后收窄 text_w 11.33→7.93 影响 16 页;若生成即预留,refine 配图零改版式。生成与配图分离架构下,"生成时留位"比"配图时让位"成本低一个量级|死路:文字占满宽度后配图硬塞(遮内容,refine 扫描证实 93 页无安全放图区)|来源:RBPS 93页配图轮(用户两次纠错配图问题)|计数:1|状态:pending|深化:下次生成含事件链/流程/条目页的 deck,text_w 参数默认预留右侧插图位
-
2026-08-18|[LRN-20260818-001]|场景:条目列表全页重叠(用户报 P3/5/6/7 文字叠一起)|根因:
_bullets里y = y + item_h误放在 for 循环外(4 空格缩进)→ 所有条目都画在 y=1.5 同一点 → 全页文字堆叠;且此前"越界检测 0"是假象(文字塌顶所以不越界)。教训:①布局循环的纵坐标递增必须在循环体内(缩进 8 空格);②改缩进/循环类 bug 后,越界检测通过 ≠ 布局正确,必须再跑正文区重叠检测(框选 y∈[1.3,6.9] 排除标题栏/页脚,shape 矩形两两相交即报)|死路:只跑越界检测就交付(假通过,放走全页重叠)|来源:化工厂入厂安全培训 95 页|计数:1|状态:pending|深化:把「正文区重叠检测」脚本沉淀进本 skill 的 QA 必做清单 -
2026-08-18|[LRN-20260818-002]|场景:python-pptx 动态行高自适应|教训:item_h 已是 Emu int(
Inches()返回值),再Inches(item_h)会二次放大(1.32"→134 万 Emu,条目全出界)。①传 Emu 值就y + item_h裸加,勿再包 Inches;②item_h 用min(Inches(1.32), int(available/n))先转 int;③描述框高度用max(Inches(0.34), item_h - Inches(0.58))随行高自适应,保证长文字不压下一条|死路:固定 desc 高 0.62" 在 6 条目页必然越界/重叠|来源:化工厂入厂安全培训 95 页|计数:1|状态:pending -
2026-09-02|[LRN-20260902-002]|场景:摸底原 deck 颜色/填充|经验:python-pptx
sh.fill.type枚举访问在部分 shape 抛异常(fill.type 为 None 或不可枚举)——直接读 XMLspPr/a:solidFill/a:srgbClr最稳(sh._element.spPr.find(qn('a:solidFill'))),文字颜色同理走rPr/a:solidFill。摸底脚本里用 XML 读法一次拿全|死路:靠sh.fill.fore_color.rgb枚举(部分 shape 报错)|来源:EHS 课件插页摸底|计数:1|状态:pending -
2026-09-02|[LRN-20260902-003]|场景:VL 视觉 QA 链路退化(08-27 验证过的链路本次部分失效)|经验:DASHSCOPE qwen3.8-max 超时、opencode-go 403、Tesseract 未装 → ray-ppt-ocr-eyes 链路本次不可用。替代方案 = 几何排版验证:①卡片/文本边界关系检查(文本框是否在卡片内);②按 68 字符/行(4.64in 宽 12pt)分词估算换行行数 × 0.21in 行高 vs 框高——数学上证明无溢出,比目测可靠。QA 时 VL 不可用不必卡死,几何验证可独立交付;但注意原 deck 角部装饰圆(如 10.42,-1.39)是刻意出界的装饰语言,越界检测须排除装饰圆只查文本/卡片|死路:VL 不可用时放弃视觉 QA(交付无验证);把装饰圆当越界误报(反复排查浪费时间)|来源:EHS 课件 OSHA/SOP 插页 QA|计数:1|状态:pending|深化:VL 链路恢复后把几何验证与 VL 描述互补(几何查溢出,VL 查观感)(⚠️ 2026-09-12 补记:原生 Read 看图已普遍可用——VL 链路不再是唯一视觉通道;几何验证仍作互补,两者并用)
-
2026-09-04|[LRN-20260904-001]|场景:PPT 高手美化建议落地(事故制度 deck 21 页重做)|经验:①6 个版式手法实战验证有效并升格为模板(2.16-2.21:时限时间轴/卡片矩阵/红绿灯对比/热力图表格/双通道地铁图/阶梯分级)——判定标准是"转 PNG 逐页目检后用户/自评认可",时间轴页是全 deck 评价最高的一页;②图形隐喻纪律:环形流程无循环箭头=散点图(退回条带布局更诚实)、旋转椭圆拼五瓣花生硬——隐喻要么连同连接语言完整实现,要么放弃;③配色微调无感:#005293→#0D3B66 这类邻近色切换用户第一眼几乎无变化感,换配色要么拉开色相/明度差距,要么干脆保留原体系只补手法(refine 铁律 3 印证)|死路:把原页小字内容原样塞进新图形(信息密度不降,"换汤不换药",用户评"效果一般"的根因)——重排必须伴随每页一个主角的减法|来源:事故管理制度宣贯 PPT v2 美化轮|计数:1|状态:pending|深化:下次美化轮先做"每页主角"规划(这一页 3 秒内先看到什么),再做版式替换
-
2026-09-04|[LRN-20260904-002]|场景:对照拆解用户自做美化版(豆包 AI 生成 deck vs 我方 python-pptx 原版,21 页逐 shape 对比)|经验:用户版观感优势的三大隐性来源,均已升格为模板——①20pt 设计网格(73% 坐标落在 20pt 整数倍 vs 我方 4%;字号全整数档)→ 模板 2.22;②序列同色相明度递进(5 步流程 #0F4C81→#156096→#1E78B4→#E87722→#BE5014 冷→暖升温,vs 我方五色相乱跳)→ 模板 2.23;③文字覆盖层模式(形状承载底色+独立透明框放文字)→ 模板 2.24。识别外部 AI 生成 deck 的指纹:内嵌"XX AI 生成"角标图、Noto Sans SC 字体、全 AUTO_SHAPE 文字覆盖层结构、Tailwind Slate 灰阶(#334155/#94A3B8/#E2E8F0)|死路:只对比"字体换了/颜色换了"这类表层差异,漏掉网格系统这种"看不见但决定观感"的结构性差异——对比分析必须 dump 坐标做量化统计,不能靠肉眼描述|来源:事故制度 deck 用户美化版拆解|计数:1|状态:pending|深化:生成新 deck 时布局坐标统一走 gx(n) 网格函数,生成后统计网格命中率 ≥60% 自检
-
2026-09-04|[LRN-20260904-003]|场景:评估 iconfont 素材能否进 PPT 生成/美化链路|经验:图标素材可行性 = 格式 × 库能力匹配,不能凭"iconfont 很全"下结论。python-pptx 实测:PNG 可直接
add_picture✅;SVG 原生不支持(add_picture 抛 UnidentifiedImageError)❌;venv 无 cairosvg/svglib(SVG→PNG 需新增依赖);图标字体 python-pptx 无原生字形支持 ❌。可行路线:①单色简单语义图标(盾牌/警报)→ 下 PNG 做图标池 或 拆 SVG path 用 FREEFORM 重绘(保矢量可编辑);②多色复杂插画 → 仍走 ImageGen/图库。能力边界已入 code-templates 2.25|死路:默认"iconfont 资源能直接用"——SVG 是 iconfont 主力格式,python-pptx 插不进,直接套用会全线失败|来源:iconfont 可用性评估|计数:1|状态:pending -
2026-09-04|[LRN-20260904-004]|场景:把"简单语义图标池"从想法做成资产(40 图标端到端)|经验:开源 Lucide + resvg 路线验证通过,比 iconfont 更适合 python-pptx 链路——①源:lucide-static 走 jsdelivr CDN(免登录、ISC 可商用),必须带 Mozilla UA(urllib 裸 UA 会 404,curl 也要加);②渲染:venv 装
resvg-py(纯 Rust abi3 wheel,秒装),API 是svg_to_bytes(svg_string=, zoom=256/24)(不是 import resvg/调 render——模块只有 svg_to_bytes 一个导出);③Lucide 是 outline 风格stroke=currentColor单 path → 重染只需把currentColor替换成目标 hex;④图片资产一律外置D:/RayClaw/skill-archives/(SkillHub 发布拒收 .png——曾把 40 PNG 放 skill assets/ 内,发布必 400,已移出);skill 内只留 build 脚本 + 路径指针,add_icon 双路径加载(外置池优先、缺失提示重建)|死路:A. iconfont 自动化下载(需登录态/逆向接口,浏览器复用成本 >500MB 不值得);B.fetch(文件名带.svg)导致 CDN URL 变成 .svg.svg 404(fetch 应传纯图标名,模板内部补后缀);C. PNG 内置进 skill 目录(阻塞发布)|来源:iconfont 可用性评估的落地|计数:1|状态:pending|深化:若未来要面性(filled)图标,Lucide 有lucide-static/filled/子目录同源可用;图标不够时改 ICONS dict 重跑 build 脚本即可 -
2026-09-22|[LRN-20260922-001]|场景:新增
scripts/qa_ppt.py --dblpage(双页隐患静态扫描)后做负控——故意植入一个"自建页 + 调用自带建页的页面函数"的脚本,验证扫描器是否真能抓到|经验:扫描源码的脚本读文件必须用encoding="utf-8-sig"——PowerShell 的Set-Content -Encoding UTF8会写 BOM,而 BOM 会让re.match(r"def\s+")在行首失配 ⇒ 整个文件被静默跳过、报"0 命中"(假阴性,退出码 0,无任何告警)。首轮负控正是这么漏掉的;改utf-8-sig后 BOM / 无 BOM 两种编码均能抓到(各 1 命中,exit=1)。判据:「扫描器说没问题」必须先由一次"成功捕获"的负控背书——"没有命中"在做负控之前不能当通过证据|死路:只跑正控(对真实脚本报 0 命中)就认为扫描器可用——正控对假阴性零分辨力|来源:701 反应热评估专报 PPT 回流审计 G3|计数:1|状态:pending
> ✅ 已毕业(2026-08-16 用户确认):LRN-001(版式函数调用契约)→ 核心原则 11;LRN-003(布局自适应+越界检测)→ 核心原则 12;LRN-004(装饰不越页)→ 核心原则 12;LRN-005(页码贴右下角)→ 常见坑表。毕业条目从缓冲区删除,规则已入主流程。
维护记录
完整维护记录见 references/changelog.md(最新版本见 frontmatter version)。