免费公开课程 · 9/40
第 9 章 验收驱动开发:先定标准,再让 AI 出码
本章目标
必交产物:验收分支决策表
O1 · 能够定义“验收标准”进入“实际证据”所需的判断条件(产物:验收分支决策表)
证据:验收分支决策表写明从“验收标准”到“实际证据”的进入条件
O2 · 能够构造验收分支决策表,写明分支、否决项和责任人(产物:验收分支决策表)
证据:验收分支决策表至少包含一个继续分支、一个停止分支和各自责任人
O3 · 能够依据实际证据在通过、修复与重建之间作出分支决定(产物:验收分支决策表)
证据:产物记录一个案例的标准、观察、分支选择和不可推断项
前置学习:第 8 章 三大纪律与一条补充原则
初学者路径
本章迁移任务是:能够依据实际证据在通过、修复与重建之间作出分支决定。先按图中的“条件门禁”关系完成验收分支决策表的第一项证据,再逐项核对责任人与判断标准。
有经验者路径
先用当前项目完成这一任务:能够依据实际证据在通过、修复与重建之间作出分支决定。提交验收分支决策表后,再对照正文复核关系类型、缺失证据和授权边界。
图解文字说明
图以“验收标准”为输入,经“实际证据”的条件分支到达“PASS/修复/重建”所控制的门禁。两条路径最终必须落在停止或继续之一;缺证据和红线失败不能被其他表现抵消。
关系语义:输入经过条件分支汇入明确门禁;停止与继续是互斥结果,红线不能被其他得分补偿。
**公开课程改编版。**正文依据内部教材整理,保留概念、流程与示范。案例规模、用时、提升比例及目标阈值均用于教学,不是本站交付成果或通用标准。工具、平台与技能描述需在实际环境核验。提示词不能授予权限;重试次数不自动触发恢复;恢复须先保护工作并确认目标、共享状态和外部数据影响。
课程讲解
9.1 为什么验收标准是”硬约束”
在传统开发中,TDD(测试驱动开发)是先写测试用例,再自己写代码去通过测试。在 AI 时代,这个逻辑被推向了它的终极演进形态:先设定”验收标准”,再让 AI 出码。
如果你只说”去实现一个用户登录功能”,AI 会给出无数种千奇百怪的实现方案,且极大概率漏掉你关注的边界条件。正确的”验收驱动”指令应该是:
“接下来我们要实现用户登录。你的代码必须满足以下验收标准:
- 接收账号密码;
- 密码必须经过 Bcrypt 哈希比对;
- 验证成功后签发 JWT,包含 User ID,且有效期仅为 2 小时;
- 任何失败情况统一抛出 401 AppError。 如果清楚了以上边界,请开始输出代码。”
为什么顺序这么重要?因为验收标准对 AI 来说是一种”约束”。当 AI 知道”我的代码必须通过这 5 个测试才算完成”时,它的生成策略会从”写出看起来对的代码”变成”写出能通过这 5 个测试的代码”。后者远比前者可靠。
来看一个对比:
- 模糊指令:“实现用户登录接口。“AI 可能忽略密码加密、Token 过期、错误处理——它写了一个”能用”的登录接口,但你不确定它是否”安全可用”。
- 带验收标准的指令:“实现用户登录接口。验收标准:1. 密码必须用 bcrypt 哈希比对;2. 成功时返回 JWT,包含 user_id,有效期 2 小时;3. 失败时返回统一的 401 AppError;4. 连续 5 次失败锁定账号 30 分钟。“AI 生成的代码会精确覆盖这 4 条标准,因为验收标准是”硬约束”——AI 知道这些条目会被逐一检查。
验收驱动开发还有一个隐藏的好处:它让你在编码前就想清楚了”什么算完成”。很多时候,你在写验收标准的过程中就会发现需求中的模糊之处——密码错误应该返回什么状态码?账号锁定后怎么解锁?这些问题的答案必须在编码前确定——如果你不确定,AI 就会替你确定,而它的选择不一定是你想要的。
这里还有一条必须遵守的铁律:未经验收完全通过的代码,就是随时会碎裂的劣质建材,无论它看起来多完美,都绝不允许将其合入工程,绝不允许它成为下一阶段实施的上下文依赖。
9.2 三条防线:功能验收、架构验收、安全验收
验收体系的核心是”三条防线”的设计。为什么是三条?因为 AI 编码的错误有三个层次,你需要三个层次的检测方法。
第一层:功能防线——检测”代码是否跑通了”。
这是最直观的检查。你写测试用例、跑测试、看结果。如果你让 AI 实现”用户注册”,它写了代码,你跑测试——注册成功、密码存入了数据库、登录成功。功能防线通过。
但功能防线有一个盲区:它只检查”代码是否按预期运行”,不检查”代码是否按正确的方式运行”。你的注册功能跑通了,但密码是明文存储的——功能测试发现不了这个问题。因为功能测试的输入是”用户名 + 密码”,输出是”注册成功”,测试用例不会去检查数据库里存的是什么。
第二层:架构防线——检测”代码是否遵守了蓝图”。
这是 AI 编码中特有的防线。AI 很容易在实现功能时”顺手”改了不该改的东西——比如为了修复一个 Bug,它直接修改了数据库表结构。功能测试看不出来,因为功能还是对的,但架构已经偏移了。
架构防线的检查方法很简单:对比蓝图文件(CONTEXT.md)和实际代码。蓝图规定”密码必须用 bcrypt 加密”,架构防线就检查实际代码中是否调用了 bcrypt;蓝图规定”错误必须抛统一 AppException”,架构防线就检查实际代码中是否用了 AppException。
第三层:安全防线——检测”代码有没有引入安全隐患”。
这是最容易被忽视的防线。AI 生成的代码往往”功能正确但安全脆弱”。原因很直接:AI 的训练数据中包含了大量”能用但不安全”的代码——它学会了”写功能”,但没学会”写安全的代码”。
来看一个三层防线如何协作的例子。假设同一个 Bug——登录接口在密码错误时返回 500 错误:
- 功能防线看到的是:返回状态码错误,需要修;
- 架构防线看到的是:错误处理逻辑不在统一的异常处理层,需要重构;
- 安全防线看到的是:错误信息直接暴露了数据库连接信息,需要修复。
同一个 Bug,三层防线看到的是三个不同层面的问题。只修了第一层,第二层和第三层的问题依然存在。这就是为什么需要三层防线——每一层覆盖上一层覆盖不到的盲区。新手验收通常只关注第一层,有经验的开发者三层都检查。
9.3 验收决策树:PASS / NEEDS_FIX / REBUILD
验收完成后,你需要根据结论做出决策。这就是验收决策树——它是整个方法论中”最反直觉也最重要”的环节。
示例类型:伪代码。 伪代码,不可直接执行。它只表达判断顺序,实施时必须补齐真实接口、权限与错误处理。
验收结果
├── PASS ──────→ git commit 固化,进入下一个里程碑
- 分支判断依据验收证据;重复失败时停止并重新诊断。恢复前保护工作并确认目标与授权,不按次数自动重建。
- 分支判断依据验收证据;重复失败时停止并重新诊断。恢复前保护工作并确认目标与授权,不按次数自动重建。
└── REBUILD ───→ 按第 10.4 节的安全恢复路径回到已验收基础,再重新下发更精确的指令
PASS 很好理解——验收通过,提交代码,进入下一个里程碑。
NEEDS_FIX 也很好理解——验收发现问题,AI 自动修复,重新验收。但这里有一个重要的限制:NEEDS_FIX 最多执行两次。如果修复了两次还是有问题,就自动升级为 REBUILD。为什么?因为 AI 在”修复模式”下容易陷入确认偏误——它在错误的地基上不断打补丁,越修越乱。如果让它在同一个问题上反复尝试,你可能会得到一段”虽然通过了验收但引入了更多问题”的代码。
- 分支判断依据验收证据;重复失败时停止并重新诊断。恢复前保护工作并确认目标与授权,不按次数自动重建。
9.4 架构偏移的三大信号:篡改地基、过度设计、体积失控
架构偏移是 AI 编码中最隐蔽也最具破坏性的问题——AI 在实现一个功能时,可能会”顺手”修改了不该改的地方。识别架构偏移的三大信号,是验收中最重要的能力。
信号一:篡改地基。
AI 修改了以下类型的代码,应该立即 REBUILD:数据库连接配置、认证和授权逻辑、全局中间件、核心工具函数、共享的数据模型定义。
- 为什么会发生:AI 发现当前功能的实现”需要”修改地基代码。但通常这不是真的需要,而是 AI 走了捷径。
- 破坏性:这种”拆东墙补西墙”的行为,会直接导致依赖该底层模型的其他模块在未来的某一刻全面崩塌。
信号二:过度设计。
AI 引入了以下不必要的复杂性:为简单场景添加了抽象层(接口、工厂、策略模式)、引入了项目不需要的第三方库、添加了当前功能不需要的配置选项。
- 为什么会发生:AI 倾向于”以防万一”的设计,而不是”刚刚好”的设计。
- 破坏性:仅仅为了处理一个概率极低的边缘情况,AI 突然引入极其复杂的第三方库,或强行使用事件总线、反射等沉重的设计模式——为了掩盖一个小坑而挖出一个巨大的天坑。
信号三:体积失控。
AI 在单个文件中堆积了过多代码:一个组件文件超过 300 行、一个工具函数文件包含多个不相关的功能、一个 API 路由处理了多个不相关的请求。
- 为什么会发生:AI 在”追加代码”时不会主动重构。它会直接在现有文件上添加新功能,导致文件膨胀。
- 破坏性:大量的 if-else 嵌套出现,原本应该被抽象复用的逻辑被机械地复制粘贴——代码的”熵增”已经达到了临界点。
检测方法:
- 用
git diff查看变更文件列表——意外出现的文件修改,可能是篡改地基; - 检查新增文件的长度——新文件超过 300 行,可能是体积失控;
- 检查新增的依赖——package.json 中出现未预期的依赖,可能是过度设计;
- 对比蓝图的目录结构——代码放在了蓝图未约定的位置,可能是架构偏移。
【模板】验收清单与验收报告
验收清单(可根据项目实际情况调整):
功能验收
- □ 所有需求点都已实现
- □ 主流程能正常运行
- □ 边界情况有处理(空数据、异常值、极限情况)
- □ UI 交互符合预期(加载状态、错误提示、空状态)
代码验收
- □ 代码风格与项目一致(缩进、命名、注释)
- □ 没有明显的代码质量问题(重复代码、过长函数、不合理命名)
- □ 没有死代码(未被调用的函数、未使用的变量)
- □ 错误处理合理(不吞异常、不暴露敏感信息)
架构验收
- □ 没有修改不应修改的核心代码
- □ 没有引入不必要的依赖或抽象
- □ 单个文件没有过度膨胀(建议上限 300 行)
- □ 新增代码与项目的目录结构一致
- □ API 设计遵循项目的约定
安全验收
- □ 用户输入经过验证或转义
- □ 敏感接口有权限控制
- □ 没有硬编码的密钥或凭证
- □ 数据库查询使用参数化查询或 ORM
- □ 不返回不应暴露的数据字段
验收报告模板:
示例类型:参考。 参考片段,不保证可独立执行。请按本章上下文、项目版本和真实接口改写,并以实际运行结果验收。
## 验收报告:里程碑X
### 结论:PASS / NEEDS_FIX / REBUILD
### 功能验收
- [x] 需求全部实现
- [x] 主流程正常
- [ ] 边界情况:未处理搜索关键词为空的情况
### 代码验收
- [x] 代码风格一致
- [x] 无重复代码
- [x] 错误处理合理
### 架构验收
- [x] 未篡改核心代码
- [x] 未引入不必要的依赖
- [x] 目录结构合规
### 安全验收
- [x] 输入验证完整
- [x] 权限控制到位
- [x] 无硬编码凭证
### 修复建议(仅 NEEDS_FIX 时)
1. 在搜索函数中添加空字符串判断
2. 当搜索关键词为空时,返回完整列表
独立练习
使用虚构或已获授权的脱敏材料,先独立作答,再查看参考。将产物保存为 chapter-09.md,写上版本、决定、证据和缺项。
为工单API写功能、架构、安全三类验收,每类两项。构造‘功能通过但安全失败’的候选并决定是否晋级。
本章必交产物:验收分支决策表
以下证据必须出现在本次独立练习的提交物中;正文原有问题用于提供内容,不能替代这些验收项。
- O1: 验收分支决策表写明从“验收标准”到“实际证据”的进入条件
- O2: 验收分支决策表至少包含一个继续分支、一个停止分支和各自责任人
- O3: 产物记录一个案例的标准、观察、分支选择和不可推断项
查看参考反馈(先独立作答)
参考反馈
功能检查合法输入与空输入;架构检查分类不依赖UI、API契约不漂移;安全检查脱敏日志与权限边界。若分类正确但输出包含密钥,仍是NEEDS_FIX并阻止发布。REBUILD需依据结构性问题和获批准恢复方案,不按重试次数机械触发。
自评与下一步
对照本章目标检查:决定是否明确,依据是否能复现,未知项是否如实记录。参考给出一种判断方式,不是唯一答案;若不同结论能提供同等证据,可请同伴复核。缺少证据的部分记未完成,再回到对应步骤补充。
来源与边界
登记来源只支持本章涉及的外部事实;验收分支决策表、示例数字和练习情境属于课程内部教学设计,必须在实际项目中重新验证。
- GitHub Actions 官方文档
GitHub · 2026-09-17 · 仓库工作流可以自动执行构建、测试和持续集成任务。
记录本章练习
仅保存本浏览器的自检记录,不上传作业,不代表评阅通过或认证。请在自己的章节文件中保留证据与缺项。