——转身:从真实需求长出来的老项目维护技能库
这是《嵌入式 AI 落地手记》的第三篇。上一篇讲了新体系怎么失败的:目标贪多,模板膨胀,试用停在需求和设计两步。这篇讲之后的事——AI 第一次在真实项目里完整跑起来,不在新体系上,而在一个不起眼的地方:老项目维护。
一张变更通知单
新体系的试用停下来之后,工作没有停下来。我们手里压着一批老项目,客户的需求变更照常来:一张变更通知单,配上更新过的几份文档——功能规范、接口定义、配置规范,加起来几百页 PDF。
这类活干过的人都知道它难在哪。要改的是老代码,写它的人可能早就不碰了;变更本身往往不大,影响面要自己去翻;几百页文档里真正变的只有标出来的那几处;改完还要担心别的东西被碰坏。当时我们还有一层自己的压力:新体系失败,积压了一批 PR 和需求评审,变更又来得频繁,人有些应付不过来。
同时我心里攒着一批想法。新项目试用那两个月,体系虽然失败了,但"AI 该怎么参与开发"这件事我隐约摸到了一些东西,一直没有机会验证。新体系太大,改不动了;维护场景刚好小、高频、真实——先在这里把想法验一遍,走通了,回头重构新体系也有底。
一周搭出来的小东西
九月初,我用大约一周时间搭了一个老项目维护用的技能库。构建方法本身也值得说:先和 AI 讨论出一个合理的流程,把前一阶段的思考落进去;搭完不急着发布,先找一个此前由人完成的变更,让 AI 照流程重做一遍,拿回放结果改技能;改过之后才放出去用。提交记录里留着当时的原话:拿两个已交付的项目自验证了一遍,"基本合理"。第一版敢拿出来给人用,依据就这四个字。
整个库只有五个技能、七百来行。流程五步,不许跳步:
- 建档:需求文档统一转成文本,建索引和项目概况。原则是索引先行、按需加载——AI 只读索引定位到的章节,禁止通读全部文档。这条是从上次失败里长出来的:读原始文件太吃上下文。
- 需求理解:把这次变更涉及的需求点逐条对照代码现状。
- 影响与假设:分析改动影响面,并把所有假设、推测、不确定的地方列成一份清单。
- 实施:按确认过的方案改代码。
- 验证归档:编译、静态检查、生成测试用例、写变更记录。
流程里有两道必须人过的闸。第一道在假设清单:AI 把清单列出来,人逐条确认,没确认完的假设不许带进实施。第二道在方案:修改方案必须明确批准才算数——技能里的原文是,对假设清单的回答、对方案的沉默,都不构成批准。
为什么要两道闸?这是第一次失败换来的认识:人和 AI 的协作界面在决策上,不在编辑上。与其让人在 AI 生成的几百行文档里通读找错,不如让 AI 先把自己不确定的地方交出来,人只审这些点。
先和人比一场
发布前的那次回放验证,后来成了很有价值的材料。做法是:找一份已经由人完成的变更,原始需求文档原样喂给技能库,让 AI 完整跑一遍流程,再拿两版实现对比。同一份需求,两条路径,各做各的。
流程留痕是完整的:二十一条假设逐条列出、逐条经人确认,其中四条按意见做了修改;生成四十五条测试用例;变更记录里逐块核对改动和需求的对应关系;编译零错误,静态检查零新增问题。
实现上的对比更有意思。两边都把功能做了出来,核心控制逻辑一致——那个关键设计最初是 AI 在假设清单里提出、经人确认定下的,人工版本用的也是同一个思路。差异在风格和覆盖面上:AI 用一个参数化结构同时处理两个通道,三百多行;人工实现写成了独立模块,接近一千行,代价是其中一组函数几乎是复制粘贴的两份。反过来,人工版本忠实实现了文档里一条很具体的收发约定;AI 把它简化成了语义近似的写法,意思差不多,但没有照着字面做。AI 又多做了另一件事:给配置值加了一层合法性校验,人工版本没有。
谁赢了?我不打算下这个结论。对我重要的是另外两点:一是没有出现人工版本纠正 AI 逻辑错误的情况;二是 AI 漏掉的是"文档字面要求"这类东西——这正是那道假设确认闸存在的理由,AI 的每个简化决定都摊开在清单里,人在确认时有机会抓住它。
真实项目里的两次试用
第一次真实试用是一个功能变更:一个报警功能的使能条件,从诊断接口控制改成配置报文控制。实际用下来,反馈是需求理解和修改都完成得很快。验证链是完整的:编译零错误、静态检查零新增,十六条测试用例全部通过。过程中人对一处逻辑提出过疑问,逐跳核实加回归之后排除了。疑问被认真对待,而不是被流程吞掉,这也是流程设计的一部分。
第二次试用没那么典型,先说明:那一批活是修复测试和现场暴露的一批问题,bug 修复多过需求变更,原始代码的设计质量不高,硬件情况也复杂。
这一批里,AI 起草了修改方案和头一批提交,人工介入至少有四次:实施前两轮方案评审;实测戳破了 AI 设计的一个机制——日志证明某个状态保持是底层的偶然行为,不是设计语义,方案推翻重做;AI 为完整性设计的一套多帧缓存处理,被"量产项目最小修改"的原则回退了;最后模拟测试中又暴露了一个问题,再修一轮。
同样在这一批里,AI 自己验证时抓出了方案原文里一处写反的比较符号;它还在反馈文件里上报了一起自己造成的事故:生成提交脚本时把转义符写错,真实换行混进了首版提交,靠字节级比对才发现,随后修正。反馈文件是技能库里专门设计的机制,每次交付都要填,限半页——模板里的原话是,超了就没人维护。
踩坑与教训
维护线走通了,不代表 AI 可靠了。这条线踩过的坑,最后都变成了技能里的条款。
最常见的一类错误藏在假设里。技能规则中留着一条记录:曾经一次确认,七条假设里有两条和真实实现完全相反。AI 列假设的时候语气向来平静,对的和错的读起来一模一样,这就是清单必须逐条过人的原因——省掉这一步,错误直接流进代码。
第二类坑是逻辑自洽、但不物理成立。前面那次试用里被实测戳破的机制就是这样:代码层面读不出毛病,它依赖的行为恰好"看起来"存在。这类问题没有别的办法,只有实测能暴露。所以流程把实测放在必经路径上,AI 的结论不能直接过关。
还有一类算不上错误,是倾向:AI 喜欢做正确而完整的方案,维护场景要的却是最小修改——改动面在量产项目里就是风险面。这条后来写成了明确规则:不顺手修清单外的 bug,不做方案外的优化。附带还有一条更朴素的:AI 的交付物也要审计,审计要到字节级,"看起来对"和"确实对"之间,得靠工具来填。
为什么这次成了
回头对照第一次失败复盘出的两个根因,维护线几乎是逐条翻转过来的。
需求是真实的。变更维护每天都在发生,不存在为假想需求设计的问题——每条流程都是被一个真实变更逼出来的,哪一步多余,下一次试用就会硌脚。
范围也小了很多。只做变更维护一件事,不贪全流程,整个技能库七百行,不到上一个体系技能量的五分之一。规模小才改得动,回放验证一轮只要一天。
确认是前置的。人的精力没有花在通读 AI 的长文档上,花在两张清单上:假设和方案。第一次失败里那个交互带宽问题,答案是让人审得更少、更准,把审阅从全文缩到决策点。
如果有人问我现在怎么起步,我的答案比上一篇又具体了一点:从维护类工作切入,需求边界清晰、验证链短、见效快,最适合验证想法;把人工确认放在假设和方案这种决策点上,不要放在全文审阅上;每次交付留一页反馈,机制比热情可靠。
下一篇
维护线验证过的东西——两道闸、索引先行、反馈机制、最小修改——后来大都带回了新体系。带着这些回头重构最初失败的那个大体系,是下一篇的事。