例外情况不能写成“其他情况另行处理”,而要写成可判定的条件:什么输入、什么上下文、期望脚本做什么、以及无法判定时输出什么。人工经验里大量“看情况”的判断,一旦落到脚本需求,如果不把例外拆成明确的判定条件和兜底动作,脚本上线后就会出现与直觉相反的结果——原本人工处理得好好的页面,被脚本误判、漏判或反复改动。下面从一种常见矛盾现象切入,说明两种解释,以及用哪些证据可以把它们区分开。
假设需求写的是“页面正文少于三百字就标记为待优化”。人工操作时,编辑会看内容类型:产品参数页字数少是正常的,资讯页字数少才是问题。脚本没有这层上下文,把所有少于三百字的页面都标记了,待办列表里塞满本不该动的页面。于是出现一个反直觉结果:脚本完全按需求执行,产出的清单却比人工判断差得多。
这类现象通常有两种解释。第一种是需求描述本身丢失了人工判断依赖的隐含条件,比如内容类型、页面模板、是否为列表页。第二种是需求描述没错,但脚本读取的输入和人工看到的不一致,比如正文提取规则把导航、推荐位也算进字数,或者把动态渲染前后的内容搞混了。两种解释的修复方向完全不同:前者要改需求,后者要改数据提取,先分清是哪一种,才不会在错误的地方反复调整阈值。
能区分解释的证据不是“脚本结果和人工结果差多少”,而是“脚本拿到的输入和人工看到的输入是否一致”。具体做法是抽出一批被脚本误判的页面,把脚本实际读取的字段值打印出来,和人工打开页面看到的内容逐项对照。如果脚本读到的正文字数明显高于人工目测,说明问题在输入提取;如果输入一致、只是判定条件缺了内容类型,说明问题在需求描述。
这个动作的结果会直接决定下一步:输入不一致时,先修提取规则再谈阈值;输入一致时,回到需求文档补条件。跳过这一步直接调阈值,往往是把两类问题混在一起,改完一类,另一类照旧出现。
描述例外情况时,每个例外至少写清四件事,脚本实现和后续验收才有依据:
假设一个需求原本写“正文为空则跳过”,改成“正文提取结果为空、且页面状态码为正常时,输出到待确认清单并记录页面地址;状态码异常时不进入本流程”。这个改动的结果是把“空正文”拆成了两种原因,后续排查时能直接看出是提取失败还是页面本身有问题,下一步动作也随之明确。
脚本上线后,比较改动前后的标记数量变化时要谨慎。标记数下降不等于判断变准了,也可能是触发条件过严导致漏判;标记数上升也不等于覆盖更全,可能是兜底分支把大量正常页面卷了进来。合理的做法是固定一批页面作为对照样本,同时记录脚本判定和人工判定,逐条核对分歧点,看分歧集中在哪类条件上。
比较时还要考虑外部变化:同一批页面在不同时间段的内容和状态可能不同,搜索需求本身也会波动,因此前后的数量差异不能直接归因于脚本改动。要说明结论,至少要让对照样本和判定条件保持一致,把差异落到具体字段上。
人工经验里还有一类例外是事后才想起来的:某个模板只在特定栏目出现,某种内容只在活动期间存在。这类例外很难在需求初稿里穷举,可行的做法是给脚本留一个可维护的例外清单,每次发现新的误判,先判断它属于触发条件缺失还是输入提取问题,再决定是补充条件、调整提取,还是把该情况加入兜底清单。每次补充都记录触发条件和期望动作,例外清单才会随着使用逐渐贴近实际判断,而不是越改越乱。