把人工经验写成脚本需求时,例外情况不能写成“特殊情况特殊处理”,而要写成可判定的条件、可观察的输入和明确的兜底动作。做法是:先选一个你手里的页面或资料,把人工判断过程拆成“正常路径 + 例外条件 + 例外时输出什么”,再让脚本对例外输出标记而不是猜测。这样做的直接结果是:脚本跑完后你能拿到一份例外清单,下一步是逐条决定人工复核、跳过还是补规则,而不是让脚本悄悄替你做决定。
人工经验里最常见的模糊表达是“看起来不合适就跳过”。这句话对人成立,对脚本不成立,因为“看起来”没有输入。把例外写清楚,需要落到三种可观察的东西上:字段是否缺失、值是否落在预期范围外、多个字段之间是否互相矛盾。
假设你手里的资料是一批页面记录,每条包含标题、正文长度、内链数量和更新时间。人工经验说“内容太薄的先不动”,这句话要变成脚本需求,就得先定义“太薄”对应哪个字段、低于多少算例外。例如可以写成:正文长度缺失,或正文长度低于你设定的下限,就归为例外。这个下限是你根据自己数据分布定的,不是通用标准。
动作与结果的关系在这里很直接:如果你把例外条件写成“正文长度缺失”,脚本跑完会给你一份缺失清单;如果你写成“正文长度低于某个值”,脚本给你的是另一份清单。两份清单指向的下一步不同,前者要回去补采集,后者要判断是否值得处理。条件写错,后面的复核全部白做。
很多脚本需求出问题,不是因为漏了例外,而是把两种性质不同的例外混在一个分支里。数据缺失是采集或输入的问题,判断为否是规则本身给出的结论。混在一起,你就无法从输出里看出该修数据还是该改规则。
把这两类分开输出,脚本的可用性会明显不同。一个只输出“异常”的脚本,你拿到结果后还得逐条回去看原始字段;一个把缺失和判断为否分成两列的脚本,你可以先处理缺失,再决定判断为否的那批要不要动。这是把人工经验转成脚本时最容易被省略、却最影响后续效率的一步。
写脚本需求时,人容易直接写动作:“遇到例外就删除”“遇到例外就合并”。更稳妥的写法是先让脚本输出例外的判定依据,动作留到复核之后。原因是:例外条件本身可能写错,如果脚本直接执行动作,你连回退的机会都没有。
可以按这个顺序描述一条例外需求:
假设一条规则是“内链数量低于阈值且正文长度也低于阈值时标记为例外”。脚本按上面的顺序输出后,你会得到一份同时命中两个条件的清单。此时先看这批记录是不是集中在某一类页面;如果集中,说明可能是采集口径问题,下一步该查采集而不是改阈值;如果分散,才考虑调整条件。这个判断依赖脚本输出了命中依据,而不是只给了一个“异常”标记。
例外条件写得对不对,不能靠读需求文档判断,要靠一次小范围试跑。选一小批你熟悉的资料,让脚本按写好的例外条件跑一遍,然后拿输出和你的人工判断对照。对照时重点看两类分歧:脚本标为例外但你人工认为正常,以及你人工认为该例外但脚本没标。
这两类分歧的原因不同。前一类通常说明条件太宽,把正常波动也圈了进去;后一类通常说明条件太窄,或者依赖的字段本身没采到。根据分歧去改条件,比一次性把条件写全更可靠,因为你无法在写需求阶段预判所有边界。
比较试跑结果时要注意:一次改动前后的差异,不能直接归因于规则本身。搜索需求会随季节变化,数据采集口径也可能不同,这些都会让两次结果不一致。判断规则是否有效,要看同一批资料在相同采集口径下的输出,而不是拿不同时间的两份数据直接对比。
例外清单不是终点。每次复核例外时,你实际上是在积累新的判断依据:哪些例外反复出现、哪些条件总是误伤、哪些字段总是缺失。把这些记录整理出来,下一轮写脚本需求时就能把高频例外升级成正式条件,把总是误伤的条件放宽或拆开。
具体动作是:给每条例外记录标注处理结果,比如“补采集”“放宽阈值”“单独人工处理”。积累一段时间后,统计哪类处理结果最多。如果“补采集”占多数,说明问题在上游数据,继续调判断逻辑意义不大;如果“放宽阈值”占多数,说明当前条件设得过紧。这个统计只用于决定下一步改哪里,不用于承诺任何效果或时间。
回到你手里的那份资料:先挑出一条你一直靠人工判断的规则,把它拆成触发条件、输出内容和默认动作三部分,再跑一小批对照。你大概率会发现,真正需要补的不是更多规则,而是把例外写成脚本能读懂的判定条件。