最近有程序员朋友吐槽:让 AI 写个简单的字符串拼接,它愣是加了三个判空和两个异常捕获。

看着那行“return user?.name ?? ‘未知’”的代码,你是不是也嘴角一抽?明明你手动写就是一行 user.Name,AI 却像穿了十层防弹衣。

这绝不是 AI 在“炫技”或者“水代码”。背后藏着它作为概率模型的生存本能。

“AI 写防御性代码,不是因为它害怕 Bug,而是因为它害怕输出一个会让用户沮丧的‘错误答案’。”

它太怕“翻车”了

AI 的终极目标是让你满意。在它庞大的训练数据中,那些能通过所有测试用例、在各种极端输入下都能稳定运行的代码,得分最高。

一个非空判断,能防止 NullReferenceException。一个 Try-Catch,能吞掉意料之外的异常。这些“护甲”让 AI 输出的代码在你随便输个空值、边界值时,也能给出一个“礼貌”的结果,而不是直接崩给你看。

它就像一个经验丰富但有点“过度保护”的老程序员,见过太多线上事故,所以下意识给每个变量都系上了安全带。

无情的“上下文成本”计算器

你有没有发现,AI 的防御性代码,最常见于它不确定的时候?

当你给它一个模糊需求,比如“处理一下用户数据”,它不知道你的 User 对象是否一定非空,不知道哪个环节可能抛异常。为了最大概率得到你的正向反馈,它选择把所有能想到的防御手段都加上

这是模型在计算“上下文成本”——写多余的代码,顶多让你觉得它啰嗦;但少写一个判空导致报错,你会直接骂它“垃圾”。两害相权取其轻,AI 选择了“宁可多干,不可犯错”。

当“好习惯”变成“坏味道”

凡事过犹不及。当 AI 的防御性代码泛滥,代码库就变成了“沼泽”。

看下面这个例子: - 每个函数入口都有 if (param == null) return null; - 每个数据库查询都包裹在 try-catch 里吃掉异常 - 所有对象访问都要加上 ? 问号运算符

这种代码虽然稳如老狗,但可读性直线下降。真正的隐患在于:过度防御会掩盖真实问题。你永远不知道一个该抛出来的“参数为null”的Bug,因为被AI“温柔”地返回了一个空值,而藏在了哪个角落。

和 AI“组队”的正确姿势

与其抱怨 AI 太怂,不如调整我们的“驾驶”方式。

第一步,给它明确“刹车边界”。 当你明确知道输入不会为空时,可以在 Prompt 里加一句“假设所有输入均为有效非空值,无需判空”。AI 会立刻收起它的“护甲”。

第二步,主动“剪枝”。 让 AI 写完第一版后,追加指令:“请移除所有不必要的非空检查和异常捕获,仅保留关键的防御逻辑。”

第三步,把它当作“实习生”,而不是“外包团队”。 实习生写的代码你肯定要 Review 和重构。AI 生成的防御性代码,本质上是一次风险对冲。你需要做的,是根据你的业务逻辑,保留真正需要的保护,删除那些出于“害怕”而加的冗余。

  • 保留:对外部输入、网络请求、数据库操作的防御。

  • 删除:内部逻辑中,函数参数之间链条清晰的、绝不可能为空的护甲。

说到底,AI 写防御性代码,是一件“甜蜜的烦恼”。

它至少证明了它比你更担心代码出错。在这个 AI 写代码越来越普遍的时代,我们的核心能力不再是“手写每一行”,而是判断哪些冗余可以删,哪些风险必须防

你平时会让 AI 先生成代码,再人工“砍冗余”吗?又或者你有让 AI 更“写你所想”的 Prompt 技巧?

欢迎在评论区聊聊你的“人机协同”心得。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