在 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 可以被放心信任。