logo

AI 写完代码别急着上线:把好审查这五道关

作者:da吃一鲸8862026.11.06 22:00浏览量:0

简介:AI 编程让功能实现提速,但“生成通过”不等于“可以上线”。本文剖析 AI 生成代码的典型风险来源,给出一套覆盖需求对齐、静态检查、人工逻辑审查、测试验证、安全扫描与灰度上线的分层审查流程,并附可直接落地的评审清单,帮助团队在上线前拦住缺陷、避免返工。

一、先想清楚:AI 生成的代码,风险到底出在哪

在决定让 AI 大规模接管编码工作之前,就要接受一个前提:如果没有配套的验证流程,“开发提速”很快会被“上线返工”抵消。这不是危言耸听,而是由 AI 生成代码的固有特点决定的。

1. “看起来对”不等于“逻辑对”

AI 生成的代码往往语法正确、结构清晰、注释完善,这恰恰是最具迷惑性的地方。审查者容易在“看起来很专业”的第一印象下放松警惕。但 AI 对业务上下文的理解是局部的:它不知道你们系统里订单状态机有哪些合法迁移,不知道某个字段在下单场景允许为空、在结算场景却必须非空。这些隐性约束不会出现在提示词里,却恰恰是生产事故的高发区。

2. 幻觉与知识过时

大模型可能编造不存在的 API、参数或配置项,也可能使用早已被废弃的旧版写法。这类问题在动态语言中编译期未必能暴露,往往要等流量跑到对应分支才“炸”。

3. 一致性劣化

多次会话、多人分别与 AI 协作,容易产生风格割裂、重复实现已有工具函数、引入功能重叠的依赖等问题,长期看会持续拉高维护成本。

4. 责任主体不能模糊

代码是 AI 写的,但提交人和评审人对它负全责。如果因为“AI 写得快”就压缩审查环节,本质上是在用线上稳定性换开发速度——这笔账大多数团队算不过来。

二、审查前的地基:先把“完成”的定义写清楚

很多返工并不是代码写错了,而是“做出来的东西不对”。所以在审查代码之前,先确认以下内容是否明确:

  • 验收条件:需求是否拆解为可验证的输入、输出、边界与异常行为;
  • 接口契约:入参、出参、错误码、幂等性、超时语义是否有明确定义;
  • 非功能指标:性能、并发量、重试策略是否有量化要求。

这一步之所以关键,是因为 AI 输出的质量上限取决于提示词与上下文的完整度。需求本身模糊,AI 就会“自行脑补”,审查时你甚至没有基准可对照。

推荐实践:先让 AI 输出实现方案——改动点、影响面、数据流向,人工确认方案后再生成代码。方案级纠错的成本,远低于代码级返工。

三、分层审查流程:上线前的五道关卡

第一道:机器审查——能自动化的绝不靠人

  • 静态检查:格式、命名、圈复杂度、潜在空指针等问题;
  • 依赖检查:是否引入了不必要的新依赖、版本是否锁定、有无已知漏洞;
  • 构建验证:确保能通过最基本的编译与质量门禁。

可以用示意性的流水线配置表达这类门禁:

  1. # CI 质量门禁(示意)
  2. stages:
  3. - lint # 静态检查,新增告警视为失败
  4. - build # 编译构建
  5. - test # 单元测试 + 覆盖率门槛
  6. - security # 依赖漏洞与敏感信息扫描

原则很简单:AI 产出代码的速度远超人工阅读速度,凡是机器能拦住的问题,绝不消耗人的注意力。

第二道:人工逻辑审查——盯住 AI 最容易错的地方

人工审查不要逐行抠格式,把精力集中在四类问题上:

  • 业务正确性:代码是否真的实现了需求,而不是实现了“一个相似的需求”;
  • 边界与异常:空值、空集合、超长输入、非法枚举、并发调用、事务边界,以及异常是否被静默吞掉;
  • 数据一致性:多表写入是否有事务保护,缓存与数据库的更新策略是否自洽;
  • 资源与权限:是否存在越权访问,连接、文件句柄、后台任务是否正确释放。

