web-video-presentation 的 outline.md 格式规范:把口播稿拆解为可开发的视频章节规划

原创2026-10-03 11:27:271,820 阅读
文章标签:AI 技能AI 插件

web-video-presentation 的 outline.md 格式规范:把口播稿拆解为可开发的视频章节规划

导读

outline.md 是 web-video-presentation 技能中"把一篇文章或口播稿做成可录屏的网页视频"这一流水线的第二份关键产出物——它是介于口播稿与章节代码之间的开发计划:只规划节奏、内容与信息密度,把口播稿按节拍切成章节与 step,并为每个章节抽出可供画面取用的"信息池"。读完本文,你将掌握 outline.md 的完整字段格式、命名约定、章节切分经验法则、素材清单写法与强制自检流程,并理解它与 script.md、narrations.ts、chapters.ts 之间的真相源关系。

outline.md 在整个工作流中的定位

在 SKILL.md 定义的 Phase 1 内容编写阶段,agent 会"一次产出"两份文件:

产出物 角色 决定什么
script.md 平台化口播稿(必有) 决定节拍:按 --- 切节拍,每节拍 1~2 step、估时
outline.md 视频章节开发计划(必有) 决定章节切分 + 每步屏幕内容 + 章节级信息池
article.md 用户原文(如有则保留不删) 决定画面信息密度:每章首段抽信息池

这被称为双源原则:节奏跟口播稿走,画面细节回原文章抽。outline.md 就是把这两条信息流合并成一份可执行规划的地方——它必须被写成人类友好的 Markdown(而不是 JSON / YAML),因为用户可以直接编辑它,在 Checkpoint Plan 环节要对齐"稿子 / outline / 主题 / 素材 / 开发模式"五件事。

在正式写 outline 之前,文档要求先完整阅读 CHAPTER-CRAFT.md(章节开发指引),了解对网页效果的真实需求;写之前还必须以双源原则为准——CHAPTER-CRAFT.md 原则 10 明确了"script 定节拍、article 定画面密度"。

outline 是开发计划,不是视觉规划

这是全文最重要的一条边界,原文用醒目的警示框强调:

outline 只规划节奏 + 内容 + 信息密度:

  • 章节切分 / 每章 step 数 / 每步估时
  • 每步屏幕内容(hero / 标语 / 数据 / 列表项)
  • 章节级信息池(从 article 抽的数字 / 引用 / 案例 / 标签)

outline 里的 step 数是初始预估,最终 step 数以章节实现时的 narrations.ts 为准——后者既是 step 数源,也是音频合成源(详见 CHAPTER-CRAFT.md 与 AUDIO.md)。如果实现时章节 step 数和 outline 不一致,回过来同步 outline 即可,不需要纠结"对得严丝合缝"。

outline 必须写 vs 不要写

outline 必须写 outline 不要写
章节切分 / 每章 step 数 / 估时 具体动画类型(blur clear / wipe / 弹簧)
每步屏幕内容(hero / 数据 / 标语 / 列表项) CSS 实现手段(filter / SVG / clip-path)
章节级信息池:从 article 抽的数字 / 引用 / 案例 / 标签 时长数值(不写 ~2.5s / 80~120ms)
步级关系名前缀("反差对照" / "递进列表" / "金句" 等可选 hint) 持续微动 / 错峰量等微观节奏

不写动画的理由:写死动画 = chapter agent 退化为翻译机;留白让 chapter agent 在每步开工时按 CHAPTER-CRAFT.md 的"内容驱动决策树"自由设计,才有真正的视频感。

完整格式骨架(抽象示例)

outline.md 的顶层结构固定如下,这份骨架必须原样继承:

# Video Outline

> **主题**:`<theme-id>`(Checkpoint Plan 已选定)—— <一句话风格描述>
> **总时长**:约 <T> 分 <S> 秒(口播 ~<X> 字 ÷ 4 字/秒)
> **章节数**:<N> 章 / <M> 步

---

## 1. <chapter-id> — <章节标题>(<S> steps · ~<T>s)

