从一次真实工程失控谈起:为什么只有 Rust 能托住 AI 编程


引言:一次“跑得通但不敢上线”的 AI 编程事故

我并不是 AI 编程的新手。
相反,我是那种每天大量、高频使用 AI 改代码的人。

重构、性能优化、接口收敛,甚至整块模块迁移,我都让 AI 参与过。
说实话,有一段时间,我甚至有点沉迷这种效率。

直到一次经历,让我对“AI 提效”这四个字彻底警惕。

那是一个看起来并不复杂的改动:

  • 一个已经运行了一段时间、但文档并不完整的已有服务

  • 一次状态处理逻辑的重排

  • 目标很简单:减少一次不必要的中间态

我把意图描述清楚,交给 AI。

第一次修改:
逻辑清晰,代码更短,测试通过。

第二次修改:
我指出一个边界情况,AI 很快修正。

第三次修改:
我让它“顺手优化一下错误处理路径”。

一切看起来都很顺。

直到第四、第五轮,我突然意识到一件事:

我已经说不清楚:这个系统,在什么情况下会失败。

代码还能跑,测试还能过,
AI 甚至能把每一行代码解释得头头是道。

但我不敢上线了。

不是因为我发现了 bug,
而是因为——
我失去了对系统行为边界的把握。

那一刻我终于意识到一个问题:

AI 并没有写错代码,它只是一步步把“不可审计性”堆了起来。


一、AI 编程真正的失控点,并不在“写错代码”

很多人谈 AI 编程,默认一个前提:

只要代码语义是对的,剩下的交给测试。

但在真实工程里,这是一个极其危险的假设。

1. 语义正确 ≠ 行为安全

AI 非常擅长一件事:
让代码“看起来像是对的”。

  • 变量命名合理

  • 逻辑分支完整

  • 注释甚至比人写得还好

但它并不知道:

  • 哪些状态不能发生

  • 哪些错误一次都不能容忍

  • 哪些路径即使极小概率也必须被禁止

这些不是语义问题,
而是工程裁决问题

2. LLM 并不知道什么是“不可接受的失败”

你可以问 AI:

“这段代码会不会 panic?”

它可以回答。

但你问它:

“这个 panic 在我们的业务里是否构成事故?”

它没有任何判断依据。

因为这些信息:

  • 不在代码里

  • 不在语言里

  • 甚至不在需求文档里

而是存在于工程经验、事故记忆和责任边界之中。

3. “能跑”反而成了最大的问题

在那次事故里,最可怕的不是 AI 犯错,
而是它每一步都在“帮我消除不确定性的表象”。

直到最后,系统变成了一种状态:

没有明显错误,但也没有任何人能为它的行为签字。

这不是 bug。
这是工程失控。


二、为什么大多数编程语言接不住 AI

很多人会把问题归结为:

  • 模型还不够强

  • 上下文不够

  • Prompt 写得不够好

但后来我意识到:

问题根本不在模型,而在语言。

1. 动态语言:错误被无限延后

在 Python、JavaScript 这类语言里:

  • AI 可以非常快地生成“能跑”的代码

  • 错误往往隐藏在运行期

  • 状态不一致、隐式副作用极难被提前暴露

在这种环境下,AI 反而如鱼得水。

因为语言本身允许你:
先跑起来,再说。

但工程恰恰相反。

2. 半强类型语言:AI 卡在“约定地狱”

即便是 Go、Java 这类语言,问题也没有消失。

AI 经常卡在:

  • 接口语义的隐式约定

  • 错误值的使用习惯

  • “大家默认会这么用”的工程常识

这些东西写不进类型系统,
只能靠人解释、靠规范约束。

而 AI,最不擅长的就是——
“默认大家都懂”。

3. 本质问题:语言没有“裁决权”

说到底,大多数语言都缺少一个能力:

在 AI 犯错之前,直接否决它。

它们更像是:

  • 尽量跑

  • 出了问题再说

  • 测试兜底

当你把一个高产但不负责任的智能体接进来时,
这种设计会被迅速放大。


三、Rust 的“反人类设计”,恰好是 AI 的安全笼子

我并不是一开始就喜欢 Rust。

相反,我一度非常讨厌它:

  • 编译器太啰嗦

  • 所有权反直觉

  • 生命周期像天书

