最近在好几个技术群里,最热闹的话题已经不是“哪个大模型写代码更强”,而是另一个更扎心的问题:AI 生成的代码越来越多,但我越来越不敢点那个 Merge 按钮。
写代码的门槛确实在归零。Completions、Codex、Cursor 这些 AI 编程工具,把“把想法翻译成语法”这件事变成了复制粘贴级别的操作,随便一个菜鸟,都能在一个下午“写”出一个看起来有模有样的项目。可是越是这样,我越发现身边的老工程师在 Merge 之前要做的事越来越多——补测试、补边界条件、查依赖版本、重新梳理调用链,活活把自己干成了 AI 代码的“质检员”。
这个现象特别值得聊一聊。它不像表面上那么简单,不是什么“AI 写的代码不可靠”一句话能带过的,而是一场关于代码信任体系的迁移。今天我就在这儿把这几年在团队里用 AI 编程、做 Code Review、踩 Merge 事故坑攒下来的真实经验掰开揉碎讲一讲。不管你是个人开发者还是团队负责人,只要手上有生产环境、身上背着发布责任,这篇就是写给你的。
1. AI 写代码的门槛,确实已经趋近于零
1.1 从“补全下一行”到“代写整个功能”,工具形态进化太快了
如果你在两三年前问一个前端工程师,AI 能不能在十分钟内搭好一个带登录态、路由和暗黑模式的 React 项目,他大概率会摇头。但今天随便一个能跑大模型的编辑器插件,就能把这种骨架代码在几十秒内生成出来。
这几年 AI 编程工具的进化轨迹,我粗暴地分为三个阶段。
第一阶段是“补全型”,代表是 GitHub Copilot 初代。它的核心能力是续写你光标后面的代码,你写个函数名,它补函数体,你写个循环,它补循环逻辑。这个阶段的价值是“减少击键”,本质还是一个加强版智能输入法。很多人在这个阶段对 AI 编程是有点不屑的,觉得它也就补补样板代码。
第二阶段是“对话型+上下文型”,代表是 Cursor 和 Copilot Chat 这类产物。它们不再满足于单行补全,而是能读懂你当前文件甚至整个仓库的索引,通过对话直接生成一个完整的文件、重构一个函数、修一个 bug。到了这个阶段,AI 编程已经从“提词器”变成了“结对程序员”——你描述需求,它给你整段实现,你只需要做审阅和微调。我自己的体感是,在这个阶段,纯重复性的、模板化的编码工作量至少下降了六成。
第三阶段是“代理型”,代表是 Codex 这类能理解任务、自主规划步骤并执行多步操作的产品。你把一个 issue 丢给它,它能自己去翻代码、改文件、跑测试、再把 PR 建好。听起来很科幻,但实测下来,这种代理在边界清晰、上下文完整的任务上的表现已经相当可用。
这三阶段变化背后有一个很本质的东西:AI 承担的“认知责任”在快速变大。以前它只负责“把这句话写完整”,现在是负责“把这个功能想清楚并实现”。责任变大,出错的空间自然也在变大。
1.2 “会写代码的人很多,会合代码的人很贵”
这句话是我最近在公司内部经常念叨的一句。为什么这么说?
因为 AI 把“写代码”这个动作的边际成本几乎压到了零,但“合代码”这个动作的边际成本却一点没降。写代码是把需求翻译成代码,AI 已经做得足够好;合代码,是把一段代码变成生产环境里真实运行、真实服务用户、真实产生收益或事故的东西。“合”这个动作背后压着的是回归测试、代码审查、兼容性验证、权限确认、性能评估、可回滚性预案,这些没有一个环节因为 AI 发生本质变化。
说得再直白一点:以前一个功能要写三天,代码质量再烂,你能在写的过程中对系统形成体感,知道这个模块还有哪些历史包袱、哪条调用链容易断。现在 AI 十分钟就把代码写完了,你可能只花了三分钟看它输出的内容,对系统的理解深度完全不在一个级别,但 Merge 之后承担线上责任的还是你。
我见过太多团队出现这个现象:工程师用 AI 写代码的生产力确实翻倍了,但 Code Review 的队列长度翻了三倍,发布窗口反而变长了。每个人都在看别人代码,每个人都被别人的代码卡住,整个团队的吞吐不升反降。以前是写代码慢、合并快,现在是写代码快、合并慢,瓶颈发生了彻底转移。
1.3 门槛归零,不等于责任归零
“写代码门槛归零”这句话本来没啥问题,但很多人把它误解成了“人人可以当程序员”。我特别想纠正一下这个认知。
写代码的门槛说的是“把逻辑变成语法的能力”,这个确实被 AI 大幅拉低了。但做软件的门槛从来都不只是写代码,而是对问题域的理解、对系统边界的设计、对异常路径的预判、对长期可维护性的权衡。这些能力并不会因为你用了 AI 就自动长出来。
打个比方,驾驶的门槛也很低,方向盘、油门、刹车,会的人很多。但真正决定一辆车能不能安全到终点的,是司机对路况的判断、对车辆性能的熟悉、对突发情况的应对。AI 相当于给你配了一个副驾,能帮你打方向盘、踩油门,但它不会替你做那个“值不值得并线”的判断,更不会替你把责任扛了。
所以每当我看到有人用 AI 写完一个功能直接点了 Merge,我就心里一紧。这跟我看到有人考完科目二第二天就上高速是一个感觉——不是不能开,是出事的概率被无限放大了。
2. 不敢点 Merge 的背后:AI 代码的四种“隐形缺陷”
2.1 上下文缺失:模型只看到“这一段”,没看到你的整个系统
如果你仔细观察过 AI 写代码的过程,会发现它本质上在做“条件概率推理”——根据前面已经出现过的代码和你的提示,预测后面最可能出现的代码。这个预测能力的上限,取决于它能看到的上下文有多长、多大。
问题在于,真实软件系统的正确性,往往不取决于单个文件内部的一致性,而取决于跨文件、跨模块、跨服务的隐式约定。比如一个方法返回的是标准时区时间还是东八区时间,跟它所在的模块历史习惯有关;一个字段到底要不要加密,跟这条链路下游的消费方能力有关;一个接口能不能加超时重试,跟上游服务是否幂等设计有关。
AI 模型即便能索引整个仓库,它在生成某一个函数时,实际“专注”的窗口依然是有限的。它很可能没意识到你这个项目的错误处理规范是“抛异常”而不是“返回空值”,没意识到你的数据库连接池在极端并发下会打满,没意识到你的定时任务对执行耗时有一个一百毫秒的硬性要求。它在一个片段里写出的代码逻辑自洽,放到整个系统里却像一块从别的机器上拆下来硬装上去的零件——能装上,但一开工就漏油。
我在审查 AI 生成的代码时,最常问的一个问题就是:“这段代码跟它周围一公里范围内的代码,共享了哪些隐式假设?”如果回答不上来,那这段代码大概率存在上下文缺失问题。
2.2 幻觉式自信:错误永远在逻辑层,而不在语法层
很多人对 AI 写代码有个误解,觉得它的主要错误是语法错误、编译不过。恰恰相反,大模型生成的代码在语法层面几乎是无懈可击的,它的错误高度集中在语义和逻辑层。
什么是逻辑层的错误?举个例子,我让 AI 写一个从 Unix 时间戳转换到“几天前”的人类友好文本函数。它写出来的代码结构非常干净,分支判断看着也合理,但它在处理“刚刚”和“1 分钟内”的边界时,用了<= 60和> 60两个条件,结果正好在 60 秒这个点上漏了一个分支,显示成了空字符串。这种错误你在快速 Review 时根本看不出来,只有跑到那一条边界用例时才会暴露。
更麻烦的是,AI 模型在被训练时见过海量代码,它对“一个正确的函数应该长什么样”有很强的统计把握,所以它生成的代码在结构和命名上都非常像“正确代码”。这反而成了一个陷阱:代码长得太像一个靠谱工程师写的,人的大脑在审查时就会启动“差不多就行”的节能模式,警惕性直线下降。这种心理机制在实验室里叫“自动化偏见”——你会发现人类对机器给出的结果,比对同事给出的结果更倾向于无脑信任。
所以我对 AI 代码的审查策略,跟对同事代码的审查策略是相反的。同事的代码我会先看逻辑再看边界,AI 的代码我会先跑边界用例再看逻辑。顺序一换,抓出来的 bug 数量立刻翻倍。
2.3 安全债与合规债:账号、权限、加密的揪心点
如果说逻辑错误是“跑出来才会出事”,那安全和合规问题就是“埋在那里随时爆炸”。
AI 模型训练时见过的代码里,充斥着大量不安全的范例。你让它写一个登录接口,它会很自然地把密码用 MD5 哈希后存进数据库,因为训练数据里这么做的人太多了;你让它写一个内网接口的鉴权逻辑,它很可能直接省略掉,因为训练数据里很多示例都是在假设“内部可信网络”的前提下写的。对于刚接触编程的新手来说,这些代码看起来完全正常,甚至很专业,但如果它们被合并进生产系统,就是实打实的风险敞口。
我前阵子帮一个朋友审查他的 AI 生成项目,发现里面一个文件上传接口没有做任何文件类型校验,用户可以直接上传任意后缀的脚本文件。这个接口还是公网可访问的。一问才知道,他的提示词只写了“实现文件上传接口”,AI 就认认真真给他实现了一个“裸奔版”。他不是不重视安全,是根本不知道“文件上传需要校验类型”这件事——而 AI 并不知道他不知道,于是默认给了自由发挥的版本。
这就是我强调“运行正确不等于安全正确”的原因。AI 可以把功能跑通的概率做到很高,但它把安全边界、权限模型、敏感数据保护这些事情做对的概率,远没有大家以为的那么高。原因很简单:安全是典型的短板逻辑,一百条代码里只要有一条没注意,整个系统就破了,而概率模型天然不擅长处理这种“少数关键点决定成败”的任务。
2.4 风格与架构的“邮票代码”:能跑,但整座大厦快塌了
第四个隐形缺陷最隐蔽,也是老工程师面对 AI 代码时最头疼的——它叫“邮票代码”。意思就是每段代码单独拿出来都像一张漂亮的邮票,但你把一百张邮票拼成一张完整的地图时,发现它们拼缝都对不上。
具体来说,AI 生成代码有严重的“风格漂移”问题。同一个项目里,你让 AI 写三个不同的模块,它很可能用三套不同的错误处理模式:第一个模块用的是返回值布尔型,第二个模块用的是异常捕获,第三个模块用的是 Optional 空值判断。单独 Review 每一段,代码都很干净,但合在一起,维护者每次切换模块都得先切换思维方式,认知成本剧增。
更严重的是架构层面的问题。AI 没有“长期记忆”,它不会记得上周你刚刚定下的“所有外部 API 调用必须走统一网关”的约束。于是你某天让它实现一个第三方支付回调,它可能就直接在业务代码里裸发了一个 HTTP 请求,绕开了你整个团队辛苦搭建的网关层。这种代码跑起来没有任何问题,但它会像白蚁一样,一点点啃噬掉你系统的架构边界。
我管这种代码叫“维护者的仇人”。因为它隐藏得很深,不会炸在你头上,而会炸在三个月后接手你代码的那个倒霉同事头上。等他看到一段没有走任何统一规范的代码,他只能默默承担理解、迁移、适配的全部摩擦成本。而这正是 Merge 真正昂贵的地方——你合并进去的不只是功能,更是未来的维护负担。
3. 我实际踩过的 Merge 事故现场
3.1 事故一:一次“优雅”的重构,把三天的对账数据算错了
先说一个让我印象最深的事。当时我们有一个对账系统,负责每天拉取第三方支付渠道的清算文件,跟本地订单流水做核对。这个模块有一块核心逻辑,涉及金额单位转换和时区对齐,历史包袱很多。我问 AI:帮我把这段对账逻辑重构一下,让它更清晰。
AI 很快给了我一个看起来非常优雅的版本。它把原来的double都换成了BigDecimal,把时区转换抽成了一个工具方法,还加了详尽的注释。代码审查时我一眼扫过去,觉得重构质量很高,甚至比我手写的好,于是点了 Merge。
事故发生在第二天凌晨的对账任务上。当天对账单里多了几千条差异记录,财务那边直接炸了。排查了半天才发现,AI 在“优化”时,把一个原本在“转换前”取整的逻辑改成了“转换后”取整,还自作主张把原来一个只处理正向金额的分支扩展成了同时处理负向金额。这两处改动单看都有合理性,甚至可以说更“健壮”,但它们违背了这个系统的业务假设——第三方清算文件的金额格式和本地订单有 0.01 元的精度差,原来的取整时机就是为了抹平这个精度差设计的。
这次事故给我上了一课:AI 的重构本质是“根据统计规律做的形态优化”,它不理解业务规则的历史成因。你以为它在帮你清理债务,实际上它是在偷偷替换你系统的地基。从那以后,我定了一个死规矩:核心业务逻辑的修改,AI 可以出第一版,但必须由熟悉业务的人逐行核对,并且必须配套针对历史问题场景的回归用例。
3.2 事故二:AI 补全的依赖升级,把整个构建环境带崩
第二个事故不是发生在运行环境,是发生在构建阶段。当时我让 AI 修一个前端构建报错,它看了一眼报错信息,很自信地告诉我:这个报错是因为某个依赖版本太旧,升级一下就好。我想也没想就让它自动执行了升级命令。
结果那个依赖从旧版本升到新版本之后,因为破坏性变更,把另一个传递依赖的 API 接口给切断了。整个项目的编译瞬间从“一个报错”变成了“三十多个报错”。更要命的是,由于那个新依赖引入了一个兼容层文件,它跟项目里另一个库在运行时有一个冲突,这个问题在本地根本测不出来,直到部署测试环境才暴露。
事后复盘我发现,AI 当时做了它训练数据里最常用的修复策略——升级依赖,但它没有能力去评估“升级这个依赖会影响到哪些其他依赖的版本约束”。人类的工程师在遇到依赖版本冲突时,会先看package.json的依赖树,会检查破坏性变更日志,会评估兼容矩阵,这些步骤 AI 并没有被明确要求执行,它就跳过了。
这次的教训是:AI 对“修 bug”的理解和人对“修 bug”的理解存在偏差。人知道 bug 只是问题的表象,依赖升级只是手段之一;AI 只知道“报错→找解决方案→输出结果”,它不关心这个结果会不会制造新的问题。所以现在我在让 AI 修复构建问题之前,一定会把限制条件写清楚,比如“不许升级任何依赖”,如果非升不可,必须先输出完整的变更影响清单。
3.3 事故三:测试全绿,但线上刷新慢了 40 倍
第三个事故是最讽刺的——所有单元测试都通过了,代码合并后,线上接口性能却崩了。
那次是让 AI 优化一个用户画像查询接口,输入参数是用户 ID,输出是该用户的标签集合。原实现是查一次数据库然后组装返回,平均耗时 80 毫秒。我让 AI 看看有没有优化空间,它给出了一版修改:把关联查询拆成了三个并行查询,再用内存合并。
从画面上看,这版逻辑没毛病,并行查询听起来当然比串行快。但问题是,AI 没有意识到这个接口的底层数据库是一个主从分离的架构,三个并行查询里有好几个打到了从库,而从库承担着大量报表查询任务,负载本来就不低。结果接口平均耗时直接从 80 毫秒飙升到了 3.2 秒,线上大量超时告警。
我后来想到一个更贴切的比喻:AI 就像一个刚拿了驾照但没跑过早晚高峰的司机,它知道“换到快车道可能更快”,但它不知道那条车道在三公里后会因为修路变成一个堵死点。它只看得到路线图上的局部路段,看不到整条路的动态路况。
这类性能问题的隐蔽性比逻辑错误更高。因为测试环境的数据量小、并发低,接口耗时差异根本测不出来;只有到了生产环境,在真实数据量、真实并发下才会爆炸。所以从那以后,我要求所有 AI 优化的接口,必须附上一份“改动前后基准测试”的对比报告,没有对比不做 Merge。
3.4 从三次事故里总结出的规律
三个事故摆在一起看,规律非常清楚:AI 生成代码的出问题模式,不是“它不够聪明”,而是“它过度自信地使用了它掌握的不完整信息”。
代码层面的错误还好发现,跑一遍测试就能暴露;但系统层面的错误,比如重构破坏了业务假设、升级破坏了依赖兼容、优化破坏了性能模型,这些都需要对系统的整体理解才能识别。AI 没有这个整体理解,而如果审查者自己也没有,那就只能交学费。
所以我慢慢形成了一个公式:AI 代码的可信度 = 模型能力 × 任务边界清晰度 × 审查者的系统理解深度。前两项是乘法关系,第三项是加了,更准确地说,审查者的系统理解是那个“挂一漏万”的最后防线。没有这道防线,前两项再高,都保不齐在某个点上翻车。
4. 让“Merge”重新变得可信的实操方法
4.1 先给 AI“立规矩”:写代码规则与提示词工程
面对 AI 代码,我最反感的一句话是“你让它自己写就行了”。自己写的前提,是你得先告诉它边界和约束。就像你请一个新员工写代码,不会丢下一句“你看着办”就走,你会先给一份团队规范文档。AI 也是一样。
我的做法是,在项目根目录放一份AGENTS.md或者“编码规则”文档,把团队的技术栈、代码风格、错误处理规范、禁止事项写得清清楚楚。然后在每次让 AI 生成代码时,把这份文档作为提示词的固定前缀喂给它。别嫌这一步麻烦,实测下来,有了规则约束的 AI 代码,和裸生成代码的质量差距是数量级的。
我举一个实际提示词的例子,你可以直接抄:
你是本项目的资深后端工程师。请严格遵循以下团队约束: 1. 所有时间类型必须使用 UTC 存储,展示层再做时区转换; 2. 所有外部 API 调用必须通过 HttpClientService 统一封装,禁止裸写 HttpClient; 3. 异常处理统一抛业务异常 BizException,禁止返回 null 或吞掉异常; 4. 所有 SQL 必须走 MyBatis 的 XML 文件,禁止在业务代码里拼 SQL; 5. 每次修改必须给出对应的单元测试用例,覆盖正常、异常、边界三条路径。 以下是我的需求:[这里填具体任务]你会发现,加了这一串约束之后,AI 生成代码的质量会立刻贴近你的团队标准。原因很简单,大模型是上下文学习模型,你在提示词里给了哪些样例和规则,它就会倾向性地产出符合这些规则的内容。提示词工程在 AI 编程里不是玄学,它就是“把团队规范塞进模型的短期记忆里”。
4.2 建立 AI 代码的“验收清单”:什么样的代码才能进主干
光有规矩还不够,你还需要一套“验收清单”,让 Merge 这个动作从“凭感觉”变成“按标准”。我把这套清单固化成了四个大项,每一项不满足都直接打回:
第一,行为正确性。不只是“测出了结果就完事”,而是要针对输入边界、异常输入、并发场景、数据量极端这些维度逐一过一遍。AI 代码最容易在边界上翻车,所以这一项不能省。
第二,系统兼容性。这段代码调用的上下文是否跟现有系统一致?走的服务发现、配置中心、监控上报是不是和团队统一方案一致?有没有绕开网关、跳过鉴权、绕过统一日志这种架构逃逸行为?
第三,数据安全性。涉及用户数据的操作有没有做权限校验?敏感字段有没有加密?文件上传有没有校验类型和大小?SQL 有没有注入风险?日志里有没有输出明文手机号、身份证这类敏感信息?
第四,长期可维护性。命名是否符合规范?有没有留下让接手者困惑的魔法数字?有没有复制粘贴三遍以上的重复代码?如果这边代码三个月后需要改,维护者需要看多少文件才能看懂它?
我把这四项做成一个 PR 模板,每次提交 AI 代码的时候,让写代码的人先自评一遍再发给我。刚开始大家都觉得烦,坚持一个月之后,所有人都真香了——因为 Merge 被拒的次数直线下降,整个团队的发布节奏反而变顺了。
4.3 把 Code Review 从“读代码”变成“验证场景”
很多人 Review AI 代码的习惯是“用眼睛读”,读完了凭感觉说没问题。我要说的是,这恰恰是最危险的做法。因为 AI 代码在“看起来没问题”这个维度上表现得非常好,你的眼睛会被它的表面正确欺骗。
我的做法是,把 Review 的重心移到场景验证上。拿到一段 AI 生成的代码,我不急着一行行读,而是先问三个问题:
这段代码要服务的核心场景是什么?
- 在这个场景里,历史上最容易出错的地方是哪里?
- 如果这段代码今天上线,最可能挂掉的环节是哪个?
然后我带着这三个问题去看代码,最后一定会落到实际操作上:把代码跑起来,构造真实用例去打它,强迫它出错。我在本地用一个构造的异常输入打断它的主流程,故意传一个空字符串、传一个超大数字、让一个下游接口超时,看它会怎么反应。一套边界用例跑完之后,AI 代码的真实可靠性才算测出来。
为什么这种方法有效?因为 AI 生成的代码最怕的不是被“看懂”,而是被“验证”。你可以不懂它内部的每一行逻辑,但只要你把它放在真实场景里暴打一顿,它会自己暴露所有你没看到的细节缺陷。这也是我从“审查代码”到“验证代码”这个思路转变的核心收获。
4.4 小步 Merge、灰度发布与快速回滚
最后一条实操原则是:让每一次 Merge 变得足够小,小到即使出事,也能在一分钟内定位并回滚。这是我经历多次事故之后总结出来的最重要的红线。
AI 编程工具天然有“生成量巨大”的倾向。你让它实现一个功能,它恨不得把一个完整模块都吐给你。如果你为了省事把这一大坨东西一次性合并,恭喜你,你已经把“容错率”三个字从词典里删掉了。因为一旦线上出了问题,你面对的一个几百行代码的巨型 PR,连逐行排查都是噩梦。
我的做法是:要求 AI 的输出必须拆成小步提交。一个功能拆成“数据模型定义 → 服务层接口 → 控制器层 → 测试用例”四五个 PR,每个 PR 控制在 200 行以内,合并一个、验证一个、再进入下一个。这样即使某一环出错,回滚范围极小,影响面也被限制在单点。
另外,凡是涉及数据库变更或者核心接口逻辑的 PR,一律走灰度发布。先用 1% 的流量跑十分钟,观察错误率和延迟指标,再逐步放量到 10%、50%、100%。这套流程听起来笨重,但它能帮你把 AI 代码的隐患卡在上线前,而不是爆在用户面前。回滚预案更不是摆设,你手上必须随时有一条“一键回滚到上一版本”的命令,不能等到出事了再去翻操作手册。
5. 常见问题与排查技巧实录
5.1 高频问题速查表
这里我整理了一些团队里被问得最多的问题,你可以直接对照排查:
| 问题现象 | 常见原因 | 排查思路 |
|---|---|---|
| 功能能跑,但边界数据异常 | AI 没有覆盖边界分支 | 构造空串、零值、超大数、并发请求逐一实测 |
| 本地测试通过,线上接口变慢 | 测试环境数据量差异 | 用生产样本量做基准测试,对比改动前后耗时 |
| 编译报错,修复后又出新错 | AI 未看清依赖约束 | 明确禁止升级依赖,或要求输出完整影响清单 |
| 代码风格跟项目不协调 | 提示词缺团队规范约束 | 在提示词前缀加 AGENTS.md / 编码规则 |
| 合入后感觉很怪但说不清 | 架构边界被绕开 | 检查是否走了统一网关、统一日志、统一状态码 |
| 重构后行为发生变化 | AI 优化改变业务假设 | 用历史问题场景回归用例重新验证 |
这个表里的每个场景,基本覆盖了我和团队这一年来遇到的八成以上问题。你可以把它直接存成团队的 PR 自查清单,每个 PR 提交前过一遍。
5.2 我对 AI 代码的“三条铁律”
经过这么多次事故之后,我给自己和团队定了三条铁律,简单粗暴,但非常好用。
第一条,AI 可以写初稿,但写代码的人必须理解每一行代码在干什么。如果你看着 AI 生成的代码,有一行看不懂,那这一行就必须被简化或者重写。不懂就 Merge,等于把命运交给了一段你不理解的黑盒。
第二条,凡是被 AI 重构过的核心代码,原实现的“历史问题回归清单”必须逐项跑一遍。因为 AI 不知道这些代码曾经踩过哪些坑,只有曾经扛过这些坑的人才知道哪里最容易复发。
第三条,AI 声称的性能优化、安全性修复,必须提供可验证的证据。说优化了,就要有前后基准测试对比;说修复了安全漏洞,就要有漏洞复现步骤和修复验证截图。没有证据的承诺,一律视为没完成。
这三条铁律执行下来,AI 编程在团队里的价值曲线变得健康了很多:它确实把重复性工作的效率拉了起来,同时没有因为效率提升而把风险敞口放大。
5.3 最后分享两个亲测实用的小技巧
收尾前再分享两个特别实用、但很少有人提的小技巧。
第一个是“反向心理测试法”。当你拿到一段 AI 写的代码,不要直接问“这个代码对不对”,而是故意跟它抬杠:“这段代码我觉得有问题,在 XXX 场景下会出错,你能找出证据证明我是错的吗?”这个技巧利用了模型的对抗性思考能力——它会主动去搜索反例来验证自己的代码,往往能逼出一些之前没暴露的边界缺陷。我多次用这个办法,在 Merge 前提前抓到了那种极其隐蔽的时区转换错误和空指针隐患。
第二个是“上下文加热法”。每次让 AI 改代码之前,不要只贴一个函数,而是把相关的三到五个文件一起贴给它,再用一两句话说明这些文件之间的关系。比如“这是控制器,这是服务实现,这是数据库实体,请你在不改变接口行为的前提下调整缓存策略”。这样做的效果非常明显——AI 生成代码的上下文微调,能让它的跨文件逻辑一致性显著提升。
说到底,AI 编程工具给我们带来的,不是“不用懂代码”的自由,而是“把精力从写转移到审”的解放。真正决定一个项目命运的,永远不是那段被 AI 快速生成的代码,而是那个在 Merge 按钮前多想了一秒、多验证了一个场景、多守住了一条底线的人。写代码的门槛确实归零了,但把代码合入生产环境的门槛,从来都没消失过——它只是换了一种方式,继续筛选着真正负责任的工程师。
这些年我最大的体会是:不要被“人人都是开发者”的口号冲昏头脑。AI 把写代码的门槛降下来,恰恰意味着“会不会写”变得不值钱了,值钱的是“敢不敢负责、能不能看穿代码背后的系统”。在每一次点击 Merge 的瞬间,AI 不会替你做决定,责任也不会因为代码是 AI 写的就减轻半分。工具越强大,使用它的门槛其实越高——因为你能造成的破坏,也因此放大了。对所有使用 AI 编程的朋友,我的建议始终只有一句话:效率可以交给 AI,信任必须留给人。