# Lecture Review

> Use when 用户拿到讲课/培训/演讲/分享活动的 raw 转录稿（听悟/FunASR），要复盘主讲人的讲授表现——口癖、语言习惯、节奏、时间分配、承诺回收、互动密度；有定稿课件时可做 deck 逐页对照（哪页讲了/跳过/挪位、min/页超载预警）；用户显式要求"课程结构复盘"时进入高级模式——课件自动体检 + 课件×实讲双向比对，产出智合复盘式结构诊断与修改建议；或要跨场次对比讲师表现、复查上次的口癖改掉了没有。触发词：讲课复盘、讲课表现、口癖分析、节奏分析、讲师档案、课件对照、课程结构复盘、复盘课程设计。不要用于：纠正转录错字、改写生成课程内容；常规复盘不评课程内容质量与方法论对错（课程评价只在高级模式经显式触发后进行）。

- Skill: `cat-xierluo/lecture-review` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add cat-xierluo/lecture-review`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cat-xierluo/lecture-review/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cat-xierluo (https://skillmd.com/u/cat-xierluo)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/cat-xierluo/lecture-review

---


# lecture-review（讲课表现复盘）

> 全部指标口径与降级规则见 [references/metrics.md](references/metrics.md)——执行本 skill 前必读。设计决策与基线测试记录见 DECISIONS.md（本地文件，不入库）。

## 概述

通读 raw 转录稿，对主讲人做讲授表现诊断：表达层（口癖/节奏/句式）+ 结构信号（时间分配/承诺回收/互动）+ 课件对照（有定稿 deck 时：设计与交付的结构落差），跨场次沉淀讲师档案，形成「复盘 → 提醒 → 复查」的改进闭环。

| 模式 | 触发 | 输出 |
|---|---|---|
| 单场复盘（默认·常规） | 一份 raw 转录稿 | `archive/.../report.md` 七段报告 + 档案追加 |
| deck 对照（增强，可选） | 转录稿 + 定稿课件 HTML | 报告内嵌「课件对照」段：页-时间映射、兑现分类、min/页超载预警 |
| **课程结构复盘（高级）** | 用户**显式要求**"课程结构复盘 / 复盘课程设计 / 课件与实讲对照找结构问题" | 智合复盘式结构诊断报告（模板见 [references/structural-review-template.md](references/structural-review-template.md)），落**项目目录** + archive 副本 |
| 跨场次对比 | 档案已有历史 + 新场次 | 报告内嵌对比段 + watchlist 复查 |
| 降级运行 | 无时间戳 / 纠错稿 / deck 解析失败 | 声明缺陷后缩小范围（见 metrics.md 降级表） |

## 依赖

### 系统依赖

| 依赖 | 安装方式 |
|------|----------|
| python3 ≥ 3.9 | macOS 自带 / `brew install python` |

### Python 包

无外部依赖（`scripts/analyze_stats.py` 纯标准库实现，词表 YAML 用内置解析器读取，失败时退回内置默认表）。

## 核心原则（不可妥协）

1. **通读动态发现优先**。必须用 Read 完整通读全文（超过单次上限就分页读完），先把「第一印象」落笔，再做逐项分析。预设词表、上场档案都只是参考与对比锚点——**禁止把分析做成对表打勾**；上场没发现过的模式往往才是本场最重要的发现。
2. **数字出自脚本，发现出自通读**。进入报告的任何数字必须由 `scripts/analyze_stats.py` 产出；agent 不估频次、不心算、不自造统计管道。通读发现的可数新模式用 `--count` 量化。
3. **只吃 raw 稿**。`_corrected` / `_polished` 稿的口癖证据已被转录纠错流程删除——警告用户后降级，口癖统计标注不可信。
4. **每条发现必须带原话例句 + 时间戳**，否则不进报告。
5. **只评表达与结构，不评内容质量**（逻辑是否成立、深浅、观点对错）。课程讲得好不好不在本 skill 范围。**课件对照同理只评"设计与交付的结构落差"**（哪页讲/跳/挪、密度、找位置摩擦）——跳页可能是主动取舍（如实报告、不扣分，挪位回收可标亮点）；方法论本身为何拆不开、结构该不该改，归项目复盘与讲者，不归本 skill。**唯一例外**：高级模式「课程结构复盘」经用户显式触发后可评课（见 Phase 6 与 D7），产出修改建议；未经显式触发永远不越此界。
6. **报告首页必须声明盲区**：ASR 引擎吞语气音，「呃/嗯/啊」类计数不可信，本报告口癖仅覆盖话语标记词与可数语言模式。

## 工作流

### Phase 0：输入检查

- 确认是 raw 稿（文件名带 `_corrected`/`_polished` → 警告降级）
- 确认时间戳是否存在（决定语速/停顿/三分场是否可用）
- 确认是否有定稿课件（HTML/PDF/逐页导出物）——有 → 本场启用 Phase 4.5 课件对照；无 → 报告声明缺省，其余流程不受影响
- 查档案：`profiles/` 下是否已有该讲师记录（有 → 本场带对比与复查）

### Phase 1：讲师隔离 + 基线数字

跑脚本（在 skill 目录下；词表首次使用先从 example 复制，真实词表被仓库 gitignore，缺失时脚本退回内置默认表，分析不受阻）：

```bash
cp -n config/marker_words.example.yaml config/marker_words.yaml
python3 scripts/analyze_stats.py '<转录稿>' --markers config/marker_words.yaml [--deck '<课件.html>'] --out <archive目录>/stats.json
```

JSON 含：主讲识别（默认字数最多者，`--speaker` 可指定编号/姓名）、排除区、固定锚点词频（含每万字频与三分场分布）、语速、长停顿（带前后文）、长句、段首起手式与连跑、求确认计数、承诺候选、幻灯片锚点（`slides_ts` 帧时间戳）、课件页表（`deck`：页数 + 每页 label/title/text——text 为页面正文摘录，每页截 600 字，够判内容覆盖度；`parse: failed` 时降级见 metrics.md）。

**隔离核验**（ASR 会犯错，基线实测有两种污染）：
- 主讲占全稿字数 < 50% → 可能选错人，与用户确认
- 抽查归属边界：开讲前后的段、结尾致谢段是否被 ASR 归错发言人（基线实例：主持人致谢被归给讲师）；污染量级 < 1 分钟则记录不阻塞

### Phase 2：通读与动态发现（主线）

- **完整通读**，先写第一印象：整体感觉 + 最突出的 2-3 件事（允许主观，但每条至少一个时间戳锚点）
- 动态识别本场讲师特有的模式。**模式类型参考**（判断启动点，非穷举、禁止当作打勾表）：
  - 万能指代（这个/那个/东西/玩意儿替代关键术语）
  - 固定模板（如「这样的一个X」整串高频复用）
  - 名词冠词化（「一个」无差别前缀）
  - 弱化词堆叠（可能/其实/我觉得/我相信）
  - 叠词重启（「我们我们」「我我」）
  - 自我修正外露且不回收（说错了承认一下继续错着讲）
  - 回指绕圈（「前面讲过」「回到这一页」高频 = 结构绕圈信号）
  - 行政碎语（稍等/先不管/没关系漏进话筒）
  - 同物多名（同一工具换着叫）
  - 句首起手式、长嵌套句
- 语气音（呃/嗯/啊）**不在发现范围**（盲区，见原则 6）
- 英文术语发音疑似不清 → 标「疑似，需对照录像」，不归责（ASR 漂移与发音问题无法区分）

### Phase 3：量化验证

- Phase 2 发现的每个可数模式，用 `--count '词1,词2,这样的一个'` 补充计数（可传完整短语/模板串）
- 脚本数字与通读印象冲突时，**以脚本为准修正印象**（agent 频次直觉不可靠，基线实测偏差可达 50%）

### Phase 4：结构信号（通读为主，脚本辅助）

- **时间分配**：把全场切成 寒暄调试 / 操作等待 / 正文演示 / 互动答疑，时间锚点用幻灯片锚点 + 长停顿 + 排除区跨度。操作等待（等扫码/装软件/排故障）**不扣分但要如实报告占比**
- **承诺回收**：`promise_candidates` 剔除误报 → 对每条真承诺在后文找兑现证据 → 输出「承诺 → ✓/✗/存疑 + 后文时间戳」
- **互动密度**：真互动 = 向听众提问并留出回应、请大家动手操作。按三分场报分布（只在开头互动 / 全程零互动都是信号）。自问自答不算互动，单独标注

### Phase 4.5：课件对照（有定稿 deck 时；起源见 DECISIONS D6）

脚本出两侧数据，**映射与分类靠通读**：

1. **页表 ↔ 帧锚点**：`deck.pages`（页数、label、title、text 均出自脚本）+ `slides_ts`（帧时间戳）。**帧 ≠ 页**——关键帧会重复拍同一页、漏拍只出现几秒的页、且帧不带页码；映射必须把帧时间戳附近的口述内容与**页面标题+正文**做内容匹配，逐页归位（text 摘录不够判断时 Read 原 HTML 对应 section 看全文）。
2. **兑现分类**（通读判断，每页归一类，进报告表格；判定依据 = 口述内容对**页面正文要点**的覆盖度，不是只看标题沾边）：
   - **实讲**（按设计位置讲透）｜ **半讲**（内容部分覆盖或未立框架）｜ **跳过**（整页未讲）｜ **挪位回收**（在别处讲了，标注时间戳——主动取舍可标亮点）｜ **主动宣判**（讲者明说"不用记/直接过掉"，引原话——设计路线与现场路线错配的最强证据）
3. **密度核算**：按模块（用 PART/hero 页或讲者口播切模块）报 页数 × 实讲时长 → **min/页**（粗口径：模块总时长；净口径：扣除现场实演与等待——两口径都报）。静态讲解 **< 1.5 min/页 且 跳过+主动宣判 ≥ 2 页** → 超载预警。
4. **找位置摩擦**：通读找「看一下顺序/翻到/在哪一页」类翻页找位置话语，`--count` 量化——页序与讲者心智顺序不一致的信号。
5. 只报落差事实，**不诊断方法论该不该改**（原则 5）；方法论层面的结论留给项目复盘。

### Phase 5：报告 + 档案 + 归档

**report.md 七段**：
1. **第一印象**（通读后的整体感觉，每条带时间戳锚点）
2. 快照（时长 / 主讲字数 / 平均语速 / 固定锚点口癖 Top 5 表）
3. 动态发现·表达层（每条 = 脚本数字 + 原话例句 + 时间戳 + 一句可操作建议；含优点保留项）
4. 结构信号（时间分配条、未回收承诺清单、互动密度）
5. 课件对照（有 deck 时：兑现分类表、模块 min/页、超载预警、找位置摩擦；无 deck 声明缺省）
6. 与上场对比（固定锚点 ↑↓ + watchlist 逐项复查「改了吗」；首场写「建立基线」）
7. 下次开讲前 3 条提醒（从档案历史趋势生成，不是只看当场）

**档案 `profiles/{讲师}.yaml`**（每场追加；讲师档案是个人数据，已被仓库 gitignore，仅存本地）：
```yaml
sessions:
  - {date: 2026-03-01, name: 某实务培训班（示例）, minutes: 120, chars: 24000,
     rate_per_min: 210.0, anchors: {这个: 95.0, 就是: 40.2, 然后: 33.1, 其实: 25.7},
     interaction: 4, promise_fulfilled: "90%", watchlist: [这样的一个X模板, 弱化词堆叠], reminders: [...],
     deck: {pages: 64, taught: 45, skipped: 6,半讲: 5, moved: 4, declared_skip: 2, min_per_page: 1.4, flip_hunts: 2}}
