1. 为什么企业级项目里的 AI 写代码总是“失控”
先说一个我观察了很久的现象:很多团队其实早就把 AI 用进了研发流程,但用的方式基本都是“个人增强”而不是“工程化落地”。开发者在 IDE 里装一个 AI 插件,选中一段代码让它补全,或者把整个文件丢给它让它重构,生成完自己看一眼就提交。这套玩法在个人项目、开源小工具上完全没问题,但放到企业级项目里,几乎必然出事。
原因也很简单。企业级项目和独立开发者的 Scratch Project 有本质区别:多人协作、历史包袱重、业务规则复杂、安全合规要求高、上下游系统耦合深。AI 生成的代码在这里不是“能不能跑”的问题,而是“敢不敢上线”的问题。我见过一个真实案例:团队用 AI 生成了一段订单状态流转的逻辑,单测跑通了,肉眼看着也没毛病,结果上线第二天发现它把“已支付”到“已完成”中间漏掉了一个对账系统要用的中间态,直接导致财务侧数据对不上。代码没有语法错误,甚至逻辑看起来是对的,但它违反了业务领域的隐含约束。
这就是“可控”这个词的价值所在。个人项目里代码是给自己看的,错了马上能发现、能修。企业级项目里代码是给整个系统、给上下游、给未来接手的人看的,错了可能要很久之后才在某个深夜以线上故障的形式暴露出来。
我自己的判断是:AI 能不能在企业级项目里产生价值,不取决于模型有多强,而取决于你围绕它搭了一套什么样的工作流。模型负责生成,工作流负责控制。没有工作流约束的 AI 生成,本质上是把你的代码库变成一个黑盒产线——产物出来了,但没人知道中间经历了什么。而我们要做的事情,就是把这个产线变成透明的、每个环节都有质量门禁的流水线。
这也是这篇文章想聊透的东西:从 PRD 出发,到可控的代码落地,中间到底要经过哪些环节、每个环节怎么做、坑在哪里。这篇内容主要面向研发团队的技术负责人、架构师,以及那些已经尝试在项目里引入 AI 但总觉得不踏实的开发者。下面分享的这套流程不是某家公司的内部方案,而是我结合多年企业级研发经验和 AI 工程化实践总结出来的一套可以照着落地的工作流。
2. 工作流全景:四阶段流水线,每一步都有质量门禁
在讲具体操作之前,我先把整个工作流的骨架摆出来。这套工作流的核心思想是:把 AI 当成一个“能力很强但需要严格管理的外包团队”,而不是一个“自动写代码的魔法盒”。对待外包团队,你会有明确的需求文档、验收标准、代码规范、review 流程,对 AI 也应该一样。
整个工作流分成四个阶段,每个阶段都有输入、产出和质量门禁。
第一阶段:需求结构化。输入是一份 PRD(产品需求文档)或者哪怕只是几句口头描述,产出是一份 AI 和人类都能读懂的结构化任务书。这个阶段的核心不是写代码,而是把模糊的产品语言翻译成无歧义的开发语言。质量门禁是:任务书里的验收标准必须能逐条对应回 PRD 的原始需求,不能有遗漏,也不能有人为添加的“私货”。
第二阶段:任务拆解与上下文准备。输入是结构化任务书,产出是一组粒度合适的开发任务,以及每个任务对应的代码上下文。企业级项目不同于 greenfield 项目,新代码永远要依赖旧代码——已有的工具类、数据库表结构、接口协议、代码风格。这个阶段要解决的核心问题是:如何把 AI 看到的信息限制在它应该看的那一小部分里。质量门禁是:每个任务的上下文包完整、无越界、无缺失。
第三阶段:代码生成与约束注入。输入是任务和上下文,产出是符合团队规范、可以提交审查的代码 Diff。这个阶段的核心是用 Prompt 工程、代码规范约束、生成策略来控制 AI 的输出质量。质量门禁是:生成的代码通过静态检查、编译、单测,且不引入超出任务范围的修改。
第四阶段:审查、验证与反馈闭环。输入是 AI 生成的代码 Diff,产出是经过审查、测试、最终合并到主干的代码。这个阶段的核心是:让 AI 生成的代码接受和人类写的代码完全一样的审查和测试标准,并且把审查中发现的问题喂回给 AI,形成迭代。质量门禁是:代码通过 Code Review、集成测试、性能和安全检查,才能合并。
我把这四个阶段画成一个循环而不是一条直线,是因为企业级项目的代码永远是持续演进的。今天的代码合并进主干,明天就是新任务的上下文。这个循环转得越顺,AI 在项目里的作用就越像一个高效的协作者,而不是一个偶尔来帮倒忙的临时工。
在实际落地的时候,这四个阶段没必要一次性全上。哪怕你先只做第一阶段——把 PRD 结构化之后再交给 AI——产出的代码质量都会有肉眼可见的提升。后面我会逐步展开每个阶段的具体操作,包括可以直接抄的模板和想清楚之后才能避开的坑。
3. 第一阶段实操:把 PRD 变成 AI 和人都能看懂的任务书
3.1 传统 PRD 为什么喂不饱 AI
很多团队拿着 PRD 直接丢进 AI 对话框,期望它“看懂需求然后写代码”,结果通常很惨。问题不出在 AI 的理解能力,而出在 PRD 这种文档本身的属性——它是写给人看的,不是写给代码生成器看的。
传统 PRD 的典型结构是:背景介绍、用户故事、页面原型图、接口字段表、异常场景说明。这些东西对产品经理和开发来说信息量足够,但喂给 AI 的时候会暴露出几个致命问题。
第一个问题是信息密度不均匀。PRD 里有大段的背景叙述、竞品分析、运营策略,这些内容对 AI 生成代码没有任何帮助,反而会干扰它对核心需求的理解。AI 是概率模型,你给它 1000 字背景描述,它可能在生成代码时“发挥创造力”,加一些需求里根本没有的逻辑。
第二个问题是验收标准缺失或模糊。PRD 里经常写“用户可以在订单列表页查看订单详情”,但没说清楚:订单列表默认按什么排序?分页参数是多少?接口返回异常时前端如何展示?“查看详情”是从新开页面还是弹窗?这些细节在产品评审时靠口头对齐,但 AI 不知道这些默认约定,它只能猜。
第三个问题是业务规则分散在不同章节。比如某个状态只有特定角色能变更,这个规则可能藏在“权限说明”那一节里。AI 读 PRD 时很容易漏掉散布在角落里的约束条件,导致生成的代码缺少关键判断。
所以我一直强调一个观点:PRD 不能直接成为 AI 的输入,必须先经过一次“翻译”,把它变成结构化的任务书。这不是多此一举,而是把人类团队里“产品转述需求给开发”这个隐性过程,显性化成一份文档。
3.2 结构化任务书的六个要件
我用了很长时间迭代出一份任务书的模板,现在基本固定成六个要件。每一份交给 AI 的开发任务,都严格包含这六部分。
需求编号和来源。每个任务都要能回溯到 PRD 的具体章节或用户故事编号。这既是为了追溯,也是为了防止 AI 在生成代码时“自行发挥”。我在 Prompt 里会明确写:“只实现下列需求,不要实现任何未列出的功能。”
业务背景(限制在 100 字以内)。AI 不需要了解这个功能在公司的战略意义,它只需要知道这段代码在业务上是干嘛的。我通常写一句类似“用户下单后系统需要生成一条履约记录,供仓储系统后续拉取”这样的说明,让 AI 对代码的用途有个基本认知。
功能范围。这个任务需要实现哪些功能点,用列表一项项写清楚。每一项都是一个动词短语,比如“新增订单状态流转接口”、“在订单详情接口中增加履约状态字段”。功能范围必须和 PRD 一一对应,不能多不能少。
非功能要求。企业级项目最容易被 AI 忽略的就是这块。我一般会写清楚:需要打日志吗?日志打在哪个级别?接口超时时间多少?要不要做参数校验?数据量大了怎么处理?这些要求如果不在任务书里明确写出来,AI 默认按最小实现处理,生成的代码在生产环境基本都不能直接上线。
验收标准。每一项都要可验证。比如“调用订单详情接口时,如果订单 id 不存在,返回 404 错误码而不是空数据”。验收标准不是写给测试看的,是写给 AI 看的——它在生成代码时会自动把自己的输出往这些标准上靠。我实测下来,验收标准写得越具体,AI 生成代码的质量越稳定。
约束和排除项。这块是我自己加的,但对企业级项目特别重要。我会明确告诉 AI:不要动现有的数据库表结构、不要修改公共工具类的签名、不要引入新的第三方依赖、不要重构与本任务无关的代码。AI 特别喜欢顺手优化它觉得“写得不好”的代码,这种隐形改动在 Code Review 时最让人头疼。
3.3 一份可以直接用的任务书 Prompt 模板
下面这份 Prompt 模板是我目前实测效果最好的,你可以直接复制过去调整。
你现在是一个企业级后端开发工程师,请严格基于以下任务要求编写代码。 ## 需求编号 - 来源 PRD 3.2.1,订单履约流程 ## 业务背景 用户支付成功后,系统需要创建一条履约记录,供仓储系统后续同步处理。 ## 功能范围 1. 新增 OrderFulfillment 实体类,字段包括:id、orderId、status、createdAt、updatedAt。 2. 新增创建履约记录的 Service 方法 createFulfillment(OrderPaidEvent event)。 3. 在订单支付成功的事件监听器中调用该 Service 方法。 ## 非功能要求 - 使用项目现有的 Lombok 注解风格。 - 方法入参和返回值不允许为 null,必要时使用 Optional 或抛出 IllegalArgumentException。 - Service 方法内打印 info 级日志,包含 orderId。 - 数据库操作使用 MyBatis-Plus 的 BaseMapper。 ## 验收标准 1. createFulfillment 方法幂等:同一个 orderId 重复调用不会创建两条记录。 2. 事件监听器调用失败时抛出异常并触发事务回滚。 3. 新代码不改变任何现有接口的出入参结构。 ## 约束和排除项 - 不要修改数据库表结构,默认表名 order_fulfillment 已存在。 - 不要修改任何现有类的代码,除非为了调用新方法。 - 不要引入新的第三方依赖。 - 不要生成单元测试,本次只需要业务代码。这份模板的核心技巧是把人类团队开发时心照不宣的“默认规则”全部显式写出来。比如“幂等”这件事,人类开发看到“创建履约记录”自然会想到订单可能会重复通知,但 AI 不一定会想到,或者想到了不敢确定要不要实现。当验收标准里明确写了“幂等”后,它就会认真处理这个逻辑。我试过同一份需求,不写验收标准的版本和写了验收标准的版本,生成的代码质量差距非常大。
注意:任务书里不要出现“优化”“重构”“整理”这类含义宽泛的词。AI 一旦看到这种词,就有很大概率去改动它认为“不够好”的代码,产生无关 Diff。任务书里的每一个动词都应该指向一个明确、可度量的交付物。
3.4 从 PRD 拆任务时,粒度控制在什么程度
这里还有一个很实操的问题:一份 PRD 要拆成多少个任务合适。拆得太粗,比如把整个订单流程让 AI 一次写完,上下文会非常大,AI 很容易迷失,生成的结果要么逻辑混乱,要么超出预期。拆得太细,比如一个接口拆成两个任务,AI 缺乏全局视角,生成代码时反而更容易出边界错误。
我总结出一个可以量化的标准:一个任务的产出 Diff 控制在 200 到 400 行左右,最多不超过 600 行。按这个标准,一个中等复杂度的后端接口(Controller + Service + DAO),拆成一个任务刚好;一个包含状态机的模块,可能需要拆成三到四个任务。
任务拆分还有一个容易被忽略的原则:按依赖顺序拆,而不是按业务模块拆。先让 AI 生成底层的实体类和工具类,再生成依赖这些类的 Service,最后生成 Controller。这样做的好处是,后面生成高层代码时,可以把前面已经生成的实体类定义作为上下文的一部分喂给 AI,减少它瞎猜的概率。这种“先生成底层、再逐层向上”的方式,比“并行生成所有层然后靠人缝合”可靠得多。
4. 第二阶段实操:代码生成前的上下文与约束准备
4.1 上下文包:让 AI 只看到它该看的东西
企业级项目动辄几十万行代码,不可能全部塞给 AI。但反过来,如果只把任务书丢给它,不给任何项目上下文,它生成的代码就是在“裸奔”——不知道项目里已有的工具类、不知道代码风格、不知道数据库字段命名规则。
这里就涉及一个关键概念:上下文包。所谓上下文包,就是 AI 生成某个任务代码时,你提供给它的项目相关信息集合。一个好的上下文包,应该包含且仅包含这个任务真正需要知道的内容。
我的经验是,上下文包由三部分组成:项目级约定、模块级信息、代码示例。
项目级约定只会变化,包括:项目使用的语言和框架版本、日志框架和规范、异常处理风格、代码格式化规则、数据库访问层框架。这部分内容我一般是写死在一个系统级 Prompt 里的,每个任务都带上。
模块级信息根据任务动态变化,包括:当前任务涉及的业务表结构和已有实体类、依赖的 Service 接口定义、相关 Controller 的现有写法。这部分是 AI 生成高质量代码的关键。我一般是把相关类的关键代码片段直接贴进上下文,而不是告诉 AI“你去项目里找”。
代码示例是最容易被忽略但效果最好的部分。我会在任务书后面附上一段风格上“完美符合项目规范”的已有代码,然后告诉 AI:请参照这个示例的代码风格实现新功能。AI 对示例的模仿能力远超对文字描述的遵循能力,给它一个“好的榜样”比写十条规范都管用。
4.2 用 Agent 模式做仓库级检索
如果团队用的是支持 Agent 模式的 AI 编程工具(比如 Cursor、Codex、开源的 Continue 等),上下文包这一步可以做得更自动化。Agent 可以读取整个代码仓库,根据任务描述自己检索相关代码。
但这里有一个我在实践中反复踩过的坑:Agent 自主检索不等于它能看到所有东西,它只会检索它“认为”相关的内容。企业级项目里,真正重要的约束条件往往不在代码里,而在代码之外——比如某个表为什么没有外键、某个接口为什么要兼容旧版本、某个字段为什么这么命名。这些背景信息 Agent 是检索不到的。
所以我的建议是:Agent 可以帮你做检索,但任务书里的“非功能要求”和“约束排除项”必须写全。把 Agent 当作一个记忆力很好但不了解项目背景的新人,你需要在任务书里把“项目里所有人默认知道但没人写进代码”的信息给它补上。
4.3 把编码规范变成强制约束
企业级项目通常都有自己的编码规范,但很多规范只存在于文档里,没有真正被执行。AI 生成代码时,它学习的是 GitHub 上海量开源项目的风格,而不是你们团队的风格。所以直接在 Prompt 里写“遵循项目现有代码风格”通常是无效的——AI 不知道你们项目的风格是什么。
更好的做法是,把编码规范中最关键的几条,具体化成可执行的指令。我不会让 AI 背诵整个规范文档,而是挑出最容易出问题的几条写进系统 Prompt:
- 使用 SLF4J 占位符而不是字符串拼接打日志
- 禁止 System.out.println 输出调试信息
- 所有对外接口的入参必须做参数校验,不允许直接信任下游传来的数据
- 实体类字段使用基本类型或包装类型需要统一,不允许混用
- 所有异常必须转成项目自定义异常,不允许直接抛出裸的 RuntimeException
这些约束不一定覆盖全部规范,但覆盖了绝大多数 AI 容易犯的错。代码风格的问题可以在格式化和 Code Review 阶段兜底,但逻辑层面的规范必须在生成阶段就约束住,否则返工成本更高。
4.4 增量生成优于整体重写
在生成策略上,我一直坚持一条原则:除非是全新的独立模块,否则禁止让 AI“整体重写”某个文件。原因很简单:AI 重写文件时,它会保持文件原有功能,但实现方式可能完全不同。即使单测全过,这种大规模重写也会让 Code Review 变得极其困难,reviewer 根本无法判断 AI 是否引入了细微的行为变化。
我比较推荐的做法是“增量生成”:明确告诉 AI,在保持文件现有结构和已有方法不变的前提下,新增一个方法或修改某个指定方法的实现。任务的表述方式对结果影响很大。
比如下面两种写法:
写法 A:在 OrderServiceImpl 中实现查询订单详情的方法。 写法 B:在保持 OrderServiceImpl 现有方法(getOrderList、cancelOrder、payOrder)不变的情况下,新增一个 getOrderDetail 方法,入参为 Long orderId,返回 OrderDetailVO。写法 B 的效果明显好于写法 A。写法 A 给了 AI 过大的自由度,它可能会顺手重构现有方法;写法 B 把边界画清楚了,AI 只在指定范围内操作。
如果不小心让 AI 生成了大范围改动,还有一个补救办法:用 Git 对比看重构前后的全量 Diff,如果关键逻辑没有变化,可以直接用git checkout把无关部分的改动丢弃,只保留新增的代码片段。这个操作我每周都要做几次,已经成为肌肉记忆了。
5. 第三阶段实操:代码生成后的审查、验证与反馈闭环
5.1 自动化质量门禁:在 AI 进入 Code Review 之前拦住基础问题
AI 生成的代码不能直接进 Code Review,原因不是 AI 水平不够,而是人工的精力是有限的。如果 review 一个 AI 生成的 Diff 时,有一半的评论都在说“日志格式不对”“缺少参数校验”“变量命名不符合规范”这类问题,那真正值得人花时间看的业务逻辑反而被淹没了。
所以在进入人工审查之前,必须有一层自动化的质量门禁。这层门禁我们在每个 AI 生成的代码分支上强制执行三件套:
静态检查:包括 ESLint(前端)、Checkstyle/PMD(Java)、Pylint(Python)等。AI 生成的代码经常有未使用的 import、不规范的命名、明显的代码坏味道,静态检查可以快速拦截。
编译和单元测试:这不用多说,编译不过或单测失败的分支直接打回重做。但要注意,单测通过不等于功能正确,尤其是 AI 生成的代码,它的单测很可能也是 AI 自己写的,存在“自证清白”的问题。所以我的原则是,AI 生成的业务代码和测试代码,至少有一方要由人类来写。如果业务代码是 AI 写的,测试代码必须由人类补充或者至少严格 review。
契约测试:这个在企业级项目里特别重要。微服务架构下,服务之间通过接口协议通信,AI 生成的新代码可能改变了现有接口的出入参结构,导致下游方编译失败或运行异常。契约测试的作用就是在这种问题被合并到主干之前就暴露出来。
一套完整的自动化质量门禁跑完,通常只需要几分钟。如果 AI 生成的代码通过了这些检查,才值得让人来 review 业务逻辑。
5.2 人工 Code Review:重点看接口边界而不是逐行读代码
AI 生成的代码在风格上通常没有大问题,真正需要人关注的是那些自动化和单测覆盖不到的地方。我在 review AI 生成的代码时,关注的顺序是:
第一,接口边界。入参校验是否完整?异常情况是否都有明确输出?会不会因为一个 null 值导致 500?这个部分 AI 通常处理不好,因为它不知道调用方会传什么进来。
第二,业务规则覆盖。验收标准里的每一条,代码里真的都实现了吗?有没有藏着“这个情况应该不会发生”的侥幸处理?我见过 AI 生成的代码里直接写if (order == null) { return; }的,这种安静失败的写法在企业级项目里是最危险的处理方式——它掩盖了问题,而不是暴露问题。
第三,与现有代码的一致性。新代码是否符合项目里现有的模式?比如项目里统一用自定义异常,AI 可能就 throw 了一个 RuntimeException;项目里统一用 Result 包装返回值,AI 可能直接返回裸对象。这些问题不会导致编译错误,但会导致系统越来越“风格分裂”,后期维护成本直线上升。
这里我分享一下自己的技巧:review AI 的 Diff 时,先不看 AI 写了什么,先想如果你是开发者,实现这个需求你会怎么设计。带着自己的设计去看 AI 的代码,差异点就是重点怀疑对象。这个“先设计后对照”的方法,要比对着 AI 代码一行行找问题高效得多。
5.3 把 Review 反馈变成 Prompt,形成迭代闭环
AI 生成代码最大的优势之一是:改代码的成本极低。人工开发时,review 提出三条修改意见,开发者可能要埋头改一小时。而 AI 场景下,只需要把 review 意见整理成反馈 Prompt,重新提交给 AI 即可。
这里有一个很关键的实操细节:反馈 Prompt 的质量,决定了 AI 修改的质量。
很多人在这个环节的做法是,把 review 完整发给 AI,让它“根据 review 意见修改”。这样做的问题在于,review 意见是写给人看的,里面有很多夹杂上下文和理解性描述。AI 看到之后,可能只改了一部分,剩下的因为“没理解”而漏掉。
我的做法是,把 review 意见逐条结构化,每条明确三要素:问题位置、问题原因、修改要求。比如:
请修改以下问题: 1. OrderFulfillmentServiceImpl 第 42 行:createFulfillment 方法没有对 orderId 做非空校验,当事件消息里 orderId 为 null 时会产生脏数据。请在方法开头增加校验,orderId 为 null 时抛出 IllegalArgumentException 并记录 warn 级日志。 2. OrderPaidEventListener 第 18 行:调用 createFulfillment 后没有捕获异常,消费者线程会中断。请使用 try-catch 包裹调用逻辑,捕获异常后记录 error 级日志,但不抛出。 3. OrderFulfillment 实体类第 35 行:status 字段使用了 String 类型,项目规范要求使用枚举类型。请改为引用项目已有的 FulfillmentStatus 枚举。这样格式化的反馈,AI 修改的准确率非常高,几乎不会漏改或误改。如果反馈是零散的聊天式句子,AI 就会像听天书一样,很可能改了这里漏了那里。
这个迭代循环可以重复多轮,每一轮之后都要重新跑自动化质量门禁。一般 2 到 3 轮之后,AI 生成的代码基本可以达到可以合并的质量标准。如果超过 3 轮还有大量问题,我建议直接把整个实现方案推翻重来——大概率是任务书阶段就出了问题,AI 在错误的地基上怎么改都是错。
5.4 企业级落地场景:分支策略与合并节奏
说完了单任务的流程,再看企业级项目里一个绕不开的问题:这些操作在多分支协作模式下怎么落。
我们团队内部推行“一任务一分支,分支过门禁才合并”的策略。每个 AI 开发任务从主干切一个临时分支,在分支上完成代码生成、自动检查、人工 review 的全部流程。任何环节没过,分支就不允许合并。这样做的最大好处是,AI 生成的质量问题被隔离在分支内,不会污染主干,也不会影响其他同事的开发。
合并节奏方面,我有一个比较稳妥的建议:AI 生成的任务分支合并频率控制在每天 1 到 2 次,而不是攒一周一次性合并。原因很简单,AI 生成的代码依赖的上下文,很大程度基于合并时的主干代码。如果分支长期没同步主干,水越来越深,合并冲突和“代码基于旧主干”的问题会集中爆发。高频小批量合并,出问题时定位也容易。
在 CI 配置上,生成环境(production)分支的合并触发条件应该更严格,至少要求:全部自动化测试通过、代码覆盖率不低于项目基线、关键安全扫描无高危漏洞。研发环境(development)分支可以适当放宽,但要保留合入门禁。
根据团队实际情况,门禁的强度可以分级上线。先跑静态检查和编译,稳定后再加入更严格的测试和覆盖率门槛。但有一条底线不能省:AI 生成的代码,没有走完和人类代码同样的合并流程,就不允许进入主干。这条底线如果没有守住,工作流就已经失控了。
6. 常见问题与排查技巧实录
6.1 AI 生成的代码风格和团队规范严重不一致
这个问题出现的频率最高。典型表现是:用了团队不用的库、缩进和命名风格不对、日志写法不符合规范。排查思路是先确认是不是任务书里的“非功能要求”没有写清楚。如果你只写了“实现订单接口”,AI 默认按它见过的开源项目风格来写,和你们的规范不一致再正常不过。
解决方法是在系统级 Prompt 里固定下来几条硬性规则,比如“所有日志必须使用 SLF4J 占位符格式”“所有接口返回值必须使用 Result 包装类”“所有实体类必须继承 BaseEntity”。如果你的规则已经写清楚了,但 AI 还是频繁违反,那更可能是你的规则表述太抽象。
某次我们写“代码风格要符合项目规范”,AI 始终无法理解。改成“在使用 Lombok 的实体类中,统一使用 @Data 注解,不要手写 getter/setter”之后,问题立刻消失了。抽象规则对 AI 是无效的,只有具体的、可对照的指令才有效。
6.2 AI 引入了不存在的依赖或版本冲突
AI 生成代码时可能会使用它训练数据里常见的第三方库,而项目里根本没有引入这个库。比如它可能用commons-lang3的 StringUtils,但项目里一直用的是 Hutool 的 StrUtil。
遇到这种情况,不要想着“用命令自动安装依赖然后继续”。企业级项目的依赖引入必须经过审查,而且很可能受公司合规和统一版本管理约束,不是开发者自行就能决定的。
最安全的做法是在任务书里直接限制:不要引入任何新的第三方依赖;如果确实需要,在代码注释里标记// TODO: 确认依赖,把决策权保留给人类。AI 的学习数据里存在大量不同依赖版本和写法,不加约束的依赖引入,是生成代码在合并阶段遇到的最琐碎的返工原因。
6.3 生成的代码跑通了单测,但集成测试一测就挂
这个场景非常经典。单测是 AI 自己写的,测试和实现是一起生成的,天然存在“共谋”倾向——实现代码里有 bug,但测试代码恰好没覆盖到那个分支。所以单测全绿并不代表代码可靠。
集成测试挂掉的原因通常集中在三类:接口协议变更、数据库 schema 不匹配、跨服务调用时序错误。排查的时候,不要盯着 AI 的代码一层层找,而是先用git diff看清楚它到底改了哪些接口定义,再顺着接口链路往下核对。绝大多数集成问题都出在“AI 改了 A 服务的接口,但 B 服务还不知道”。
6.4 PRD 在开发中途变更了,AI 代码如何同步更新
企业级项目的 PRD 变更很常见,但用 AI 开发时,需求变更的影响被放大了。因为 AI 不像人类开发者那样对代码有全局记忆,它只知道任务书里写了什么。
正确的做法是:修改任务书,而不是直接在变更点让 AI 改。不要告诉 AI“把订单状态增加一个新枚举值”,而是回到任务书,找到对应功能范围和验收标准,更新它们后重新生成那一部分代码或让 AI 在现有新代码上做增量修改。
因为任务书是 AI 对需求的唯一认知来源,你只在某个局部让它改,它的其他部分仍然保留旧认知,后续生成代码时逻辑就会不一致。每次 PRD 变更,都要同步更新任务书,并且把变更点高亮标注,这种“双写”操作虽然繁琐,但能避免大量后期纠错成本。
6.5 问题排查速查表
| 常见问题 | 根因分析 | 优先排查动作 | 解决方案 |
|---|---|---|---|
| 代码风格与团队规范不一致 | 系统 Prompt 缺少具体规范条目 | 检查任务书“非功能要求” | 把抽象规则改写为可对照的强制指令 |
| 引入不存在的第三方依赖 | AI 训练数据中的惯性选择 | 使用git diff检查依赖声明文件 | 在任务书明确禁止新增依赖,或要求标记 TODO |
| 接口出入参被隐性修改 | 生成默认逻辑与项目约定不符 | 契约测试、接口签名 Diff | 在验收标准中固定接口出入参,增加契约测试门禁 |
| 单测全绿但集成失败 | 测试代码与实现代码同源生成 | 审查测试断言覆盖的业务分支 | 关键业务代码的测试由人来写,至少严格走查 |
| 需求变更后 AI 改错地方 | AI 对变更边界认知不完整 | 核对任务书是否同步更新 | 修改任务书后重新生成增量片段,不直接局部改代码 |
| 合并时大量冲突 | 分支长期未同步主干 | 检查分支滞后程度 | 控制合并频率,每天小批量合并 |
最后的实践心得
上面这套工作流,我是在一个中等规模的后端项目上逐步打磨出来的。从最初“AI 写完我看一眼就上线”的自由状态,到现在的“任务书 + 上下文包 + 自动门禁 + 人工 Review”四阶段流水线,踩过的坑比写出来的还多。每砍掉一个 AI 引入的生产麻烦,回头看都是因为工作流的某道防线没搭好。
如果你团队正准备引入 AI 辅助研发,我的建议是从最轻量的一步开始:先要求团队把交给 AI 的任务写成任务书,尤其是验收标准那段。只做这一步,AI 代码的可用率就能提升一大截。等工作流跑顺了,再加入上下文管理和更严格的自动门禁。
再分享一个收尾小技巧:在 AI 工作流里,代码评审的人选要固定下来,不要每次随机换人。因为 AI 会犯的错误有一定模式,固定的人 review 会逐渐形成对 AI 常见问题的直觉,发现问题的速度会越来越快。这个角色不一定是最资深的工程师,但一定是对项目规范有较深理解的人。
研发工作流里的 AI 到底应该是个什么位置?我现在的答案很明确:它不是一个“写代码的替代者”,而是一个“产能放大器”。真正决定代码质量的,仍然是人设计的那套流程。