在 AI 原生软件工程中,最重要的也许不是生成,而是约束。
这是「AI 原生软件工程」系列的第二篇。
本文承接上一篇:AI 原生软件工程(一):智能体编程中的心智模型。
上一篇讨论的问题是:
如果理解系统不再主要依靠亲手写代码,
人类要如何在智能体工作流中建立心智模型?
接下来的问题是:
如果实现工作交给了 AI,
正确性从何而来?
谈到 AI 辅助软件开发,人们往往只关心一件事:
我们能将软件产出提高多少?
编码更快。
上下文更长。
智能体可以自主运行。
一次改动多个文件。
工作流能够自我修复。
但用 AI 智能体做了一段时间项目后,我却得出了相反的结论:
最重要的工程问题,不是如何让 AI 更自主。
而是如何更严格地约束 AI。
因为毫无限制地生成代码,几乎从来不是瓶颈。
正确性才是。
这里暂且不谈约束对创造力或搜索空间的影响,只谈正确性。
真正要回答的是:
怎样才能让 AI 生成的实现可以被放心信任?
传统软件开发的基本假设 链接到标题
传统软件开发建立在一个简单的假设上:
人
-> 实现
-> 验证
写系统的人,也会在动手实现的过程中逐渐理解系统。
很多时候,验证并不会被单独提出来。
因为实现出自自己之手,你自然更愿意相信它。
在小团队中,这套做法出人意料地管用。
直到复杂度不断攀升。
AI 打破了这个假设 链接到标题
智能体编程改变了原有结构。
现在,整个循环变成了:
人
-> 意图
AI
-> 实现
人
-> 审查
乍看之下,效率很高。
但其中藏着一个问题。
审查的成本比亲手实现低得多。
也正因为审查更便宜:
人们会放行自己并未充分理解的改动。
尤其是在以下情况下:
- 多个文件同时发生变化
- 抽象设计发生了变化
- 框架惯例变了
- 生成的代码看起来合情合理
这种危险很难察觉。
系统也许能够正常运行。
直到它无法正常运行。
生成很便宜,正确性很昂贵 链接到标题
一旦实现成本骤降,验证就会成为主要成本。
这正是验证框架工程越来越重要的原因。
验证框架不等于测试套件。
它是对可接受行为的可执行定义。
与其只说:
给我做一个通知系统。
不如明确规定:
给定:
1000 个请求
预期:
p95 < 200ms
失败处理:
重试 <= 3 次
不变量:
不得重复送达
这样一来,正确性就有了独立于具体实现的定义。
验证框架就是契约 链接到标题
一套好的验证框架,就是一份契约。
它会明确规定:
输入
存在哪些条件?
输出
哪些结果可以接受?
约束
哪些情况绝不能发生?
故障模式
承压时,系统应该如何表现?
恢复
出错后,系统如何恢复正常?
例如:
功能:
上传图片
验收:
响应时间 < 2s
拒绝:
文件 > 10MB
保证:
元数据一致
AI 可以生成十种实现。
再由验证框架选出符合要求的一种。
约束界定搜索空间 链接到标题
这改变了我理解 AI 的方式。
大多数人想象中的 AI 编程是:
更多自由
-> 能力更强
而我越来越倾向于认为:
更多约束
-> 能力更强
因为软件不是创造力。
软件开发是在约束中探索。
验证框架会缩小搜索空间。
它能避免:
- 架构逐渐偏离原有方向
- 隐性复杂度
- 非预期行为
- 只顾局部最优
验证框架由此划定了可接受实现的边界。
工程师角色的转变 链接到标题
我认为,软件行业中的角色可能会慢慢发生变化。
过去的模式是:
工程师
=
设计
+
实现
+
验证
正在形成的新模式是:
工程师
=
意图
+
约束
+
评估
AI 则成为承接实现工作的基础设施。
人类仍然要对正确性负责。
我现在采用的工作流 链接到标题
每个功能都要经过:
规格说明
-> 验收标准
-> 验证框架
-> 智能体
-> 评估
-> 合并
而且,每个功能都必须回答以下问题:
为什么要做这个功能?
什么绝不能被破坏?
怎样才算成功?
出了问题,怎么调试?
如果连这些答案都写不出来,就不该让 AI 开始编码。
结语 链接到标题
AI 并没有消除工程工作。
它只是让实现不再稀缺。
于是,真正稀缺的资源变成了:
正确性。
正确性很少是生成出来的。
它是设计出来的。
验证框架工程不是为了赋予 AI 更强的能力。
而是为了让 AI 可以被放心信任。