```
watchlist = 本场新发现的个人模式，**下场优先复查，但仍先通读**（原则 1）。

**归档双写**：`archive/{YYYYMMDD_HHMMSS}_{原文件 basename}/report.md`（含 stats.json）+ 源目录镜像 `{原文件 basename}_review.md`。原始转录稿永不动。

**产物落点约定**（避免沉淀物到处散落）：

| 产物 | 主本落点 | 副本落点 | 用途 |
|---|---|---|---|
| 七段常规报告 `report.md` | **skill archive/** | — | 跨场对比的最小集 |
| 带 deck 的结构复盘 `review.md` | **项目课程目录**（如 `4 - 课程演示/讲课实录/{basename}_review.md`） | **skill archive/** 存副本 | 主本服务讲者改课；副本供跨场深度对比 |
| `stats.json`（脚本机械产物） | **skill archive/** | — | 跨场对比的客观锚点；带 deck 的版本用 `stats_deck.json` 区分 |
| 讲师档案 `profiles/{讲师}.yaml` | **skill 内部** | — | 评人纵向记录（course review 不进档案） |

落点理由：review.md 形态（deck 对照 + 跨版对比 + 方法论回流）远大于常规报告、含方法论层内容，主本必须在项目目录与讲者决策上下文在一起；skill archive 存副本保证跨场索引可达。原始转录稿**永不动**——所有产物都是派生。

**skill 内不做跨项目资产沉淀**：沉淀的可复用教学经验/心法（厨房比喻、递进修辞、受众差异等）属于 wiki 的"培训知识沉淀"职能，不进 skill；skill 只沉淀**复盘方法论本身**（口径、模板、watchlist 体系）。

### Phase 6（高级模式·显式触发）：课程结构复盘

> 与常规复盘的分界（D7）：常规复盘**评人**（讲师表现），高级复盘**评课**（课程设计）——因突破 D2 边界，必须用户显式要求才启动；输出是给讲者改课件/改方法论的依据，不进讲师档案。

前置：转录稿 + 定稿 deck 缺一不可（只有 deck → 只做第 1 步课件体检；只有转录稿 → 退回常规模式）。骨架模板：[references/structural-review-template.md](references/structural-review-template.md)。

1. **课件自动体检（deck 单侧）**：读 `deck.self_check`——
   - `module_distribution`：各模块/步骤页数分布（agent 把细粒度 label 组归并为大模块）；
   - `near_dup_pages`：同主题双视图/近重复页候选（滤掉目录↔hero 良性误报）——同一判断排两页独立内容，是"页数超载"的常见来源；
   - `title_term_index` + 全文检索 `deck.pages[].text`：查同一概念挂在多页/多步骤下的**归属重叠**；
   - 路线假设：deck 中是否存在多种创建路线的页（手写六部分 vs 生成器），与本场实际演示路线是否一致。
2. **双向比对（deck × 实讲）**：在 Phase 4.5 兑现分类基础上补三个方向——
   - **设计了没讲**：跳过/半讲页的知识点是否在别处口述出现（挪位）还是真丢失；
   - **讲了没设计**：口述大块内容无页对应（即兴发挥）——标时间戳与时长，判断"值得加页 / 有意丢弃"；
   - **涌现位置错配**：某页设计在步骤 A 的内容，实际在步骤 B 的语境中才被讲出（教学顺序 ≠ 工作顺序的信号）。
3. **结构诊断**：综合 1+2，找 deck 设计假设与实际交付路线的系统性失配（不止单页问题）——每条诊断必须有页码 + 时间戳证据链，并区分"deck 设计根源"与"现场发挥根源"。
4. **修改建议**：分三层——deck 层（页级动作：合并/删除/改排/加现场动作标记）、讲法层（节奏分配、演示时机）、例子层（例子与方法的匹配度）；可执行的写到页号。
5. **回流出口**：方法论层面的发现（步骤框架本身的问题）指明回流去向（书籍章节/方法论 owner）——本 skill 只指出，不替书籍项目做决定。
6. **产物落盘**：报告按模板写入**项目目录**（如 `3 - 课程内容/YYMMDD 课程结构复盘（主题）.md`），archive 存 stats.json + 副本；讲师档案只追加 `deck:` 字段组，不追加课程评价。

## 常见坑（2026-08-24 基线实测，全部真实发生过）

| 坑 | 后果 | 对策 |
|---|---|---|
| 幻灯片锚点 URL 行混入正文自造管道统计 | 字数虚高 50%（46,652 > 全稿 36,176），语速全错 | 禁止自造 awk/grep 统计管道；只用本 skill 脚本（已剔 URL/标点） |
| 时间戳 59:59 后切换 HH:MM:SS 格式 | 「26:20」被解析成 26 小时，时长为负 | 脚本已处理双格式；自己写时间解析前先想到这个坑 |
| 子串重叠（「这个」⊃「在这个里面」） | 重复计数 | 脚本最长优先去重叠；`--count` 传完整短语 |
| 语速分母自造（"实际发言时长"口径漂移） | 跨场次不可比 | 只用脚本 rate 口径（定义见 metrics.md） |
| 发言人归属污染未核验 | 主持人语句计入讲师口癖 | Phase 1 隔离核验两步 |
| 拿预设词表当分析本身 | 漏掉词表外的主口癖（基线中「一个」477 次不在任何预设表内） | 通读优先；词表只是锚点 |
| 把帧锚点当页码（帧≠页：关键帧重复拍/漏拍/无页码） | "无帧出现"被误判为跳页 | 帧-页映射靠口述内容与页标题匹配（Phase 4.5 第 1 步）；无帧只是弱证据 |
| min/页只报一个口径 | 含现场实演等待的粗口径掩盖静态页超载（实测 73min/28页看似 2.6，扣实演后实为 1.4） | 粗/净两口径都报（Phase 4.5 第 3 步） |

## 与相邻 skill 的边界

| | 本 skill | transcription-corrector | course-generator |
|---|---|---|---|
| 输入 | raw 稿 | raw 稿 | raw/纠错稿 |
| 动作 | 表现诊断（只读原文，产出报告） | 纠错改稿（Edit 落盘） | 生成课程 |
| 对口癖证据 | 要保留（统计对象） | 要删除（清理对象） | 不关心 |

同一份 raw 稿想既复盘又纠错：先跑本 skill（读原文），再跑 transcription-corrector。

