方法论与洞察

2026-08-13 Codex 教程操作部分 · 26 段重录复盘(19/26)

事实记录(不可修改区)

接手时的现场


一、上一轮 26 条为什么几乎全废

这是本批最有价值的部分:参数 26/26 全过,内容 26/26 几乎全错。抽帧核实的实际画面:

镜号应该是什么实际录到什么
318 / 321 / 322 / 323Codex 各种界面操作全黑画面
319左上角切换 GPT/Codex微信 + WorkBuddy
324 / 326-331做 PPT、许愿式提示词全是 ChatGPT 定价页
332-338七段提示词逐条输入输入框始终是空的
339 / 340滚动展示完整需求、发送空会话,没东西可滚可发
341打开网页点按钮拖窄的窗口露出桌面壁纸

四个根因,没有一个出在”鼠标怎么动”这类难的地方:

① 中文一个字都打不进去。 keyboard.type_keysVkKeyScanW,该 API 对 CJK 字符返回 -1,函数直接 return False——而调用方不检查返回值。332-338 七条全是中文提示词,所以输入框自始至终是空的;330 因为提示词是英文,反而”正常”。

② 新开的窗口没人管。 脚本只把 ChatGPT 挪到副屏,subprocess.Popen 起的 Chrome / 资源管理器 / PPT 一律开在主屏。而 OBS 录的是副屏——于是副屏上停着的还是上一条留下的画面。317 开的定价页没人收走,324-331 就全录成了定价页;318/321/322/323 那几条录制时副屏干脆是黑的。

③ 点击坐标落在空白处。 输入框点的是 (x + 0.5w, y + 0.65h),实际落在对话区空白,根本没聚焦输入框。

④ 窗口找错。 317 的 find_window("ChatGPT", timeout=15) 优先命中的是 ChatGPT 桌面端,而不是刚开的 Chrome,于是被摆到副屏的是错的那个窗口。

共同点和上一批一模一样:动作本身没错,错在动作发生时舞台上不是我以为的那个东西。 区别是上一批错在”版面”(面板开合、窗口最大化),这一批错在**“舞台上站着谁”**。


二、本轮自己新踩的坑

① 清屏把主角也清走了。 我写的 clear_secondary() 把副屏上所有窗口最小化,包括 ChatGPT 自己;随后 find_window("ChatGPT") 找不到它——最小化窗口 GetWindowRect(-32000,-32000),被 all_windows()min_size 过滤掉了。这条交接文档里白纸黑字写过(坑 2),我还是原样踩了一遍。 正确顺序是先把目标窗口摆上台,再清场。

② 差点对着浏览器录整集。 ChatGPT 桌面端是 Electron,窗口类名和 Chrome 同为 Chrome_WidgetWin_1;浏览器开着 chatgpt.com 时标题也含 “ChatGPT”。find_any("ChatGPT") 抓到了「ChatGPT - Google Chrome」。是断言当场拦下的:空输入框判据 CLEAR 应为 0.0019,实测 0.99329(浏览器上那块区域是深色),脚本立刻退出。

③ 设置页顶掉主界面。 ChatGPT 的设置是占满整屏的页面,不是弹窗。它一开,左上角标题区变空,“新建任务""输入框""工作区胶囊”全部错位。316 第三段因此录成了「常规设置」;后面连着三次 UI 探索失败也都是这个原因。

④ markdown 自动列表反咬一口。 输入框把 1. 开头认成有序列表,Shift+Enter 换行时自动补下一个编号,正文再自带 2. 前缀就成了「2. 2. 项目状态」。解法:只有第一段带编号,后面几段只打正文,让编辑器自己续号。

⑤ 断言方向写反。 322 用”对话区暗像素增加”判断收到回复,结果 0.00521 → 0.00056 判失败——因为新会话的大标题「我们该在…处理什么?」字号很大,暗像素比一句「2 + 2 = 4.」还多,发送后读数反而下降。判据应该是”变化”而不是”增加”。素材其实是好的,白重录一条。


三、方法论沉淀

[交接文档不是需求原文,接手第一件事是回溯上游]

核心:交接文档是转述。转述会丢信息、会掺入转述者的判断,而且读起来和原文一样确定。接手一项任务时,第一件事是找到需求原文,而不是直接照交接文档执行。

