直接回答:不要只写“遇到例外人工处理”,而要把例外写成可判定的条件、可观察的信号和明确的兜底动作。以你手里一份已经人工改过的页面清单为对象,先标出哪些页面是标准情况、哪些是人工干预过的例外,再把例外归成三类:数据缺失、规则冲突、结果不可逆。每一类都给出触发条件、脚本应采取的动作、以及动作之后由谁复核。这样脚本需求才能被开发或自动化工具准确执行,而不是把人工经验压缩成一句模糊的“特殊情况特殊处理”。
假设你手上有 200 个页面,其中 180 个按统一规则改了标题和描述,另外 20 个是人工单独判断的。这 20 个就是例外的来源。把它们逐条打开,记录三列:页面标识、人工当时做了什么、为什么没走统一规则。原因通常集中在几处:页面本身是聚合页,标题模板会重复;页面是旧内容但仍有流量,改标题可能影响已稳定的展示;页面缺少可用的主关键词数据,无法套用替换逻辑。
这一步的实际动作是:把 20 个页面按“原因”分组,而不是按“页面类型”分组。分组之后你会发现,真正需要脚本单独处理的可能只有 5 到 8 种情况,其余只是同一条件的不同表现。下一步是给每种情况写一条判定语句,例如“若页面标题与同目录下另一个页面标题相似度超过阈值,则跳过自动改写并标记待复核”。这里的阈值需要你根据人工判断时实际使用的标准来定,不能凭空设一个数字。
脚本需求里最容易出问题的是只描述“要做什么”,不描述“什么情况下不做”。对每一个例外,至少写清三层:触发条件、可观察信号、兜底动作。触发条件回答“什么情况算例外”;可观察信号回答“脚本怎么知道它遇到了这个情况”,例如字段为空、两个值冲突、目标页面返回状态异常;兜底动作回答“遇到之后是跳过、记录、还是用保守值继续”。
写完这三层后,拿其中一条去问执行脚本的人或工具:如果只给这句话,能不能判断出该跳过还是该继续?如果对方需要再问你一次,说明条件还不够具体。这个动作的结果会直接影响下一步:条件越明确,后续复核清单就越短;条件越模糊,复核负担就越重,脚本也就越难真正替代人工。
把人工经验转成脚本时,常见两种做法。第一种是统一规则优先,例外全部走人工队列;第二种是例外优先,先给每条例外写专门分支,再处理标准页面。两种做法都成立,但适用条件不同。
如果例外数量少、且每条例外差异很大,统一规则优先更划算。代价是人工队列会保留一部分重复劳动,但脚本结构简单,出错时容易定位。如果例外数量多、但例外之间能归成少数几类,例外优先更划算。代价是脚本分支变多,每次新增一类例外都要改需求,维护成本上升。判断依据不是例外总数,而是例外能否被稳定归类。你可以先尝试把 20 条例外归成不超过 5 类;如果归并后每类仍有大量互不相同的判断,说明还没到适合脚本化的程度。
假设某页面标题为空,同时该页面属于旧内容且近期仍有访问。人工经验可能是“标题为空就补一个,但旧页面不要动”。写成脚本需求时,可以这样描述:当标题字段为空且页面被标记为旧内容时,脚本不写入新标题,只生成一条待复核记录,记录中附带当前标题、建议标题和页面标识;当标题字段为空且页面未被标记为旧内容时,脚本写入建议标题并记录变更。
这条描述里,“标题为空”是可观察信号,“旧内容标记”是触发条件,“不写入、只记录”是兜底动作。验证方法是:把这条需求交给另一个人,让他判断两个页面分别会走哪个分支。如果两人判断一致,说明描述可执行;如果出现分歧,就回到条件层补充定义。这个动作的结果决定了下一步是继续扩大脚本覆盖范围,还是先补充页面标记数据。
脚本执行后,不要只用“处理了多少页面”来判断对错。要保留每条例外被跳过或写入的原因。原因记录至少包含:页面标识、命中的例外类型、脚本动作、执行时间。这样当结果不符合预期时,你能区分是条件写错了、信号判断错了,还是页面本身发生了变化。
另外,比较改动前后时,要考虑季节、搜索需求变化和数据采集差异。某段时间某项数据下降,不一定由这次脚本处理引起;同样,数据上升也不能单独证明例外描述写对了。把例外记录和改动记录放在一起看,才能判断下一步是调整条件、补充数据,还是把某类例外重新交回人工。整个流程的终点不是脚本跑通一次,而是例外描述足够稳定,让后续同类页面可以直接复用这套判断。