把“文档”当成接口,而不是当成交付物,是这类合作能继续推进的前提。供应商负责定义字段、状态和边界条件,你的团队负责按文档实现并反馈偏差;如果文档里没有可验证的输入输出约定,接口就没有真正建立,后续规模化时必然出现例外。
小样本阶段,供应商给一份字段说明,你的开发照着做,通常能跑通。样本一多就出现例外,往往有两种解释。第一种是文档确实描述了接口,但描述的是理想路径,没有写清异常输入、缺省值和顺序依赖;第二种是文档只覆盖了供应商自己那一段,跨系统的那一段被默认为“你们自己看着办”。前者是接口设计不完整,后者是责任边界被悄悄挪走。
这两种解释对应的处理方式完全不同。如果是前者,补的是约束条件;如果是后者,需要重新谈谁对端到端结果负责。判断依据不是文档厚不厚,而是文档里有没有出现“当……时,返回……”这样的条件句,以及这些条件句是否覆盖了你实际遇到的那批例外样本。
拿最近出现例外的三到五个样本,逐个对照文档,看例外落在哪个位置:
如果例外集中在第一、二、四类,说明供应商的文档能力可以继续用,你只需要推动它把隐含假设写出来。如果例外反复落在第三类,说明当前分工下接口不可能靠文档补全,必须调整责任划分,否则每加一个样本就多一次扯皮。
不管责任怎么分,接口本身要能被执行。一个可用的最小约定包含四件事:输入、输出、失败时的行为、以及谁在什么时候确认。假设一个场景:供应商提供内容字段规范,你的团队负责入库和展示。文档只写了标题、正文、作者三个字段,但实际数据里作者可能为空。
这时接口约定应该写成:输入为标题(非空)、正文(非空)、作者(可为空);输出为入库成功或失败;作者为空时,展示层使用“未署名”作为占位,而不是丢弃整条记录;双方在联调时各跑一遍含空作者的样本,确认结果一致。这个约定里,“作者为空时用占位而不是丢弃”就是一个可执行的动作,它的结果直接决定下一步:如果双方跑出的结果一致,说明接口可以进入批量验证;如果不一致,说明还有隐含假设没写出来,需要继续补约定,而不是直接扩大样本量。
这个例子的数字和字段名都是假设,用来演示怎么把一句模糊的“作者可能为空”变成可判定的行为。实际字段以你们自己的数据结构为准。
文档接口在小样本下成立,不代表在规模化后成立。原因是样本量一大,罕见组合就会出现,而文档通常只覆盖常见路径。可以在正式放量前做一次边界测试:从历史数据里挑出字段缺失、格式异常、顺序颠倒的样本,各取少量,按接口约定跑一遍,记录哪些样本触发了未定义行为。
测试结果的处理方式取决于前面判断出的问题层级。如果是接口设计不完整,补完约定后重跑同一批样本,看未定义行为是否消失。如果是责任转移,补文档解决不了问题,需要先明确中间环节由谁实现,再谈接口细节。这一步的动作是“用异常样本验证约定”,它的结果是决定继续扩大合作范围,还是先停在当前规模把责任和约定理清。
如果供应商只交文档,你可以要求文档至少包含以下三类内容,缺哪一类就说明哪一类还没有接口:
这三类内容不要求写成正式规范,但要求能被双方独立执行。执行结果不一致时,以文档里写明的判定条件为准,而不是以哪一方解释得更合理为准。
回到最初的问题:供应商只交文档不实施时,双方接口的设计重点不是把文档写得更长,而是把文档变成可判定的约定,并明确中间环节的责任方。先用手上的例外样本判断问题出在接口设计还是责任转移,再决定是补约定还是调分工,最后用异常样本验证约定是否真的可执行。这个顺序能避免在小样本成立时就盲目扩大合作范围。