5 软件工程的来龙去脉:弥合意图与实现的 gap
软件工程从诞生起就在弥合意图、规格和实现之间的 gap;AI 让实现变便宜,意图和验收变得更重要。
5 软件工程的来龙去脉:弥合意图与实现的 gap
我的理解
- first principle:把问题拆到最基本、不可再简化的事实,再从这些事实推导解决方案。
- 软件工程要解决的是 intent、spec、implementation 之间的 gap。
- 历史上的方法,如瀑布、DAG 视角下的 BFS 与 DFS、形式化语言、UML,要放到 AI 时代重新看定义和取舍:哪些保留,哪些更替。UML 已经死了,至少我现在不会用。
意图、规格与实现
软件工程要弥合的,是三层之间的 gap:
- intent:想要什么。
- spec:架构、接口、约束。
- implementation:实际运行的代码。
需求出自人的设想,提出需求的人往往也没有想清楚边界情况。以选课系统的先修课为例:它是硬约束还是软约束?谁有权特批?学生临近毕业、只差这一门时,学校通常会破例。

这些 gap 无法靠事先想清楚来消除,原因在于下面三条基本事实。
三条基本事实
- 测试之前,程序无法运行:设计阶段只有文档,缺乏强约束,偏差要到测试才暴露。例如做 OJ 题时先选定了错误的算法,写完运行样例,才发现整个思路不成立。
- 不会发生的事终会发生:Hamilton 默认任何假设都可能被违反。阿波罗 11 号下降时触发报警,软件依靠优先级调度与恢复机制,保证下降控制继续运行。
- 每一步翻译都会出错:从 spec 到代码会出错,不崩溃、不泄漏资源这类隐含的 spec 也会遗漏。例如为 Eiffel 的取款函数写前置条件时,才会考虑余额不足如何处理。
gap 既然无法消除,历史上的方法便沿两条路线去收窄它。
两条路线
- 提前反馈:pilot、MVP、敏捷、TDD、QuickCheck(描述性质,自动生成用例寻找反例)。
- 确定语义:自然语言 → checklist → UML 与 DSL → 编程语言加契约 → 形式化证明(Dafny、Verus)。

traceability 把依赖关系显式记录下来,防御性编程默认前提会被违反,二者是两条路线的补充。评估一种新工具时,可以先问:它属于提前反馈,还是确定语义?
瀑布:返工沿依赖传递
提前反馈这条路线,源自对瀑布模型的反思。Royce 在 1970 年的论文中提出瀑布,本意是批判它。将需求、设计、实现之间的关联视为 DAG,测试失败后须向上追溯,依赖错误设计的实现全部作废;问题发现得越晚,代价越大。

- 瀑布即 BFS:逐层铺开,最后测试。
- MVP 与敏捷即 DFS:先打通优先级最高的一条依赖,每一步都获得反馈。
- Do it twice:先构建一个准备丢弃的 pilot。丢弃的是代码;需求随之修正,意图保持不变。过去代码昂贵,至多做两遍;如今代码廉价,可以反复迭代。

两条路线的取舍,始终受制于写代码的成本。AI 改变的正是这一成本。
AI 时代的取舍
讲师认为:LLM 解决了人与人难以对齐、checklist 难以检查的问题,剩下的只有「没有想清楚、没有说清楚」。
| 方法 | 原本解决的问题 | AI 时代 |
|---|---|---|
| UML 等中间语言 | 编码前让人与人对齐 | 不再需要,AI 可在自然语言与代码之间直接翻译 |
| 人工 checklist | 防止遗漏 | 检查交给 AI,与客户确认仍由人负责 |
| MVP、do it twice | 尽早获得反馈 | 更重要,也更廉价 |
| TDD、契约、断言 | 定义何为正确 | 更重要:AI 负责实现,人负责验收 |
| traceability | 定位依赖 | 更重要:AI 修改快,漂移也快 |
| 任务划分 | 分工 | 不变:leader 须先划分任务,不能交由团队自组织 |
从 spec 到实现几乎不再有成本,intent 到 spec 的定义与结果的验证因此更有价值。AI 同样让 BFS 变得廉价,可以一次生成整套系统;但 intent 一旦有误,成果仍会全部作废,坚持 DFS 依然依赖人的判断。
人的职责
- 决定哪些定死,哪些留白:前述所有方法,归根到底都在回答这一问题。
- 给出可验收的结果,过程交给 Agent:任务划分是否合理,取决于每一部分能否写出验收标准。
漂移:以验收为源头
AI 修改代码的速度远超文档与测试的更新。对策是以 spec 和验收为源头,代码可随时重新生成:
- 验收写成测试与断言,漂移在运行测试时自动暴露,不依赖人工阅读文档。
- 修改代码时,在同一次提交中同步更新文档与测试,并写入
AGENTS.md作为规则。 - 小步提交,每步运行测试,将漂移限制在单步之内。
- 由 Agent 定期比对文档与代码,报告不一致之处,思路同第 4 讲的 repo.db。
附录:读一手资料
教科书对所有读者做同一种有损压缩。借助 AI,可以直接阅读原文,压缩成适合自己的版本。