**信息池**(chapter agent 按需挂角标 / 副标 / pull-quote / mono cue):
- <类型:数字 / 引用 / 出处 / 案例 / 词义 / 时间 / 对比 / ...>:<内容> —— <来源 article §X / Lxx>
- ...

**开发计划**:

- step 1 (~Ts) — <屏幕内容>
- ...

口播节选:
> <1~3 句节选,对应到 script.md 完整文本>

---

## 2. <chapter-id> — ...

注意一个细节:关于时长,outline 里只写 step 的 (~Ts) 口播估时(供音画对齐),绝对不写动画时长 / 错峰量 / keyframe 数值——这些都在章节开发阶段决定(见 CHAPTER-CRAFT.md Part 3 时长参考)。

字段约定详解

顶部 metadata block

用引用块(>)形式,方便扫一眼整体规模:

字段 必填 说明
主题 ✓ Checkpoint Plan 必须已选定。chapter agent 实现时按主题颜色 / 字体 token 走,动画 / 节奏 / 视觉演示由章节自由发挥
总时长 ✓ 估算口播时长(中文 ~ 250 字 / 分钟)
章节数 ✓ N 章 / M 步

主题的选定发生在 Checkpoint Plan:agent 先读所有 themes/*/theme.json 的 nameZh / descriptionZh / bestFor / mood,再按 script.md 的内容类型主动推荐 2~3 套。当前仓库内置了 bauhaus-bold、midnight-press、terminal-green、chalk-garden 等 20+ 套主题(见 themes 目录与 THEMES.md)。

章节标题:## N. <id> — <title>(<S> steps · ~<T>s)

部分 规则
N 1-indexed 顺序,对齐 chapters.ts 的注册顺序
<id> 小写 + 连字符。会成为 React key / 文件夹名 (src/chapters/0N-<id>/) / 音频子目录 (public/audio/<id>/)
<title> 给人看的中文标题。不会进 React 代码
<S> steps 该章 step 总数
~<T>s 该章口播总估时(中文 ~ 4 字/秒)

合法 id 示例:coldopen、hook、why-good、why-good-text-render。 不合法 id:why_good(必须用连字符)、Hook(必须小写)、第一章(必须是拉丁字符)。

id 之所以如此严格,是因为它直接决定磁盘上的多个物理位置:章节文件夹名、React key、音频子目录名,以及音频文件名。这一约束可以从脚手架的 scaffold.sh 中看到——它把章节骨架放在 src/chapters/01-example/,并在注册表 chapters.ts 中以 id: "example" 注册。

章节首段「信息池」(双源原则核心落地)

每章独立列出从 article.md 抽的细节集合,让 chapter agent 实现每步画面时按需取用——可能挂成右下角 mono 角标 / 副标小字 / pull-quote 引用 / 数据浮层。

信息池条目格式

- <类型>:<具体内容> —— <来源 article §X / Lxx 或简注>

没有 article(用户直接给 script)时:信息池退化为"主动设计画面信息密度"——靠数字 / 对比 / 元数据等让画面比口播信息密,可以列"画面装饰元素池"而非"article 抽取池"。

case-tech-review 案例展示了信息池的实战形态:在 outline-snippet.md 中,每个 step 都标注了 article 补:……,例如 step 2 口播只说"换榜首",画面却把"领先多少 / 多少票投出来的"全挂上——画面信息密度必须大于口播信息密度,这正是双源原则的落地。

Step 列表:每步 1 行

- step N (~Ts) — <屏幕内容>
规则 原因
step N 1-indexed agent 实现时 if (step === N - 1) ...(注意零基偏移)
(~Ts) 必填 按 script.md 本步对应口播段字数 ÷ 4 估算(中文 ~ 4 字/秒)。范围 3~10s
屏幕内容 一句话讲清楚这一步舞台上有什么:hero / 标语 / 数据 / 装饰元素。≤ 1 行,再多就该拆 step
不写动画 写死 = 翻译机化
不写时长数值 / 错峰量 这些在章节开发阶段决定
不写实现手段 filter / SVG / Canvas 选型留给 chapter agent

关于零基偏移,可以从 useStepper.ts 中确认:全局 step 计数器以 cursor.step 从 0 开始,章节代码用 if (step === N) 判断当前屏——所以 outline 里写 step 1,代码里实际是 step === 0。这也解释了为什么 self-check 要求"所有 step (~Ts) 累加 ≈ 顶部声明的总时长":每步估时来自口播字数,是后续音频合成与 Auto 模式推进的时间基准。

口播节选(每章末尾,可选但推荐)

精炼 1~3 句,不是完整稿子,仅供章节规划阶段对照"这章在讲什么"。完整文本回 script.md。outline.md 章节 = script.md 中两个明显主题切换之间的段落。

音频合成(AUDIO.md)会回到 script.md 切分完整文本,不用 outline 节选。

命名规则速查

对象 规则 示例
章节 id 小写 + 连字符 coldopen, why-good
章节文件夹 0N-<id> src/chapters/01-coldopen/
章节组件 PascalCase Coldopen.tsx, WhyGood.tsx
章节 CSS 类前缀 章节缩写(避免跨章冲突) .cd- / .wg- / .mg-
音频子目录 <id>/ public/audio/coldopen/
音频文件 <step-N>.mp3 (1-indexed) public/audio/coldopen/1.mp3

音频命名约定的实现证据在 extract-narrations.ts 中:它按 chapters.ts 的注册顺序读取 id,动态 import 各章的 narrations.ts,产出 { chapter, step, text, audio: "<chapter>/<step>.mp3" } 的扁平段列表——JSON 里的 step 为 1-indexed,与音频文件名完全对齐。

章节切分的经验法则

  • 每章 3~8 步。少于 3 步太薄;多于 8 步观众会忘记这章在讲啥
  • 总时长 ÷ 30 秒 ≈ 章节数(一章约 30~60 秒讲完)
  • 每章 = 一个聚焦主题。"为什么强 + 怎么用" 是两章,不是一章
  • 章节边界 = 口播稿里讲者会换语气 / 换主题的位置。读 script.md 时哪里你下意识想"咳一声接下一段",那里就是章节边界
  • 慢节奏 / 长镜头风主题(midnight-press / 电影感片头)每章可少到 2~3 step;信息密集型(科技测评 / 对比表)每章可放宽到 8~10 step

case-tech-review 案例给出过具体参照:一篇 AI 工具实测对比文章被切成 7 章 36 步、约 6 分 30 秒,结构为"钩子 → 优点 → 场景 → 进阶 → 收束",每章 4~6 step 防疲劳(见 README.md)。

另外还有两种常见章节 anchor 可以参考(注意它们是结构示意,不是抄袭模板,详见 EXAMPLES/README.md):

例子 适用场景 结构要点
hook-chapter 钩子型开场:抛 N 张可疑图 → 引出主题 → hero takeover 每张图独占视觉(~70% 屏),最后缩入侧栏 + 大字 takeover
list-reveal 列举型:口播说"N 件事",每项 1 step 单网格 N 槽位,每 step 只填一个槽位,位置不重排

其中 list-reveal 对应的 outline 章节长这样:

## 4. <chapter-id> — <主题 N 件事>(N+1 steps)

- **step 1** (~3s) — masthead 引子"<N 件事>"
- **step 2** (~6s) — 第 1 件:<标题> + <article 抽来的细节>
- **step 3** (~6s) — 第 2 件:<标题>
- ...
- **step N+1** (~6s) — 第 N 件:<标题>

它背后的原则是"布局不重排,只是单元格内容变化":整个章节只有一个网格布局,N 个槽位的位置完全不变,变的只是每个槽位的内容状态(ghost / active / past)。反模式是每点一次重新渲染整个布局——已揭示的项也跟着抖动 / 重新入场,观众不知道该看哪。

素材清单(outline.md 末尾)

## 素材清单

### 1. coldopen
- ✓ <资源 1 描述> (<已就位路径>)
- ⚠️ <资源 2 描述>(待提供)
- ⚠️ <资源 3 描述>(待提供)

素材清单是 Checkpoint Plan 中对齐"真素材怎么准备"的直接依据:粗看本视频要的图,然后由用户决定"从现有素材路径帮挑 / 自己提供 / 全部 placeholder"。注意缺素材时用 placeholder 占位卡(一张写着"image · 16:9 描述"的卡片,按真实比例留位),不要用 emoji 凑、不要找无关图凑、不要编数字——"没有就承认没有,比 fake 强一百倍"(见 CHAPTER-CRAFT.md「避免 AI 味」一节)。

自检(写完 outline 强制执行,不可跳过)

⚠️ 硬性流程:outline 写完后必须走自检 → 修改 → 提交 三步。禁止写完直接进入 Checkpoint Plan 让用户对齐。

执行方式(按能力降级):

  1. 优先 Agent Teams:开一个独立 reviewer agent,传入 outline.md + 本节自检清单 + script.md / article.md 路径,让它逐项核查 + 出结论(哪几条 fail + 证据)。
  2. 其次 subAgent:当前 agent 没 Teams 但能开 subagent,用 subagent 走同样流程。
  3. 都没有:自己严格逐项核查。

拿到结论后先按 fail 项改 outline,再进入 Checkpoint Plan。这与 SKILL.md 的「硬性自检协议」一致:script.md 按 SCRIPT-STYLE.md 三层自检、outline.md 按本文件自检、单章实现按 CHAPTER-CRAFT.md 完工自检,每个产出"完成后必须走自检 → 修复 → 再汇报 / 推进",直接拿原始结论汇报但不修复 = 违规。

outline 的逐项自检清单:

  • [ ] 每个 step 都是单一句屏幕内容描述,没有"动画"行 / "手段"行
  • [ ] 没有任何 step 写了具体毫秒 / 秒数(除 (~Ts) 口播估时)
  • [ ] 每章首段都有「信息池」block,至少 3 条 article 抽取项,每条必带来源标注(—— 来源 article §X / Lxx)——没标注 chapter agent 回不到原文
  • [ ] 所有 step (~Ts) 累加 ≈ 顶部声明的总时长(误差 < 10%)——不一致说明节奏规划失真
  • [ ] 章节切分符合"每章 3~8 步 / 30~60s 一聚焦主题"经验
  • [ ] 末尾「素材清单」分章节列出,✓ / ⚠️ 标注清楚
  • [ ] 脚本不得包含标题、序号等非口播内容,仅包含人类正常可读的内容

写完后最后看一眼:outline 是不是干净到 chapter agent 看了能立刻开工 + 还有设计空间?是 = 合格。如果你看了都觉得"太空,agent 不知道动画选什么"——那说明边界守住了:动画本就该由 chapter agent 按 CHAPTER-CRAFT.md Part 1 开工五问在实现阶段决定。

源码级佐证:outline 如何与代码层对齐

narrations.ts 是唯一的真相源

outline 里的 step 数只是"初始预估",真正的真相源是每章目录下的 narrations.ts。以脚手架自带的示例章节 narrations.ts 为例:

export const narrations: Narration[] = [
  // step 0 — magazine cover
  "这是示例章节的第一步。把这一行换成你这一步的口播文案。",
  // step 1 — split layout
  "第二步。每个数组元素对应章节里 step === N 的那一屏。长度必须严格相等。",
  // step 2 — pull-quote close
  "第三步。这个数组就是音频合成 + 自动播放的唯一真相源——再也不会和章节代码漂移。",
];

数组长度 = 章节 step 数,索引 i = step === i 那一屏的口播文本。这条约定保证了 5 处地方(script / outline / 章节代码 / chapters.ts / 音频文件)永远不会漂移,因为它把"step 数"收敛为唯一事实。空串 "" 表示无声过场 step,Auto 模式会按字数估时撑过。

chapters.ts 的注册顺序 = outline 的章节序号

chapters.ts 中每个章节用 { id, title, narrations, Component } 注册,数组顺序即呈现顺序:

export const CHAPTERS: ChapterDef[] = [
  {
    id: "example",
    title: "示例章节",
    narrations: exampleNarrations,
    Component: ExampleChapter,
  },
];

outline 里的 N(1-indexed)必须对齐这里 CHAPTERS 的数组顺序——extract-narrations.ts 正是靠这个顺序决定音频段落的排列。这也解释了 outline 的 id 规则为什么要"小写 + 连字符":它会被用作文件夹名、React key 与音频子目录名。

useStepper.ts:全局 step 驱动与零基偏移

useStepper.ts 是运行时的心跳:它维护 { chapter, step } 游标,用 narrations.length 作为每章 step 数计算偏移,并支持 next / prev / jumpToChapter / jumpToGlobal。if (step === N - 1) 的零基偏移就在这里体现——outline 里写 step 1,代码判断的是 step === 0。另外它还持有一个 STORAGE_KEY(当前为 presentation-cursor-v4),当章节数量 / step 结构变化时必须 bump 版本号,否则持久化游标可能落到不存在的 step 上——这是章节大改后容易踩的坑。

音频合成流水线

outline.md 不参与音频合成,合成完全基于 narrations.ts:npm run extract-narrations 产出 audio-segments.json(含 chapter / step / text / audio 字段),npm run synthesize-audio 按段合成 mp3 到 public/audio/<id>/<N>.mp3。运行时三种模式(Manual / Audio / Auto)由 URL 参数 ?audio=1 / ?auto=1 或按 M 键切换;Auto 模式推进规则只有一句:每段音频播完 + 200ms 缓冲 → 自动 next,没有"等动画跑完"的兜底。因此 outline 里 (~Ts) 口播估时做得准,直接决定动画能否在 Auto 模式下完整播放。

实战:一个 outline 章节的完整样例

结合 case-tech-review 的 outline 节选,可以看到规范在真实题材中的形状(注意新版 outline 已不再写动画描述,这里展示的是信息池与 step 切分的落地):

## 2. why-strong — 强在哪(5 steps · ~80s)

**信息池**(chapter agent 按需挂角标 / 副标 / pull-quote / mono cue):
- 数字:主分数(来自 article §1,具体数字)
- 对比:第 2 名名字 + 差距分(article §1)
- 引用:官方原话 1~2 句 + 落款出处(article §1)
- 元数据:测评窗口("X 月 N 日 ~ Y 日")+ 投票数(mono cue 角标)

**开发计划**:

- step 1 (~6s) — hero"强在哪 · 四个方向" + 4 个 ghost 占位卡
- step 2 (~16s) — 第 1/4 项填实 + 大图慢镜 takeover
- step 3 (~16s) — 第 2/4 项填实 + 列表/演示
- step 4 (~16s) — 第 3/4 项填实 + before/after 慢镜对照
- step 5 (~16s) — 第 4/4 项填实 + 多参数预览

口播节选:
> 实测下来强在四个方向 ……

每个 step 的画面都做到"口播说一件事,画面挂多件事":比如 step 2 口播只是"第一项很强",画面同时呈现本项关键词 / 大图实例 / 具体数据点 / 副标补充——这就是双源原则在 outline 层面的具象落地。

总结:写好 outline 的三个心智模型

  1. 它是开发计划,不是视觉规划——动画、时长数值、实现手段一律下放到章节开发阶段,outline 只负责把"讲什么、分几步、每步屏幕放什么、每章有哪些可挂的细节"钉死。
  2. 它服务于双源原则——节拍来自 script.md,画面密度来自 article.md 的信息池,两者在每章首段汇合,让 chapter agent 拿到即可开工。
  3. 它与代码层通过 id 与 step 数对齐——小写连字符的 id 决定文件夹与音频路径,step 数是初始预估但最终以 narrations.ts 为准,写完必须走强制自检再进 Checkpoint Plan。

参考路径速查:SKILL.md(工作流总览)、CHAPTER-CRAFT.md(章节开发单一必读入口)、AUDIO.md(音频合成)、THEMES.md(主题系统)、EXAMPLES(结构示意 anchor)。

登录后查看全文
garden-skills