第十七章 试用、检测与可靠性
一、一个能工作的新工具,还不是已经成熟的工具
设想一件新工具第一次完成任务,制造者和使用者都会感到兴奋。这个成功很重要,因为它展示了一种此前尚未实现的可能。但它主要回答了“在这一次条件下做到了什么”,还没有回答换一个对象、换一位操作者、重复使用或者接近边界时会发生什么。
王德生所说封装要经过无数次试用和检测,强调的正是从一次可能到可持续调用之间的距离。可靠性不是从设计者的信念中直接产生,也不是因一次演示被赞赏便成为事实。它需要在差异中形成,而差异又必须有途径进入设计、规程与使用方式的改变。
因此,重复使用至少有两种不同性质。一种只是相同条件下多次出现相同结果,另一种则有意识地使关键条件变化,观察哪些能力能够保持、哪些边界开始显露。前者也能提供信息,却不能被无边界地推广;后者能够扩大理解范围,但仍需说明具体覆盖了什么。
本章研究的不是怎样取得一个绝对可靠的标签,而是怎样形成有条件的可靠性判断。对数学证明系统而言,测试支持使用某种工具;对每一个当前命题而言,仍然需要它自己的成立依据。工具成熟与当前任务验证的区别,将贯穿整个讨论。
二、试用和检测为什么需要分别组织
试用使工具进入实际任务,观察它是否帮助使用者完成真正需要完成的事情。检测则可以针对明确条件,使用相应方法辨认某项结构或功能是否满足要求。两者可以在同一活动中结合,但观察角度不同,不宜彼此代替。
一个工具可能符合设计指标,却不适合预期使用方式;也可能在熟练设计者手中表现顺畅,换成实际使用者以后,关键差异不再容易识别。NASA的系统工程指南区分对既定要求的符合性验证与在预期使用条件中满足用户需要的确认,并要求相应活动考虑实际的人机配合。[R9][R10]
沿着本书的封装理论,这意味着需要同时观察内部承接与外部调用。一个证明模块是否正确处理输入,是一类问题;研究者是否知道哪些输入适用、怎样理解未完成状态,是另一类问题。内部正确与使用适当相互支持,却不能只检查其中一边。
这也解释为什么试用不是正式检测之前的随意玩耍,检测也不是项目末尾才出现的盖章。试用可以暴露指标尚未表达的需要,检测可以把模糊的不稳定拆成可分析问题。两者不断改变彼此,才可能形成真正适合当前任务的封装。
三、零次失败究竟说明了多少
为了看清成功次数的限度,考虑一个明确简化的数学模型。假设每次试验相互独立,条件保持同一统计分布,每次失败概率都是未知常数p,而且失败能够被完整观察。在这组假设下,连续n次都没有失败的概率是(1-p)的n次方。
若采用单侧百分之九十五置信上界的常见构造,观察到零次失败时,上界可以写为p上=1-0.05的(1/n)次方。这来自把零失败事件的概率设为0.05并求解p。它是一种在反复抽样意义下具有相应覆盖性质的上界,不应被说成“真实p有百分之九十五概率位于这里”的未经指定先验的后验结论。
计算可见,n=100时,上界约为0.02951;n=1000时,约为0.002991。零失败并没有给出p=0。样本增加能够在这些假设成立时收紧范围,却不能把有限观察变成绝对无失败证明。大样本时,利用指数函数的局部展开,上界约为2.996/n,常可粗略记成3/n。
这个计算只是说明推理边界,绝不是高铁、医疗设备或任何现实系统的安全认证方案。现实中的独立性、恒定条件和失败可观察性都可能不成立,失败类型及后果也不能被一个二元变量完整表达。忽略这些假设,用大量成功记录计算一个漂亮数字,反而可能形成新的失真。
数学模型的价值在于逼迫我们说清楚借用了什么。它既反对“成功很多次所以永远可靠”,也不要求否定全部经验积累。相同条件下的观察可以支持有范围的判断;条件变化以后,需要研究这种支持是否仍然适用,而不是把过去数字当成没有边界的通行证。
四、相关失败会怎样削弱重复的意义
假设一千次任务都使用同一份错误输入,结果当然可能高度一致。若检查器也依赖同一份输入,它甚至可以一千次报告通过。此时,重复提供的主要信息可能只是整个系统稳定地复制了同一条件,而不是它经受了足够独立的挑战。
相关性也可能来自任务相似。把同一个数学问题换十种措辞,不能简单当成十类不同能力的测试;把同一份材料拆成许多片段,也不自动形成许多独立来源。样本数量是一个事实,独立信息量则需要另外研究。二者不能因为都能写成数字就混为一谈。
对于生成系统,还要考虑运行条件是否保持。模型版本、提示结构、检索来源或验证流程改变以后,过去的成功记录可能只支持旧组合。新的组合不必全部从零评估,但需要说明哪些依据可以继承,哪些部分必须补做检验。版本控制因此不是文书管理的附属工作,而是可靠性判断的一项条件。
这并不意味着只能用完全独立的测试。完全独立在很多任务中并不现实。更有用的是识别重要的共同依赖,并设计能够触及它们的不同检查。某些任务需要换对象,某些需要换表示,某些需要独立确认目标,不能用一种增加次数的方式替代所有差异。
五、边界测试怎样使封装知道自己不能做什么
一个成熟封装不只展示适用范围内的成功,还需要研究接近范围边缘时会怎样。对象规模改变、输入不完整、定义发生歧义、使用者误解返回状态,都可能使原来稳定的能力出现不同表现。边界不是失败后的借口,而应在设计和试用中逐渐被辨认。
以证明工具为设想对象,可以分别输入满足条件的命题、不满足条件的命题、表达不完整的目标,以及工具当前无法处理的问题。期待的并不是每一种都成功证明,而是不同情形得到与其状态相称的响应。不能处理时准确报告,可能比给出貌似完成的文本更能支持整体可靠性。
边界检验也要避免为了通过测试而偷改任务。若某系统无法处理一般情况,可以明确缩小支持范围;这是一种合理的能力说明。但不能在缩小以后仍沿用原先广泛的能力名称,让使用者误以为全部任务已经得到支持。名称、范围和证据需要一起更新。
封装的边界还可以随实践发展。一个原来需要人工核验的子任务,在新方法获得支撑后进入整体调用;另一个曾经稳定的部分因为新用途而重新展开。可靠性不是只增不减的等级,而是与任务、条件及验证安排相关的持续判断。
六、失败为什么必须能够改变设计
一个团队可能拥有很详细的失败日志,却年复一年重复相同问题。日志确实记录了差异,但差异没有改变后续D和E。按本书的观点,这还不能称为充分的发生积累。反复试用之所以支持封装,是因为失败能够进入比较、修订与再次检验。
需要说明反馈改变了什么。一次失效可以引出更明确的条件说明,也可以改变内部结构、检查位置或用户训练。不同措施对应不同原因,不应把所有问题都归为使用者没有阅读说明。若许多使用者在同一处误解,也需要检查界面和任务组织是否正在稳定制造误解。
修改以后还要检查原来的有效部分。一个补丁消除了某类错误,却破坏另一个已经可用的功能,不能仅凭新测试通过就宣称全部改善。NASA的验证指南把修改后的回归检验列为检查已有功能是否受影响的方法之一。[R10] 本书在此借用其基本区分,不把任何有限测试集当成绝对完备的证明。
这使封装形成呈现为不断选择、保留和淘汰的过程。失败不必全部导致重做,成功也不必永久保留。关键是相关价值评估能够进入实际改变,并且改变后的状态不被新的宣传或进度压力提前封死。
七、谁的试用能够代表实际使用
设计者熟悉内部机制,能够自动避开模糊输入,也知道哪些异常无需担心。他的成功试用很有价值,却不能无条件代表所有后来者。一个工具要在不同使用者那里形成封装,需要研究他们实际能够感知什么、理解什么、改变什么。
这不是把使用者当作固定缺陷来源。不同经验与任务可能揭示设计者未曾看到的价值需求。某个看似多余的提示,对新手是理解状态的关键;某个方便专家的默认操作,对另一类任务可能引发条件误用。使用差异因此能够改写工具,而不只是要求使用者适应工具。
研究可以保留不同参与者的任务背景与支持条件,避免把所有成绩压成一个平均数。熟悉工具、理解领域和具备复核资源,是不同因素;一位领域专家也可能刚接触界面,一位工具熟练者也可能不了解命题条件。复合能力的评估应当允许这些区别进入解释。
在本书提出的机制中,使用者侧的可靠调用与技术侧的运行支撑需要同时检查。前者并非后者的心理影子,后者也不能由前者的满意度代替。两侧怎样连接,正是下一章封装在使用者心中发生的重点。
八、什么时候可以开始封装
如果要求一个工具在所有可能任务中永不失败,封装就永远不能形成;如果一次成功便足以封装,可靠性又失去意义。更可行的做法,是先限定任务范围、关键条件和错误处置方式,再判断是否具有足够依据支持相应程度的整体调用。
“足够”不能由一个普遍数字决定。错误容易发现且可以撤回的低影响任务,与缺口可能长期隐藏的高影响任务,需要不同的证据与复核安排。本书不在这里替所有领域设定统一阈值,而要求阈值有可说明的依据,并与当前代价、可逆性和验证能力相称。
可以先形成局部封装。某类格式转换得到支撑,便在这类任务中使用;某类证明检查获得依据,也只承担其相应范围。新的层级通过组合形成以后,还需要检查连接。局部成熟不会自动升级成整个系统全能,但可以为继续发展提供稳定起点。
这样的路径也避免把早期大量人工介入规定为永久状态。随着证据和工具能力变化,检查分配可以调整。研究者不必永远逐行重复已经由适当机制承担的工作,同时仍需保留目标、边界和异常的相应判断。
九、可靠性提高与人的放心不是同一条曲线
即使技术系统确实改善,使用者也可能因为过去经历而仍然频繁担忧;反之,流畅界面与多次顺利体验也可能使人过早放心。封装的使用史因而需要研究证据怎样进入信任,而不只是研究内部指标怎样变化。
适当的反馈不应只强调成功率,还应说明当前支持范围、最近重要变化和无法处理的状态。信息呈现需要与使用者的任务相称,过多无差别警报可以使真正重要的差异被淹没,过少信息又可能形成虚假的整体保证。这里同样需要分层与粒度判断。
用户不必阅读全部测试报告,才能形成有依据的使用。文明积累允许专业检测和可信说明参与能力传递。但这种传递需要保留关键边界,不能只把复杂检验压成一句“放心”。一个成熟的公共封装,应当让普通使用者能够适当调用,同时让必要复核有实际路径。
因此,可靠性的社会发生不是让所有人重复全部工程工作,而是让不同层级的判断彼此承接。个人经验、专业证据、操作安排和异常反馈共同参与,不能把其中任何一项单独提升为全部保证。
十、证明系统为什么仍然要检查当前证明
数学工具的成熟尤其容易被误读为“过去做对很多次,所以现在不必验证”。事实上,过去记录支持的是关于工具表现的条件性判断;当前命题需要的是其推理与前提的成立依据。二者属于相连而不同的任务,不能以一个层级的可靠性取消另一个层级的证据义务。
工具封装成熟以后,改变的是谁怎样承担这些义务。研究者可能不亲自检查每个证明项,而由相应验证机制完成;语义对照和研究目标判断又可以由其他过程承担。个人的阅读减少,与系统的必要验证持续进行,可以同时成立。
也有些数学活动处于探索阶段,暂时只需要生成可能路线。此时可以使用尚未完成的结果,但必须保留其候选身份。可靠系统可以经常找不到证明,只要不把找不到包装成已证明。解决率与完成声明的可信度,是两项不同的能力指标。
由此,可靠性形成不必以消灭所有内部错误尝试为目标。探索可以失败、推导可以被否定,关键是未处理的缺口不能被封装成完成成果传到上层。工具越能够准确报告边界,使用者越有可能形成适当而非盲目的整体调用。
十一、试用历史怎样成为下一轮的起点
反复试用、检测与评估,最终要形成可以继续使用的改变:哪些任务得到支持,哪些条件需要保留,什么异常可以由系统处理,什么情况必须重新展开。这些内容进入结构、规则、说明和实践经验,才使过去的努力不必被后来者完整重演。
本章的数学小模型提醒我们,经验支持带着假设;不同测试方式提醒我们,重复需要差异;失败修订提醒我们,记录必须进入改变;使用研究则提醒我们,系统可靠与使用适当需要彼此连接。它们共同解释封装何以是一项发生过程,而不是一枚静态标签。
可靠性的形成与使用者的放心,应当分别观察又相互连接。前者需要试用、检测和修正的证据,后者还涉及这些证据怎样进入日常预期与行动。当过去的检查开始成为下一次使用的起点,人就可能不再逐项展开全部过程。王德生从2023年逐句查看GPT输出到逐渐整体使用的自述,将使这种使用中的封装获得一个具体入口。