通过语义合约重获对AI生成代码的信任
针对AI生成代码速度快于人类审查而导致的信任危机,本文提出“语义合约”——一种类型安全、编译时检查的蓝图,位于需求与代码之间,确保任何实现(无论人工还是AI编写)的正确性。文章通过排序算法和电商结账示例展示了语义合约的构建块、状态处理和集成方式。
近年来,AI辅助开发(又称“Vibe Coding”)极大提升了编码速度。然而,由于AI模型的决策过程不透明,我们正面临一场根本性的信任危机——没有人能确信AI产生的代码是否真正符合预期。传统的单元测试和提示工程在AI代码面前显得力不从心,因为代码审查的速度永远赶不上AI生成的速度。
本文提出了一种实用解决方案:语义合约(Semantic Contracts)。语义合约是一种结构化的、可验证的核心业务逻辑蓝图,它恰好位于原始需求和实际代码之间。通过使用类型化状态、简单组合子(combinators)以及编译时检查,它保证任何符合合约的实现——无论由人类还是AI编写——都自动具备可信赖性。
为什么传统方法不够?
在AI时代之前,软件工程依靠一个高度结构化的流水线来建立信任:需求→架构→详细设计→编码→测试→代码审查→部署。每个步骤都有清晰的输入输出和人为负责。然而,AI打破了这一链条:从提示直接到代码,中间环节全部消失。AI的不可知行为、不可追溯的bug、不可预测的修复以及无法跟上速度的代码审查,共同摧毁了信任基础。
语义合约并不试图证明一切。相反,它专注于流程保证——通过结构化构建块,使代码变得“设计正确”而非“偶然正确”。
什么是语义合约?
一个语义合约包含三部分:签名(输入状态和输出状态)、定义(由基本组合子构成的表达式树)和能力(附加行为如数据库事务、重试、限流等)。状态是合约的关键——合约不抛出随机异常,而是返回明确的状态,如“成功(交易ID)”或“余额不足(可用金额)”。如果后续步骤没有处理某个状态,编译器会报错,迫使开发者或AI处理所有边缘情况。
基本组合子包括:Seq(顺序执行)、Par(并行执行)、Batch(列表批量处理)、Race(竞速)、ScatterGather(分散-聚合)、Transaction(回滚)和Timed(超时)。这些组合子具有可预测的数学规则,编译器可以轻松检查流水线是否合理。
示例1:排序算法
合约定义:先检查列表是否已排序,若未排序则进行划分(Partition)、并行排序两部分,最后合并(Merge)。只要原子操作(Partition和Merge)正确,整个排序过程就由编译器保证正确。
示例2:电商结账
PlaceOrder合约涉及支付和库存扣减。通过细化支付状态(成功、余额不足、失败)和库存状态(成功、库存不足、失败),编译器强制开发者处理这些状态。后续还可以轻松添加通知功能——用Transaction组合子包裹核心操作,无论成功失败都发送通知。
核心思想:将业务逻辑提升为类型系统
传统编程中,业务规则隐藏于嵌套的if/else、数据库调用和异常捕获中,无法自动证明其协调性。语义合约将“支付”转化为一组严格的类型化规则:payment是一个类型,可以在任何更大的结账系统中安全使用,编译器即时验证逻辑是否匹配蓝图,且任何满足合约的实现都可以互换而不破坏系统。
如何集成?
现有代码库大多没有语义合约。文章提出信任层级:底层基础设施(如Linux内核、TCP/IP、PostgreSQL)因其广泛使用而被假定正确,应用层逐步采用语义合约。开发者可以从关键业务流程开始,逐步将现有代码包装到合约中。
总之,语义合约并非AI时代的专属工具,但它对于防止AI“幻觉”特别有效——因为合约剥离了无关细节,强制执行类型约束。如果AI生成错误实现,编译器会直接拒绝构建。这为AI驱动的开发提供了一条切实可行的信任重建之路。