来源:交接文档「决策 3」写着——

332-338 是”输入提示词不发送”系列,每条必须独立展示自己的那一段提示词,不能累积前一段

我照此录完 7 条、验收通过。之后为了找素材,翻到了给同事核对用的 对位表.md(需求原文),上面写的是:

3.3 | 镜号 332 | 输入提示词片段 1(不发送,文字累积) 3.10 | 镜号 339 | Codex 输入框缓慢滚动展示完整需求

完全相反。 而且三处证据都指向”累积”才是原意:① 对位表原文;② 只有累积,339 的”完整需求”才有东西可滚;③ 作者当天已独立裁定 339/340 要用完整七段。交接文档那条大概率是把知识库里另一个项目「05 段内容重复」的教训误套了过来。

验证状态:初次发现 ⚠️

操作规则

  1. 接手任务先问一句”需求原文在哪”,把交接文档和原文对齐一遍再动手。本例的原文就躺在交付目录里(对位表.md),只是没人提
  2. 发现冲突时不要自己选一个执行——把两边原文并列摆给决策人,附上自己的判断和理由,让他一句话定。本例裁决只花了一次问答,但如果我闷头按交接文档做完 26 条,返工的是整集
  3. 冲突暴露得越早越便宜。本例代价是重录 7 条(约 3 分钟),因为脚本已经写好,只是去掉”清空”那一步
  4. 交接文档里带感情色彩的条款(“这是上一轮被点名的错误”)尤其要回溯——它读起来最像定论,也最可能是转述者的加工

边界:原文不可得时(口头需求、原始文档已丢),交接文档就是最高权威,此时应该反过来——把自己的执行假设写清楚,让它成为下一版的原文。

[固定坐标的前提,还包括”舞台上站着谁”和”应用在哪个视图”]

核心:既有的 UI自动化的固定坐标必须绑前提断言_v1 列的前提是版面类的(面板开合 / 窗口最大化 / 输入框为空 / 侧栏滚动位置)。本批贡献两个新形态的前提,它们比版面类更隐蔽:

来源:本批「差点对着浏览器录整集」(类名和标题双重撞车)、「设置页顶掉主界面」(316 第三段录成常规设置 + 三次 UI 探索失败)。

验证状态:贡献给母律的第三次验证(仍在录屏域内,跨域验证依然缺

操作规则

  1. 窗口一律按进程名认,不要按标题或类名。Electron 应用(ChatGPT 桌面端、VS Code、Discord…)类名清一色 Chrome_WidgetWin_1;标题由页面内容决定,随时会和别的窗口撞
  2. 每条录制前把应用收敛到已知视图ensure_main_view()),别假设它还停在上一条结束时的样子
  3. 判据要能区分”没找到”和”找错了”。本例 CLEAR=0.99 一眼就知道是找错了窗口——如果判据只有”有没有内容”,就会误判成”输入框有残留”,然后去清空一个浏览器页面

[累积型镜头:用单调递增的基线序列做强断言]

核心:一串”逐步累加”的镜头(第 N 条要求画面里正好有 N-1 段内容),可以先离线标定一条单调递增的像素基线,录每条前用它校验”进行到第几步”。链一旦错位(漏录 / 重复追加 / 中途被人手改),当场拒录。

来源:332-338 是七段提示词逐条累积。先跑一次标定得到 GROW 序列:

0 段 .0032 → 1 段 .0190 → 2 段 .0344 → 3 段 .0452
    → 4 段 .0569 → 5 段 .0701 → 6 段 .0800 → 7 段 .0904

每段增量 ≥.008,容差取 ±.012,正式录制时 7 条读数逐条落在基线上。

验证状态:初次发现 ⚠️

操作规则

  1. 判据区域要罩住内容的最终形态(七段全展开时的高度),不能只罩第一段的位置
  2. 同时留一个小区域判”空/非空”:大区域用来判深度,小区域用来判起点是不是干净的。本例 CLEAR(空 .0019 / 有字 .031,差 17 倍)和 GROW(深度)各司其职
  3. 累积模式下自动重试必须关掉attempts=1)。重录会把同一段再追加一遍,越”重试”越错。失败就停下,从第一条重新起链
  4. 基线会随环境轻微漂移(本例换到 Codex 模式后整体低 .0016),所以容差要留够,但必须远小于单段增量,否则断言失去意义

