lecture-review(讲课表现复盘)
全部指标口径与降级规则见 references/metrics.md——执行本 skill 前必读。设计决策与基线测试记录见 DECISIONS.md(本地文件,不入库)。
概述
通读 raw 转录稿,对主讲人做讲授表现诊断:表达层(口癖/节奏/句式)+ 结构信号(时间分配/承诺回收/互动)+ 课件对照(有定稿 deck 时:设计与交付的结构落差),跨场次沉淀讲师档案,形成「复盘 → 提醒 → 复查」的改进闭环。
| 模式 | 触发 | 输出 |
|---|---|---|
| 单场复盘(默认·常规) | 一份 raw 转录稿 | archive/.../report.md 七段报告 + 档案追加 |
| deck 对照(增强,可选) | 转录稿 + 定稿课件 HTML | 报告内嵌「课件对照」段:页-时间映射、兑现分类、min/页超载预警 |
| 课程结构复盘(高级) | 用户显式要求"课程结构复盘 / 复盘课程设计 / 课件与实讲对照找结构问题" | 智合复盘式结构诊断报告(模板见 references/structural-review-template.md),落项目目录 + archive 副本 |
| 跨场次对比 | 档案已有历史 + 新场次 | 报告内嵌对比段 + watchlist 复查 |
| 降级运行 | 无时间戳 / 纠错稿 / deck 解析失败 | 声明缺陷后缩小范围(见 metrics.md 降级表) |
依赖
系统依赖
| 依赖 | 安装方式 |
|---|---|
| python3 ≥ 3.9 | macOS 自带 / brew install python |
Python 包
无外部依赖(scripts/analyze_stats.py 纯标准库实现,词表 YAML 用内置解析器读取,失败时退回内置默认表)。
核心原则(不可妥协)
- 通读动态发现优先。必须用 Read 完整通读全文(超过单次上限就分页读完),先把「第一印象」落笔,再做逐项分析。预设词表、上场档案都只是参考与对比锚点——禁止把分析做成对表打勾;上场没发现过的模式往往才是本场最重要的发现。
- 数字出自脚本,发现出自通读。进入报告的任何数字必须由
scripts/analyze_stats.py产出;agent 不估频次、不心算、不自造统计管道。通读发现的可数新模式用--count量化。 - 只吃 raw 稿。
_corrected/_polished稿的口癖证据已被转录纠错流程删除——警告用户后降级,口癖统计标注不可信。 - 每条发现必须带原话例句 + 时间戳,否则不进报告。
- 只评表达与结构,不评内容质量(逻辑是否成立、深浅、观点对错)。课程讲得好不好不在本 skill 范围。课件对照同理只评"设计与交付的结构落差"(哪页讲/跳/挪、密度、找位置摩擦)——跳页可能是主动取舍(如实报告、不扣分,挪位回收可标亮点);方法论本身为何拆不开、结构该不该改,归项目复盘与讲者,不归本 skill。唯一例外:高级模式「课程结构复盘」经用户显式触发后可评课(见 Phase 6 与 D7),产出修改建议;未经显式触发永远不越此界。
- 报告首页必须声明盲区:ASR 引擎吞语气音,「呃/嗯/啊」类计数不可信,本报告口癖仅覆盖话语标记词与可数语言模式。
工作流
Phase 0:输入检查
- 确认是 raw 稿(文件名带
_corrected/_polished→ 警告降级) - 确认时间戳是否存在(决定语速/停顿/三分场是否可用)
- 确认是否有定稿课件(HTML/PDF/逐页导出物)——有 → 本场启用 Phase 4.5 课件对照;无 → 报告声明缺省,其余流程不受影响
- 查档案:
profiles/下是否已有该讲师记录(有 → 本场带对比与复查)
Phase 1:讲师隔离 + 基线数字
跑脚本(在 skill 目录下;词表首次使用先从 example 复制,真实词表被仓库 gitignore,缺失时脚本退回内置默认表,分析不受阻):
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)
脚本出两侧数据,映射与分类靠通读:
- 页表 ↔ 帧锚点:
deck.pages(页数、label、title、text 均出自脚本)+slides_ts(帧时间戳)。帧 ≠ 页——关键帧会重复拍同一页、漏拍只出现几秒的页、且帧不带页码;映射必须把帧时间戳附近的口述内容与页面标题+正文做内容匹配,逐页归位(text 摘录不够判断时 Read 原 HTML 对应 section 看全文)。 - 兑现分类(通读判断,每页归一类,进报告表格;判定依据 = 口述内容对页面正文要点的覆盖度,不是只看标题沾边):
- 实讲(按设计位置讲透)| 半讲(内容部分覆盖或未立框架)| 跳过(整页未讲)| 挪位回收(在别处讲了,标注时间戳——主动取舍可标亮点)| 主动宣判(讲者明说"不用记/直接过掉",引原话——设计路线与现场路线错配的最强证据)
- 密度核算:按模块(用 PART/hero 页或讲者口播切模块)报 页数 × 实讲时长 → min/页(粗口径:模块总时长;净口径:扣除现场实演与等待——两口径都报)。静态讲解 < 1.5 min/页 且 跳过+主动宣判 ≥ 2 页 → 超载预警。
- 找位置摩擦:通读找「看一下顺序/翻到/在哪一页」类翻页找位置话语,
--count量化——页序与讲者心智顺序不一致的信号。 - 只报落差事实,不诊断方法论该不该改(原则 5);方法论层面的结论留给项目复盘。
Phase 5:报告 + 档案 + 归档
report.md 七段:
- 第一印象(通读后的整体感觉,每条带时间戳锚点)
- 快照(时长 / 主讲字数 / 平均语速 / 固定锚点口癖 Top 5 表)
- 动态发现·表达层(每条 = 脚本数字 + 原话例句 + 时间戳 + 一句可操作建议;含优点保留项)
- 结构信号(时间分配条、未回收承诺清单、互动密度)
- 课件对照(有 deck 时:兑现分类表、模块 min/页、超载预警、找位置摩擦;无 deck 声明缺省)
- 与上场对比(固定锚点 ↑↓ + watchlist 逐项复查「改了吗」;首场写「建立基线」)
- 下次开讲前 3 条提醒(从档案历史趋势生成,不是只看当场)
档案 profiles/{讲师}.yaml(每场追加;讲师档案是个人数据,已被仓库 gitignore,仅存本地):
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。
- 课件自动体检(deck 单侧):读
deck.self_check——module_distribution:各模块/步骤页数分布(agent 把细粒度 label 组归并为大模块);near_dup_pages:同主题双视图/近重复页候选(滤掉目录↔hero 良性误报)——同一判断排两页独立内容,是"页数超载"的常见来源;title_term_index+ 全文检索deck.pages[].text:查同一概念挂在多页/多步骤下的归属重叠;- 路线假设:deck 中是否存在多种创建路线的页(手写六部分 vs 生成器),与本场实际演示路线是否一致。
- 双向比对(deck × 实讲):在 Phase 4.5 兑现分类基础上补三个方向——
- 设计了没讲:跳过/半讲页的知识点是否在别处口述出现(挪位)还是真丢失;
- 讲了没设计:口述大块内容无页对应(即兴发挥)——标时间戳与时长,判断"值得加页 / 有意丢弃";
- 涌现位置错配:某页设计在步骤 A 的内容,实际在步骤 B 的语境中才被讲出(教学顺序 ≠ 工作顺序的信号)。
- 结构诊断:综合 1+2,找 deck 设计假设与实际交付路线的系统性失配(不止单页问题)——每条诊断必须有页码 + 时间戳证据链,并区分"deck 设计根源"与"现场发挥根源"。
- 修改建议:分三层——deck 层(页级动作:合并/删除/改排/加现场动作标记)、讲法层(节奏分配、演示时机)、例子层(例子与方法的匹配度);可执行的写到页号。
- 回流出口:方法论层面的发现(步骤框架本身的问题)指明回流去向(书籍章节/方法论 owner)——本 skill 只指出,不替书籍项目做决定。
- 产物落盘:报告按模板写入项目目录(如
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。