下面是一个典型反例——AI 很喜欢生成的“吞异常”写法:

  1. # 反例:异常被静默吞掉,问题在下游才暴露
  2. try:
  3. save_order(order)
  4. except Exception:
  5. pass # 线上将出现“操作成功但无记录”的诡异现象
  6. # 修正:明确异常类型、保留上下文、决定重试或上抛
  7. try:
  8. save_order(order)
  9. except DBTimeoutError:
  10. logger.error("save_order timeout, order_id=%s", order.id)
  11. raise RetryableError("save_order retryable")

第三道:测试验证——用测试反向约束 AI

  • 单元测试:覆盖核心分支尤其是边界条件。可以让 AI 辅助生成用例,但断言值必须人工核对——AI 非常擅长写“永远通过”的测试;
  • 集成测试:验证模块协作以及真实依赖(数据库、缓存、消息队列等)下的行为;
  • 回归测试:确保新改动没有破坏既有功能。

一个重要提醒:不要让“生成代码的 AI”和“验证代码的 AI”基于同一份上下文自证清白。测试的预期结果必须来自需求文档,而不是来自被测代码本身,否则测试只是复述了实现,而非验证了实现。

第四道:安全与合规扫描

  • 敏感信息:AI 可能在示例代码中生成硬编码的密钥、内网地址,需自动扫描拦截;
  • 注入类风险:SQL 拼接、命令拼接、路径穿越等;
  • 依赖安全:新引入的第三方包是否存在已知漏洞;
  • 数据合规:日志中是否打印了手机号、证件号等敏感字段。

第五道:上线兜底——假设仍有漏网之鱼

无论审查多严格,都要承认“总有漏网的”,用发布策略兜底:

  • 灰度发布:小流量验证核心指标,再逐步放量;
  • 可观测性先行:关键路径埋点、错误日志、告警规则在发布前配置到位;
  • 回滚预案:发布前确认可快速回滚;涉及数据变更时采用先加后删、双写过渡等兼容方案。

四、AI 代码高频问题清单(可直接用于评审)

  • 是否存在不存在的 API、虚构的配置项(以编译和运行结果为准);
  • 新增依赖是否必要,版本是否锁定,有无已知漏洞;
  • 异常是否被吞掉或过度捕获;
  • 空值、空集合、超长输入、并发场景是否处理;
  • 是否重复实现了项目中已有的公共函数;
  • 是否存在硬编码的配置、密钥与魔法数字;
  • 事务边界与数据一致性是否有保障;
  • 日志与监控埋点是否覆盖关键路径;
  • 测试断言是否来自需求而非被测代码;
  • 是否有性能隐患(N+1 查询、循环内远程调用、无界缓存)。

五、把审查固化为团队流程,而不是个人习惯

  1. 提交人负全责:AI 是工具,代码质量的责任主体是提交人与评审人,这一点应写进团队规范;
  2. 评审模板增加自查项:例如“AI 引用的 API 是否验证过真实存在”“测试预期是否经人工核对”;
  3. 门禁前置:所有检查在代码合并前完成,而不是上线后补救;
  4. 闭环沉淀:把审查中发现的 AI 典型错误整理进团队知识库,反哺提示词模板与编码规范,让同类问题的发生率持续下降。

六、结语

“用 AI 写代码前,就要做好返工准备”——这句话背后真正的含义是:返工不是 AI 的宿命,而是流程缺失的代价。把审查拆成五道关卡——机器检查、人工逻辑审查、测试验证、安全扫描、上线兜底——让 AI 负责“写得快”,让流程负责“错得少”,速度红利才能真正落进口袋,而不是在一次次线上返工中被消耗殆尽。

发表评论

活动