AI 写一个功能只要几秒钟代码干净、看起来专业90% 的情况下还能跑起来。但“跑起来”和“安全到可以上线”是两回事而两者之间的距离正是现在大部分工作真正发生的地方。2026 年的一项研究显示只有约 35% 的 AI 生成后端代码同时满足安全和正确的要求。Veracode 对 100 多个模型、80 个任务的测试则发现接近一半的代码自带已知安全弱点。这些问题不会让代码编译失败也不会让常规测试报错它们藏在表面之下一眼看不出来。审查 AI 生成的代码已经成为一门独立技能而且和“自己写代码”的技能完全不同。模型没有写代码时的思考过程它只是根据训练数据里的模式“猜”出了答案也无法解释自己为什么这样选择。因此只验证“能不能跑”远远不够你必须像资深 reviewer 一样一层层往下挖。在开始具体步骤前先记住 AI 的三个底层特性它们是后面所有习惯的根源AI 工具被优化为“快速给出让人信服的答案”。可信和正确大量重叠这让危险变得隐蔽——你会下意识停止质疑。当你的需求留有空白时模型不会追问它会用训练数据里最常见的东西填补。模型在正确和错误时听起来同样自信。没有“语气破绽”你只能靠实际检查来判断。第一步先确认需求再看代码AI 可以完美解决一个根本不该被问的问题。你让它写“更新发票的接口”它会给你干净的更新逻辑却很可能完全没有权限校验。代码本身是正确的它只是回答了不该被问的问题。先找到原始需求工单、规格、甚至一句写下来的话。如果需求只剩一行 prompt就要格外警惕——模型已经把所有没说清楚的部分用常见模式填满了你现在审查的其实是那些“猜”出来的部分。然后把代码和需求对照这里要求的是什么它实际做了什么是否一致如果你连一句话都说不清这段代码原本要解决什么问题就不要急着 review。第二步质疑每一个工程决策每个技术选择都应该有权衡。模型通常跳过权衡直接拿训练数据里最常见的答案。举个真实例子一个需要高并发、大量等待外部服务的轻量服务用 FastAPIasync-first更自然。但你让 AI 写它大概率还是给你 Django因为“Python Web 后端”在训练数据里最常对应 Django。它没有权衡只是模式匹配。半年后团队可能在和框架死磕却没人知道当初为什么选它。对每个重大选择都要问一句这个选择是因为它真的适合当前场景还是因为它最常见“因为大家都这么用”不算理由。第三步读逻辑而不是读“拼写”语法错误会被编译器和 linter 免费抓住这些是廉价 bug。真正昂贵的是逻辑错误——边界条件、竞态条件、失败路径。AI 生成的代码特别擅长把“提示里描述的那条幸福路径”写得漂漂亮亮。真正的 bug 往往藏在提示没提到的边缘空列表、零、负数、最大值、并发冲突、记录不存在……把代码当成白板推演数据从哪里进来、怎么流动、每个步骤的失败路径是什么而不是只看它长得漂不漂亮。第四步猎杀隐藏假设这是我审查时抓到最多真实 bug 的一步。隐藏假设是代码默认“世界必须是这样”才能正常工作输入永远合法、外部服务永远响应、记录永远存在、网络永远通畅。这些假设在平静的 review 里完全看不出来因为代码在假设成立时确实能跑。但真实世界里第三方 API 变慢、用户发来畸形请求、网络中途断开……假设一旦不成立就变成线上事故。每看到一段代码就反复问它在默认什么把假设列出来然后为“假设不成立”的情况补上处理逻辑。第五步专门做一次安全检查模型可以给你一段跑得完美却完全敞开的代码这两者在模型眼里互不冲突。重点检查项按重要性排序认证与授权谁在调用这个人被允许做这件事吗OWASP Top 10 连续多年把 Broken Access Control 排第一输入验证是否在信任数据前做了清洗敏感信息密码、密钥有没有硬编码SQL 注入用户输入是否通过参数化查询幻觉依赖SlopsquattingAI 建议的包名是否真实存在先去真实 registry 查证再安装。另外别忘了反向检查你自己有没有把真实密钥、敏感逻辑粘到 prompt 里第六步用真实数据量测试行为开发环境只有十几条数据时性能问题几乎不会暴露。最经典的就是 N1 查询。AI 经常生成这样的代码# AI 生成版看起来没问题实际扩展性灾难defpost_list(request):postsPost.objects.all()forpostinposts:print(post.author.name)# 每条 post 都额外查一次数据库10 条数据 → 11 次查询1 万条数据 → 1 万零 1 次查询。正确做法是用select_related或prefetch_related把关联数据一次性取出来。审查数据库相关代码时问自己当表里数据量变大后这段代码的成本是多少第七步砍掉过度工程AI 既会偷懒也会过度设计。它喜欢从训练数据里抄来大而全的架构多层 service、各种抽象、为未来可能出现的情况做准备。结果是一个本来 10 行的功能被包在三层间接调用里。改一个小需求要改三四个文件bug 藏得更深维护成本直线上升。用 YAGNI 原则检验每个抽象它是否正在吸收真实发生的变更如果只是“以防万一”就删掉。需要的时候再加通常比提前加要便宜得多。第八步检查错误处理AI 生成的代码几乎把所有篇幅都花在“幸福路径”上失败路径写得极少或者完全没有。要找的信号一个可能失败的操作完全没有失败处理用了宽泛的except Exception把所有错误吞掉外部调用没有超时、重试、降级没有 fallback 机制对每个可能失败的操作都要追问它失败了会发生什么代码给出了答案吗第九步评估可维护性代码被读的次数远多于被写的次数。六个月后回头看或者别人接手时能不能快速理解和修改AI 代码常有的问题局部很聪明但整体难跟、跨多次 prompt 生成导致风格不一致、过度抽象导致调试困难。问自己三个问题六个月后我冷启动还能看懂吗一个没参与过的人能不能独立维护出问题时能不能快速定位任何答案为“否”的地方都是现在就该改的。最终检查清单合并前必过需求我清楚它原本要解决什么问题吗它真的解决了吗决策每个框架/数据库/模式的选型有真实理由还是只是默认答案逻辑我追踪过数据流检查过边界和失败路径了吗假设它默认了哪些输入、服务、记录、网络条件安全认证、授权、输入验证、密钥暴露、SQL 注入、幻觉依赖都检查过了吗性能有 N1 查询、缺失索引、过度调用吗复杂度每一层抽象都在为当前需求服务吗错误处理失败路径、降级、重试都考虑了吗可维护性六个月后的自己或同事能轻松接手吗输入安全我有没有把真实密钥粘进 promptAI 负责生成代码你负责判断它是否安全、正确、值得上线。这两件事从来都是分离的只有一件事被自动化了。把每次生成的代码当成一个快速、自信、偶尔粗心的贡献者提交的 draft而不是最终答案。多花在审查上的时间远比生成时省下的时间更有价值。下次你用 AI 生成一段代码后会先做哪一步审查或者你目前最常忽略的是清单里的哪一层欢迎在评论区分享你的实际案例。我是紫微AI在做一个「人格操作系统ZPF」。后面会持续分享AI Agent和系统实验。感兴趣可以关注我们下期见。
审查AI生成代码的9步实战指南:从“能跑”到“能安全上线”的完整检查
AI 写一个功能只要几秒钟代码干净、看起来专业90% 的情况下还能跑起来。但“跑起来”和“安全到可以上线”是两回事而两者之间的距离正是现在大部分工作真正发生的地方。2026 年的一项研究显示只有约 35% 的 AI 生成后端代码同时满足安全和正确的要求。Veracode 对 100 多个模型、80 个任务的测试则发现接近一半的代码自带已知安全弱点。这些问题不会让代码编译失败也不会让常规测试报错它们藏在表面之下一眼看不出来。审查 AI 生成的代码已经成为一门独立技能而且和“自己写代码”的技能完全不同。模型没有写代码时的思考过程它只是根据训练数据里的模式“猜”出了答案也无法解释自己为什么这样选择。因此只验证“能不能跑”远远不够你必须像资深 reviewer 一样一层层往下挖。在开始具体步骤前先记住 AI 的三个底层特性它们是后面所有习惯的根源AI 工具被优化为“快速给出让人信服的答案”。可信和正确大量重叠这让危险变得隐蔽——你会下意识停止质疑。当你的需求留有空白时模型不会追问它会用训练数据里最常见的东西填补。模型在正确和错误时听起来同样自信。没有“语气破绽”你只能靠实际检查来判断。第一步先确认需求再看代码AI 可以完美解决一个根本不该被问的问题。你让它写“更新发票的接口”它会给你干净的更新逻辑却很可能完全没有权限校验。代码本身是正确的它只是回答了不该被问的问题。先找到原始需求工单、规格、甚至一句写下来的话。如果需求只剩一行 prompt就要格外警惕——模型已经把所有没说清楚的部分用常见模式填满了你现在审查的其实是那些“猜”出来的部分。然后把代码和需求对照这里要求的是什么它实际做了什么是否一致如果你连一句话都说不清这段代码原本要解决什么问题就不要急着 review。第二步质疑每一个工程决策每个技术选择都应该有权衡。模型通常跳过权衡直接拿训练数据里最常见的答案。举个真实例子一个需要高并发、大量等待外部服务的轻量服务用 FastAPIasync-first更自然。但你让 AI 写它大概率还是给你 Django因为“Python Web 后端”在训练数据里最常对应 Django。它没有权衡只是模式匹配。半年后团队可能在和框架死磕却没人知道当初为什么选它。对每个重大选择都要问一句这个选择是因为它真的适合当前场景还是因为它最常见“因为大家都这么用”不算理由。第三步读逻辑而不是读“拼写”语法错误会被编译器和 linter 免费抓住这些是廉价 bug。真正昂贵的是逻辑错误——边界条件、竞态条件、失败路径。AI 生成的代码特别擅长把“提示里描述的那条幸福路径”写得漂漂亮亮。真正的 bug 往往藏在提示没提到的边缘空列表、零、负数、最大值、并发冲突、记录不存在……把代码当成白板推演数据从哪里进来、怎么流动、每个步骤的失败路径是什么而不是只看它长得漂不漂亮。第四步猎杀隐藏假设这是我审查时抓到最多真实 bug 的一步。隐藏假设是代码默认“世界必须是这样”才能正常工作输入永远合法、外部服务永远响应、记录永远存在、网络永远通畅。这些假设在平静的 review 里完全看不出来因为代码在假设成立时确实能跑。但真实世界里第三方 API 变慢、用户发来畸形请求、网络中途断开……假设一旦不成立就变成线上事故。每看到一段代码就反复问它在默认什么把假设列出来然后为“假设不成立”的情况补上处理逻辑。第五步专门做一次安全检查模型可以给你一段跑得完美却完全敞开的代码这两者在模型眼里互不冲突。重点检查项按重要性排序认证与授权谁在调用这个人被允许做这件事吗OWASP Top 10 连续多年把 Broken Access Control 排第一输入验证是否在信任数据前做了清洗敏感信息密码、密钥有没有硬编码SQL 注入用户输入是否通过参数化查询幻觉依赖SlopsquattingAI 建议的包名是否真实存在先去真实 registry 查证再安装。另外别忘了反向检查你自己有没有把真实密钥、敏感逻辑粘到 prompt 里第六步用真实数据量测试行为开发环境只有十几条数据时性能问题几乎不会暴露。最经典的就是 N1 查询。AI 经常生成这样的代码# AI 生成版看起来没问题实际扩展性灾难defpost_list(request):postsPost.objects.all()forpostinposts:print(post.author.name)# 每条 post 都额外查一次数据库10 条数据 → 11 次查询1 万条数据 → 1 万零 1 次查询。正确做法是用select_related或prefetch_related把关联数据一次性取出来。审查数据库相关代码时问自己当表里数据量变大后这段代码的成本是多少第七步砍掉过度工程AI 既会偷懒也会过度设计。它喜欢从训练数据里抄来大而全的架构多层 service、各种抽象、为未来可能出现的情况做准备。结果是一个本来 10 行的功能被包在三层间接调用里。改一个小需求要改三四个文件bug 藏得更深维护成本直线上升。用 YAGNI 原则检验每个抽象它是否正在吸收真实发生的变更如果只是“以防万一”就删掉。需要的时候再加通常比提前加要便宜得多。第八步检查错误处理AI 生成的代码几乎把所有篇幅都花在“幸福路径”上失败路径写得极少或者完全没有。要找的信号一个可能失败的操作完全没有失败处理用了宽泛的except Exception把所有错误吞掉外部调用没有超时、重试、降级没有 fallback 机制对每个可能失败的操作都要追问它失败了会发生什么代码给出了答案吗第九步评估可维护性代码被读的次数远多于被写的次数。六个月后回头看或者别人接手时能不能快速理解和修改AI 代码常有的问题局部很聪明但整体难跟、跨多次 prompt 生成导致风格不一致、过度抽象导致调试困难。问自己三个问题六个月后我冷启动还能看懂吗一个没参与过的人能不能独立维护出问题时能不能快速定位任何答案为“否”的地方都是现在就该改的。最终检查清单合并前必过需求我清楚它原本要解决什么问题吗它真的解决了吗决策每个框架/数据库/模式的选型有真实理由还是只是默认答案逻辑我追踪过数据流检查过边界和失败路径了吗假设它默认了哪些输入、服务、记录、网络条件安全认证、授权、输入验证、密钥暴露、SQL 注入、幻觉依赖都检查过了吗性能有 N1 查询、缺失索引、过度调用吗复杂度每一层抽象都在为当前需求服务吗错误处理失败路径、降级、重试都考虑了吗可维护性六个月后的自己或同事能轻松接手吗输入安全我有没有把真实密钥粘进 promptAI 负责生成代码你负责判断它是否安全、正确、值得上线。这两件事从来都是分离的只有一件事被自动化了。把每次生成的代码当成一个快速、自信、偶尔粗心的贡献者提交的 draft而不是最终答案。多花在审查上的时间远比生成时省下的时间更有价值。下次你用 AI 生成一段代码后会先做哪一步审查或者你目前最常忽略的是清单里的哪一层欢迎在评论区分享你的实际案例。我是紫微AI在做一个「人格操作系统ZPF」。后面会持续分享AI Agent和系统实验。感兴趣可以关注我们下期见。