正在刊行长文 · Essay
2026-06-19所有内容
随机比特 · Random Bits

怎么让 AI 别在你项目里乱改代码:约束工程的四道防线

2026-06-19AI Engineering / Systemsrbits.uk
怎么让 AI 别在你项目里乱改代码:约束工程的四道防线

怎么让 AI 别在你项目里乱改代码:约束工程的四道防线

只想让 AI 写个 50 行的数据清理脚本,一小时后回来一看:项目里多出了三个微服务、一个没人要的前端仪表盘、一套 Docker 编排,还顺手引了 Redis——而那个脚本依然报着诡异的类型错误。

这不是个例,是 AI 编程的默认行为。它是个极度迎合你的"顺向执行器",给它越大的视野,它能顺手污染的面就越大。光靠在 prompt 里写"请不要乱改别的文件"是拦不住的——它会越界,因为没人真的拦着它。

真正能拦住它的,是一套叫约束工程的东西:提前把你脑子里的"全局不变量",沉淀成 AI 每一轮都绕不过去的硬关卡。这篇把它讲透。

先分清:软约束 vs 硬约束

这是整件事的地基,搞混了后面全白搭。

01-soft-vs-hard

约束工程的全部功夫,就一句话:尽量把软约束升级成硬约束。 下面四道防线,按"兜底强度"从弱到强排。

防线一:全局不变量硬编码

把你脑子里那几条高压线写下来,放进规则文件。但有三个铁律,违反任何一条,规则文件就退化成噪音:

判断信号:如果你在 review 里反复纠正 AI 同一类越界(又穿透分层了、又直连那张表了),说明这条高压线该进规则文件,而不是靠你每次人肉拦。

防线二:TDD 当锁链

这是约束工程里最被低估、却最该立刻做的一件事。

以前觉得写单测太慢?在 AI 时代这个判断彻底反转了——单测现在是你手里唯一一道不靠 AI 自觉的退出闸门。

注意因果顺序,它是约束工程和 Vibe Coding 的分水岭:

为什么这道闸门能兜底?回想成本不对称:生成 O(1)、验证 O(N),你的审查瓶颈降不下来。测试是把 O(N) 的人肉验证,一次性固化成 O(1) 的自动验证。你写一次断言,它替你审查一万次。 那个降不下来的瓶颈,第一次有了杠杆。它还顺手治了并发、竞态这类静态读代码看不出来的雷——你写一个能复现它的测试,AI 就再也绕不过去。

防线三:类型与契约——把防线提前到编译期

测试是运行期的闸门,类型和契约是编译期的闸门,更早、更狠,AI 连"写出来"的机会都没有。

核心是把你脑子里的隐式假设,从脑子里搬进类型系统:

这就是"让非法状态无法被表示"(make illegal states unrepresentable)。一旦一条潜规则被编码进类型,它就从"靠 AI 记得"升级成"AI 违反就编译不过"。你把一条隐式契约,变成了一道硬关卡。

防线四:DDD 划边界——切断它感知全局的能力

前三道防线都在"拦 AI 别越界"。第四道更釜底抽薪:让它根本看不到可以越界的地方。

永远不要把整个代码库的上下文,直接扔给一个全局的 AI 助手。用 DDD 的 Bounded Context 严格限制它的可见范围:你要做哪个领域的功能,就只喂给它那个领域的核心实体和接口规范,其余一概不给。

它看不到那张可以直连的表,就没法直连;它看不到那个可以穿透的底层接口,就没法穿透。可见性即权力——你限制了它的视野,就限制了它的破坏半径。 这一招还顺带治了 Scope Creep:AI 看不到全局,就发不起"既然加了鉴权,顺便把 OAuth2 全家桶接了吧"这种"贴心"建议。

合起来:动手前走一遍

接一个新任务、动一段 AI 代码之前,从上到下过一遍:

  1. 不变量:这次涉及的架构高压线,写进规则文件了吗?
  2. 测试当锁链:核心断言是我写的吗?还是 AI 写完我事后追认的?
  3. 类型/契约:这次的隐式契约,编码进类型了吗,让 AI 违反就编译不过?
  4. 可见性:我喂给 AI 的上下文,是"只够干这一件事",还是"整个 repo"?

这四步的共同点是一个词:前置。约束工程的全部秘密,就是把所有"判断",从"AI 写完之后我来兜"前置成"AI 动手之前就立好的硬关卡"。

你不再是那个在后面给屎山打补丁的人,你变成在前面立笼子的人。你给 AI 定义的边界有多清晰,AI 吐出的代码就有多强壮。


我是随机比特,腾讯十年开发,天天拿 AI 干活、被坑过、把判断沉下来。更多 AI 工程化的硬核拆解,关注公众号「随机比特」,或来 rbits.uk 翻完整的 270+ 篇。

—— 随机比特

随机比特公众号二维码
公众号 · 随机比特
从 AI 工具热闹里拆工程真相

写边界、控制面、上下文、成本与安全。