直到我把 AI 引进 Rust 工程。

1. 把运行时的不确定性,强行提前到编译期

在其他语言里,
AI 可能会在并发或异步场景下写出这样的逻辑:

  • 状态在多个路径被共享

  • 生命周期靠“约定”维持

  • 问题只在极端情况下偶发

在生产环境中,这类问题往往表现为:
低概率、难复现、难归因的事故。

而在 Rust 里,
AI 只要试图写出类似行为,
编译器就会直接“掀桌子”。

不是警告,
不是建议,
而是拒绝。

你这个行为,我无法证明是安全的。

2. Ownership / Lifetime 强迫 AI 修正假设

最有意思的是:

AI 在 Rust 里会被反复迫使修改自己的理解。

  • 它假设数据可以被随意引用 → 不行

  • 它假设状态可以跨作用域存在 → 不行

  • 它假设“人会保证没问题” → 不接受

最终,AI 只能在语言允许的空间内思考。

不是你在教育 AI,
而是语言在教育它

3. Rust 编译器,是天然的“第二审计员”

可以把两种范式对比得非常清楚:

  • 传统 AI 编程
    AI(决策者) + 人类(疲劳的 Code Review)

  • Rust 的 AI 协作范式
    AI(提案者) + Rustc(硬性审计员) + 人类(终审裁决者)

这是一种天然的“三权分立”。


四、我在 Rust 工程中如何使用 AI(但不让它做主)

说清楚一点:
我不是反对 AI 写代码。

我反对的是——
让 AI 决定工程行为。

1. AI 被允许做的三件事

在我的 Rust 项目里,AI 只被允许:

  1. 展开逻辑路径,把隐含分支显性化

  2. 对照边界条件,检查是否有遗漏情况

  3. 解释已有代码,尤其是历史遗留部分

这些工作,AI 做得非常好。

2. AI 被明确禁止的事

但有几件事,我从不让 AI 决定:

  • 状态的唯一可信来源

  • 错误是否可以被吞掉

  • 行为失败时系统应如何反应

另外还有一条明确规则:

在 AI 协作中,我严禁它使用 unsafe
那等于给 AI 的牢笼开了一个后门。

3. 人类只保留一个职责:裁决

有趣的是,当你把 AI 的权限收紧到这个程度:

  • 它反而更稳定

  • 输出更可控

  • 修改次数显著减少

因为它不再试图“帮你做决定”。


五、结论:未来不是“AI 写代码”,而是“AI 服从语言”

很多人把 AI 编程看成一场效率竞赛:

谁写得快,谁赢。

但我越来越确信,真正的分水岭在这里:

谁能让 AI 接受约束,谁才能长期使用它。

1. Rust 不是最适合 AI 的语言,而是最不纵容 AI 的语言

正因为 Rust:

  • 不信任隐式行为

  • 不接受模糊边界

  • 不允许“差不多能跑”

它才成了 AI 时代极其罕见的安全基座。

2. 并不是所有项目都适合 AI

如果你的系统:

  • 不需要可追责

  • 不关心失败后果

  • 可以频繁重来

那 AI + 任意语言都没问题。

但一旦你面对的是:

  • 金融

  • 安全

  • 基础设施

  • 核心业务

你需要的不是更聪明的 AI,
而是更严苛的语言。

3. 给想用 AI 写 Rust 的三条生存建议

最后,三条非常现实的建议:

  1. 不要指望 AI 教你 Rust,它只能在你理解之后帮你加速

  2. 让编译器当坏人,不要急着“绕过它”

  3. 把裁决权永远留在人类手里,哪怕慢一点


终章 · 作者结论签名

未来的工程竞争,不是比谁的 AI 更“聪明”,
而是比谁的语言更“严厉”。

当生成代码变得越来越廉价,
“拒绝”本身,正在变成最昂贵的技术能力。

我选择 Rust,并不是因为它能让 AI 跑得更快,
而是因为它拥有一种在 AI 试图摧毁系统确定性时,
敢于直接说“不”的权力。

它不安抚你,
不迁就效率,
也不接受“差不多能跑”。

代码可以因 AI 而高效,
但在我参与过的这些工程里,
系统之所以还能被托付,
正是因为语言本身始终保持着昂贵。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