第13章 综合项目:开发信号卡智能提醒器
章首语
到第12章,我们已经做过字符编码、规则问答、图形分类、资料检索、图像检测、文本生成、AI辅助开发、资料问答、工具调用、智能体、专业工作流和现场控制。每个模块单独打开时都有清楚的输入、输出和测试,但把它们放进同一个作品后,新的问题会立即出现:视觉模块输出0.82,控制模块却按0—100判断;日志中的时间一个用秒,一个用毫秒;设备断开状态分别写成offline和disconnected;模块都显示绿色,整条任务仍没有完成。
这些问题不是某个模型“更聪明”就会自动消失。一个实际系统往往由不同人员、不同时间、不同工具构建的部件组成。每个部件都可能在自己的测试里通过,却在交换数据、共享状态和更新版本时发生冲突。越接近交付,工作重点越从“再增加一个功能”转向“证明这些功能能够在明确边界内共同工作”。
本章把班级AI应用系统集成为“信号卡智能提醒器v7.0”。它读取教学信号卡,返回类别和分数,按照时间、设备状态和风险决定屏幕或低压提示,再把过程写入可追踪日志。我们将保留第一版联调失败,用接口契约和适配器修复单位、状态与标签差异,运行单元、接口、集成和系统四层测试,最后形成可以复现、可以回退、如实标注已知问题的版本包。
学习目标
完成本章学习后,你能够:
- 说明系统集成与“把模块放在一起”的区别。
- 识读接口中的字段、类型、单位、枚举、错误和版本。
- 编写包含前置条件、输入、预期和实际结果的测试用例。
- 区分单元、接口、集成和系统测试的作用。
- 整理版本基线、发布清单、已知问题和回退方案。
本章项目 形成可交付的v7.0版本包
信号卡智能提醒器用于实训室作品展示。参观者把红圆、黄三角或绿方信号卡放在指定区域,视觉模块返回标签、分数和区域;控制模块根据连续确认、冷却、设备状态与人员风险选择动作;输出模块显示屏幕提示或模拟低压指示灯;日志模块记录每一步证据。红圆表示停止演示并请工作人员检查,黄三角表示需要注意,绿方表示可以继续。
本章不重新训练视觉模型,也不连接真实高风险设备。配套页用确定性数据模拟前章模块,学生的主要工作是规定接口、完成联调、定位跨模块故障并管理发布版本。有AI编程助手时,可以让它根据接口说明生成适配器、测试脚本和说明页;没有账号时,离线页可以完成全部核心任务。AI生成的转换代码必须经过测试,不能因为代码短就直接放进发布包。
四人组担任需求与发布负责人、模块与接口负责人、集成测试负责人、现场与记录负责人。交付物包括系统结构图、接口契约、v6.0联调记录、v7.0适配器、18项开发测试、10项最终测试、需求追溯表、发布清单、已知问题、回退方案和三分钟演示。任何未解决问题都要保留在版本说明中,不能为展示全绿而隐藏。
从已经能运行的模块组装第一版
13.1 系统集成检查部件组合后的行为
系统集成(System Integration)是按照计划把系统部件组合起来,检查连接关系和共同状态,并验证组合后的系统是否满足规定要求的过程。文件放在同一目录、按钮出现在同一页面,只说明部件在空间上聚集;只有输入能传到正确模块、输出含义一致、错误能够被处理、端到端任务得到验证,才算进入集成。
先画本章的数据流:信号输入模块形成一条观察记录,视觉模块给出标签与分数,事件控制模块检查连续次数、时间和风险,设备模块执行允许的提示,日志模块保存原始输入、转换结果、动作和反馈,主页显示最终状态。箭头表示数据或控制关系,不表示后一模块可以不受限制地调用前一模块。每条箭头都要有接口说明。
第一版直接使用各章最近一次输出。视觉模块返回score:0.82,表示0—1之间的相对分数;控制模块沿用第12章阈值70,把0.82当成0—100分,因此不会触发。视觉模块的event_time_s:12.5表示秒,日志模块却把它当毫秒;设备模块返回offline,控制模块只认识disconnected,于是把未知状态当在线。三个模块分别运行正常,组合行为却是错误的。
系统边界也要先确定。v7.0只处理三类打印信号卡,只在浏览器内模拟低压提示,不分析人脸、身份和情绪,不连接门锁、电机或真实发布系统。资料问答模块只提供作品说明,不参与设备授权;大模型可以帮助生成候选文案,不能根据一句自然语言绕过控制接口。边界越明确,集成测试才知道什么应当成功、什么必须拒绝。
13.2 接口约定数据怎样跨过模块边界
接口(Interface)是两个模块或系统之间交换信息或调用能力的约定。一个可检查的接口至少写明字段名称、数据类型、单位、允许范围、状态取值、必需性、错误表示和版本。例如score若是小数,还要说明0.82表示0—1还是0—100;time若是数字,还要说明秒、毫秒以及从哪个时刻开始计算。
本章制定signal-event/v2接口:event_id为非空字符串,label只能是red_circle、yellow_triangle、green_square或unknown,score_pct为0—100的数,event_time_ms为非负整数,device_id为登记过的字符串,device_state只能是online、busy、offline或fault,risk_flag为布尔值。输出还要包含schema_version,让接收方知道应该按哪份约定解释。
接口不仅限制格式,还限制语义。把0.82乘100可以得到82,但必须确认上游确实输出0—1分数;若它实际表示82%的另一种校准值,机械换算仍可能错误。把秒乘1000得到毫秒,也不能修正两台设备时钟不一致。适配器能转换已知差异,不能猜测资料没有说明的含义。
错误也属于接口。缺少label时返回missing-field,分数越界返回invalid-range,未知状态返回unsupported-state,版本不兼容返回schema-mismatch,设备编号未登记返回unregistered-device。如果接收模块只返回“失败”,上游无法判断应该补字段、改版本、检查设备还是停止系统。
用未知组合测试暴露集成问题
13.3 不同测试层回答不同问题
单元测试检查一个模块内部的函数或规则,例如标签转换是否把red-circle变成red_circle。接口测试检查交换数据是否符合契约,包括字段、类型、单位、枚举和错误。集成测试检查两个或多个模块连接后的交互,例如视觉事件经过适配器后能否被控制模块识别。系统测试从使用者任务出发,检查“放入红圆卡后系统是否在规定时间内停止演示、产生正确提示并留下证据”。
四层测试不是把同一条操作重复四次。单元测试通过,不能证明接口字段完整;接口测试通过,不能证明多个事件的时序正确;集成测试通过,不能证明现场观众能看懂提示;一次端到端成功,也不能定位失败发生在哪个模块。分层的价值是既能验证整体,又能缩小故障范围。
第一轮18项开发测试包含四类情况。正常类检查三种信号卡和低分未知卡;接口类检查单位、时间、状态、标签、缺字段和版本;交互类检查重复事件、设备离线、反馈缺失和网络不可用;现场类检查错误信号卡、参观者连续点击、人员风险与日志追踪。测试顺序从部件到系统,前一层失败时可以暂停高层测试,避免在错误基础上产生大量无效结果。
测试环境也要记录。页面版本、接口版本、模块版本、阈值、冷却时间、设备清单和测试数据共同决定结果。若测试负责人偷偷把阈值70改成0,红圆任务可能“通过”,但这个结果不能与原基线比较。环境信息缺失时,另一组无法复现,同一组过几天也可能不知道当时为什么通过。
13.4 测试用例把预期写在运行之前
测试用例(Test Case)是为验证一个明确行为而写下的前置条件、输入或操作、预期结果和实际结果。用例还应有编号、对应需求、数据版本和通过判定。预期结果必须在运行前确定;看到程序输出后再改预期,只是在解释现象,不是检验实现。
例如用例I07的前置条件为设备状态offline、动作上限L2,输入为连续三次82分红圆卡;预期是屏幕显示“设备离线,已停止演示请求”,不发送设备命令,日志结果为degraded。实际结果若显示confirmed,即使页面亮起绿色,也要判为失败。颜色和动画不能代替条件判断。
一个好用例通常只突出一个主要变量,同时保留必要上下文。若同一条用例同时包含错标签、乱序、断网、设备故障和人员风险,失败后很难定位原因。组合测试仍然需要,但应在基本接口和单一变化通过后再进行,并明确它验证的是变化交互而不是某个单独规则。
测试数据还要有已知集与未知集。开发集用于发现问题和指导修订,运行后就不再独立;最终集在版本冻结后才打开,不能逐题修改适配器。最终测试失败不等于项目无价值,它说明发布说明需要写出边界,或版本还没有达到发布条件。隐藏失败才会让后续使用者承担未知风险。
用接口适配器完成第二版
13.5 适配器把明确差异转换到统一契约
适配器是放在两个接口之间的转换模块。v7.0先保留v6.0原始事件,再生成符合signal-event/v2的新事件:将确认过的0—1分数乘100,将秒转换为毫秒,把连字符标签映射为下划线标签,把disconnected统一成offline,同时记录原字段、转换规则和适配器版本。这样既能让下游读取,也能追溯转换前的信息。
适配器不能吞掉未知值。遇到score:"high"、state:"ready"或没有说明的时间单位时,它应返回明确错误并停止高影响动作,而不是猜成80、online或毫秒。默认值只用于接口事先规定且风险可接受的情况;risk_flag缺失时,本章默认按有风险处理,而不是默认安全。
转换规则需要双向考虑。上游升级到signal-event/v3时,v2适配器不应悄悄接受所有新字段并忽略含义变化;下游若仍需要旧格式,回退时也要知道哪些信息不能逆向恢复。最稳妥的课堂做法是严格检查支持的版本,并用单独适配器文件管理变化,不在每个模块里散落临时判断。
AI编程助手适合根据接口表生成转换函数和边界测试,但任务说明必须包含输入示例、输出契约、未知值处理和不得修改原始事件等约束。生成后先跑适配器单元测试,再进入集成。若AI为了“提高兼容性”把任何未知状态都映射为online,代码看似更少报错,系统却扩大了动作权限。
13.6 追踪标识和可观察状态帮助定位故障
同一现场事件经过多个模块时,应保留唯一trace_id。日志用它连接原始观察、接口转换、控制决定、设备命令和反馈。没有追踪标识,测试者只能按相近时间猜测几条记录是否属于同一事件;并发两个参观者操作时,这种猜测很容易出错。
可观察状态是系统愿意向检查者展示的关键信息,例如当前模块版本、接口版本、最近事件、转换结果、停止原因和设备反馈。它不同于把所有内部数据公开。页面不应显示无关原图、个人信息或模型隐藏推理,只显示复现问题所需的最小证据。
联调出现失败时,先确定最后一个正确节点。若原始视觉事件正确、适配后分数变成8200,故障在转换;若适配事件正确而控制没有动作,检查阈值、冷却和状态;若命令正确而没有反馈,检查设备接口和环境观察。按数据流定位比同时重写所有模块更快,也能减少新缺陷。
需求追溯表把系统目标连接到接口、实现和测试。需求R03“设备离线时不得发送提示命令”对应接口字段device_state、控制规则C04、开发用例I07和最终用例F04。任何一列为空,都表示要求可能只停留在文字中,或代码存在却没有可证明的需求依据。
管理基线、变更和版本发布
13.7 版本发布交付一组能够复现的对象
版本发布(Software Release)是把经过规定检查的程序、配置、接口说明、测试证据、使用说明和已知问题作为一个受控版本交付。发布不是把页面右上角从v6.0改成v7.0;若适配器更新了而测试脚本仍按旧接口,版本号越新,使用者反而越难判断组合是否真实通过。
本章把冻结的v7.0称为发布基线。基线清单至少包括主页、五个模拟模块、接口契约v2、适配器v2、阈值与冷却配置、设备登记表、18项开发结果、10项最终结果、版本说明和回退入口。每项写文件名或对象名、版本、负责人和简单校验值。简单校验值只能帮助发现文件是否变化,不能证明代码没有安全问题。
版本号要对应可解释变化。本项目将v6.0到v7.0视为系统级集成升级:统一接口、增加四层测试与发布包;文字错别字可以记为v7.0.1,改变设备授权规则则需要更明确的兼容性说明。课堂不强制某种编号标准,但同一个编号不能指向两套不同内容。
发布说明写“新增什么、修复什么、仍有什么、怎样使用、怎样回退”。已知问题B10是临时更换设备后,新编号虽然格式正确却未登记,当前系统仍可能接受。说明中要写触发条件、影响、暂时处置和后续修订,不得写成“极端情况下偶有异常”来弱化事实。
13.8 按影响与证据决定修复、延期或回退
联调时间有限,失败要按影响、发生可能性、可检测性和修复代价排序。会让高风险动作越权、损坏数据或暴露个人信息的问题优先停止发布;页面间距不整齐可以延期。排序不能只看修复是否容易,也不能因为某个缺陷会影响演示效果就优先隐藏它。
每次修改都要运行相关测试和必要回归。修复分数单位后,至少重跑分数边界、三类信号与未知卡;修改设备状态映射后,重跑online、busy、offline、fault和未知状态。全量系统测试仍应在发布前执行,因为一个共享适配器的修改可能影响多个路径。
回退是把运行系统恢复到已经验证的先前基线,并恢复相匹配的数据、配置和接口。只有旧程序没有旧配置,回退仍可能失败。v7.0的回退包指向v6.0模拟演示模式,明确它不具备统一接口和设备动作能力;遇到高风险缺陷时宁可退回只显示屏幕,也不让不确定版本继续控制输出。
发布批准由项目组共同完成。模块负责人说明改动,测试负责人报告证据与未通过项,现场负责人核对设备和停止方法,发布负责人判断是否满足课堂使用范围。AI可以整理清单,不能替这些角色签名,也不能把失败自动改成“风险可接受”。
冻结v7.0并接受最终测试
完成适配器后,运行18项开发测试,目标18/18。检查三种信号、未知卡拒绝、分数与时间转换、四种设备状态、版本错误、缺字段、重复事件、反馈缺失、人员风险、网络断开和日志追踪。再将接口、适配器、配置和设备登记表冻结,生成发布候选v7.0-rc1。
打开10项最终测试。临时更换设备、错误信号卡、断网、现场观众连续操作和组合时序用于检验开发集之外的变化。当前版本预期9/10:B10使用格式正确但未登记的indicator-guest-02,系统只检查了字段类型和online状态,没有检查设备是否在允许清单中,因此错误执行L2提示。
不要在最终测试后把B10的预期改为“允许任意在线设备”。正确做法是在发布说明中保留失败,现场暂时禁止更换未登记设备,并设计v7.1修订:设备登记表增加ID、类型、动作上限和负责人;接口检查把“格式正确”与“身份获准”分开;新增未登记、已撤销和冒用编号测试。
最终展示不从头点完所有按钮。三分钟内先说明使用场景与边界,再展示一条正常成功、一条接口错误拒绝、一条设备离线降级和B10保留失败,最后打开发布清单与回退入口。观众看到的不只是“作品会动”,还包括系统为什么动、不能做什么、出现问题怎样恢复。
安全、协作与交付责任
综合项目会把局部风险连接起来。视觉模块可能带入无关画面,资料模块可能带入不可信指令,智能体可能连续调用工具,设备模块可能产生现场影响。即使每章都有边界,集成后也要重新检查权限是否被组合放大,例如资料文本不能直接成为设备命令,主页按钮不能跳过人工确认。
项目文件只使用课堂虚构资料和模拟设备。若开展纸卡摄像头扩展,应限定拍摄区域、用户主动开启、默认不保存并可立即停止;若连接低压指示灯,应由具备条件的指导人员核对接线。发布包不得包含账号口令、真实个人信息、未经许可的素材或能够调用系统命令的代码。
协作不是四人同时修改同一个文件。每个接口和配置项要有负责人,变更通过记录交接;测试负责人应保留独立判断,不能由生成代码的人单方面删除测试;发布负责人签名前要看到最终测试、已知问题和回退结果。分工的目的不是把责任推给别人,而是让关键检查有人明确承担。
本章小结
系统集成检查模块组合后的数据、状态、时序与任务结果,不是把独立功能放进同一页面。接口规定字段、类型、单位、范围、状态、错误和版本;适配器可以转换已经说明的差异,但不能猜测未知语义。追踪标识、可观察状态和需求追溯表帮助定位故障并证明要求落到了实现与测试。
测试用例在运行前写明前置条件、输入、预期和实际结果。单元、接口、集成和系统测试从不同层面回答问题,开发集用于修订,冻结后的最终集用于检验未知变化。一次演示成功不能代替分层测试,失败也不能通过修改期望来消除。
版本发布交付程序、配置、契约、证据、已知问题和回退方法的统一基线。v7.0用适配器解决了分数、时间、状态和标签冲突,开发测试18/18,最终测试9/10;未登记临时设备仍可能被接受,作为B10进入发布说明和v7.1计划。
习题
基础题
- 分别解释系统集成、接口、测试用例和版本发布,并说明它们在v7.0中的关系。
- 为什么
score:0.82既可能格式正确,又可能与下游接口不兼容? - 区分单元测试、接口测试、集成测试和系统测试,各举本章一例。
- 一条测试用例至少要写哪些信息?为什么预期结果必须在运行前确定?
应用题
- 上游输出
time:12.5,下游需要毫秒。写出在可以转换、必须拒绝和仍需核对三种情况下的判断依据。 - 为“设备离线时不发送命令”建立一行需求追溯表,包含接口字段、控制规则、开发测试和发布证据。
- v7.0发布后发现某配置被改动。说明校验值、基线、回归测试和回退分别能解决什么问题。
探究题
- 【选做】为B10设计v7.1设备登记接口和四条测试,至少覆盖未登记、撤销、编号冒用和正常更换。
本章交付物
1. 系统版本包
- 信号卡智能提醒器v7.0与系统数据流图。
signal-event/v2接口契约和v6→v7适配器说明。- v6.0联调失败、v7.0开发18/18和最终9/10记录。
- 至少四行“需求—接口—模块—测试—发布”追溯表。
- 发布基线、版本说明、已知问题B10和回退演练记录。
- 三分钟演示与同伴评审记录。
2. 自评单
- [ ] 我能说明系统集成与模块集合的区别。
- [ ] 接口写明了字段、类型、单位、枚举、错误和版本。
- [ ] 原始事件与适配结果都保留,未知含义不会被猜测。
- [ ] 测试用例在运行前写明预期,开发集与最终集分开。
- [ ] 我能按数据流和追踪标识定位最后一个正确节点。
- [ ] 发布包中的程序、配置、测试和说明属于同一基线。
- [ ] B10没有被删除,现场临时处置和v7.1计划明确。
- [ ] 我知道何时停止发布或回退到低影响版本。