很多团队并不是没有 Code Review,而是审查发生得太晚、标准不一致、反馈也缺少统一处理方式。
这篇文章介绍如何将标准化代码审查 CR 集成到 SDD,也就是 Spec-Driven Development,需求驱动开发流程中。
核心思想是:
SDD 负责定义应该实现什么以及如何设计,Spec-CR 负责验证实际实现是否符合设计、是否安全可靠、是否具备长期维护条件。
一、先定义要解决的问题
研发任务至少包含四类信息:
需求:用户需要什么
设计:系统准备如何实现
代码:实际实现了什么
验证:实现是否满足要求如果这四类信息没有关联,就容易出现四种问题:
- 实现偏离需求;
- 代码绕过既定架构;
- API 和数据模型与契约不一致;
- 审查标准依赖个人经验。
因此,真正需要解决的不是要不要做 Code Review,而是三个问题:
1. 什么时候必须审查?
2. 审查时应该检查什么?
3. 收到反馈后如何判断、修复?
二、SDD 与 Spec-CR 的分工
SDD 的核心是先把需求和设计结构化,再进入实现阶段。
一个典型的 SDD 产物包括:
spec.md :为什么做、做什么、验收标准是什么
plan.md :系统如何分层、模块如何协作
data-model.md : 数据结构和关系是什么
contracts/ :API、事件或模块接口如何约定
tasks.md :具体拆分成哪些任务Spec-CR 则验证实现阶段和交付阶段:
- 代码是否实现了 spec 中的需求;
- 模块划分是否符合 plan;
- 数据模型和接口是否符合约定;
- 是否存在运行时缺陷;
- 是否存在安全和并发风险;
- 代码是否已经复杂到难以维护;
- 反馈是否被合理验证和处理。
两者可以表示为:
spec.md
↓
plan.md / data-model.md / contracts
↓
tasks.md
↓
代码实现与测试
↓
Spec-CR 审查
↓
修复、验证、阶段交付三、完整研发闭环
一个阶段的完整流程可以设计为:
需求澄清
↓
编写 spec
↓
制定 plan
↓
定义数据模型和接口契约
↓
拆分 tasks
↓
逐任务开发与自测
↓
提交代码
↓
阶段代码审查
↓
修复并验证
↓
进入下一阶段项目全部阶段完成后,再执行一次全量审查。阶段审查关注局部实现是否可靠,全量审查关注跨模块契约、重复实现、临时方案和部署配置。
四、代码审查的触发时机
阶段完成时强制审查
当一个开发阶段的全部任务完成后,执行阶段审查:
/speckit.codereview Phase X阶段审查的作用是阻止问题进入下一阶段。比如,一个阶段负责权限和数据接口,如果阶段结束时没有检查越权、错误处理和接口契约,后续页面开发可能建立在错误接口之上。
全项目完成时强制审查
当所有阶段完成后,执行:
/speckit.codereview all全量审查不只是重复阶段审查,还要检查跨模块问题:
- 模块之间的契约是否一致;
- 是否存在跨模块权限漏洞;
- 是否有临时方案没有清理;
- 文档、代码和测试是否仍然一致。
高风险功能完成后主动审查
权限、认证、敏感数据、并发、事务、文件上传、网络访问、复杂 Bug 修复和大规模重构,都适合提前审查。
五、审查范围如何确定
推荐按以下优先级确定范围:
用户明确指定的 commit、文件或阶段
↓
Git 提交和工作区变更文件
↓
根据 tasks.md 推断关联文件审查报告应该明确写出审查范围,避免审查者和开发者对“这次到底审了什么”产生误解。
六、审查的四个维度
1. 规范合规
先对照 spec、plan、data-model 和 contracts:
- 用户故事是否完整实现;
- 验收标准是否满足;
- 模块是否放在正确分层;
- 数据字段、API 请求和响应是否一致;
- 是否增加了需求没有要求的复杂功能。
2. 基础代码质量
重点关注:
- 异常是否被吞掉;
- 异步是否有错误处理;
- 网络、文件和数据库操作是否处理失败;
- 是否存在 N+1 查询、无限集合和主线程阻塞;
- 是否处理空值、空数组、除零、超长输入和合法的 0 值。
3. 安全与并发可靠性
重点关注:
- XSS、SQL 注入、路径遍历和 SSRF;
- IDOR 越权和缺失的服务端权限校验;
- 密钥硬编码和敏感日志;
- 依赖漏洞和资源耗尽;
- 无锁共享状态、缺失事务和竞态条件。
4. 设计与可维护性
关注真实维护成本:
- 函数是否承担太多职责;
- 类是否变成上帝类;
- 是否出现魔法值和死代码;
- 是否过度抽象;
- 抽象是否真的有多个使用场景;
- 是否依赖具体实现而不是稳定接口。
七、收到反馈后的六步流程
开发者不要看到一条反馈就立刻修改。推荐顺序是:
通读全部反馈
↓
复述并澄清问题
↓
回到代码验证
↓
判断建议是否适用
↓
按优先级修复
↓
逐项测试验证审查意见是待验证的判断,不是自动成立的事实。需要确认问题是否真实存在、是否可以复现、是否已经被其他层覆盖,以及建议是否符合业务上下文。
问题可以分成四级:
| 等级 | 典型问题 | 处理策略 |
| ---- | ------------------------ | ---------------------- |
| P0 | 崩溃、安全漏洞、数据损坏 | 立即修复并阻塞流程 |
| P1 | 逻辑错误、严重性能退化 | 当前任务完成前修复 |
| P2 | 一般质量问题 | 当前修复或创建跟踪任务 |
| P3 | 优化建议 | 可选或集中治理 |
每个修复都要有验证结果。比如,发现接口存在越权风险,不只是增加一行判断,还要补充非资源所有者访问测试。
八、如何处理不合理反馈
Code Review 不是审查者单方面下结论。以下情况可以基于事实推回:
- 采纳建议会破坏已有功能;
- 审查者不了解完整业务上下文;
- 建议与项目架构或技术栈冲突;
- 引入的复杂度高于它解决的问题。
推荐这样回复:
当前实现的行为是……
这样设计的原因是……
如果改成建议方案,会导致……
因此本次暂不采纳。
如果未来出现……场景,再考虑引入该抽象。例如,目前一个策略只有一个稳定调用方,增加策略模式不会减少重复代码,反而会增加配置和测试成本,那么可以保留直接实现,等出现第二种策略时再抽象。
九、如何集成到 SDD 项目
建议把审查记录和 SDD 文档放在同一套项目结构中:
spec.md
plan.md
data-model.md
contracts/
tasks.md
reviews/
├── phase-1.md
├── phase-2.md
└── final.md项目约定可以包括:
1. 没有执行验证命令,不声明任务完成;
2. 阶段任务全部完成后,必须执行阶段审查;
3. P0 和 P1 未关闭时,不进入下一阶段;
4. P2 和 P3 必须决定当前修复还是创建跟踪任务;
5. 最终审查必须覆盖跨模块契约和部署配置;
6. 审查报告记录范围、发现、修复和验证结果。
任务流可以写成:
读取 spec 和 plan
↓
确认 task 的验收标准
↓
编码与单元测试
↓
提交代码
↓
必要时执行单任务审查
↓
阶段完成后执行 Phase X 审查
↓
修复 P0/P1 并重新验证
↓
进入下一阶段十、一个完整案例
假设某阶段实现“用户查看订单详情”。
spec 要求:
- 用户只能查看自己的订单;
- 订单不存在时返回明确错误;
- 订单列表支持分页;
- 数据接口返回统一错误结构。
plan 要求:
- Controller 负责参数接收;
- Service 负责业务判断;
- Repository 负责数据访问;
- 权限校验必须在服务端完成。
审查发现三个问题:
P0:存在越权风险
代码直接使用客户端传入的 orderId 查询数据,没有验证订单是否属于当前用户。
修复方式:
- 从服务端登录上下文取得 userId;
- 查询时同时使用 orderId 和 userId;
- 增加其他用户访问订单的失败测试。
P1:列表没有分页
数据访问层直接返回全部订单,数据量增大后可能造成内存和响应时间问题。
修复方式:
- 增加 page 和 pageSize;
- 限制最大 pageSize;
- 增加数据库排序和索引;
- 增加大数据量测试。
P2:Controller 直接调用 Repository
这违反了 plan 中的分层约定,但当前不影响功能。
处理方式:
- 当前阶段完成 Service 层迁移;
- 如果迁移范围较大,则建立跟踪任务;
- 不为了修复一个 P2 问题而引入未经验证的大规模重构。
这个案例体现了三层校验:
需求合规:权限是否符合 spec
架构合规:调用层次是否符合 plan
运行质量:分页、边界和安全是否可靠十一、如何判断体系是否有效
流程建立之后,还需要观察结果:
- 阶段审查发现的问题数量;
- P0/P1 问题比例;
- 合并后才发现的问题数量;
- 审查反馈平均处理时间;
- 审查修复引入的回归缺陷;
- P2/P3 跟踪任务关闭率;
- 需求、契约与实现不一致的次数。
不要把“发现问题越多”简单等同于成功。早期问题数量增加,可能只是审查能力变强。更重要的是观察高风险问题是否更早被发现,线上缺陷和返工成本是否下降。
结语
SDD 和代码审查不是两套独立流程。
SDD 通过 spec、plan、data-model、contracts 和 tasks 明确:
为什么做
做什么
如何设计
如何验收Spec-CR 则进一步验证:
实现是否符合需求
代码是否符合架构
运行时是否安全可靠
反馈是否被合理处理
修复是否经过验证最终形成的质量闭环是:
需求
→ 设计
→ 任务
→ 实现
→ 自测
→ 阶段审查
→ 修复验证
→ 全量审查
→ 交付一套有效的代码审查体系,不是增加更多表格,也不是让审查者拥有更大的权力,而是让团队在同一套需求、架构和验证标准上讨论代码。
当审查有明确触发点,标准可以被复用,反馈必须经过验证,P0/P1 问题能够阻止流程继续,代码质量就不再依赖某个“经验丰富的人刚好看到了问题”,而会成为研发流程本身的一部分。
参考资料
- GitHub Spec Kit. GitHub Spec Kit Documentation
- GitHub Spec Kit. What is Spec-Driven Development?
- GitHub Spec Kit. Agentic SDD Reference
- GitHub Spec Kit. Reference Overview