lecture-review · git:20260824.a47cadd · 2026-08-24 · sha256 3cc9d99d966500a9

lecture-review git:20260824.a47caddA

Immutable. This exact content never changes and is served at /api/v1/blob/3cc9d99d966500a9.

---
name: lecture-review
description: Use when 用户拿到讲课/培训/演讲/分享活动的 raw 转录稿(听悟/FunASR),要复盘主讲人的讲授表现——口癖、语言习惯、节奏、时间分配、承诺回收、互动密度;或要跨场次对比讲师表现、复查上次的口癖改掉了没有。触发词:讲课复盘、讲课表现、口癖分析、节奏分析、讲师档案。不要用于:纠正转录错字、改写生成课程内容、或评判课程内容质量。
---

# lecture-review(讲课表现复盘)

> 全部指标口径与降级规则见 [references/metrics.md](references/metrics.md)——执行本 skill 前必读。设计决策与基线测试记录见 DECISIONS.md(本地文件,不入库)。

## 概述

通读 raw 转录稿,对主讲人做讲授表现诊断:表达层(口癖/节奏/句式)+ 结构信号(时间分配/承诺回收/互动),跨场次沉淀讲师档案,形成「复盘 → 提醒 → 复查」的改进闭环。

| 模式 | 触发 | 输出 |
|---|---|---|
| 单场复盘(默认) | 一份 raw 转录稿 | `archive/.../report.md` 六段报告 + 档案追加 |
| 跨场次对比 | 档案已有历史 + 新场次 | 报告内嵌对比段 + watchlist 复查 |
| 降级运行 | 无时间戳 / 纠错稿 | 声明缺陷后缩小范围(见 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 范围。
6. **报告首页必须声明盲区**:ASR 引擎吞语气音,「呃/嗯/啊」类计数不可信,本报告口癖仅覆盖话语标记词与可数语言模式。

## 工作流

### Phase 0:输入检查

- 确认是 raw 稿(文件名带 `_corrected`/`_polished` → 警告降级)
- 确认时间戳是否存在(决定语速/停顿/三分场是否可用)
- 查档案:`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 --out <archive目录>/stats.json
```

JSON 含:主讲识别(默认字数最多者,`--speaker` 可指定编号/姓名)、排除区、固定锚点词频(含每万字频与三分场分布)、语速、长停顿(带前后文)、长句、段首起手式与连跑、求确认计数、承诺候选、幻灯片锚点。

**隔离核验**(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 5:报告 + 档案 + 归档

**report.md 六段**:
1. **第一印象**(通读后的整体感觉,每条带时间戳锚点)
2. 快照(时长 / 主讲字数 / 平均语速 / 固定锚点口癖 Top 5 表)
3. 动态发现·表达层(每条 = 脚本数字 + 原话例句 + 时间戳 + 一句可操作建议;含优点保留项)
4. 结构信号(时间分配条、未回收承诺清单、互动密度)
5. 与上场对比(固定锚点 ↑↓ + watchlist 逐项复查「改了吗」;首场写「建立基线」)
6. 下次开讲前 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: [...]}
```
watchlist = 本场新发现的个人模式,**下场优先复查,但仍先通读**(原则 1)。

**归档双写**:`archive/{YYYYMMDD_HHMMSS}_{原文件 basename}/report.md`(含 stats.json)+ 源目录镜像 `{原文件 basename}_review.md`。原始转录稿永不动。

## 常见坑(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 次不在任何预设表内) | 通读优先;词表只是锚点 |

## 与相邻 skill 的边界

| | 本 skill | transcription-corrector | course-generator |
|---|---|---|---|
| 输入 | raw 稿 | raw 稿 | raw/纠错稿 |
| 动作 | 表现诊断(只读原文,产出报告) | 纠错改稿(Edit 落盘) | 生成课程 |
| 对口癖证据 | 要保留(统计对象) | 要删除(清理对象) | 不关心 |

同一份 raw 稿想既复盘又纠错:先跑本 skill(读原文),再跑 transcription-corrector。