跳至正文
小莱沃 257 篇手记
← 返回首页

技术

AI 让代码更容易写,但软件仍需要开发者掌控

AI 正在降低写代码的难度,但系统的复杂性仍需要开发者理解、协调和掌控。局部实现正确,不代表整个系统正确。

暖白背景上,带有抽象纹样的彩色方块通过深青与陶土色线条相互连接,一只手调整其中一处连接。

写代码的“难”和“复杂”,应该分开讨论。

难,描述的是解决一个问题需要多高的能力。复杂,描述的是解决这个问题时,需要同时理解和协调多少关系。

一个算法可能很难,但它的输入、输出和目标都很清楚。一个业务系统里的每段代码可能都不难,但状态、规则、权限和历史数据交织在一起,修改任何一处,都可能影响其他地方。

过去,这两种障碍经常混在一起。我们既要弄清楚系统应该如何工作,又要花大量时间研究代码到底怎么写。

AI 改变了后面这件事。

“不会写”正在失去阻碍作用

不熟悉一个框架,可以让 AI 解释并给出实现;遇到一个报错,可以让它协助定位;需要一种算法,也可以让它提供方案,再通过测试验证。

AI 还没有解决所有技术难题,但它已经跨过了日常开发中的大量知识门槛。许多过去需要反复查资料、做实验才能完成的工作,现在可以更快地得到一个可运行的结果。

于是,开发者越来越少地被“我不会写这段代码”挡住。

但代码能够运行之后,另一类问题才真正显露出来:它应该怎样与整个系统一起工作?

复杂性藏在关系里

以订单系统为例。

创建订单、扣减库存、发起支付、处理退款,每个功能单独看都有明确的实现方法,AI 也能很快写出来。

但这些功能之间存在关系。

支付成功时,库存扣减失败怎么办?用户取消订单后,已经使用的优惠券是否返还?部分退款之后,订单算已完成还是已退款?财务结算应该使用下单时的规则,还是当前的规则?

这些问题里的代码未必难写。难以处理的是:每个答案都必须与其他答案一致。

左侧展示可独立验证的订单状态更新,右侧展示订单与支付、库存、退款之间需要共同协调的关系。

假设我们为了处理支付失败,增加一个自动取消订单的任务。它本身可能完全正确,却可能与支付回调发生冲突:任务刚取消订单,延迟到达的回调又把订单改成已支付。

两个局部实现都符合各自的要求,放在一起却出现了问题。

复杂性就在这里。我们需要理解的,已经超出了某个函数的实现,还包括状态变化的顺序、规则之间的约束,以及异常发生时系统如何收场。

AI 加快了实现,也加快了系统的增长

过去,写代码需要时间。一个想法能否进入系统,往往要经过成本评估和取舍。

现在,增加一个页面、一组接口或一段判断,可能只需要几次对话。

这带来了很大的自由,也改变了复杂性积累的速度。

遇到一种例外,就补一个判断;发现一个需求,就加一个功能;觉得某段逻辑不够通用,就抽象一层。每次修改都有理由,也都能顺利完成。几个月之后,系统里却可能出现大量互相影响的规则,连开发者自己也解释不清。

生成代码的速度,可以超过理解系统的速度。

一旦出现这种情况,开发就会逐渐变成试探:改一处,看看哪里出问题;再补一处,看看能否恢复。AI 仍然可以继续写代码,但开发者已经越来越难判断,这些修改究竟是在解决问题,还是在增加新的问题。

开发者需要掌控什么

掌控软件,不要求开发者亲手写出每一行代码,也不要求他记住所有细节。

但至少需要掌握三个方面。

第一,关键规则。

什么必须始终成立?例如,同一笔支付不能重复入账,已取消的订单不能直接发货,历史账单不能因为当前配置变化而悄悄改变。

这些规则是判断实现是否正确的依据。没有它们,代码写得再完整,也只能说明它完成了某些操作。

第二,变化的影响。

修改一个订单状态,会影响哪些流程?调整一个字段,哪些页面、接口和报表需要同步变化?

开发者不必记住所有调用位置,但需要有办法查明影响,并知道哪些关系值得重点检查。

第三,验证和恢复的方法。

怎样证明修改符合预期?异常出现时,如何定位?如果方案有问题,能否撤回修改,修复数据?

掌控最终要落实到这些动作上。能够清楚描述系统,只是开始;能够可靠地改变它,才说明这种理解真正有用。

把 AI 的任务放在自己能够验收的范围内

因此,使用 AI 编程时,除了问“它能不能写出来”,还应该问:

“它写完之后,我能不能判断对错?”

边界明确、规则清楚、输入输出可验证的任务,很适合交给 AI。开发者提供目标和约束,AI 完成实现,再通过检查和测试确认结果。

而对于职责模糊、规则冲突的需求,需要先理清问题。

例如,“支持订单取消”看起来是一个简单任务,但如果没有明确取消的时间限制、库存释放方式、支付中的处理规则,AI 就只能自行补充假设。代码越快完成,这些假设就越快进入系统。

所以,任务拆分也不只是为了方便 AI 执行。它应该让每一次变化都处于开发者可以解释、可以验收的范围内。

重要的业务规则值得记录,关键的状态流转值得画清楚,共享的数据契约值得明确。这些工作会让后续修改有据可依,让开发者能够持续理解自己的软件。

更容易实现之后,更需要取舍

AI 让“这个功能能不能做”越来越容易回答,却没有替开发者决定“这个功能值不值得做”。

一个新功能带来的成本,不仅包括实现,还包括它加入之后,与现有规则产生的关系,以及未来每次修改时必须继续照顾它的责任。

有些复杂性来自业务本身,必须处理。有些来自历史选择,需要逐步调整。还有一些只是因为实现太方便,在缺少取舍时被加入了系统。

开发者需要判断这些区别。

过去,我们可能因为写不出来而无法完成软件。以后,我们可能因为写出来太多,却无法掌控而难以继续维护。

AI 已经大幅缓解了写代码的难度。软件能否持续发展,仍然需要开发者理解它的关键关系,控制它的变化,并对其中的决定负责。

发表评论