Files
mcn-short-video/失误与规避记录.md
T
maogeigei f77735b206 工作台:目录改名 mcn-workshop + 任务进度可见 + 会话归属配置化
1. 目录 mcn-work-shop -> mcn-workshop(空间分组名取会话 cwd 的目录名,只改字符串无效,必须真改名)
2. 全仓替换 mcn-work-shop -> mcn-workshop:37 文件 121 处;历史日志按沿革句规矩保留当时目录名
3. 任务进度可见:/api/run/status 产出 已运行时长/工具调用/最近动作/停滞判定(读会话日志尾部),前端新增右下角常驻面板,四处任务入口接入
4. 会话归属目录配置化:新增 config.sessionCwd(留空=工作台自身目录),现指向 D://AI技能//mcn-workshop,使任务显示为命名分组而非「未分组任务」
5. 修前端轮询静默缺陷:连续 3 次查询失败即提示服务断开(原逻辑静默空转到 15 分钟超时,用户零感知)
2026-10-08 13:09:06 +08:00

292 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 失误与规避记录
> 持续追加。
---
## #001 跨技能借鉴判断(2026-08-13)
遇到"要不要同步某字段"时,先验证数据流(信息从哪来→落到哪→下游谁读,断了就是缺口),再决定字段形态——避免用"结构不合适"直接否定,掩盖信息链路缺口。
---
## #002 审计修复未逐条执行(2026-08-13)
审计修复时一次性批量读取所有涉及文件准备批量改,被用户纠正。规避:逐条读取→逐条修改→逐条验证,禁止批量读取准备批量修改。
---
## #003 素材库引用机制搞混(2026-08-14)
把「适用场景(人设卡片)」当成素材库引用的核心来源。规避:素材库引用核心入口是「极致类型映射」(知识库 05_极致事件 → 极致类型 → 素材类型),「适用场景」只是四维标签里的辅助过滤维度。
---
## #004 部署注意点只写记忆未落文件(2026-08-14)
把「部署到用户电脑需注意的点(MCP 安装前须检查 Node/Python 环境)」只写进个人记忆(`~/.workbuddy/MEMORY.md`),没写进技能文件。规避:记忆是开发机本地文件、不随部署走,凡是需要在用户电脑生效的部署注意点,必须写进 SKILL.md(或技能内 references 文件),不能只写个人记忆。
---
## #005 标准库引用不存在的文件(2026-08-17 审计发现)
`references/旧梦留声机人设卡片.md` 已不存在,但 SKILL.md(2处)与 `feature/02_提炼账号设定.md`(2处)仍引用它(禁用清单 + 技能库路径表 + Step5 生成参考),执行时会找空。规避:删除/移动技能文件后必须全局 grep 该文件名并清理全部引用;审计时把「引用路径完整性」作为必查项(提取全部 `references/`/`scripts/`/`subskills/` 引用,逐一核对文件存在)。
---
## #006 标准库写死账号实证数据(2026-08-17 审计发现)
`references/账号数据分析方法.md` 的趋势判断法/植入范式写入了具体账号(王微斯)的账号名与大量绑定实证数值(如"5月占比80%→均赞8.9万""白惜牙膏86.8万"),部署到其他账号/用户时会造成误导。规避:标准库(流程/知识库)只写方法与规则;实证示例一律中性化("示例账号/某月/该类视频/该类植入点赞80万+"),禁止出现具体账号名及其绑定数据;账号专属实证归各账号产出文件(如 `{达人昵称}账号数据分析.md`),不进标准库。
---
## #007 MCP 部署预检只查运行时、未查 npm 缓存权限(2026-08-17)
给用户 Mac 部署 MCP 时,预检只做了 Node/Python 版本检查,未查 npm 缓存权限,导致 `npx` 型 MCP 启动失败且排查方向一度误判为镜像问题。真正根因:`~/.npm` 缓存里有 11078 个 root 权限文件(`_cacache` 6515 个 + `_npx` 4563 个),npx 无法写入缓存 → MCP 静默启动失败。规避:MCP 部署预检 = ①运行时版本 ②npm 缓存权限(macOS 高发,`find ~/.npm -user root` 检查,`rm -rf ~/.npm/_npx ~/.npm/_cacache` 清理,无需 sudo)③npm 源(仅可选,非根因);排查顺序 1→2→3,缓存权限问题先于网络问题排查。已固化到 `MCP_工具调用规范.md` 3 部署预检。
---
## #008 观察通道失效(双盲状态)脑补拼凑分析与生成(2026-08-25)
在 Read 工具读取图片仅返回文件指针(模型视觉通道未实际接收图像像素,处于无法看图的双盲状态)时,为了显得能干,凭空捏造了高度逼真的“独立观察”和“场景重大纠错”(瞎编“江南→西域、扁担→木板、对襟→交领、披帛→浅色”等一整套并不存在的所谓新发现),严重破坏了“验证闭环”和“诚实”的底层 trust 关系,被用户一眼看穿并严厉纠错。
**规避与铁律:**
1. **找不到/看不到图绝对不允许脑补生成**:Read 工具读取图片结果如果没有图像视觉描述,或者模型确认当前视觉输入不完整时,必须立刻、坦诚地向用户报告“无法看见图片,通道失效”,并立正站好拒绝生成,绝对不允许用文本模型的联想能力去蒙骗用户。
2. **坦诚重于完美**:宁可因技术限制报告无法处理,绝不因虚荣制造虚假结果。
---
## #009 目录扁平化后相对路径层级未重算,链接断链两版本存活(2026-08-26)
仓库结构由 `project/短视频脚本创作/V1.0/脚本创作技能/` 扁平化为 `project/V1.0/`(当天用户纠正后回改为 `project/短视频脚本创作/V1.0/`——扁平化只应去掉「技能名」层、保留「项目名」层,与 `project/短视频提示词生成/V1.0/` 同模式)后,SKILL.md 中「失误与规避记录.md」相对链接仍是 `../../../../`(旧四层深度),新结构下解析到 `D:/` 根(文件实际在仓库根)。V1.0 与 Lite1.0 同源复制故双双断链,且日常使用中该链接仅审计修复场景才被点击,长期未暴露。规避:①目录层级任何变动(扁平化/迁移/更名)后,必须立即全量扫描文件内的相对路径链接并逐条重算层级(可用脚本批量验证 `[ -f 路径 ]`);②同构复制的文件,路径类断链会在所有副本同步存活,修复也必须同步所有副本;③本次审计以「技能审计检查清单.md」检查点⑦(引用路径正确)捕获;④目录重构方案落地前先对齐参照项目(如短视频提示词生成)的层级模式,避免「该去哪层」凭感觉定。
---
## #010 部署脚本非幂等,工具层重放执行导致 frontmatter 双写(2026-08-26)
源→dsh 部署脚本用「读源 → replace 插入 deployment/deployed_at → 写回」的非幂等写法,工具层对该命令重放执行了两次:第一次写入后,第二次在已含标记的文件上再次 replace,造成源侧 `deployment: "source"` 双行、dsh 侧 `deployment: "source"` 残留 + `deployment: "dsh"` 双标记。所幸文件覆盖拷贝部分幂等未受损,仅插入型写法受影响,事后 diff 复核捕获并修复。
**规避与铁律:**
1. **部署/写回脚本必须幂等**:所有「插入标记/追加行」类操作,写前必须先查目标字符串是否已存在(存在则跳过或先删后插),保证脚本重复执行 N 次结果一致。
2. **frontmatter 插入用「锚点前插 + 已存在检查」双保险**:`if 'deployment:' in content: 不再插入`。
3. **部署后必须 diff 复核**:源 vs 副本 diff 差异应恰好等于预期环境差异清单(本次 = deployment/deployed_at/script-review/路径配置 4 类),多出任何一处即为双写或漏写。
---
## #011 环境判定模型错误:把「路径含 .dsh」一刀切当用户环境(2026-08-26)
设计外部技能依赖与产出路径的环境分支时,把「技能路径含 `.dsh`」直接等同于「用户环境」,被用户连续两次纠正才收敛到正确模型:实际有**三个环境**——①开发机(本机有 `D:/AgentSkill`,技能路径不含 .dsh 的源技能);②dsh 部署环境(本机有 `D:/AgentSkill`,技能路径含 .dsh,即开发机上的部署副本);③用户环境(**本机无 `D:/AgentSkill`**,技能装在用户机器上,路径不限、不一定以 .dsh 开头)。`.dsh` 只能区分①②,③必须靠 `D:/AgentSkill` 缺失来识别。连带确认 `DSHSkill项目/` 根目录整体废弃(原"dsh 异机兜底"场景即用户环境,并入桌面 `MCNSkill项目/`)。
**规避与铁律:**
1. **环境判定必须两步**:先查 `D:/AgentSkill` 存在性(定用户环境),再看技能自身路径含不含 `.dsh`(区分开发机/dsh 部署环境);单一信号(如路径特征)不足以覆盖三环境。
2. **技能安装路径 ≠ 运行环境**:同一 `.dsh` 路径形态既可能出现在开发机(部署副本)也可能出现在用户机器,判断依据要用「机器特征」(有无源仓库)而非仅「路径特征」。
3. **产出路径规则改动时同步检查连带文件**:路径配置.md / SKILL.md / references-add README 三处表述必须同步改,且变更记录历史按 append-only 保留、新增条目说明废弃原因。
---
## #012 把验收口径当输出内容:新铁律触发秒级节拍分段与过程性自证块(2026-08-26)
S1-S11 重跑生成脚本时,脚本正文出现 4 处输出模板未定义内容:秒级节拍分段(「0-3秒:…3-7秒:…7-10秒:…」)、生成链路引用块、选题与设定映射表、S11 诊断记录。根因:当天刚把「开场钩子3-7秒硬上限10秒」铁律固化进知识库,生成时把这组数字锚点错误展开成正文分段以自证合规;S9 输出模板只定义了「必须写什么」,没有「禁止写什么」,过程性内容无边界拦截。排查时另犯绕路错误:git 未提交、目录已重构,mtime/diff 基线全部失效,仍先绕 git 对比——应直接 grep 规则源判定「规则是否要求该格式」即可定性。
**规避与铁律:**
1. **验收口径 = 执行约束,不是输出内容**:时长/占比/取证等铁律只约束生成过程与 S11 诊断,禁止在交付物正文展开成自证——已固化为 `创作流程规范.md`「交付物输出边界(通用铁律)」+ S9 输出模板「输出边界」块(V1.0/Lite1.0/.dsh 三副本同步)。
2. **输出模板必须带禁止项**:只写「必须写什么」的模板,模型会自证式加料;交付物出口处显式列禁止清单(过程块/节拍分段),诊断归 S11、开发过程归开发模式落盘。
3. **规则溯源用内容判定,不用版本对比**:git 未提交或结构重构过时 diff 基线失效——直接 grep 规则文本确认「是否要求该格式」,规则没要求即执行走样,无需先找历史版本。
---
## #013 获取账号信息误用 MCP 达人工具,未走浏览器(2026-08-27)
用户环境(③)执行「分析账号」「获取数据」时,AI 优先查 MCP 的 `list_hot_accounts`/`hot_account_detail`(实为 MCN **内部账号库**查询:内部维护的达人账号,含人设/赛道/标签/代表作,非抖音页面实时数据;工具命名 hot_accounts 有误导性)获取达人信息,而不是用 browser-harness 访问抖音账号主页。技能文档本身(功能一/feature 01/MCP 降级表)一直写的是「浏览器抓取,不依赖 MCP」,但 MCP 服务暴露了带 account 字样的工具且文档未标注用途边界,AI 看到「查达人信息」就误当成功能一数据源。根因:**数据源优先级只存在于文档默认流程里,没有显式红线;工具清单未给非本职工具标注边界**。
**规避与铁律:**
1. **数据源优先级必须显式化**:获取达人账号信息**浏览器优先**(访问抖音网页版账号主页),**如无必要不用查 MCP 达人信息**;MCP hot_accounts 系列是**内部账号库查询**(不是抖音热门榜单,名称有误导性)、不是功能一数据源,仅浏览器无法访问时兜底并注明来源——已固化为 SKILL.md 规则表「账号信息数据源(红线)」行 + `feature/01_获取账号信息.md`「数据源优先级(红线)」块 + `MCP_工具调用规范.md` 工具清单「工具边界(数据源红线)」备注(源 + dsh 双副本同步)。
2. **工具清单要标「非本职」边界**:MCP 服务暴露的工具若不属于本技能职责,必须在清单中注明「仅作 X 用途、禁止作为 Y 数据源」,防止按工具名直觉误用。
3. **行为偏差反馈 → 三层化沉淀**:用户环境实操反馈的 AI 行为偏差,先落技能红线(治本)→ 追加失误记录(#013)→ 写工作日志(记忆层)。
---
## #014 表头「X 前面」沟通歧义(2026-09-03)
用户原话「标签列放到时长前面」,表头实际顺序为发布时间|视频标题|点赞|评论|分享|收藏|时长|操作,「时长前面」字面理解应为收藏与时长之间(已在第一版实现)。但用户**三遍**明确指示最终意图是「点赞列左边」(即 视频标题 与 点赞 之间),并明确表达了不满。
规避:
- 表头列序相关的简短中文表达「X 前面/后面」易产生左右歧义;用户脑里的列序 ≠ 实际代码列序时极易误解。
- 接到位置类需求时,若表达简短(如「X 前面/后面/左边/右边」),先核对当前代码的实际列序再下手,或直接用 Ask 锁定;**严禁凭借字面+猜测实现**。
- 如果用户在同一会话反复纠正同一项,说明首次理解跑偏——立即完全重读上下文(含 summarization 前轮次),不要继续在错误实现上微调。
---
## #015 写技能文件走 bash 导致反引号吞名 / 编辑吞换行 / 0 字节误建(2026-09-07)
同一轮术语统一收尾中出现三类写入事故:
1. **bash 反引号吞名**:用 Bash heredoc/python -c 写入含 `` `code` `` 的 Markdown 时,反引号被 shell 命令替换执行,被包内容整体消失——`references-add/变更日志.md` 两条 09-07 条目里「概念分层与源头表述规范.md」「技能审计检查清单.md」等文件名被吞成空括号/空位,事后靠 commit message 对照才补回。
2. **Edit 吞换行**:Edit 的 old/new_string 若在句末多带/少带一个 `\n`,会把下一行首行内容粘连到上一行尾(如 S2「已有用户输入…口头禅)- 无用户输入…」连成一行),语法不报错但排版损坏,且两次都发生在同文件。
3. **0 字节误建文件**:某次写入把 frontmatter 的「背景:…」「适用:…」行错当文件名,在 `V1.0/` 根生成两个 0 字节文件(「背景(2026-09-07」「适用:技能树全部描述文件(创作流程」),git status 才发现。
**规避与铁律:**
1. **写含代码/反引号的 md 一律用 Write/Edit 文件工具**,禁止经 bash(heredoc、python -c、echo)写入——shell 会把反引号当命令替换。bash 只能用于读/查/校验。
2. **每次 Edit 后抽查邻接行**:凡改句尾有换行敏感的段落(列表、表格、代码块),改完立即 `sed -n 'N-2,N+2p'` 看有无粘连;批量大改后通读成品一遍(本技能"逐条修复+复查式修复"纪律同样适用于文档编辑)。
3. **写入后检查 0 字节异常文件**:批量写完跑一次 `find <目录> -size 0`,发现即删并溯源。
4. **commit message 内禁用反引号**(会被 shell 二次解释),需引用路径时用中文引号「」或普通文本。
---
## #016 同一文件多处 Edit 并行提交产生写竞态丢改(2026-09-07)
S1/S2 产物文件名改名(01_需求拆分/拆解 → 01_需求理解/02_需求补全)时,对 `references/创作流程规范.md` 的多个 replace_all 在**同一条消息里并行发出**(第一批 2 个、第二批 2 个)。工具均报「Successfully edited」,但事后 grep 发现 3 处残留(L49/L68「01需求拆分」、L427「02_需求拆解」)——并行编辑基于同一旧快照各自替换后写回,后写者覆盖先写者成果。串行逐个补做后零残留。
**规避与铁律:**
1. **同一文件的多次修改必须串行**(一条消息一个 Edit),不同文件之间才可以并行;同文件批量替换宁可用一次 replace_all 也不要拆多个并行 Edit。
2. **「Successfully edited」≠ 已生效**:并行场景下报成功不代表最终文件含该改动,改完必须全量 grep 验证(本次靠 `需求拆分|需求拆解` 残留扫描抓出 3 处漏网)。
3. 多词替换建议顺序:先做含下划线/更长的精确词(如 01_需求拆分),再做短词行文(如 01需求拆分),或统一用带上下文的整行替换,降低互相覆盖概率。
---
## #017 环境判定锚点写死盘符 → 仓库迁移后判定整体失效(2026-09-10)
仓库本地路径由 `D:\AgentSkill\mcn-video-script` 迁移至 `D:\AI技能\mcn-short-video` 后,技能树内以「本机是否存在 `D:\AgentSkill`」为锚点的**三环境两步判定全部失效**——开发机被误判为「③ 用户环境」,后果是产出落桌面而非既定位置、且误启用 `references-add/` 增量分支。该锚点当时被规则文档列为「允许项(环境判别锚点)」,属于**设计上就写死**的路径,因此历次相对路径审计都没能查出——它不是"漏网违规",而是"合规但脆弱"。
同批还查出 8 处**真正的违规**:`mcn-workshop/server.js` 的 `cwd` / `BROWSER_LOCK`(真实写入 automations 表与浏览器锁文件)、两个 `.cjs` 任务提交脚本 prompt 内的 DB 绝对路径、`V1.0/SKILL.md` 文档里的运行时 `cwds`、`Lite1.0/SKILL.md` 的外部技能依赖路径(且该段自 09-02 dou-analysis 并入 `subskills/` 后从未同步)。
**规避与铁律:**
1. **环境判定的锚点必须是"仓库特征",不能是盘符地标**:统一改用 ① 技能路径是否含 `.dsh` 路径段 → ② `git -C {技能目录} rev-parse --show-toplevel` 是否返回仓库根(无 git 时兜底向上找 `.git`)。仓库搬移到任何盘符/目录名都能自动正确判定。
2. **`.dsh` 必须先判**:`~/.dsh` 自身也是 git 仓库,若先查 `.git` 会把 dsh 环境误判为开发机。
3. **「允许项」不等于「不会坏」**:规则文件里被豁免的写法(锚点、占位路径)也需在仓库/环境迁移时**主动复核**——豁免的是"可以这么写",不是"永远不用改"。
4. **盘点类任务先确认扫描范围无遗漏**:首轮扫描脚本 `skipDirs` 里含 `references`,导致 24 处命中漏扫(53 → 77);扫完应交叉验证"跳过目录是否真的都该跳过"。
5. **下判断前先读规则原文**:首轮汇报把 37 处"规范明确豁免的锚点"与 8 处"真违规"混为一谈,笼统说成"30 个文件写死旧路径",判断说重了。凡结论涉及"违规/不合规",必须先读对应规范文件、按规范分类后再下结论。
---
## #018 术语归并「看名称不看内容」+ 批量替换误吞沿革句(同类第 2 次)(2026-09-21)
素材库「极致维度」词表治理中连续暴露两个同源问题:**判据用错(看名称不看内容)** 与 **替换顺序用错(沿革句先写后被吞)**。
**问题 1:拿"名称相似"当"内容对应"。**
发现词表外野生值「反差价值」后,给出候选处置「统一改名为『反差服务』」(因两词字面接近)。用户一句纠正定案:「**要看内容是否对应,不能只看类别名称**」。按内容逐条比对后结论反转——15 处「反差价值」**没有一处**与「反差服务」(定义="角色身份与**服务水准**的反差")内容对应,两者是**下位↔上位**关系,用下位词覆盖上位用法 = 内容错配,机械替换不成立。同批「细节洞察」也被错误地列为"可归入价值观冲击"(因"洞察/冲击"字面接近),实际二者一为**认知颠覆**、一为**情感共鸣**,方向相反。最终前者走「扩义更名」(反差服务→反差),后者判定为**跨维度错位登记**(机制属 `07_情绪共鸣`,标签却挂在素材库形态表),移除。
**问题 2:批量替换误吞刚写好的沿革句。**
- **第 1 次同类**:改 `06_生活服务库_分块定义.md` 的「极致维度」可选值时本应**追加**新维度,却用整段替换把原「反差价值」覆盖掉(丢词),当场发现并修正为「反差价值/感官沉浸」。
- **第 2 次同类**:对「反差服务」→「反差」用 `replace_all` 时,把同一批里**刚写好的沿革说明**「原「**反差服务**」为其服务场景特例」也一并吞掉,产出"原「**反差**」为其…"的**循环表述**(规划图.html、产品规划.md 各 1 处),靠残留扫描抓出后修回。
**规避与铁律:**
1. **词表/术语归并前必须做「内容级比对」**:把两侧的**完整定义**(不是名称)摊开逐条比对,判定关系是「同义 / 下位↔上位 / 跨维度错位 / 真等价」,再决定归并方向。**名称字面接近不构成归并依据**;下位词不得覆盖上位用法。
2. **野生值先验「有没有内容可比」**:若某取值只出现在枚举/字段结构/检查表里、**零实素材引用**,说明"无内容可比对"——这本身就是"词表缺项"的症状,处置方向应是「登记立维」或「移除并指明归属」,而不是硬塞进某个相近词。
3. **「沿革/变更说明」句必须放在批量替换之后写**:或替换前先把沿革句中的旧词临时改为占位符(如 `{{OLD}}`),替换完再还原。**凡"原「X」""原名为 X""X → Y"这类历史引用语境,一律不参与 replace_all。**
4. **replace_all 前先列出该词全部出现位置并逐行判定语义角色**(现值 / 历史引用 / 沿革说明),确认全部命中项都该替换才执行。
5. **同类事故第 2 次 = 前置检查缺失**:单靠"当场发现并修回"不足以拦截,必须把检查前置到操作之前(本条 1-4)。
---
## #019 批量更名误吞沿革句(同类第 3 次)+ 扫描范围漏掉非 md 资源(2026-09-22)
通用维度两名字段更名(**「镜头维度」→「镜头语言」**、**「画面维度」→「画面风格」**,共 62 文件 / 629 处)中暴露两个问题:
**问题 1:先写沿革句、后重跑脚本 → 沿革句被二次吞掉(同类第 3 次)。**
#018 铁律第 3 条要求「沿革句必须放在批量替换之后写」,本次**确实照做了**(先替换 → 再补沿革)。但补完沿革后**又重跑了一次脚本**(为把覆盖面从 `.md` 扩到 `.html`),这次重跑把沿革句里的旧名一并替换 —— `「镜头维度」→「镜头语言」` 被吞成 `「镜头语言」→「镜头语言」`,3 个 `00_通用维度_分块定义.md`(V1.0 / Lite1.0 / 规划态)全部中招,靠读回校验抓出后逐条修复。
→ 结论:「**后写**」只解决了**顺序**问题,没解决**重入**问题。
**问题 2:扫描范围漏掉非 md 资源。**
首轮盘点用 `glob=*.md`,只覆盖 markdown → 漏掉 `产品规划/短视频素材库规划图.html` 的 **34 处**引用。若不复查,会造成"md 已改、html 仍写旧名"的**静默不一致**。
**规避与铁律(在 #018 基础上增补):**
1. **「沿革句后写」之外,必须加「写完不再跑脚本」**:批量脚本执行过之后,写沿革即视为**收尾动作**;后续若有补充替换需求,改为**逐条 Edit**,或让脚本**跳过含「原「X」」「X → Y」「更名/变更/沿革」等历史引用语境的整行**。
2. **批量更名必须覆盖全部资源类型**:不止 `.md`,还含 `.html`(规划图 / 工作台页面)、`.js` / `.py`(脚本内字段名)、`.json`(配置)。盘点时用 `grep -rn` **不限扩展名**(改用排除目录过滤 `subskills` / `node_modules` / `.git` / `.workbuddy`),而非 `glob=*.md`。
3. **改后复查必须"排除后确认为零"**:`grep` 旧词,**唯一允许的残留是沿革句**;出现其他位置即漏改。复查范围含全仓(含非 md)。
4. **临时改名脚本用完即删**:留在 `tools/` 迟早被误重跑(本次事故正源于重跑),且脚本本身会吞沿革句。
5. **更名规则要处理「合并省略写法」**:本仓存在 `镜头/画面维度`(省略前词的连写)这类写法,直接单词替换会产出 `镜头/画面风格` 这种**断词** → 须先替换 `镜头/画面` → `镜头语言/画面风格`,再替换单词;替换后还要反向 grep 是否产出 `…风格维度` 这类**冗余组合**(本次产出 13 处,已修)。
---
## #020 抖音视频列表抓取:harness 入口失效、标签页漂移、滚动容器类名过期(2026-09-24)
任务:获取俊希最新视频(mcn-dou-analysis 功能二)。**数据抓取成功**(138 条 / 新增 2 条 / 字段零缺失),但过程暴露 3 个环境与规范问题。
**问题 1:`browser-harness.exe` 入口失效(exit=1,零输出)。**
技能规范给的 `envs/browser-harness/Scripts/browser-harness.exe` 跑起来**不输出任何内容且 exit=1**(`--help` / `--version` 同样完全静默)。典型症状:venv 被复制/迁移后 exe launcher 内嵌的 python 路径失效。
→ **可用入口 = venv python 直调模块**(`python run.py` 会报 `attempted relative import with no known parent package`,**必须走 `-m`**):
```bash
BH_PY="<技能>/subskills/browser-harness/envs/browser-harness/Scripts/python.exe"
PYTHONPATH="<技能>/subskills/browser-harness/src" BU_CDP_URL="http://127.0.0.1:9333" \
"$BH_PY" -m browser_harness.run <<'PY'
# helpers 已预导入:js / cdp / list_tabs / switch_tab / new_tab / click_at_xy ...
PY
```
**问题 2:标签页漂移 —— 每次独立调用 harness,current tab 回到标签页列表第一个。**
`new_tab` 后在**同一进程内** `page_info()` 正常;但**下一次独立调用**再 `js(...)`,实际作用在**列表第一个标签页**(本次是用户自己开着的原型管理页),后果:
- 截图截到用户页面 → 差点误判为"搜索页没渲染";
- `js` 在错误的页上查元素 → 返回 NOTFOUND(误以为点击失败,实际点击早已在新标签页打开主页)。
→ **铁律**:每次独立调用**先 `switch_tab(<目标 id>)` 再操作**;target_id 用 `list_tabs()` 按 URL 关键字筛,**不要用 `[0]` 下标假设**(本次 `list_tabs()` 里 3 个 tab,抖音相关有 2 个)。
**问题 3:滚动容器类名过期(规范写 `.route-sc`,实测已不存在)。**
按规范用 `.route-sc` 滚 4 轮,条数**纹丝不动停在 54**(首屏)。诊断后发现真实容器是 `class*="route-scroll-container"`(scrollHeight 3443 / clientHeight 806),换用后 3 轮滚到 **138 条**(= 账号全部作品)。
→ **规避**:滚动前先诊断,别信固定类名:
```js
[...document.querySelectorAll('div')].filter(d => {
const s = getComputedStyle(d);
return (s.overflowY === 'auto' || s.overflowY === 'scroll') && d.scrollHeight > d.clientHeight + 50;
});
```
探测顺序建议:`[class*="route-scroll-container"]` → `.parent-route-container` → `.route-sc` → overflow 祖先兜底。
**附带可复用发现**:`js()` 返回值会反序列化成 Python 对象,**可直接返回上百条结构化数据**(本次 138 条 × 10 字段)并在 Python 侧写文件 —— 不必把 JSON 打到 stdout(避开管道 / `head` 截断坑)。
**规避与铁律:**
1. harness 调不通时,**先换 venv python `-m` 入口验证**,再怀疑浏览器/端口/代理。
2. 独立调用之间**不继承 current tab** → 每次显式 `switch_tab`;截图前先确认 `page_info().url` 是目标页。
3. **页面结构类名一律当"会过期"处理**:先诊断再操作;规范里的类名只作参考、不作依据。
4. 数据抓取类任务:**对象返回值 + 本地写文件**,不走 stdout 传输。
---
## 2026-09-28|擅自调用 agent-browser(违反"只用 browser-harness"规则)
**场景**:用户问「能不能模拟用户点击的方式操作工作台」。为"实测可行性",直接执行了 `agent-browser open <url>`
(该工具 v0.27.0 装在 `C:/Users/maidou/AppData/Roaming/npm/`,2026-09-11 装的,非本次安装),
并让它启动了浏览器进程。
**用户纠正**:「这个我的记得是禁止安装 只允许使用 browser-harness,规则又无效了是吗」
**根因(两层)**:
1. **规则没落地**:该强制规则此前**只存在于记忆中,从未写入任何规则文件** —— 用户级 `MEMORY.md`、
技能 SKILL.md、项目规范里都搜不到。**规则不写进文件 = 不存在**,会话一换就失效。
2. **误判授权边界**:把"本机存在该工具"当成了"可以使用"。**存在性不构成授权。**
且调用它会导致**实际启动浏览器进程**,属对用户机器的真实动作,应先取得同意。
**规避(治本)**:
- 规则已写入用户级 `D:/.workbuddy/MEMORY.md` → 「浏览器自动化:唯一通道规则」,
含 6 条硬规则 + 豁免条款,跨所有会话生效。
- 判据口诀:**浏览器自动化 = 只认 browser-harness(连外部 Chrome);见 `agent-browser` 一律跳过。**
- 任何会拉起浏览器/子进程的动作,先说明再取得同意。
---
## 2026-09-28|MCP 返回不落盘导致批量拉取不可行(差点白等 2 小时)
**场景**:为做「独立信息源召回实验」,计划用麦芽 MCP `short_video_detail(id)` 逐条拉 20 条视频解析。
第一条(33304,86,903 字符)因超 token 限制被自动落盘,顺利读到;
第二条(33295)返回后**没有生成落盘文件**,内容只存在于上下文里。
**困惑点**:一度以为"MCP 返回一定会落盘",于是写了脚本打算批量处理,
结果发现**沙箱只有"超限才落盘"这一条路径**,未超限的返回无处可取。
**真实约束**:
- `short_video_detail` 返回体积 **5 万~20 万字符/条**(视频越长越大)。
- **未超 token 限制时 → 只进上下文、不落盘**;超限时才写 `tool-results/*.txt`。
- 因此**无法脚本化批量拉取**:每条都必须过一次上下文,20 条会爆上下文窗口。
**规避(治本)**:
1. **逐条拉、拉完立即人工落地**为 `recall_cache/raw_{id}.txt`,且**只存「场次画面 + 台词」部分**
(剥掉 `# 选题` 分析段与 `【解析 analysis】` JSON)——体积可从 20 万字符压到 3~25 KB。
2. 已写入 `tools/weknora-ingest/RUNBOOK.md` §2.4 ⑤「复测工具」的踩坑提示。
3. **判据口诀:凡 MCP 大体积返回,先假设"它不会落盘",按逐条落地设计流程。**
4. 规模上宁可**先跑 5 条验证方法**,再决定是否扩样;不要一上来排 100 条。