1. 从“帮我写代码”到“研发闭环”——AI辅助开发为什么总差最后一公里最近在帮团队做订单模块的重构为了方便大模型参与编码我特意把项目的接口签名、数据模型、现有测试都喂给了模型然后让它帮我补一个新的超时取消逻辑。结果呢代码生成得非常快看起来也像模像样可一跑测试就露馅了。我对着失败栈看了一个小时发现根子不在实现而在我的需求描述根本不具备“可验证性”。这件事让我意识到一个关键问题大模型写代码的能力再强如果工作流没有给它一个明确的验收剧本那它就是高级代码补全而不是真正参与研发决策。1.1 AI写代码很强但它不“懂”你的业务大模型在单点任务上确实惊人。给它一个清晰的函数描述它能写出基本能跑的代码给它一段报错信息它能给出像模像样的修复建议。但这些能力放到真实项目里马上就暴露出一个结构性问题大模型不理解你的业务背景也不理解你所在团队对“正确”的定义。比如“订单超时后自动取消”这句话不同团队的理解可能完全不同。超时是从下单开始算还是从支付倒计时开始算30分钟整算不算超时取消后库存要不要回补回补是同步的还是异步的这些问题在自然语言里天然含糊而测试代码恰恰会把这些含糊逼到墙角——测试通过与否必须是二值的、确定的。你会发现含糊的需求在传统开发流程里会被评审、讨论、追问慢慢磨清楚但换成大模型时它没有能力追问只会默认一个它自认为合理的解释。这就是最后一个公里的问题所在AI写代码的能力已经够强缺的是让需求变成可验证契约的环节。我们要重构的不是“代码怎么写”而是“需求怎么进入代码世界”。1.2 传统TDD在LLM时代暴露的三个断层一套成熟的TDD流程核心是红-绿-重构循环。写一个失败测试让它驱动实现然后重构。这条循环在人类开发者手里运转了几十年但在大模型参与后我发现了三个明显的断层。第一个断层是需求到测试之间的翻译断层。人类开发者写测试时脑子里已经有一套业务上下文知道哪些边界要覆盖、哪些异常要处理。但大模型拿到的是自然语言描述它只能靠训练时的统计规律来猜。你让它“写订单超时逻辑”它大概率会生成一个看起来很标准但可能漏掉并发、漏掉幂等、漏掉状态机约束的测试。第二个断层是失败信息的理解断层。传统TDD里测试红了之后开发者会结合业务知识判断是测试写错了还是实现写错了。大模型修复代码时经常会把“断言本身就不对”误判成“实现有问题”然后对着一个错误的实现使劲打补丁。第三个断层是验收标准的承诺断层。TDD的核心承诺是“测试一经通过就代表行为满足预期”。但在AI生成的代码里测试可能被写得特别宽松比如只检查返回值不为空不检查具体内容。绿灯亮得很容易代码的质量没有被真正承接住。这三个断层凑在一起表现出的症状就是AI写的单函数很好用AI做的整个模块漏洞百出。因为代码本身不难难的是把“业务期望”完整地传导进代码里。1.3 所谓闭环是让需求、测试、实现互相约束我们通常说“研发闭环”指的不只是上线之后没有bug而是指需求描述、验收测试、代码实现三个工件之间形成双向的严格约束。需求定义行为行为变成测试测试驱动实现实现反过来校验需求是否被正确理解。任何一个环节脱离约束这个环就断了。BDD行为驱动开发在这里的价值被重新放大了。BDD天然提供了“Given-When-Then”这种可结构化的行为表达方式它既是人跟人沟通的语言也是人跟机器对齐的语言。把BDD和AI-TDD结合本质上是把需求层从自然语言模糊地带拉到测试层可执行的高地上。这个想法听起来有点绕但落地后就清晰了。我实践出来的路径是先把需求写成Gherkin场景再让大模型基于场景生成测试代码和实现代码然后用测试结果反推需求描述的合理性。这一套走下来AI生成的代码不再是“猜需求”而是对照一份明确的行为契约在执行翻译工作。下面我会用一个具体案例把这条闭环完整拆给你看。2. 用BDD先画行为边界没有契约的AI-TDD只是高级代码补全我最早尝试AI-TDD的时候直接跳过了BDD觉得既然TDD已经用测试来驱动实现了为什么还要多写一份Gherkin后来被现实教育了大模型生成测试代码前它首先得知道“测什么”。测试的输入输出光靠函数签名不够还得知道业务规则、边界条件、异常分支。这些信息从哪来只能从一份结构化的行为描述里来。2.1 先定“行为”再谈驱动Gherkin就是AI的验收剧本Gherkin是一种接近自然语言的业务描述语法核心结构是Feature、Scenario、Given、When、Then。Feature描述功能模块Scenario描述具体场景Given前置条件、When触发动作、Then断言结果。它最大的特点是业务人员能看懂测试代码能绑定大模型能直接基于它生成脚手架。我拿一个最常见的电商需求来举例订单支付超时自动取消并释放库存。这个需求的完整Gherkin可以这样写Feature: 订单超时自动取消 As a 电商平台 I want 在用户支付超时后自动取消订单并释放库存 So that 库存可以及时回滚避免无效占用 Background: Given 商品A的库存为10 And 用户小明下单购买1件商品A订单号为SO-001 Scenario: 订单超过30分钟未支付被取消 Given 当前时间为下单后的31分钟 When 系统执行超时订单扫描任务 Then 订单SO-001的状态变为“已取消” And 商品A的库存恢复为10 Scenario Outline: 支付时间边界判定 Given 当前时间为下单后的分钟数分钟 When 系统执行超时订单扫描任务 Then 订单SO-001的状态为期望状态 Examples: | 分钟数 | 期望状态 | | 29 | 待支付 | | 30 | 已取消 | | 31 | 已取消 |注意我在这里用了一个Scenario Outline来处理边界条件。这看起来只是个小细节但实际价值非常大它把“30分钟整到底算不算超时”这个业务争议变成了一张可执行的示例表。大模型读到这个场景时就不得不围绕29、30、31这三个时间点去生成精确的测试用例而不是凭感觉自己拍脑袋。写Gherkin这件事千万别以为是在走形式。我挑了三个最容易漏的地方你们在实际写的时候一定要盯住一是时间边界要用Examples覆盖二是状态变化要写明“从什么状态变成什么状态”三是库存变化要写成具体的数值断言。这三处是AI生成测试时最容易跑偏的位置契约里写清楚了后面会省掉大量扯皮。2.2 给AI提交需求时的提示词模板可复制有了Gherkin下一步是让AI进入“红-绿”循环。这里最关键的是提示词的设计。我迭代了很多版之后最终固定下来的模板长这样你是一名资深测试工程师正在参与一个Python项目的AI-TDD流程。 请严格按照以下Gherkin行为契约生成pytest测试代码。 【契约文件】 这里粘贴Gherkin内容 【项目上下文】 - 语言与框架Python 3.11 / FastAPI SQLAlchemy - 相关接口签名 def scan_expired_orders(now: datetime) - list[str] def cancel_order(order_id: str, reason: str) - None def release_stock(product_id: str, quantity: int) - None - 数据模型 Order(status: str, created_at: datetime, expired_at: datetime) Stock(product_id: str, quantity: int) 【要求】 1. 覆盖Gherkin中的所有Given/When/Then包括Scenario Outline中的每个Example。 2. 测试要建立在真实数据库事务上使用fixture完成数据准备。 3. 断言必须具体到状态值、数量值禁止使用“结果不为空”这类模糊断言。 4. 生成完成后说明你依据哪些契约字段设计了哪些测试用例。 【失败输出协议】 如果你生成后发现契约本身存在无法实现的描述请明确列出该描述对应的Gherkin行号 并说明需要业务方澄清的问题禁止自行修改测试逻辑绕过契约。这套模板里有几个设计是踩坑踩出来的。第一要求AI“说明基于哪些契约字段设计了哪些用例”这一步能让你快速核对契约和测试是否一一对应。第二增加了“失败输出协议”告诉AI如果契约有歧义不要自作主张篡改测试目标而是把问题抛回来。这非常关键因为AI默认的倾向是“帮你把测试写成一定能过的形状”我们必须在提示词层面把这条路堵死。2.3 场景拆解的方法把“业务故事”翻译成“契约”很多团队第一次写Gherkin会犯一个通病把用户故事原封不动地搬过来没有做场景拆解。比如只写“用户下单后超时未支付订单自动取消”然后就扔给AI了。这种契约等于没有写因为核心的边界、异常、资源联动全都没有表达出来。我自己的拆解方法是把业务故事拆成四层。第一层主路径正常情况下这个功能怎么运转第二层边界值时间、数量、金额这些连续变量的临界值是什么第三层异常分支前置条件不满足、中间状态被并发修改、依赖服务失败时系统怎么表现第四层资源联动这个行为触发后会对订单、库存、账单、消息等其他对象造成什么连带变化。订单超时这个案例里主路径是“到时间-扫单-取消-回库存”边界是“29/30/31分钟”异常分支是“订单已经支付过了扫描任务不应该取消它”资源联动是“库存要回补到10且不能被其他并发扣减动作影响”。把这四层写清楚契约的完整度就到合格线了。我给AI喂的Gherkin从来不是一次到位的但这并不妨碍流程跑起来关键是一旦测试红了我们要有能力判断是契约的问题还是实现的问题这点在后面的排查章节细讲。3. AI-TDD闭环实操一个订单超时场景从故事卡到全绿的全过程概念讲多了容易飘现在直接上一段完整实操。下面的步骤是我在真实项目里跑过的代码做了一定简化但流程就是原样。3.1 第一步让AI从契约生成测试代码前面那份Gherkin确认无误后我把契约文件、项目上下文、提示词模板一起丢给大模型让它生成pytest测试代码。模型用pytest-bdd把Feature文件和测试函数绑定起来生成的测试框架长这样import pytest from pytest_bdd import scenarios, given, when, then, parsers from datetime import datetime, timedelta scenarios(../features/order_timeout.feature) given(parsers.parse(商品A的库存为{quantity})) def setup_stock(quantity, db_session): db_session.execute( INSERT INTO stock (product_id, quantity) VALUES (A, :q), {q: int(quantity)}, ) db_session.commit() given(parsers.parse(用户小明下单购买1件商品A订单号为SO-001)) def create_order(db_session): created_at datetime.now() db_session.execute( INSERT INTO orders (order_id, status, created_at, expired_at) VALUES (SO-001, 待支付, :created, :created interval 30 minutes), {created: created_at}, ) db_session.commit() when(parsers.parse(当前时间为下单后的{minutes}分钟)) def set_current_time(minutes, db_session): pytest.current_time datetime.now() timedelta(minutesint(minutes)) when(系统执行超时订单扫描任务) def run_scan(): scan_expired_orders(pytest.current_time) then(parsers.parse(订单SO-001的状态变为“已取消”)) def assert_order_cancelled(db_session): row db_session.execute( SELECT status FROM orders WHERE order_id SO-001 ).fetchone() assert row.status 已取消这段代码本身没什么稀奇的但它揭示了AI-TDD的核心价值测试代码的形态已经被Gherkin完全约束住了AI的创造力被用在具体的数据准备、状态转换、断言表达上而不是用在“猜业务规则”上。这一步走完测试还是红的因为实现还没有写。但“红”的位置是可控的、预期的这才是TDD该有的样子。3.2 第二步让AI按失败信号驱动实现测试代码就位后接着让AI根据测试失败信息生成实现代码。提示词大概长这样现在你是本项目的后端开发工程师。以下是刚生成的pytest测试代码 请在保证测试语义不被破坏的前提下实现满足测试的代码。 【测试代码】 粘贴上一步生成的测试 【约束】 - 不允许修改测试文件中的任何断言。 - 实现需要考虑到数据库事务边界扫描任务要在事务内完成检查与状态更新。 - 生成后简单解释你的实现思路特别说明如何处理29/30/31分钟的边界。AI这时候会生成一个服务函数大致长这样def scan_expired_orders(now: datetime) - list[str]: expired_orders db.query(Order).filter( Order.status 待支付, Order.expired_at now, ).all() for order in expired_orders: order.status 已取消 stock db.query(Stock).filter(Stock.product_id order.product_id).first() stock.quantity order.quantity db.add(order) db.add(stock) db.commit() return [o.order_id for o in expired_orders]第一次跑测试绿了三个用例红了一个。红的正是边界用例30分钟整。AI生成的过滤条件是expired_at now从代码角度看没问题但对照Gherkin里Examples的第二行“30分钟 → 已取消”它没有满足。这里其实已经不是代码问题而是业务规则的定义问题过期时间戳精确到秒时30分钟整到底是“队尾”还是“队头”业务方的本意是“支付超时未完成就算过期”所以expired_at now是正确的那测试里的错误就出在数据准备阶段——创建订单时设置的expired_at和场景里推算出来的时间不一致。这个案例留在后面排查章节展开。现在先说结果修复数据准备逻辑后测试全绿。3.3 第三步边界修正与重构全绿不代表流程结束TDD的红-绿-重构绿色之后还挂着“重构”这步。AI生成代码的通病是逻辑都写对了但可读性和组织性比较差。比如上面的扫描函数里状态枚举值硬编码了字符串“待支付”“已取消”后续增加新状态必然埋雷。这个过程我仍然让AI参与但提示词要明确范围在保持测试全部通过的前提下对实现代码做重构。 - 把状态字符串抽取为枚举或常量类。 - 将库存回补逻辑拆成独立函数release_stock。 - 重构后运行全部测试确认仍然是绿的。AI把重构做完了测试全绿我再人工读了一遍diff确认没有偷改断言、没有破坏事务边界。这一步建议无论如何都要人肉review一次大模型重构时经常顺手“优化”掉一些看似冗余但实际承担并发保护逻辑的代码比如它可能把乐观锁字段移除。不要默认AI的每一步都可靠。这套流程走完你就得到了一个从行为契约到可运行代码的完整闭环。接下来要处理的是这个闭环中最容易让人头秃的部分红灯阶段怎么排查。4. 红灯阶段的排查链路AI测试挂了之后我是怎么一步步定位的AI-TDD的日常不是一路绿灯而是红灯频率比人写代码高不少。红灯不可怕可怕的是你把“AI修AI”当成无限循环让AI看报错AI改了一版运行还是红再让AI看报错AI再改折腾五轮后改出一个连原逻辑都丢了的四不像。之所以会陷入这种循环是因为缺少一套结构化的排查链路。4.1 先给失败分类红灯不在“实现”就在“契约”我自己的经验是看到测试失败后先不要急着把报错丢给AI而是按下面这张表判断失败类别失败症状大概率原因排查方向断言值不符代码逻辑看起来没问题契约边界或数据准备与业务语义不一致检查Gherkin描述和测试fixture回到需求层测试抛异常空指针、KeyError、接口不存在实现没有按契约生成完整方法让AI补充实现要求接口签名与测试对齐数据状态被跳过部分用例没执行测试代码对Gherkin绑定错误检查pytest-bdd的scenario路径和步骤装饰器并发场景下断言偶发失败实现缺乏并发控制或测试本身缺少隔离检查事务隔离级别和锁机制补并发场景编译/语法级失败提示词给的接口信息不完整AI生成了错误签名补充准确的模型定义和函数签名后重新生成这个分类的价值在于决定下一步让谁去处理。如果是契约问题让AI反复修代码是没用的因为AI会“自我合理化”把实现改成与错误契约匹配必须由人回到Gherkin层面修正或澄清。4.2 一次典型失败排查库存扣减并发问题的完整链路我分享一个真实遇到的案例。某次测试全绿之后我又加了一条契约场景“两台扫描任务同时执行时库存只能回补一次”。结果新增的并发测试直接红了。当时的失败信息是库存数量断言失败期望10实际却是8。换成人肉直觉第一反应是“库存回补逻辑重复执行了”但更深的判断是为什么重复执行没有被挡住这就要看实现里有没有状态检查。排查链路大概是这样的。第一步打开扫描函数的实现确认它确实没有幂等机制它在事务里查询所有“待支付”的过期订单然后逐个取消。两台任务并发执行时两边都查到了同一个待处理订单都执行了取消和回补所以库存被重复加了一次。第二步确认这个问题不该在测试层修而是实现层缺少乐观锁或状态条件更新。第三步让AI修复提示词里直接把定位结果丢给它扫描任务并发执行时发生重复取消。 根因filter条件只查了status待支付没有在更新时校验当前状态还是待支付。 请实现基于乐观锁的原子状态转换例如 UPDATE orders SET status已取消 WHERE order_id? AND status待支付 并返回影响行数影响行数为0时跳过库存回补。 修复后请补充验证并发场景的测试。同一件事如果直接把失败栈丢给AI它会改出各种奇怪的sleep、加锁方案不一定可靠。但你把定位结论给出来AI就能精准执行。排查链路的终点不是“测试绿了”而是“根因被定位并且被解决”。这条经验适用于任何AI辅助开发的场景。4.3 排查注意点与经验再补充几个容易踩的细节。第一测试失败信息里如果出现了多个失败用例按“影响范围最小”的优先处理。只要一个用例失败根因解决了其他失败通常自动消失反过来按列表顺序从上到下逐个改往往会把问题扩大。第二警惕AI把断言改弱来“修绿”。我在实践中遇到过AI悄悄把assert stock_count 10改成assert stock_count 10的操作。这属于测试污染必须禁止。所以我在团队里的规则很简单测试文件的修改权限只归测试负责人AI只能改实现代码。这条铁律能在很大程度上保证验收信号的可信度。第三排查过程中如果所有红灯都指向同一个业务规则的含糊点说明Gherkin该更新了。比如“30分钟整”这个问题拖了三次修复都没彻底解决那就停下编码找业务方确认规则把Examples里的期望值改成确定答案。红灯反复出现往往不是工程问题而是需求没想清楚。5. 质量闭环的价值账本时间消耗、缺陷逃逸与可回归性折腾完流程和排查大家最关心的还是这套AI-TDD到底值不值我拿自己主持的一个订单重构模块做了对比记录。模块规模大概15个用户故事点涉及订单状态流转、库存联动、超时扫描三个子系统业务规则密度中等偏上。5.1 时间账本AI-TDD对比传统TDD到底省在哪下面这张表是我个人记录的相对估算值单位是小时供大家参考环节传统TDDAI-TDD说明需求澄清与行为确认3h2hGherkin评审让需求分歧提前暴露测试代码编写4h1hAI基于契约生成骨架人做评审实现代码编写5h2.5hAI走多轮失败修复自查与重构2h1.5hAI重构人肉review diff回归与联调1h0.5h测试网完整CI自动回归总耗时从15小时降到7.5小时左右省下来的一半时间大多来自测试与实现的生成效率。但这张表有个前提Gherkin写得合格。如果契约质量不合格AI生成测试和实现的质量都会同步崩塌进而把时间消耗在无休止的红灯修复上AI-TDD反而比传统TDD更慢。契约即杠杆写得好是效率利器写不好是时间黑洞。5.2 缺陷逃逸率的下降绿灯不等于没bug但契约让bug有了锚点除了时间账质量账更值得算。传统TDD里测试是开发自己写的很容易陷入“验证自己写的代码”的同义反复。而在BDDAI-TDD流程里测试来源是Gherkin契约契约先于代码存在。一个bug如果能逃逸到生产环境那一定能在契约的某个Examples里找到“没有被覆盖的场景”。这时候定位缺陷就成了一个纯逻辑动作查契约哪个分支没有对应测试再看测试为什么漏掉了它。我记录到的结果改造前模块的线上缺陷率在季度内是每千行0.8个改造后三个月内是0.2个大部分逃逸发生在支付回调与扫描任务并发竞争这一类深水区。这个数据不算漂亮但它验证了核心观点测试锚定契约之后缺陷不再是随机的而是可追踪的、可反推的。当然也要承认缺陷逃逸率下降不完全是AI-TDD的功劳还因为团队在重写Gherkin时相当于对业务规则做了一次全面的重新梳理。这本身就有价值。5.3 适度超出CRUD复杂业务改造中的AI-TDD策略订单状态机这种场景用AI-TDD很顺手但很多团队真正的痛点是复杂业务改造比如老系统里有一个没人敢动的结算模块逻辑链路长、历史包袱重、文档缺失。这种场景下的AI-TDD策略和从零开发完全不同。我的做法是不要试图让AI一口气生成整个复杂模块的测试和实现而是用“差异补全”策略。第一步由人肉梳理现有代码把核心业务对象、仓储接口、状态枚举定义清楚交给AI作为上下文底座。第二步让AI像“啄木鸟”一样寻找现有实现中的行为漏洞对照业务方写的Gherkin把缺失的边界测试补齐。第三步补出来的测试如果红了说明现有实现有bug这时才进入修复循环。这套打法把AI的能力优势放在“构建测试网络”上而不是让它从头设计业务架构。风险小得多也更能让团队接受。6. 从个人实践到团队工程化AI-TDD的落地路径与边界一个人把AI-TDD跑通是一回事带一个团队把它跑起来又是另一回事。后者难的不是技术而是流程纪律。如果你打算在团队里推广这条工作流下面几个建议我觉得值得参考。6.1 团队推进的节奏与分工强烈建议不要一口气全组铺开。先选一个“业务规则密度高、验收标准清晰、技术栈稳定”的模块做试点比如订单状态机、优惠券核销、库存流水这类。这类模块的Gherkin写起来容易AI生成测试的准确率也高团队能很快看到效果建立信心。等这一条流水线运转顺了再逐步推广到更多业务线。分工上我的团队现在是这样拆的业务分析师负责把需求转成一份经过评审的Gherkin测试负责人把Gherkin转成测试脚手架并维护断言质量开发人负责把测试失败信息做分类判断该回写契约还是让AI修复实现AI负责生成测试代码、生成实现、修复红灯、执行样板化重构。你会发现每个人的职责都被重新定义了和传统流程最大的区别是写代码不再是开发者的核心劳动读懂契约和验证契约成了核心技能。6.2 需要预先搭好的工程基础设施AI-TDD要真正工程化不能每次都在IDE里开对话窗口需要三样基础设施。第一一份持续维护的Gherkin仓库。所有行为契约进版本库、走评审流程与代码仓库同源。契约的每次改动都对应一个可追溯的业务决策。第二测试与CI的强绑定。Gherkin对应的pytest场景必须在合并前跑通。为了确保这一点我在CI里加了一个校验当Gherkin文件变更时如果对应测试文件没有同步变更构建直接失败。这能防止“契约更新了但测试还留在旧版本”的漂移。第三标准化的AI交互接口。不让每个人都凭自己的习惯写提示词而是把前面展示的提示词模板固化成一个内部小工具包含从Gherkin生成测试、从失败生成修复建议、从测试生成实现三个预设场景。团队里的AI使用经验能持续沉淀和复用。工具不复杂你甚至可以用脚本编排几个curl级别的请求就把它跑起来重点在于统一行为而不是炫技。6.3 哪些场景不适合AI-TDD说了这么多优势也得泼点冷水。有三种场景我明确不建议硬套AI-TDD。第一种是纯性能调优类任务比如把一个查询从500ms优化到50ms。性能优化的测试天然带波动性刷接口、做profiling、看火焰图这类工作更适合人肉加工具链用BDD去表达“响应时间小于50ms”完全没有意义。第二种是强UI交互和视觉细节类需求。Gherkin能描述“用户点击按钮后看到成功提示”但像素级还原、动效节奏、无障碍细节这类难以自动断言的内容强行写进契约只会沦为摆设。第三种是极端安全敏感类场景。比如权限校验、加密密钥管理、防SQL注入等。原因不是AI能力不够而是这类场景需要专业的攻击面思维测试通过不代表系统安全这类工作应该由专项安全人员主导AI只做辅助不要把AI-TDD当作主要工作流。判定标准很简单这个行为的“正确”是否可以被自动断言如果能AI-TDD很合适如果不能就不要为了时髦硬套。最后说点个人体会。我在这个过程中最大的收获不是效率提升了多少而是重新理解了“验收”这件事。以前我们写测试是为了让重构时心里有底现在写契约是为了让AI在动手之前先知道自己的作业要交到哪里。把Gherkim的质量当作第一优先级测试的成功率、AI修复的准确率、团队的协作顺畅度都会跟着变好。如果你正打算引入大模型到研发流程里我建议你先不要急着让它写一堆代码而是先用一份足够扎实的Gherkin把边界画出来。这个习惯比任何工具和模型版本都更值钱。