AI 生成的代码,哪些地方最容易埋坑? 📅 发布时间:2026/8/21 8:00:38 👁 浏览次数: 文章目录开篇本文不会讨论什么一、第一类坑AI 把业务规则补错了审查时要问什么二、第二类坑边界条件只写了“正常情况”建立边界检查表三、第三类坑异常处理把真实问题吞掉了四、第四类坑权限校验写了但位置不对五、第五类坑SQL、命令和文件操作存在安全风险六、第六类坑并发、重复提交和数据一致性被忽略七、第七类坑测试看起来很多却没有覆盖真正风险八、一次可复用的 AI 代码风险审查 Prompt九、我会按这 3 轮审查而不是只问一次第一轮需求一致性第二轮工程可靠性第三轮交付完整性十、我的 AI 代码埋坑检查卡十一、总结✍创作者全栈弄潮儿²⁰²⁶ 个人主页全栈弄潮儿²⁰²⁶ 专栏地址AI 编程进阶实战建议在此处插入文章头图深蓝色代码编辑器背景中央是一条发光的代码审查路径路径两侧有边界警示、锁、数据库、并发、测试和 AI 芯片图形画面不放文字不使用圆角。开篇AI 生成的代码最危险的地方是什么很多人会回答语法可能有问题 接口可能调用错 代码可能运行不起来这些问题当然存在。但它们通常比较容易被发现。编译器、类型检查、单元测试和本地启动都有机会把它们暴露出来。真正麻烦的是另一类问题代码可以运行但业务规则理解错了。测试可以通过但边界条件没有覆盖。接口可以返回结果但权限校验放错了位置。数据可以保存但并发时会出现重复或覆盖。日志看起来很完整却泄露了敏感信息。代码结构很“标准”却和当前项目的真实约定不一致。上一篇文章我们用 AI 建立了陌生项目的代码库导览。当 AI 开始基于项目上下文生成代码后下一步就不是继续追求“写得更快”而是要知道哪些地方必须人工审查。这篇文章整理一份我会固定检查的风险清单。能编译 ↓ 能运行 ↓ 符合需求 ↓ 符合项目约定 ↓ 边界、安全和并发可靠前两步只是起点不是交付标准。本文不会讨论什么本文不是一份针对某个编程语言的完整安全规范也不是说 AI 生成的代码一定不能使用。本文不会认为人工编写的代码就天然没有问题。建议逐行重写所有 AI 生成的代码。用静态检查工具代替业务评审和测试。把“代码风格不喜欢”直接等同于严重缺陷。只列出风险却不给出可执行的审查方法。本文关注的是哪些风险最容易被“看起来合理”的 AI 代码隐藏以及我们应该如何提前把它们问出来。一、第一类坑AI 把业务规则补错了AI 最常见的问题不是不会写代码而是在信息不足时擅自做决定。例如需求是用户可以修改收货地址。这句话没有说明用户能否修改已经发货的订单修改后是否需要重新计算运费一个订单是否允许多次修改地址是否需要经过风控校验修改地址后是否需要通知仓库AI 可能会生成一段逻辑if(order.getUserId().equals(currentUserId)){order.setAddress(newAddress);orderRepository.save(order);}代码没有明显语法问题但它可能绕过了订单状态、地址有效性、仓库同步和审计要求。审查时要问什么请审查这段实现是否完整覆盖了需求中的业务规则。 请分别列出 1. 代码明确处理的规则。 2. 代码隐含假设的规则。 3. 需求中尚未被代码覆盖的规则。 4. 需要产品或业务确认的问题。 不要因为代码可以运行就默认业务行为正确。看到 AI 代码中的if、默认值和兜底分支时要特别关注它是在实现已确认的规则还是在替我们发明规则二、第二类坑边界条件只写了“正常情况”AI 很容易先完成主流程再用几个简单判断补充异常。但真实系统的失败场景通常不止一种。以分页查询为例下面这段代码看起来很常见intoffset(page-1)*size;returnrepository.find(offset,size);它可能遗漏page为 0 或负数。size过大导致数据库压力。(page - 1) * size整数溢出。排序字段不稳定导致分页重复或漏数据。查询结果为空时的返回约定。用户是否有权限查看全部数据。建立边界检查表类型需要检查的内容空值null、空字符串、空集合是否有明确行为数值0、负数、最大值、溢出和精度字符串长度、格式、特殊字符和编码集合空集合、重复元素、超大数量状态状态已完成、已取消、已删除时还能否操作时间时区、过期、跨天和并发时间窗口资源文件不存在、网络超时、数据库连接失败可以让 AI 专门做第二轮边界审查请不要修改代码只审查边界条件。 请按“输入、状态、时间、数据量、依赖失败、并发”六类分析 1. 当前代码已经覆盖的场景。 2. 当前代码遗漏的场景。 3. 每个遗漏场景可能造成的结果。 4. 建议补充的测试用例。三、第三类坑异常处理把真实问题吞掉了为了让程序“不要报错”AI 有时会生成过度宽泛的异常处理try{returnpaymentClient.pay(request);}catch(Exceptione){log.error(支付失败,e);returnPayResult.failed();}这段代码的问题不只是捕获范围太大。支付请求超时并不一定代表支付没有发生。如果直接返回失败用户可能再次支付最终形成重复扣款。异常审查至少要确认捕获的异常是否过宽。是否区分参数错误、业务拒绝、超时和系统故障。异常发生时数据是否已经部分写入。是否需要回滚、重试或人工补偿。返回给用户的信息是否足够明确。日志是否保留了排查所需的上下文。可以使用这段 Prompt请审查这段代码的异常处理不要只检查有没有 try-catch。 请逐项回答 1. 哪些异常可以直接返回失败 2. 哪些异常代表结果未知不能简单重试 3. 是否存在部分成功或部分写入 4. 是否可能吞掉真正的系统故障 5. 日志和用户提示是否分别满足排查与体验需要 6. 是否需要回滚、幂等、重试或补偿机制异常处理的目标不是“所有情况都返回一个结果”而是让系统在失败时保持可理解、可恢复。四、第四类坑权限校验写了但位置不对AI 经常会补充权限判断但权限并不只是一个if。下面这段代码看起来像是做了权限控制if(!currentUserId.equals(request.getUserId())){thrownewForbiddenException();}但它仍然可能存在问题request.getUserId()是否可以被用户篡改管理员是否拥有特殊权限资源实际归属是否需要从数据库查询确认查询接口是否已经在权限校验前返回了敏感信息列表接口是否只校验了页面而没有校验每条资源删除、导出、批量操作是否使用了同样的权限规则审查权限时我会让 AI 先画出“身份、资源、动作”的关系谁当前用户、管理员、服务账号 对什么订单、文件、用户资料 做什么读取、修改、删除、导出 在什么条件下资源归属、组织范围、状态限制对应 Prompt请审查这段代码的鉴权和越权风险。 请不要只判断“有没有权限判断”还要分析 1. 身份来自哪里是否可信。 2. 资源归属在哪里确认。 3. 当前用户可以执行哪些动作。 4. 是否存在水平越权和垂直越权。 5. 列表、批量和导出场景是否可能绕过单条校验。 6. 权限判断发生在敏感数据返回之前还是之后。权限校验应该靠近业务边界并且覆盖所有能够改变或暴露资源的入口。五、第五类坑SQL、命令和文件操作存在安全风险AI 生成外部输入相关代码时最容易出现“示例能跑生产不安全”的问题。重点检查这些位置SQL 拼接。Shell 命令拼接。文件路径拼接。URL 或重定向地址拼接。HTML、Markdown 和模板渲染。反序列化和反射调用。日志内容中的用户输入。例如Stringsqlselect * from user where name name;代码可能可以执行但输入一旦来自用户就存在注入风险。安全审查 Prompt 可以这样写请对这段代码做一次输入安全审查。 请重点检查 1. 用户输入流向了哪些数据库、命令、文件、HTML、URL 或日志位置。 2. 是否存在拼接、未编码、未校验或未限制长度的输入。 3. 当前使用的防护是否真正覆盖了对应场景。 4. 是否可能造成注入、越权、路径穿越、敏感信息泄露或资源滥用。 5. 请给出最小修改建议不要直接大范围重写。不要只问 AI“这段代码安全吗”。要把输入从哪里来、最后去了哪里写清楚审查结果才更具体。六、第六类坑并发、重复提交和数据一致性被忽略很多 AI 生成的代码在单线程、单请求环境下表现正常但线上请求永远不是这样。典型问题包括两个请求同时创建相同资源。先查询再插入导致重复数据。库存扣减出现超卖。重复消费消息。重试导致重复支付、重复发券或重复通知。缓存更新早于数据库提交。多个线程同时修改同一条记录。例如if(couponRepository.findByUserId(userId)null){couponRepository.insert(userId,couponId);}只要两个请求同时通过查询就可能插入两次。审查并发问题时可以让 AI 按时间顺序推演请对这段代码进行并发和幂等审查。 至少模拟以下场景 1. 两个相同请求同时到达。 2. 请求执行到一半后重试。 3. 数据库写入成功但响应丢失。 4. 消息被重复消费。 5. 外部接口超时但实际已经成功。 请说明 - 哪一步会产生竞态。 - 当前代码是否有唯一约束、锁、版本号或幂等键。 - 可能造成什么重复或不一致。 - 应该通过代码、数据库还是消息层修复。并发安全不能只靠 AI 在代码里加一个锁。要结合数据库约束、事务、消息语义和业务幂等一起判断。七、第七类坑测试看起来很多却没有覆盖真正风险AI 很擅长生成测试样例但它容易围绕“代码分支”写测试而不是围绕“业务风险”写测试。例如测试覆盖了有效参数 → 成功 无效参数 → 失败却没有覆盖权限不足。重复请求。状态不允许操作。依赖超时。数据库写入后消息发送失败。同一个资源被并发修改。敏感字段没有出现在响应和日志中。可以让 AI 先做测试矩阵而不是直接生成测试代码请根据这段实现设计测试矩阵暂时不要写测试代码。 请按以下类别输出 1. 正常流程。 2. 参数边界。 3. 业务状态。 4. 权限安全。 5. 并发幂等。 6. 数据库和外部依赖失败。 7. 日志、响应和敏感信息。 每项包含 - 前置条件 - 操作 - 预期结果 - 验证重点 - 当前测试是否已有覆盖测试数量多不代表风险覆盖完整。八、一次可复用的 AI 代码风险审查 Prompt当一段 AI 代码准备进入项目时我会先使用下面这份 Prompt请作为一名严格的代码审查者审查下面这段 AI 生成的代码。 已知需求 填写需求和验收标准 已知项目约束 填写项目分层、异常、鉴权、事务和测试规范 请按严重程度输出问题 - Blocker可能导致严重数据、安全或资金问题 - High可能导致核心功能错误或线上故障 - Medium边界、维护性或可观测性问题 - Low风格、可读性或改进建议 重点检查 1. 业务规则和隐含假设 2. 空值、边界和状态流转 3. 异常、回滚、重试和补偿 4. 鉴权、越权和敏感数据 5. SQL、命令、文件和模板注入 6. 并发、幂等和数据一致性 7. 日志、监控和可观测性 8. 测试是否覆盖关键风险 9. 是否符合现有项目约定 每个问题请包含 - 严重程度 - 文件和代码位置 - 问题描述 - 触发条件 - 可能后果 - 最小修改建议 - 建议增加的测试 如果没有足够上下文请明确列出“无法确认项”不要自行假设。 最后请给出 1. 必须修复的问题 2. 建议修复的问题 3. 可以暂不处理的问题 4. 进入测试前还需要补充的上下文这份 Prompt 的价值在于它要求 AI 说明“什么情况下会出问题”而不是只给出模糊评价。九、我会按这 3 轮审查而不是只问一次一次审查通常不够。我更倾向于分三轮进行第一轮需求一致性这段代码是否实现了正确的业务规则重点看范围、状态、权限和隐含假设。第二轮工程可靠性这段代码在异常、并发、重试和依赖失败时是否可靠重点看事务、幂等、数据一致性和可恢复性。第三轮交付完整性这段代码是否有足够的测试、日志、监控和文档支持重点看验证闭环而不是只看主流程。分轮审查的好处是避免把所有问题混在一起也方便开发者逐项处理。十、我的 AI 代码埋坑检查卡在合并 AI 生成的代码前我会快速确认[ ] 业务规则不是 AI 自行猜出来的 [ ] 范围、状态和边界条件已经明确 [ ] 异常不会被宽泛捕获后静默吞掉 [ ] 失败时的数据状态可以解释和恢复 [ ] 鉴权覆盖了读取、修改、删除、批量和导出入口 [ ] 外部输入经过了正确校验、编码或参数化处理 [ ] 并发、重复提交和消息重复消费已经考虑 [ ] 事务、缓存、消息和外部调用的边界已经确认 [ ] 日志没有泄露密码、令牌、验证码和完整隐私数据 [ ] 测试覆盖了正常、边界、异常、安全和并发场景 [ ] 代码符合当前项目已有约定 [ ] AI 的结论已经回到源码、测试或运行结果中验证如果这张卡还有多项无法回答说明代码还不适合直接合并。十一、总结AI 生成的代码最容易埋坑的地方通常不是语法而是那些没有被明确写进需求的部分业务规则和隐含假设。边界条件和状态流转。异常、回滚、重试和补偿。权限、越权和敏感信息。输入安全和外部依赖。并发、幂等和数据一致性。测试是否覆盖真正的风险。因此拿到 AI 代码后不要只问这段代码能运行吗还应该继续问它在什么情况下会出错 出错后系统会处于什么状态 它是否符合真实业务和项目约定 我怎样用测试证明它没有遗漏关键风险请记住AI 可以快速生成代码但只有经过风险审查的代码才有资格进入工程系统。下一篇文章我们把今天的风险清单进一步固化成一套可直接复用的资产我的代码审查 Prompt从“能跑”到“可维护”。如果这篇文章对你有帮助欢迎点赞、收藏、关注专栏。也欢迎在评论区留言你审查 AI 代码时最容易忽略业务逻辑、并发问题还是安全风险✍坚持原创求关注点赞收藏