# PPT 全流程 · 一键自包含编排提示词(单文件版) > **两种启动方式,效果完全一样**: > **① 一句话触发(推荐)**:`@本文件名 帮我完成这个文件的任务` —— 只要本文件在工作目录里,agent 读了它就会自动开跑; > **② 粘贴启动**:把下面 §0 那 4 条复制粘贴进对话框。 > **不需要任何其他文件**:准备提示词(1/2)、准备提示词-2(生图通道)、PPT 提示词库(一~十一节)的内容**已全部内联在本文件里**。 > **幂等**:已完成的步骤只验证不重做;缺什么补什么。**只打断你四次**(检查点 0/①/②/③),其余全自动。 > **迭代方式 2026-09-14 重写**:可以自己开浏览器看效果,但**常驻窗口 ≤ 2**(当前轮 + 上一轮, > 更早的关掉);**一轮 = 看全册 → 列全清单 → 一次改全 → 只验一次**,每轮必须有净变化(见 §0.6); > 只有**最终交付物**报绝对路径 + `present`,中间产物不打开、不登记。 > **转 PPTX 不再手写转换器**:跑插件自带的确定性管线 `scripts/deck/`(见 C7)——上一轮手写了 48 个一次性脚本、 > 跑了 1 小时 44 分,最后仍然没动画、翻页按钮被烤进幻灯片、文字错版。 > **开工第一件事是确认权限预设**(见 A0)——不确认的话后台每一步都会弹权限确认,而且**无头浏览器根本起不来**。 --- ## §-1 触发约定(**重要:先读这一节**) **只要用户说了下面任意一句,就视为已授权按本文件从头执行全流程,不要再等用户粘贴 §0:** - "帮我完成该文件的任务" / "按这个文件执行" / "跑这个提示词" / "照这个文件做" / "执行这个 md" - 或用户用 `@本文件名` 引用了本文件并说了类似的话 **触发后立即按这个顺序做——不要先复述一遍文件内容、不要先问"你确认要跑吗":** 1. 若**无法确定用户指的是哪个文件**(目录里有多个候选 .md)→ **只问一句**"你是指 `<本文件名>` 吗?",得到确认后继续;**不要猜、不要挑一个就开跑**; 2. 立刻进入 **§一 阶段 A**(准备环境:验证 + 补齐),做完出就绪报告; 3. 到 **§二 检查点 0** 时**必须先问**用户要不要 AI 生图 —— 说"不要"就**整段跳开阶段 B**,配图改走【七B】; 4. 之后按 **§三 阶段 C** 走完(一 → 十一),在**检查点 ①/②/③ 停下等用户选**; 5. 全程守 **§四 硬规则**;每阶段做完停下等确认再进下一阶段;最后按 §四 D5 交报告。 > 一句话总结:**§0 是给"粘内容"的用法准备的;用一句话触发时,本文件本身就是完整指令。** --- ## 0. 启动指令(复制这一整段;用 §-1 方式触发时可跳过) > 按本文件(`PPT全流程_一键编排提示词.md`)执行全流程,**自包含,不要去找别的文件**: > 1. 先做 §一 阶段 A(准备环境):先跑 **A1.5 新用组件自检**(缺什么自动装),再验证两个 skill 与工具链,出就绪报告; > 2. **动任何生图步骤之前先问我"要不要 AI 生图"**(检查点 0):要 → 做 §二 阶段 B;不要 → **整段跳开阶段 B,配图走 §三 C5 的「七B」**,不许碰 arkcli、不许注册火山方舟; > 3. 然后按 §三 阶段 C 顺序跑完 PPT 全流程(一 → 十一),其中**检查点 ①(要需求)/ ②(选风格)/ ③(转不转 PPTX)必须停下等我选**; > 4. 全程守 §四 的硬规则;每个阶段做完停下等我确认再进下一阶段;最后按 §四 D5 格式交报告。 --- ## §0.5 交付纪律(**2026-09-14 用户反馈后重写**) 上一轮的真实故障有四个,全部由本节负责防住:**一个下午开了几十个 HTML 标签页**、 **每改一次就多一个 HTML 文件**、**1 小时只做了 HTML**、**转出来的 PPT 文字错版**。 ### 0.5.1 唯一的权威文件(**禁止版本爆炸**) - 一份稿子**只有一个** HTML 文件:`build/<稿名>.html`。 - **原地修改**(`edit` 工具改同一路径)。**严禁**写出 `-v2` / `-终稿` / `-新版` / `-修复版` 这类平行副本;需要留底就拷到 `assets/_backup/<稿名>_<日期>_<原因>.html`,**备份不算交付物**。 - 每轮结束只打印**这一个**文件的路径。 ### 0.5.2 视觉复核窗口协议(**不是禁止看,而是规定"怎么看"**) **自己打开浏览器看自己的效果是对的,必须做** —— 改一处不看一眼才是真瞎。 上一轮错的不是"看",而是**没有节流**:每改一处就新开一个窗口,旧的不管,20 页 × 多轮堆成几十个标签页。 按下面四条走,既看得见,又不堵浏览器: 1. **一次尽量多看**:每轮复核**先做"整册视口"** —— 把**全部页面**渲染成**一张总览图** (contact sheet:一行 N 页)或**一个包含全部页面的复核页**,一眼扫完全篇, **一次性把问题列全**。禁止"看一页、改一页、再看一页"。 2. **只保留两扇窗**:复核用**同一个专属窗口**(独立 profile,**不碰用户日常浏览器**)。 - 第 N 轮用它;进入第 N+1 轮时**复用同一扇窗**(导航到新的复核页/总览图), 并**把第 N-1 轮及更早的窗口与标签全部关掉**; - **常驻窗口/标签 ≤ 2**(当前 + 上一轮,供前后对比)。**严禁累积**。 3. **复核页是生成物**:总览图/复核页由管线或脚本**生成一个**,不要一页一个文件散着开。 4. **用户不喊关就不关**:复核窗口留着给下一轮复用;用户说不用了再关。 > 一句话:**看全册、留两窗、旧的关掉、别堆。** **渲染/验收(截图这一步)仍然走插件自带的 `scripts/deck/`**:它拉的是**无头**实例 (`--headless=new` + 临时 profile + 自动选端口),不开窗、不抢标签页、跑完自己退出 —— **截图用无头,肉眼复核用那扇专属窗口**,两者不要混。 ### 0.5.3 只把"最终交付物"登记成卡片 | 类别 | 例子 | `present` | 报绝对路径 | |---|---|---|---| | **最终交付物** | 终稿 HTML、导出的 PPTX | ✅ 要 | ✅ 要 | | 中间产物 | 文字稿、风格预览、总览图、复核页、渲染图层、`build/render/` 里的任何东西 | ❌ 不要 | 只在报告里写一行目录 | **最终交付时**做满三件套:① 报**真实工具输出**的绝对路径;② 调 `present` 登记成能点开的卡片; ③ 说明打开方式(HTML → 双击或点卡片;PPTX → PowerPoint / WPS)。 **中间产物不 `present`、不逐个报路径。** > **例外(2026-09-15 用户反馈)**:只要你在回复里**点名提到了某个图** > (渲染参考图、图层、常驻动效 GIF、总览图…),就**必须同时把它 `present` 成可点击卡片** —— > 说了"生成了 5 张图"却不给能点开的位置,用户只能自己去翻目录。 > 换句话说:**没提到就安静放着;提到了就必须可点击。** ### 0.5.4 落盘位置 - 演示稿:`build/<稿名>.html`(唯一权威文件);导出物:`build/<稿名>.pptx` - 渲染中间件:`build/render/`(管线自动生成,**不要手改**) - 素材:`assets/`;回退快照:`assets/_backup/` - **不要**把风格演示散成 `build/directions/方向N-xxx.html` 让用户自己找(见 C2【三】)。 --- ## §0.6 批量迭代协议(**一次看全 · 一次改全 · 每轮必须净变化**) > **上一轮的真实教训**:516 次工具调用里,`build-deck` 跑了 **26** 次、`verify-deck` 跑了 **24** 次、 > `pptx-capture` 跑了 **19** 次,而其中很多轮**其实什么都没改**(或只改一处就全量重跑一遍)。 > **检查本身不是成果,改完才叫成果。** **一轮 = 一个批次**,严格四步: | 步骤 | 做什么 | 硬约束 | |---|---|---| | **① 看全** | 渲染**全部页面** → **一张总览图/一个复核页**;逐页扫,**一次列出全部问题** | 禁止"看一页改一页" | | **② 列清单** | 输出**缺陷清单**:`页码 | 现象 | 期望 | 优先级(P0/P1/P2)`,**一次列尽** | 清单里没有的,本轮不改 | | **③ 一次改完** | **一个批次**内把所有 P0/P1 一次改掉(同一个权威文件**原地改**) | 禁止"改一处 → 重跑 → 再改一处" | | **④ 只验一次** | 重渲染(**只重渲染改动过的页**,靠哈希缓存)→ 对照清单**逐条销项** | 一轮只跑**一次**全量验收 | **每轮结束必须给出净变化**:① 改了哪几页的哪几件事;② 清单销掉几项、新增几项。 **若某一轮没能销掉任何一项(净变化为零)→ 立刻停止本轮,不要再继续检查**, 报告"本轮无净变化 + 剩余清单",把决定权交回用户。 ### 0.6.1 修改到什么程度算完(**边界必须事先写死,否则会无限打磨**) 在检查点①之后就把这四条写给用户,之后按它收工: 1. **清单清空**:缺陷清单里的 **P0/P1 全部销项**(P2 允许留下,但必须在报告里逐条列明)。 2. **连续一轮零新增**:一次**全册**复核**没有发现新问题**。 3. **验收通过**:C7 的三道闸门(结构 / PowerPoint 真机 / 逐页像素)全过。 4. **轮次上限**:HTML 阶段**最多 3 轮**"复核→修改"循环;到顶仍未清空 → **停下报告**, 把剩余项交给用户决定继续还是收工。**不要自己无限打磨。** > 一句话:**"看全 → 列全 → 一次改全 → 只验一次",到位就停。** ### 0.6.2 禁止无意义的确认与复检 - **输入没变的检查不许重跑**:同一份文件、同一份配置,已经 PASS 过的检查不要再来一遍; 渲染管线有**按页哈希缓存**,直接说"p7 未变,复用"即可。 - **不要为了"确认一下"打断用户**:只有 §四 D1 的四个检查点允许停下。 - **不要写平行脚本**:动手前先看 `_diag/`、`build/render/`、插件 `scripts/` 里有没有现成的; 同一件事不要写"改进版""2""b""c"(上一轮 `_diag/` 里堆了 **48** 个,其中 12 个叫 `debug-*`)。 - **脚本只判机器可判的**(页数 / 溢出 / 计数 / 报错);画面好坏用 `read_image` **自己看**, 不要用脚本编个数字糊弄,也不要为一个口径写错的指标追几轮。 --- ## 1. 总流程图 ``` 阶段 A 准备环境(幂等:验证 → 补齐,不用问) 产出:就绪报告 ↓ 检查点 0 ★ 问:要不要 AI 生图? ├─ 要 → 阶段 B:arkcli + Seedream 通道(幂等验证/补齐;登录闸门① 已 0 手动,只剩 ②③) └─ 不要→ 跳过阶段 B,配图走「七B」 ↓ 阶段 C PPT 全流程 【一】文案(插槽 1–12 + A–G) ← 检查点 ① 先向用户要需求 【二】5 个美术视觉风格方向 【三】每个方向一张「首页风格演示」HTML ← 检查点 ② 让用户选方向 【四】完整初稿(必须预留图表/3D 容器) 【五】creative-director 智能匹配 【六】按需素材收集 【七】AI 生图 或 【七B】程序化图形/SVG(二选一,按检查点 0) 【八】ECharts 图表 /【九】Three.js 动效 /【十】转场动画 【十一】转 PPTX ← 检查点 ③ 问要不要转;跑 scripts/deck/ 三步管线(不手写转换器) ↓ 交付:文件 + 参数对照表 + 验收方法 + 已知限制 + 回退方式 ``` --- --- # 一、阶段 A|准备环境(自动执行,不用问用户) ## A0. 权限预设(**开工第一件事|不先做这一步,后面几乎必然卡死**) **先判断当前会话的沙箱/审批设置**,必须是「**完全访问**」(能写工作区以外的路径)。为什么: | 后续动作 | 会写到工作区外 | 权限不足的后果 | |---|---|---| | 装 skill(A2) | `~/.agents/skills`、`~/.dsh`、npm 缓存 | 每装一次弹一次审批 | | npm 装 9 个包(A3) | 用户级 npm 缓存目录 | 同上 | | **走过【七】AI 生图** | **`%USERPROFILE%\.arkcli*` 暂存目录** | **arkcli 每调用一次弹一次**(这就是上轮"一直让我确认权限"的真因) | | **渲染 / 转 PPTX(C7)** | 无头浏览器要建临时 profile、要用命名管道 IPC | **受限沙箱会直接秒杀浏览器进程**(实测:启动即退出 `0x80000003`,`DevToolsActivePort` 永不生成)。这不是"要不要批准"的问题,是**根本跑不了** —— 不想切「完全访问」就只能走【七B】且**不做** C7 的自动验收 | **处理顺序(只做一次,不要反复问):** 1. 一句话告诉用户:**请用 `/permission` 把权限预设切到「完全访问」**,并说明原因(否则后台每步都会弹确认)。 2. 用户切好 → 继续 A1。 3. 用户**不切** → **不要硬跑**: - 直接建议 **检查点 0 选 B**,并说明"B(程序化图形/SVG)全程**零工作区外写入、零弹窗**"; - 用户仍坚持要 A → 把需要放宽的审批点**一次列全**(不是几十个小命令逐个触发审批),再继续。 **防卡死硬规则(与 D3-11 同一条):** 同一条命令被拒或失败 **不得原样重试**;同一操作最多重试 1 次; 连续 2 次被拒、或同一错误出现 ≥3 次 → **立刻停下**,贴原始报错 + 说明"需要你放宽权限/需要你本人操作",等用户答复。 **严禁**为了绕开审批而把工作区外写入偷偷改到别处,也**严禁**循环重试同一条命令。 ## A1. 能力自检(逐项给证据,不要只说"已确认") ① 命令执行 ② 文件读写 ③ 联网抓取 ④ Node / npm / npx ⑤ 模型可正常对话(不贴 key)。 缺 ① 或 ②(纯聊天环境)→ **不执行**,直接输出 §四 D6 的人工清单让用户照抄。 **Node 预检**:`node -v`、`npm -v`、`npx --version`。缺 Node **不要硬跑 npx**,报告并给安装指引后停下等用户。 **Windows 命令行预检(重要,先做)**:先试 `npm.cmd -v`、`npx.cmd -v`。 若裸 `npm`/`npx` **没有任何输出**或报 `running scripts is disabled` → PowerShell 拦了 `.ps1` 垫片, **后续一律用 `.cmd` 后缀**并在报告里注明。**静默无输出 = 失败,不是成功。** **联网方式预检**:分别实测 Node `fetch` / `Invoke-WebRequest` / `curl.exe`。 实测结论:Windows 上后两者**经常整体不可用**(`curl` 可能返回 `http=000`), **一切下载动作都用 Node `fetch` 脚本**,不要依赖它们。 ### A1.5 本次流程新用组件:自检 + 自动安装(**第一步就跑,一条命令|2026-09-13 新增**) "0 手动登录"依赖下面 4 个组件。**开工先整体体检一遍,缺什么自动装什么**——不要等用到某一步才发现缺、再回头打断用户。 ```powershell # <插件目录> = 已安装的 dsh-ppt-maker 目录,**按顺序取第一份存在的**(不要问用户、也不要让用户去找): # ① %USERPROFILE%\.dsh\local-plugins\dsh-ppt-maker ← link: 安装 # ② %USERPROFILE%\.dsh\profiles\web\node_modules\dsh-ppt-maker ← dsh plugin add / pnpm 安装 # 两份都不存在 → 安装不完整:停下报告,不要自己下载脚本凑 powershell -NoProfile -ExecutionPolicy Bypass -File "<插件目录>\scripts\check-env.ps1" # 只体检、不安装:末尾加 -NoInstall ``` | 组件 | 为什么需要 | 检查方式 | 缺失时自动做什么 | |---|---|---|---| | **Node ≥ 22** | `scripts/cdp/*.mjs` 用的是 Node **自带的全局 `WebSocket`**(Node 21+ 才有,故要求 22;这样零第三方依赖) | `node -v` | 报告 + 给安装指引(**不许静默降级到装 `ws`**) | | **`arkcli`** | 火山方舟通道(生图/模型/用量) | `%APPDATA%\npm\arkcli.cmd --version` | `npm i -g @volcengine/ark-cli@latest` | | **`dsh-chrome-cdp` 插件** | 让 agent 拥有原生 `chrome_*` 浏览器工具。**注意:0 手动登录并不依赖它**——`scripts/cdp/*.mjs` 自己直连 CDP | 读 `~\.dsh\profiles\web\package.json` 的 `dsh.profile.bundles` 是否含 `dsh-chrome-cdp` | `dsh plugin --profile web add github:xiaobai2017666/dsh-chrome-cdp`(**装完要重启宿主**才会出现工具) | | **专属自动化浏览器(CDP)** | 自动点【授权】/【开通】等页面操作;独立 profile,**不碰用户日常浏览器** | 探 `http://127.0.0.1:9222/json/version` | **按需**拉起:只有"确实需要登录"时才由脚本启动;**已登录则一个窗口都不弹**。受限沙箱会秒杀 GUI 进程 → 需「完全访问」预设(见 A0) | **判定**:脚本最后打印 `[DONE] environment ready` = 全绿,直接继续; 打印 `[DONE] unresolved: ...` = **把该行原文贴给用户**并停下等答复,不要自己硬猜。 **唯一可能落到真人身上的一步**(脚本会明确标 `[HUMAN]`): 专属浏览器**从未登录过火山**时,需要用户在那个窗口里用**手机验证码或扫码**登录**一次**。 之后所有登录/续期都是 0 手动(实测单次约 40 秒)。**除这一步外,不许请用户手工操作。** --- ## A2. 装两个 skill(幂等:先验证,缺才补) **判定"已安装"的唯一标准**:`SKILL.md` 存在且非空(>200 字节,内容以 `---` 和 `name:` 开头)。 **目录存在但没有 SKILL.md = 失败残留**,必须先整目录删掉再重装。 | skill | 目标路径 | 校验基准 | |---|---|---| | `creative-director` | `~/.agents/skills/creative-director/SKILL.md` | 约 **2857** 字节 | | `emilkowalski-motion` | `~/.agents/skills/emilkowalski-motion/SKILL.md` | 约 **2573** 字节 | > 落盘可能多出 UTF-8 BOM(实测 **+8 字节**),属正常。 **先判断本地有没有 skill 目录**:列 `~/.agents/skills`(及宿主自带 skill 目录)。 **目录不存在或为空 → 跳过"先读 SKILL.md",直接进安装流程**(全新环境的正常情况,不是错误,不要因此停下或反复自检)。 只有**已存在同类 skill** 时,才先读它的 `SKILL.md` 再决定装/不装。 **安装顺序固定 A → B → C,A 超时立刻转 B,不要反复重试 A**: - **A 官方 CLI**:`npx.cmd --yes skills add nexu-io/open-design@ --yes --global`(给 120 秒,超时/留空目录 → 转 B) ⚠️ 该命令会**先 clone 整个 `nexu-io/open-design` 仓库(约 2.2GB / 165 个 skill)**,慢且易超时 —— 超时是常态。 - **B 直链下载(推荐,最快最稳)**——直接跑这段(含镜像回退): ```powershell node -e "const fs=require('fs'),p=require('path');(async()=>{for(const s of ['creative-director','emilkowalski-motion']){const d=p.join(process.env.USERPROFILE,'.agents','skills',s);fs.mkdirSync(d,{recursive:true});const us=[['https://cdn.jsdelivr.net/gh/nexu-io/open-design@main/skills/'+s+'/SKILL.md',{}],['https://api.github.com/repos/nexu-io/open-design/contents/skills/'+s+'/SKILL.md?ref=main',{'user-agent':'skills-fetch','accept':'application/vnd.github.raw'}]];let ok=false;for(const [u,h] of us){try{const r=await fetch(u,{headers:h});if(!r.ok){console.log(' http',r.status,u.split('/')[2]);continue;}const t=await r.text();if(t.length<200||!t.includes('name:')){console.log(' bad body',t.length);continue;}fs.writeFileSync(p.join(d,'SKILL.md'),t);console.log('OK',s,r.status,t.length+' bytes <-',u.split('/')[2]);ok=true;break;}catch(e){console.log(' miss',u.split('/')[2],e.cause?e.cause.code:e.message);}}if(!ok)console.log('FAILED',s,'- all mirrors unreachable');}})()" ``` > **为什么必须带第二条回退**:jsdelivr 对部分文件返回 `301` 跳到 `raw.githubusercontent.com`, > 而该域名在部分网络下**根本解析不了**(`getaddrinfo ENOENT`)。第二条走 `api.github.com` + > `accept: application/vnd.github.raw` 直接拿正文,实测稳定。 - **C GitHub API 兜底**:`GET https://api.github.com/repos/nexu-io/open-design/contents/skills/`,按 `download_url` 逐个下。 **每个 skill 装完立刻验证**:文件存在、字节数合理(见基准)、能打印前 20 行。 > `find-skills` 由宿主内置,**不需要安装**。以后缺别的 skill:用 `npx skills find <关键词>` 拿到 > `owner/repo@skill` 形式的包名,再按 A→B→C 装(**不要凭名字硬猜包名**)。 ## A3. 工具链与目录(幂等;检查逻辑已按实测修正) **不要只在项目根 `require.resolve`** —— 包可能装在子目录(本机实测:`_ppt-build\node_modules` 里有 5 个, 而 `echarts / three / gsap / lottie-web` 四个是缺的)。**根 + 已有 `node_modules` 子目录一起查,只补真正缺的**: ```powershell # ① 找有哪些 node_modules Get-ChildItem . -Directory -Recurse -Depth 2 -Filter node_modules | ForEach-Object { $_.FullName } # ② 逐个包在这些目录里查 $pkgs = 'pptxgenjs','jszip','pngjs','gifenc','fast-xml-parser','echarts','three','gsap','lottie-web' foreach($d in @('.','_ppt-build')){ Push-Location $d -ErrorAction SilentlyContinue $chk = node -e "const m=process.argv.slice(1);let bad=[];m.forEach(x=>{try{require.resolve(x)}catch(e){bad.push(x)}});console.log(bad.join(',')||'ALL_OK')" $pkgs "[$d] 缺失: $chk"; Pop-Location } # ③ 只把缺的装上(装到项目根,保证后续从根运行都能解析) npm.cmd i pptxgenjs jszip pngjs gifenc fast-xml-parser echarts three gsap lottie-web # ④ 复检 node -e "const m=['pptxgenjs','jszip','pngjs','gifenc','fast-xml-parser','echarts','three','gsap','lottie-web'];let bad=[];m.forEach(x=>{try{require.resolve(x)}catch(e){bad.push(x)}});console.log(bad.length?('缺失: '+bad.join(',')):'全部 9 个可解析 ok')" ``` - **必须是这 9 个包**:后 4 个是八/九/十节要用的,漏了会跑到一半卡住 - 子目录里已有同名包**不算完成**(后续脚本从项目根跑解析不到)→ 缺的补到根上 - 浏览器侧若另有独立文件(根目录已有 `echarts.min.js` / `three.min.js`),HTML 稿可直接 `