先给结论:不要在原输入规范上打补丁。当工具开始接受新对象格式时,应把输入规范拆成“对象定义、字段映射、校验规则、失败样本”四层,逐层确认哪一层发生了变化,再决定是扩展旧规范还是另建一条并行规范。只改字段名或加一个转换脚本,通常会把格式差异掩盖成数据错误,让后续排查失去方向。
格式变化通常有三种来源,处理方式完全不同。第一种是同一对象的序列化方式变了,例如从分隔符文本换成结构化标记,字段含义没变;第二种是对象本身扩充了维度,例如原来一条记录对应一个页面,现在对应一个页面加一组变体;第三种是工具把原本由使用者保证的约束收归自己处理,例如自动补齐缺失字段。前两种需要改输入规范,第三种往往只需要改校验规则。
可核对的证据是:取一份旧格式样本和一份新格式样本,逐字段列出“名称、含义、是否必填、取值范围”。如果只有名称和嵌套层级不同,属于第一种;如果出现旧格式里根本不存在的字段,属于第二种;如果新格式允许旧格式中必填的字段为空,属于第三种。这个对照表本身就是判断依据,不需要依赖工具文档的措辞。
建议按下面顺序重写,而不是直接编辑原来的字段列表:
一个假设的例子:某工具原本接受每行一条“标题+链接”的纯文本,现在改为接受带层级结构的标记。如果直接把纯文本按行拼成标记,标题中本身含分隔符的行会被错误切分。正确做法是先定义“一条记录”的边界,再决定分隔符是否需要转义。动作是先写对象定义,结果是校验规则里会多出一条“标题内不允许出现未转义分隔符”,下一步才能确定转换脚本要处理哪些字符。
格式变化后最常见的误判,是把内容问题当成格式问题。区分方法是:把同一份失败输入中的字段值替换成明显合法的占位值,再跑一次。如果仍然失败,问题在格式或结构;如果通过,问题在具体内容。
另一种情况是请求量、抓取量或某类记录数突然归零。这不能单独证明输入规范改对了。合理解释至少包括:校验规则过严导致整批被拒、对象粒度变化导致计数口径不同、工具侧对某类格式暂时未处理。要排除这些解释,需要分别用旧格式样本、新格式样本和混合样本各跑一次,比较失败位置是否一致。
两个选择都成立,条件不同。满足以下条件时,扩展旧规范更省事:新旧格式描述的是同一粒度对象;旧字段能一一映射到新字段;下游消费方不需要同时处理两种格式。满足以下条件时,应另建并行规范:对象粒度发生变化;存在旧格式中完全没有的必填字段;或者新旧格式需要在一段时间内共存,且下游无法自行判断版本。
并行规范的关键是让输入方能够自描述版本,例如在输入开头放一个版本标识,而不是靠字段是否存在来猜测。动作是先在规范里固定版本标识的位置和取值,结果是校验规则可以先判断版本再套用对应字段表,避免把两种格式的字段混在一张表里。如果暂时无法加入版本标识,退而求其次的做法是为两种格式分别保留失败样本,并在交付说明中写明“按样本判断,不按字段名判断”。
输入规范不是孤立文档。改完后要同步:给输入方的填写说明,重点写清哪些字段不再由输入方负责;内部校验脚本的规则表,确保规则与规范中的“校验规则”一节逐条对应;以及失败样本库,把本次格式变化中新出现的失败案例补进去。这三件事没有同步,格式变化就会以“偶发失败”的形式反复出现,而排查者只能从零开始猜。
如果工具是外部提供的,其对象格式、字段约束和版本策略属于可能随时调整的信息,应以该工具当前公开的说明为准,并在接入前用一份最小样本验证,不要仅凭旧文档推断现行行为。