[出片不等于合格 —— 这批是最极端的一次实证]

核心:机器只能验参数,内容必须过人眼。

来源:接手时那 26 条 参数 100% 合格(1920×1080 / 60fps 全过),内容几乎 100% 错误。之前两批的数字是 19 条里拦下 4 条、19 条里拦下 2 条;这批是整批

如果只看 ffprobe,这 26 条是一批完美素材。

本批新增的一条操作规则给机器关加一条”内容非空”的粗判据。本批在 ffprobe 之后加了一道”抽帧算纯黑像素占比 >55% 判废”,318/321/322/323 那种全黑片机器就能拦下,不必等人眼。粗判据挡不住”内容错”,但挡得住”内容无”,成本几乎为零。

→ 已在 自动化产出双重验收_机器验参数人眼验内容_v1 补录本批实证。

[录屏脱敏:危险的不是画面主体,是自动弹出来的东西]

核心:录教程时人会盯着”主体内容有没有露馅”,真正漏出去的往往是自动弹出的辅助 UI——地址栏补全、侧栏历史、通知气泡。它们不在剧本里,所以不会被检查。

来源:本批拦下三处:

位置会漏什么解法
Ctrl+L 唤起地址栏Chrome 历史自动补全铺出钉钉文档、B站 Toy 链接、MEGA 网盘地址改成预先开两个标签页,录制中用 Ctrl+1/2 切换,全程不碰地址栏
网页版 chatgpt.com 侧栏全部会话历史 + 账号名开录前折叠侧栏并断言(暗像素 <0.01),录后还原
桌面端「快速聊天」浮层最近聊天列表已入镜,抽帧交作者裁决

验证状态:初次发现 ⚠️(上一批的同族做法是”F11 全屏 / Chrome --app 规避书签栏”,本条把它推广到”自动弹出的辅助 UI”这一类)

操作规则

  1. 列一张”这条镜头会自动弹出什么”的清单,比列”我要展示什么”更重要
  2. 能绕过就别遮挡:地址栏补全没法关,但换成标签页切换就完全不出现
  3. 改了对方环境的(折叠侧栏、切审批模式)当场记下并在收工时还原,还原动作也写成脚本(record_317.py restore

四、下次改进

如果重来,最想改哪一步

接手后先花 10 分钟做一次”能力自检”,而不是直接开录。 → ✅ 次日(08-14)已落地为 humancast/examples/preflight.py:11 项检查 + --fix 自动拉起,实测从空环境到全绿。见 2026-08-14_Codex教程录制链路打磨_复盘

上一轮 26 条全废,四个根因里有三个(中文打不进去、窗口没挪、坐标落空)都能被一次 10 分钟的自检拦下:在真实窗口上打一行中文、开一个新窗口看它落在哪块屏、点一次输入框看焦点在不在。实际做法是照着交接文档”按正确方案重录”,直到抽帧才发现问题。

交接文档描述的是”方案”,自检验证的是”能力”。方案对,不代表每个动作真的能执行。

下次同类型任务的行动清单

  1. 接手先要需求原文,和交接文档逐条对齐(交接文档不是需求原文_接手先回溯上游_v1
  2. 开录前跑一次能力自检:中文输入、窗口落屏、焦点、OBS 空闲状态
  3. 窗口一律按进程名认;每条录前 ensure_main_view() 收敛视图
  4. 累积型镜头先标定基线序列,attempts=1,失败就重新起链
  5. 机器关加”内容非空”粗判据(黑屏占比),把人眼关留给”内容错”
  6. 列一张”会自动弹出什么”的清单;改了对方环境的当场记下并写还原脚本
  7. 判据方向要先想清楚:是”增加”还是”变化”?322 那条白录一次就是因为默认了”内容多了暗像素一定变多”

五、一句话结论

上一批的教训是”动作发生时版面不对”,这一批是它的下一层:动作发生时,舞台上站着的根本不是我以为的那个窗口——而这一切的上游,是我照着一份转述在执行,没去看原文。


关联文档

类型/IP视觉主题/口播教学主题/自动化录屏工具/humancast工具/OBS工具/Codex