大模型显著降低了生成代码的成本,却没有降低理解业务、做出取舍、验证正确性和承担生产风险的成本。相反,当代码可以在几分钟内大量生成时,错误的需求和设计也会以更快的速度扩散。

因此,大模型时代的软件开发重点正在发生变化:开发者不再只是逐行编写代码,而要建立一套能约束大模型的工程系统。这套系统必须回答四个问题:

  1. 我们为什么要做这件事?
  2. 系统应该表现出什么行为?
  3. 准备如何实现并证明它正确?
  4. 上线后如何知道它真的创造了价值?

本文给出一套完整方法,并用三个案例说明它如何应用于不同任务:

  • 从零到一:开发一个团队工单管理系统。
  • 二次开发:在陌生电商系统中增加订单取消与退款。
  • 持续迭代:为已经上线的工单系统增加优先级、SLA 和自动分派。

整套方法可以概括为:

flowchart LR
    A[业务探索] --> B[DDD 领域建模]
    B --> C[确定 MVP]
    C --> D[SDD 变更规格]
    D --> E[架构与 ADR]
    E --> F[垂直切片]
    F --> G[BDD 验收场景]
    G --> H[TDD 实现]
    H --> I[审查与验证]
    I --> J[发布与观测]
    J -->|真实反馈| A

这不是要求每个任务都使用最重的流程。方法的价值恰恰在于:先判断风险和复杂度,再选择足够的工件与检查,而不是对所有改动一视同仁。


第一部分:重新理解大模型时代的软件开发

1. 为什么有了大模型,开发反而更需要方法

1.1 大模型改变了哪些开发活动

大模型擅长快速展开已经相对明确的问题:阅读代码、生成样板、比较方案、补充测试、修改文档、搜索调用链和解释失败日志。过去需要数小时完成的机械工作,现在可能只需要数分钟。

但它没有自动解决这些问题:

  • 用户描述的是表面方案,还是真实问题?
  • 两条冲突的业务规则以哪一条为准?
  • 团队能否长期维护某个架构?
  • 某项生产风险是否可以接受?
  • 生成的测试是否真的证明了需求?

这些问题依赖真实业务、组织责任和风险偏好,不能靠语言模型从文本概率中替团队决定。

1.2 代码生成速度不等于交付速度

交付周期不仅包括编码,还包括需求澄清、方案评审、联调、测试、迁移、发布和反馈。AI 把编码阶段压缩后,需求错误、跨模块依赖和验收不清会成为更明显的瓶颈。

例如“增加批量退款”看似只是一个接口,但真正交付可能涉及:

  • 哪些订单允许退款;
  • 一笔失败是否中止整批;
  • 重试是否会重复打款;
  • 谁拥有操作权限;
  • 如何对账和审计;
  • 如何灰度与回滚。

如果这些问题没有在编码前明确,生成代码越快,返工越大。

1.3 大模型开发最常见的失败模式

  1. 直接实现模糊需求:AI 自行填补空白,结果逻辑完整但方向错误。
  2. 一次生成整个系统:大量代码缺少逐层验证,问题彼此叠加。
  3. 只靠聊天保存决策:换会话后背景丢失,几轮之后前后矛盾。
  4. 测试与实现一起犯错:AI 按错误理解同时生成代码和测试,两者恰好一致。
  5. 无边界地顺手重构:一个小需求演变成大量无关修改。
  6. 完成声明缺少证据:模型说“应该可以”,却没有运行测试和构建。
  7. 技术看起来先进,团队无法维护:方案满足想象中的规模,不适合当前现实。

1.4 从“人工编程”转向“约束 AI 完成工程”

高质量 AI 开发不是写一个完美提示词,而是建立反馈系统:

1
明确输入 → 生成小改动 → 自动检查 → 人工审查 → 反馈修正

规格限制“做什么”,架构规则限制“放在哪里”,测试限制“必须保持什么行为”,静态检查限制“代码必须满足什么形式”,Git 限制“每次变更如何被审查和恢复”。约束越清晰,AI 的速度越容易转化为可靠产出。

1.5 人和大模型应该如何分工

活动 大模型适合承担 人必须负责
需求探索 追问、归纳、寻找冲突 确认真实问题与优先级
领域建模 生成候选模型和场景 确认术语与业务规则
架构设计 比较方案、分析权衡 决定风险和长期成本
编码 实现、重构、补测试 定义范围并验收结果
代码审查 扫描缺陷和不一致 判断业务、安全和可维护性
发布 生成脚本和检查项 授权生产变更并承担责任

1.6 什么可以交给 AI,什么必须由人决定

可以将“可验证、可回滚、边界明确”的任务大胆交给 AI。涉及资金、隐私、删除、生产权限、法律合规或不可逆迁移时,应保留人工审批。原则不是“不信任 AI”,而是让权限与失败代价匹配。


2. 一套完整开发方法需要解决什么问题

2.1 是否值得开发

先验证问题是否真实、解决后是否能产生价值。如果指标和目标用户都说不清,技术方案再完整也没有意义。

2.2 用户真正需要什么

用户通常会表达一个方案,例如“增加 Excel 导出”,但真实任务可能是“每周向财务提交汇总”。理解任务后,也许定时报表比手工导出更合适。

2.3 如何理解复杂业务

复杂业务必须形成共同语言、边界和规则。否则产品文档说“客户”,支付模块说“账户”,数据库又叫 member,AI 只能猜它们是否是同一个概念。

2.4 如何定义本次变更

项目愿景描述长期目标,变更规格描述这一次可交付的增量。两者不能混为一谈。每次变更都应有范围、行为和完成条件。

2.5 如何选择技术方案

技术方案要同时满足功能需求和质量属性,如安全性、可用性、性能、成本与可演进性,并记录为什么选它以及放弃了什么。

2.6 如何拆分可实施任务

任务需要小到 AI 能在有限上下文中独立完成,又要大到形成可验证的业务增量。最好的边界通常是垂直切片,而不是“写完所有 Model”。

2.7 如何保证代码正确

正确性来自多层证据:规格场景、单元测试、集成测试、端到端测试、静态分析、代码审查和真实运行,而不是来自模型的自信程度。

2.8 如何安全发布和持续迭代

上线需要迁移、兼容、灰度、回滚和观测。发布后的指标与反馈会验证原始假设,并成为下一次变更的输入。


3. DDD、SDD、BDD、TDD 与敏捷开发的关系

3.1 DDD:理解和建模业务

DDD(Domain-Driven Design)回答“业务世界如何划分和表达”。战略设计关注子域、限界上下文和上下文关系,战术设计关注实体、值对象、聚合、领域服务和领域事件。

DDD 不等于创建 domain/ 目录。只有当代码使用统一语言、业务不变量被模型保护、模块边界与业务边界一致时,领域模型才真正发挥作用。

3.2 SDD:把变更写成可审查的规格

本文中的 SDD 指 Spec-Driven Development。它回答“这次要改变什么”。规格把目标、行为、设计和任务从短暂聊天中提取出来,形成可版本控制的工件。

OpenSpec 是一种 SDD 工具。它以 specs/ 保存当前系统行为,以 changes/ 保存尚未完成的规格增量。

3.3 BDD:用行为场景定义验收标准

BDD(Behavior-Driven Development)通过真实示例建立共同理解。典型场景使用 Given、When、Then:

1
2
3
4
5
Scenario: 处理人接单后开始计算 SLA
Given 一个尚未分派的高优先级工单
When 管理员将工单分派给工程师
Then 工单状态变为“处理中”
And 系统记录首次响应截止时间

BDD 不只是 Gherkin 语法,而是发现规则、形成示例、自动验证的协作过程。

3.4 TDD:用测试驱动具体实现

TDD(Test-Driven Development)回答“如何用快速反馈实现代码”:

1
2
3
Red:写一个因为缺少行为而失败的测试
Green:写最少代码让测试通过
Refactor:在测试保护下改善设计

TDD 对金额、状态机、权限、幂等和数据转换尤其有效。它不意味着所有视觉探索都必须先写单元测试。

3.5 ADR:记录关键技术决策

ADR(Architecture Decision Record)记录背景、选择、理由和后果。例如“第一阶段采用模块化单体”比只留下一张架构图更有价值,因为后来者知道这个决定在什么条件下成立。

3.6 CI/CD:建立自动化交付闭环

CI 持续验证格式、类型、测试和构建;CD 把已通过检查的产物安全部署到环境。它们把团队约定变成机器执行的门禁。

3.7 这些方法如何组合,而不是相互替代

1
2
3
4
5
6
DDD:认识业务和边界
SDD:定义一次业务变化
BDD:把变化表达为可验收示例
TDD:实现示例背后的代码
ADR:保存关键技术取舍
CI/CD:持续验证并安全交付

它们工作在不同层次,不是相互竞争的流派。

3.8 什么情况下可以简化或跳过某种方法

任务 推荐工件
文案和一行配置修复 问题说明、差异检查
边界明确的小功能 轻量规格、相关测试
跨模块业务功能 Proposal、场景、Design、Tasks、完整测试
高风险核心业务 DDD、正式规格、ADR、威胁模型、灰度与回滚
探索性原型 时间盒、假设与结论,允许先 Spike 后补规格

流程应随不确定性和失败代价增长,而不是随代码行数增长。


第二部分:大模型时代的统一开发流程

4. 总体工作流

4.1 从业务目标到线上反馈的完整链路

完整流程包括两个循环:项目级循环负责愿景、领域和架构,功能级循环负责每次增量。

flowchart TB
    subgraph Project[项目级循环]
        V[愿景与指标] --> DM[领域模型]
        DM --> MVP[MVP 与架构]
        MVP --> Base[工程基线]
    end
    subgraph Change[变更级循环]
        P[探索问题] --> S[编写规格]
        S --> T[拆分任务]
        T --> C[测试驱动实现]
        C --> R[审查验证]
        R --> D[发布观测]
        D --> P
    end
    Base --> P

4.2 阶段、活动、产物与验收门槛

每个阶段都应有可检查的出口:

阶段 核心产物 进入下一阶段的条件
探索 愿景、用户、指标、非目标 问题和价值已确认
建模 术语表、边界、规则 关键歧义已解决
规格 Proposal、场景、设计 行为可验证、范围可交付
实施 代码、测试、迁移 自动检查通过
发布 构建物、回滚方案 风险已接受、可观测
反馈 指标、故障、用户反馈 形成继续、调整或停止的决定

4.3 项目级流程与功能级循环

项目愿景不应为每个任务重写,但领域模型和架构不是永久不变。一次迭代发现旧模型无法表达新规则时,应更新模型并记录决策。

4.4 瀑布式大计划与小步迭代的区别

“设计在前”不等于一次设计完整系统。正确方式是为当前最小闭环做足够设计,然后用线上反馈修正。每个切片都经过规格、实现、验证和发布,能够独立产生价值。

4.5 推荐的开发闭环

日常开发可以使用下面的短循环:

1
2
探索需求 → 确认规格 → 设计最小方案 → 写失败测试
→ 实现 → 全量验证 → 审查差异 → 小步提交 → 观测结果

5. 第一阶段:定义问题和项目目标

5.1 从一个想法开始

把“我要做一个工单系统”改写为问题陈述:

客户问题散落在微信群和私聊中,负责人不明确,处理进度无法追踪。客服团队需要一个统一入口,使每个问题都有归属、状态和历史记录。

5.2 识别目标用户和核心问题

列出主要用户、他们要完成的任务以及现有替代方案。不要使用“所有企业用户”这类无法指导设计的描述。

5.3 使用 Jobs To Be Done 分析用户任务

模板如下:

当____发生时,我想要____,从而能够____。

例如:

当客户报告故障时,客服想快速创建并分派工单,从而让问题不会因交接而丢失。

5.4 编写项目愿景

项目愿景应包含问题、用户、价值和差异,不需要提前写所有功能。

5.5 定义成功指标

工单系统可以使用:首次响应时间、超时率、重复工单率、平均解决时间和用户满意度。指标需要有当前基线和目标值。

5.6 定义项目范围与非目标

首期范围:创建、分派、流转、评论、通知。非目标:多租户计费、智能客服、复杂报表、开放插件市场。

5.7 识别时间、预算和合规约束

明确上线时间、团队技能、部署环境、数据地域、隐私分类、外部 API 预算和可接受停机时间。

5.8 让大模型追问需求,而不是立即写代码

推荐输入:

1
2
3
4
你现在是需求分析伙伴,不要设计架构或编写代码。
请基于下面的项目想法,一次提出一个最影响范围的问题。
重点确认用户、核心任务、成功指标、非目标、业务规则和风险。
每得到一个答案后更新“已确认事实”和“仍待确认问题”。

5.9 本阶段的交付物和检查清单

  • 项目愿景不超过一页;
  • 目标用户和核心任务具体;
  • 成功指标能够观测;
  • MVP 与非目标明确;
  • 事实、假设和未知问题分开记录。

6. 第二阶段:业务探索与领域建模

6.1 判断项目是否需要 DDD

如果系统的主要难点是业务规则变化、多团队术语冲突、复杂状态和跨模块一致性,DDD 很有价值。如果只是读取数据并展示,轻量术语表和模块边界通常足够。

6.2 建立统一语言

统一语言需要进入会议、文档、API 和代码。工单系统规定使用“工单”“报告人”“处理人”“分派”“解决”“关闭”,不要在不同位置混用 ticket、issue、任务和请求。

6.3 识别角色、命令、事件和规则

1
2
3
4
角色:报告人、客服、处理人、管理员
命令:创建工单、分派工单、解决工单、重新打开工单
事件:工单已创建、工单已分派、工单已解决
规则:已关闭工单不能继续评论;只有管理员可以跨团队分派

6.4 使用事件风暴梳理业务流程

先按时间线写出已经发生的业务事实,再补触发它们的命令、执行者、规则和外部系统。对大模型输入访谈记录后,可以让它生成候选事件,但必须由业务人员确认。

6.5 划分子域

  • 核心域:工单处理和 SLA;
  • 支撑域:用户、团队、通知;
  • 通用域:身份认证、文件存储、审计日志。

6.6 划分限界上下文

首期可以划分工单上下文、组织上下文和通知上下文。它们可以部署在同一个进程中,限界上下文不等于微服务。

6.7 识别实体、值对象和聚合

工单是有身份和生命周期的实体;优先级、联系方式和 SLA 时长可以是值对象;工单聚合负责保护合法状态转换。

6.8 识别业务不变量

不变量是任何操作都不能破坏的规则,例如:

  • 已关闭工单不能被再次分派;
  • 一个工单同一时刻最多有一个处理人;
  • 状态变化必须记录操作者和时间;
  • 重复处理同一命令不能重复发送关键通知。

6.9 生成领域模型初稿

1
2
3
4
5
6
请只基于“已确认事实”生成候选领域模型:
1. 给出统一术语表;
2. 识别子域和限界上下文;
3. 列出聚合及其保护的不变量;
4. 列出仍然缺少业务依据的推断;
不要根据数据库表直接决定领域边界。

6.10 如何审查大模型生成的领域模型

检查模型是否来自业务行为而非技术名词,是否出现万能聚合,是否把“发送邮件”这类基础设施动作误当核心领域,以及边界之间的数据所有权是否清楚。

6.11 本阶段的交付物和检查清单

  • 术语定义没有同义混用;
  • 关键流程和事件可追踪;
  • 每条重要规则有业务来源;
  • 模块拥有的数据和责任明确;
  • 未确认推断没有伪装成事实。

7. 第三阶段:确定 MVP 和产品路线

7.1 从完整愿景中找到最小闭环

MVP 不是功能数量最少,而是最小的价值闭环。只有“创建工单”没有处理和反馈,不构成闭环;创建、分派、处理、关闭才构成一次完整流转。

7.2 使用用户故事地图组织需求

1
2
3
4
提交问题       跟踪处理       解决问题       复盘
创建工单 查看状态 标记解决 搜索历史
上传附件 添加评论 重新打开 导出报表
接收通知

先沿横向保留一条完整主路径,再按纵向增加细节。

7.3 区分核心功能、支撑功能和未来功能

核心功能决定价值闭环;支撑功能使闭环可运行;未来功能有价值但不影响当前验证。AI 常把“可能有用”误判为“首期必需”,需要人为裁剪。

7.4 使用 MoSCoW 进行优先级排序

  • Must:没有它就无法验证核心价值;
  • Should:重要但可以短期人工处理;
  • Could:成本允许时加入;
  • Won’t:本次明确不做。

7.5 按用户价值拆分垂直切片

推荐切片:用户登录、创建工单、分派工单、处理并评论、解决并通知。每个切片同时包含必要的页面、接口、领域逻辑和存储。

7.6 为什么不要按前端、后端和数据库拆任务

按技术层拆分会导致很长时间没有任何可验收行为,也容易让接口假设在联调时才暴露。垂直切片可以尽早验证全链路。

7.7 识别高风险功能并提前验证

对陌生 SDK、性能上限或第三方集成做时间盒 Spike。Spike 的产物是结论,不是直接进入生产的临时代码。

7.8 形成 MVP Backlog

每项 Backlog 至少包含价值、范围、验收场景、依赖和优先级。只有标题的待办不能为 AI 提供稳定边界。

7.9 本阶段的交付物和检查清单

  • MVP 覆盖一条完整用户路径;
  • 每个切片可以独立演示;
  • 高风险假设有验证计划;
  • 非目标和未来功能明确记录;
  • Backlog 顺序反映价值和依赖。

8. 第四阶段:使用 SDD 编写规格

8.1 为什么不能只依赖聊天上下文

聊天会被截断、总结和遗忘,也难以在 Pull Request 中审查。规格应保存在仓库中,与代码共同演进。

8.2 项目规格与变更规格

项目规格描述系统当前承诺的行为;变更规格描述相对于当前行为的增量。变更完成后,将增量合并到当前规格。

8.3 Proposal、Spec、Design 和 Tasks

  • Proposal:为什么做、范围和影响;
  • Spec:系统必须提供的可观察行为;
  • Design:技术方案、权衡、风险和迁移;
  • Tasks:可执行、可验证的实施步骤。

8.4 使用 OpenSpec 管理规格

OpenSpec 需要 Node.js 20.19.0 或更高版本:

1
2
3
4
npm install -g @fission-ai/openspec@latest
cd your-project
openspec init
openspec --version

openspec ... 在终端运行,OpenSpec 工作流命令或 Skill 在 AI 编程助手的对话中调用。不同工具的命令形式可能不同,应以 openspec init 生成的说明为准。

默认核心工作流包括 explore、propose、apply、update、sync 和 archive。一次典型变更是:

1
2
3
4
5
6
explore:只探索问题,不创建变更
propose:创建 Proposal、Specs、Design、Tasks
apply:按规格和任务实施
update:修改已有规划工件
sync:不归档,先把规格增量同步到主规格
archive:归档变更并更新主规格

8.5 编写清晰的功能需求

需求使用“系统必须……”描述可观察能力,避免“优化体验”“支持高并发”这类无法验收的形容词。性能要求需要明确负载和指标。

8.6 使用 Given、When、Then 描述场景

1
2
3
4
5
6
7
8
9
10
11
### Requirement: 分派工单

系统必须允许管理员把未关闭工单分派给一个有效处理人。

#### Scenario: 成功分派待处理工单

- Given 工单处于“待处理”状态
- And 目标处理人属于该工单团队
- When 管理员分派工单
- Then 工单处理人变为目标用户
- And 系统记录“工单已分派”事件

8.7 正常流程、异常流程与边界条件

至少覆盖成功、权限不足、状态不允许、输入边界、外部依赖失败、重复请求和并发竞争。

8.8 区分业务需求和技术方案

“重复请求不得重复退款”是需求;“使用 Redis 分布式锁”是候选设计。把两者分开,才能在不改变行为的情况下更换实现。

8.9 规格如何与代码一起进入 Git

变更目录应和实现一起进入分支与 PR。团队可以选择合并前归档或合并后归档,但必须约定一致。OpenSpec 不替代 Git,也不会自动替团队推送代码。

8.10 规格审查的检查清单

  • 价值、范围和非目标清楚;
  • 每个需求至少有一个具体场景;
  • 术语与领域模型一致;
  • 异常、权限、幂等和兼容性被考虑;
  • 设计能够追溯到需求;
  • 任务覆盖全部需求。

8.11 本阶段的交付物和验收门槛

只有当需求可验证、范围足够小、关键未知已解决、利益相关者同意后,才进入大规模实现。


9. 第五阶段:架构设计与技术决策

9.1 先识别质量属性

先明确安全、可用、性能、可维护、成本和一致性要求,再讨论框架。否则技术选型只是在比较流行度。

9.2 单体、模块化单体与微服务

新项目通常优先模块化单体:部署简单、事务直接,又保留业务边界。只有当独立扩缩、团队自治、故障隔离等收益超过分布式复杂度时,再考虑拆分服务。

9.3 使用 C4 模型描述架构

C4 从系统上下文、容器、组件逐层表达。大多数项目使用前两层和关键组件图已经足够,不需要为每个类画图。

9.4 根据限界上下文划分模块

1
2
3
4
5
6
src/
├── identity/
├── organization/
├── ticketing/
├── notification/
└── shared/

模块之间通过公开应用接口或事件协作,禁止直接修改另一个模块的内部数据。

9.5 数据存储与事务策略

明确谁拥有数据、事务边界在哪里、失败如何恢复。不要因为“未来可能拆服务”就在首期引入不必要的最终一致性。

9.6 同步调用、消息和领域事件

需要立即结果且调用链短时使用同步调用;允许异步、需要解耦或重试时使用消息。事件表达已经发生的事实,不应伪装成远程命令。

9.7 身份认证与权限模型

认证回答“你是谁”,授权回答“你能做什么”。规格需要覆盖对象归属、角色、租户边界和审计,而不仅是接口是否携带 Token。

9.8 日志、指标、追踪与告警

日志解释单次事件,指标展示总体趋势,追踪连接跨组件调用,告警提示需要行动的异常。敏感信息不能为了排障而写入日志。

9.9 使用 ADR 记录关键决策

1
2
3
4
5
6
7
8
9
10
# ADR-001:首期采用模块化单体

## 背景
团队只有三名开发者,业务边界仍在变化,需要两个月内验证 MVP。

## 决策
使用一个部署单元,按限界上下文划分代码模块和数据访问边界。

## 后果
部署和事务更简单;需要架构测试防止模块绕过接口直接依赖。

9.10 使用技术 Spike 验证高风险方案

为 Spike 设置时间盒和退出标准,例如“用两天验证 WebSocket 网关能否在目标环境保持一万连接”。验证代码可以丢弃,结论写入 ADR。

9.11 防止大模型过度设计

要求 AI 对每个新增组件说明它解决的当前问题、最简单替代方案和运维成本。没有当前需求依据的抽象、缓存、队列和服务应暂缓。

9.12 本阶段的交付物和检查清单

  • 架构对应当前质量属性;
  • 模块职责和数据所有权明确;
  • 重要选择有 ADR;
  • 外部依赖和失败模式已识别;
  • 方案能被当前团队部署和排障。

10. 第六阶段:建立工程基线

10.1 设计项目目录结构

目录要表达业务边界和依赖方向。避免把所有领域逻辑散落在 utils/、Controller 和 ORM Hook 中。

10.2 选择语言、框架和依赖

优先选择团队熟悉、维护活跃、生态稳定的方案。让 AI 核对当前版本和官方文档,但不要让它仅凭训练记忆虚构 API。

10.3 初始化 Git 仓库

建立主分支保护、提交约定和忽略规则。环境文件、密钥、构建产物、IDE 状态和本地 AI 记忆通常不应提交。

10.4 建立格式化、Lint 和类型检查

将可机械判断的规则交给工具,避免浪费人工审查。所有检查要能够在本地和 CI 以同一命令运行。

10.5 配置单元测试和集成测试

项目初始化时就提供最小测试样例、隔离数据库、Fixture 工具和覆盖率报告,降低后续 AI 跳过测试的诱因。

10.6 配置数据库迁移

迁移必须可重复执行,并考虑滚动发布期间新旧代码同时运行。危险数据变更使用 expand-migrate-contract,而不是一次重命名生产字段。

10.7 建立配置与密钥管理

仓库保存配置模板,不保存真实密钥。明确开发、测试、预发布和生产环境的覆盖顺序。

10.8 建立统一日志与错误处理

统一关联 ID、错误码、结构化字段和脱敏规则。领域错误与基础设施故障需要有不同处理策略。

10.9 建立 CI 流水线

1
格式检查 → Lint → 类型检查 → 单元测试 → 集成测试 → 构建 → 安全扫描

快速检查优先运行,失败立即停止。

10.10 编写 README 和开发环境说明

README 至少说明用途、依赖、安装、启动、测试、构建、迁移和常见问题。命令必须实际运行验证。

10.11 使用 AGENTS.md 约束 AI 编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# AGENTS.md

## 架构
- ticketing 不得直接访问 notification 的数据库表。
- 领域层不得依赖 Web 框架和 ORM。

## 修改要求
- 实现前阅读对应 OpenSpec Change。
- 业务规则必须先写失败测试。
- 不修改规格范围外的文件。
- 完成前运行 format、lint、typecheck 和 test。

## 完成报告
- 列出修改文件、设计选择、验证命令和遗留风险。

10.12 本阶段的交付物和检查清单

新成员从干净环境可以按 README 启动项目;一次错误修改会被自动检查拦截;敏感配置不会进入 Git;AI 能从仓库读取稳定约束。


11. 第七阶段:把功能拆成可执行任务

11.1 从规格生成实施计划

任务不是复述需求,而是说明哪些文件、接口和测试需要变化,以及如何验证。

11.2 从垂直切片继续拆分任务

一个切片内部可按业务能力拆分,例如先实现工单聚合状态转换,再实现持久化和接口,最后接入通知。每一步都应保持可测试。

11.3 任务应该小到什么程度

判断标准不是固定分钟数,而是能否由一个新的审查者独立判断对错。如果一个任务同时引入权限系统、消息队列和报表,它显然过大。

11.4 标记任务依赖和实施顺序

先实现不变量与接口契约,再实现外层适配器;先做兼容性准备,再迁移数据;先增加观测,再切换流量。

11.5 区分确定性任务与探索性任务

确定性任务可以直接实施;探索性任务应先创建 Spike,例如验证支付网关退款回调是否携带幂等键。

11.6 给每个任务定义完成条件

1
2
3
4
5
- [ ] 未发货订单可以取消
- [ ] 已发货订单返回明确业务错误
- [ ] 重复请求只创建一笔退款
- [ ] 单元和集成测试通过
- [ ] API 文档已更新

11.7 如何为 AI 准备最小充分上下文

提供对应规格、相关入口、架构规则、常用命令和完成条件。不要一次粘贴整个仓库,也不要只给一句任务标题。

11.8 防止 AI 顺手修改无关代码

明确允许修改的模块和非目标;实施后检查 git diff --stat、未跟踪文件和依赖变化。发现额外问题时先记录,不自动扩展范围。

11.9 本阶段的交付物和检查清单

任务覆盖所有规格场景,每项都有验证方法,依赖顺序合理,单项失败不会迫使整个计划推倒重来。


12. 第八阶段:使用 BDD 和 TDD 实现功能

12.1 从规格场景生成验收测试

规格场景描述外部行为,验收测试将其自动化。不要为迎合当前实现而弱化场景。

12.2 测试金字塔

大量快速单元测试覆盖规则,适量集成测试覆盖数据库和外部接口,少量端到端测试覆盖关键路径。全靠 E2E 会慢且难定位,全靠单元测试则无法证明模块协作。

12.3 Red、Green、Refactor

必须看到测试因预期原因失败,才能证明它具有检测能力。实现时只增加使当前行为通过的代码,通过后再消除重复和改善命名。

12.4 哪些代码应该测试驱动

状态机、权限、计算、幂等、解析、调度、数据转换和错误恢复应优先 TDD。一次性技术 Spike 和早期视觉探索可以采取不同策略,但进入生产前仍需相应验证。

12.5 领域规则的单元测试

领域测试不应启动 Web 服务器或真实数据库:

1
2
3
4
5
def test_closed_ticket_cannot_be_assigned():
ticket = Ticket.closed(id="T-100")

with pytest.raises(TicketAlreadyClosed):
ticket.assign(agent_id="U-9")

12.6 数据库和外部系统的集成测试

验证 ORM 映射、约束、事务、消息序列化和第三方契约。外部服务使用 Sandbox 或契约明确的 Fake,不要用与真实行为差异巨大的万能 Mock。

12.7 关键用户流程的端到端测试

E2E 只保留最重要路径:登录、创建工单、分派、解决。失败时应能通过截图、网络日志和关联 ID 排查。

12.8 前端组件和交互测试

测试用户可见行为和可访问性,而不是组件内部状态。视觉差异可使用截图测试,但需要稳定基线和人工审查。

12.9 使用契约测试保护模块边界

跨服务或跨团队 API 使用消费者驱动契约,防止提供方修改字段后才在联调环境发现问题。

12.10 防止大模型写出“看起来通过”的无效测试

检查测试是否先失败、断言是否具体、是否只验证 Mock 被调用、是否遗漏负面场景、是否把实现细节复制进预期值。可以临时破坏实现验证测试会变红。

12.11 本阶段的完成条件

实现覆盖全部规格场景;相关测试与全量测试通过;没有跳过或弱化测试;任务清单更新;差异中没有无关修改。


13. 第九阶段:代码审查与系统验证

13.1 规格与实现一致性检查

逐条建立“需求 → 场景 → 测试 → 实现”追踪。某个需求没有测试,或某段实现找不到需求来源,都需要解释。

13.2 功能正确性检查

实际执行正常、异常、边界和重复请求。不要只阅读代码推断运行结果。

13.3 架构边界检查

检查模块是否绕过公开接口访问内部数据、领域层是否依赖基础设施,以及共享模块是否变成无边界垃圾场。

13.4 代码质量检查

重点看命名、复杂度、重复、错误处理、资源释放和可读性,而不是只争论格式。

13.5 安全检查

验证身份、对象级权限、输入、输出编码、密钥、日志、依赖、上传和速率限制。高风险系统应使用威胁模型和专门安全审查。

13.6 性能和容量检查

基于目标负载测试,不凭代码直觉优化。记录测试环境、数据量、吞吐、延迟分位数和资源使用。

13.7 数据迁移和兼容性检查

验证升级、回滚、新旧版本共存、旧数据和失败恢复。数据库迁移成功不等于业务数据正确。

13.8 让独立 AI 上下文进行第二次审查

让没有参与实现的会话只读取规格与差异,按严重程度报告问题。独立上下文更少受到原方案锚定,但结论仍需证据。

13.9 人工审查不能交给 AI 的部分

真实业务规则、法律责任、生产风险接受、用户体验取舍和组织影响必须由人确认。

13.10 验收清单与发布门槛

只有自动检查通过、关键场景人工验收、迁移和回滚演练完成、监控已就绪、遗留风险被接受时,才能发布。


14. 第十阶段:提交、发布与反馈

14.1 按问题拆分 Git 提交

每个提交解决一个可解释的问题,例如先提交保护性测试,再提交重构,再提交功能。不要把格式化整个仓库混入业务修复。

14.2 分支与 Pull Request 策略

一个小型 Change 通常对应一个分支和 PR。大型功能先拆多个独立 Change,而不是维持一个数月不合并的巨型分支。

14.3 规格、测试和代码一起审查

先审“是否构建正确的东西”,再审“是否正确地构建”。只有代码差异而没有规格依据,审查者只能猜需求。

14.4 自动构建和自动部署

构建产物应不可变,并在不同环境提升同一份产物。避免每个环境重新编译出不同结果。

14.5 数据库变更的发布顺序

先扩展兼容结构,再发布同时兼容新旧结构的代码,完成数据回填和验证后,最后删除旧结构。

14.6 灰度、特性开关和回滚

高风险功能先对内部用户或小流量启用。特性开关必须有负责人、到期时间和清理任务,避免永久债务。

14.7 生产环境可观测性

为关键业务行为建立指标和关联 ID。发布后能回答“多少请求成功、失败在哪里、影响哪些用户”。

14.8 监控技术指标和业务指标

技术指标正常不代表功能有价值。工单系统不仅看错误率,也看首次响应、解决时间和超时率。

14.9 将线上反馈转化为下一轮规格

反馈先进入问题探索,确认根因和优先级,再形成新的 Change。不要把用户的一句建议直接翻译成生产代码。

14.10 归档 OpenSpec Change

完成验证后归档变更,使规格增量进入主规格,并保留实施历史。若只是工具或文档变更,可根据团队约定跳过主规格更新。


第三部分:如何与大模型协作

15. 为大模型建立稳定的项目上下文

15.1 聊天上下文为什么不可靠

上下文有长度限制,会被压缩,也无法天然与代码版本绑定。重要事实不能只存在聊天中。

15.2 项目知识应该保存在哪里

1
2
3
4
5
6
7
README                 如何运行项目
AGENTS.md AI 工作规则与常用命令
openspec/specs/ 当前系统行为
openspec/changes/ 进行中的变更
docs/adr/ 架构决策
代码和测试 最精确的可执行事实
运行监控 生产环境真实状态

15.3 README、AGENTS、Specs 与 ADR 的分工

README 面向开发者入门;AGENTS 面向编程代理执行;Specs 描述业务行为;ADR 解释技术取舍。不要把所有信息塞进一个超长提示文件。

15.4 让 AI 先阅读再行动

要求 AI 先汇报已读取的约束、相关文件和未知问题。对于诊断任务,先收集证据;对于实现任务,先确认规格和验证命令。

15.5 为不同任务提供不同上下文

修复登录 Bug 不需要加载整个报表模块。上下文应围绕任务入口、调用链、规格和测试逐步展开。

15.6 控制上下文长度与信息密度

优先给出路径和检索方法,让代理按需读取;删除重复文档;用清晰标题、表格和短规则提高信息密度。

15.7 防止过期文档误导大模型

文档进入代码审查;命令由 CI 验证;过时 ADR 标记为 Superseded;规格与变更归档同步。无法维护的文档宁可删除,也不要保留错误事实。


16. 大模型任务的标准执行协议

16.1 探索型任务

目标是收集事实和选项,不修改代码。输出事实、推断、未知问题、候选方案和建议验证。

16.2 设计型任务

输入已确认需求和约束,输出方案、替代项、权衡、接口、数据流、迁移与风险。设计必须等待用户或团队批准。

16.3 实现型任务

输入规格、计划和完成条件;先检查工作区与测试基线;小步实施;完成后提供命令结果和差异摘要。

16.4 调试型任务

先复现、收集证据、建立假设、设计最小实验,再定位根因。没有证据时不应连续尝试随机修复。

16.5 重构型任务

冻结外部行为,建立测试保护,定义目标指标,分步修改。重构与新功能应尽量分开提交。

16.6 审查型任务

只报告能够定位和复现的问题,按严重程度排序,说明触发条件和影响。审查不是重写代码风格。

16.7 每类任务的输入、输出与权限

任务说明应明确允许读取和修改的范围、是否允许联网、是否允许安装依赖、是否允许提交、是否允许操作外部系统。只读请求不应被扩大为自动修改。

16.8 先计划、再实施、最后验证

计划不是仪式,而是暴露遗漏。实施时计划可以因新证据更新,但必须说明原因。验证必须运行,不接受“理论上通过”。

16.9 什么时候必须暂停并询问用户

  • 需求存在会改变结果的歧义;
  • 需要删除或覆盖重要数据;
  • 需要扩大访问权限或操作生产环境;
  • 实际代码与规格严重冲突;
  • 发现方案将产生用户没有授权的新成本或外部影响。

17. OpenSpec 与 Superpowers 如何组合

17.1 OpenSpec 负责管理什么

OpenSpec 管理系统规格、变更增量和 Artifact 工作流,强调“这次改变什么”和“完成后系统承诺什么”。

17.2 Superpowers 负责管理什么

Superpowers 是面向编程代理的技能化开发流程,覆盖 brainstorming、writing-plans、TDD、系统化调试、代码审查、验证、工作树和分支收尾,强调代理“如何可靠地工作”。

17.3 从需求探索到规格提案

可以先用 Superpowers brainstorming 或 OpenSpec explore 澄清问题。两者目标相近,不必机械重复。探索结论稳定后,由 OpenSpec propose 形成可版本控制的变更工件。

17.4 从规格到实施计划

OpenSpec Tasks 可以保持业务级实施清单;Superpowers writing-plans 可进一步展开文件路径、测试步骤和提交边界。小功能只保留一套任务即可,避免双重维护。

17.5 使用 TDD 执行计划

每个任务按 Red、Green、Refactor 实施。计划应明确失败测试、预期失败原因、最小实现和验证命令。

17.6 使用系统化调试处理失败

测试失败时切换到根因分析,而不是让代理不断改代码直到绿色。修复完成后补回归测试。

17.7 完成前验证与代码审查

先审规格符合性,再审代码质量;最后从干净状态运行测试、构建和差异检查,基于新鲜证据声明完成。

17.8 两套工作流发生冲突时如何处理

指定唯一事实来源:业务行为以 OpenSpec 为准,具体执行步骤以当前实施计划为准,仓库规则以 AGENTS.md 为准,用户最新明确指令优先。发生冲突时更新工件,不靠口头约定覆盖。

17.9 一套推荐的组合流程

flowchart LR
    A[Explore / Brainstorming] --> B[OpenSpec Propose]
    B --> C[人工审查规格]
    C --> D[Writing Plans]
    D --> E[Worktree / 分支]
    E --> F[TDD 实施]
    F --> G[规格符合性审查]
    G --> H[代码质量审查]
    H --> I[Verification]
    I --> J[OpenSpec Archive]

工具名称可能随版本变化,但工件和门槛比具体命令更重要。


18. 多模型与多智能体协作

18.1 什么时候需要多个模型

当任务可以清晰拆分、信息收集耗时或需要独立审查时,多模型有价值。一个小函数修改通常不值得增加协调成本。

18.2 规划者、实施者和审查者

规划者维护规格和边界;实施者完成单个任务;审查者在较少锚定的上下文中检查规格符合性和质量。角色可以由同一开发者在不同会话中组织。

18.3 如何拆分可并行任务

按独立模块、独立研究问题或独立测试面拆分。存在共享文件或严格顺序依赖的任务不应强行并行。

18.4 如何避免多个智能体修改同一文件

使用独立工作树或明确文件所有权;在分派前声明接口;合并前运行全量测试。不要让多个代理同时格式化整个仓库。

18.5 如何合并不同智能体的结论

要求结论携带证据和假设,由主执行者对照同一规格整合。多数投票不能替代事实验证。

18.6 多智能体不能替代架构边界

如果模块高度耦合,增加代理只会增加冲突。先改善接口和依赖方向,再扩大并行度。

18.7 成本、速度和质量的权衡

独立审查能提高质量,但会增加 Token、等待和协调成本。把并行资源用于高风险、可分离和耗时任务,而不是为了形式上的“多智能体”。


第四部分:实战一——从零到一开发新项目

下面从一个模糊想法开始,开发团队工单管理系统 HelpFlow。示例使用 Python、FastAPI、PostgreSQL 和普通 Web 前端,但方法不依赖具体技术栈。

19. 从一个模糊想法开始

19.1 原始需求

最初只有一句话:

帮我开发一个类似 Jira 的工单系统,要有用户、工单、评论、通知和报表,以后还要支持 AI 自动分类。

如果直接实现,AI 很可能生成大量接口和复杂架构,但“谁为什么使用它”仍然不清楚。

19.2 让 AI 进行需求访谈

第一轮明确禁止写代码:

1
2
3
4
5
6
7
我们准备开发工单系统。你是产品探索伙伴,不是代码生成器。
请一次只问一个最影响 MVP 范围的问题,并维护:
1. 已确认事实;
2. 当前假设;
3. 未决问题;
4. 明确非目标。
当信息足以定义首个价值闭环时停止追问并总结。

访谈得到:客户问题来自客服,不开放客户自助注册;客服创建工单;管理员分派;工程师处理;客服确认后关闭。首期只支持单个公司内部使用。

19.3 识别目标用户和核心问题

用户 任务 当前痛点
客服 记录并跟踪客户问题 微信消息易丢失
管理员 分派和监督工单 不知道谁在处理
工程师 查看待办并反馈结果 上下文散落在多处
负责人 发现积压和超时 缺少统一指标

19.4 确定 MVP

MVP 主路径:

1
2
客服登录 → 创建工单 → 管理员分派 → 工程师评论并解决
→ 客服确认关闭 → 所有人可以查看历史

基础通知作为支撑功能,但首期只做站内通知,不做邮件、短信和 WebSocket 实时推送。

19.5 明确暂时不做的功能

  • 多租户和计费;
  • 客户门户;
  • 自定义工作流;
  • AI 自动分类;
  • 复杂 SLA 日历;
  • 数据仓库和可视化大屏。

这份非目标会进入 Proposal,防止 AI 看到“类似 Jira”就复制 Jira 的全部能力。

19.6 形成项目愿景文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# HelpFlow 项目愿景

## 问题
客户问题通过即时消息传递,缺少负责人、状态和可追踪历史。

## 用户
客服、支持团队管理员和工程师。

## 价值
让每个客户问题都有唯一工单、明确处理人和完整流转记录。

## 成功指标
- 一周内未分派工单比例低于 5%;
- 90% 的工单在一个工作日内首次响应;
- 因交接丢失的问题数量降为 0。

## MVP
登录、创建、分派、评论、解决、关闭和站内通知。

## 非目标
多租户、计费、客户门户、AI 分类和自定义工作流。

检查点:业务负责人认可问题、目标和非目标后,才开始领域建模。


20. 对工单业务进行领域建模

20.1 建立统一语言

术语 定义
工单 Ticket 对一个客户问题的可追踪记录
报告人 Reporter 创建并跟踪工单的客服
处理人 Assignee 当前负责解决问题的工程师
解决 Resolve 工程师声明问题已经处理
关闭 Close 客服确认结果后结束工单
重新打开 Reopen 结果无效时恢复处理

“解决”和“关闭”是不同业务动作,这个差异会进入状态模型和代码命名。

20.2 梳理工单生命周期

stateDiagram-v2
    [*] --> Open: 创建
    Open --> InProgress: 分派
    InProgress --> Resolved: 解决
    Resolved --> Closed: 确认关闭
    Resolved --> InProgress: 重新打开
    Open --> Closed: 作废

20.3 识别命令和领域事件

命令 领域事件
CreateTicket TicketCreated
AssignTicket TicketAssigned
AddComment CommentAdded
ResolveTicket TicketResolved
CloseTicket TicketClosed
ReopenTicket TicketReopened

事件使用过去式,因为它表示已经发生的事实。

20.4 划分工单、用户和通知上下文

  • Identity:认证用户,管理登录凭据;
  • Organization:团队、成员和角色;
  • Ticketing:工单生命周期、评论和处理规则;
  • Notification:根据业务事件创建通知。

首期它们位于一个仓库和数据库中,但代码访问仍经过模块接口。

20.5 识别工单聚合及业务不变量

工单聚合保护这些规则:

1
2
3
4
5
关闭工单不能分派或评论;
只有处理中工单能够解决;
只有已解决工单能够正常关闭;
重新打开必须记录原因;
状态变化必须产生对应事件。

通知不放进工单聚合。工单先完成自己的事务,再由事件驱动通知模块,避免一个通知故障阻塞核心状态转换。

20.6 生成领域模型图

classDiagram
    class Ticket {
        +TicketId id
        +Title title
        +TicketStatus status
        +UserId reporterId
        +UserId assigneeId
        +assign(userId)
        +resolve(resolution)
        +close()
        +reopen(reason)
    }
    class Comment {
        +CommentId id
        +UserId authorId
        +string content
    }
    class TicketRepository {
        <>
        +get(id) Ticket
        +save(ticket)
    }
    Ticket "1" o-- "many" Comment
    TicketRepository ..> Ticket

这个模型是候选设计,不是凭空成为事实。每个方法都必须能够追溯到已确认业务动作。


21. 编写项目规格和架构方案

21.1 初始化 OpenSpec

1
2
cd helpflow
openspec init

初始化后提交 openspec/config.yaml、规格目录以及为当前 AI 工具生成的指令或 Skill。不要提交全局配置和用户机器上的缓存。

21.2 编写项目级规格

初始 openspec/specs/ticket-lifecycle/spec.md 保存系统已经确认的行为。首个尚未实施的功能放在 changes/,不要提前伪装成系统现状。

21.3 为第一个垂直切片创建 Change

在 AI 对话中调用 propose 工作流:

1
2
3
4
为 HelpFlow 提议 add-create-ticket 变更。
范围只包括已登录客服创建工单,并能在详情页查看刚创建的工单。
不要加入分派、通知、附件、自定义字段或搜索。
沿用项目统一语言和模块化单体架构。

21.4 编写 Proposal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Proposal: 创建工单

## Why
客服需要把客户问题从即时消息转为可追踪记录。

## What Changes
- 客服可使用标题、描述和优先级创建工单;
- 系统生成唯一工单编号;
- 创建者可以查看工单详情。

## Non-goals
- 附件、分派、通知、搜索和客户自助提交。

## Impact
新增 Ticketing 模块、工单数据表和创建/查询接口。

21.5 编写验收场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
### Requirement: 创建工单

系统必须允许具有客服角色的已登录用户创建工单。

#### Scenario: 使用有效数据创建工单
- Given 用户已经以客服身份登录
- When 用户提交标题、描述和优先级
- Then 系统创建状态为 Open 的工单
- And 工单报告人为当前用户
- And 系统返回唯一工单编号

#### Scenario: 标题为空
- Given 用户已经以客服身份登录
- When 用户提交空标题
- Then 系统拒绝请求
- And 不创建工单记录

#### Scenario: 普通工程师尝试创建工单
- Given 用户只有工程师角色
- When 用户提交创建请求
- Then 系统返回权限错误

21.6 选择模块化单体架构

首期一个 API 服务和一个 PostgreSQL 数据库足以满足规模;边界通过模块 API 和架构测试保护。此时不引入消息队列、搜索引擎和微服务。

21.7 编写关键 ADR

项目记录三个初始决策:模块化单体;PostgreSQL 作为唯一事实源;领域层不依赖 FastAPI 和 ORM。每份 ADR 同时写出重新评估条件。

21.8 生成实施任务

1
2
3
4
5
6
7
8
9
10
11
12
## 1. Ticket 领域模型
- [ ] 1.1 编写创建工单的失败测试
- [ ] 1.2 实现 Ticket.create 及输入不变量

## 2. 持久化与用例
- [ ] 2.1 添加工单表迁移和仓储集成测试
- [ ] 2.2 实现 CreateTicket 应用用例与权限检查

## 3. API 与页面
- [ ] 3.1 实现创建和详情接口
- [ ] 3.2 实现创建表单和详情页
- [ ] 3.3 添加关键流程端到端测试

每组任务都能产生独立测试证据,不使用“完成后端”“完成前端”这类模糊描述。


22. 建立项目工程基线

22.1 初始化前端和后端

使用官方脚手架生成最小工程,锁定依赖版本。脚手架只建立运行能力,不批量生成尚未确定的业务模块。

22.2 建立模块边界

1
2
3
4
5
6
7
8
9
backend/src/helpflow/
├── identity/
├── organization/
├── ticketing/
│ ├── domain/
│ ├── application/
│ ├── infrastructure/
│ └── api/
└── notification/

依赖方向为 API → Application → Domain,Infrastructure 实现 Domain 定义的端口。

22.3 配置数据库和迁移

本地使用容器启动 PostgreSQL;测试使用独立数据库;迁移在 CI 中从空库执行,也从上一个发布版本执行升级测试。

22.4 配置测试环境

为领域测试提供对象工厂,为集成测试管理事务和清理,为 E2E 提供确定性用户。测试不能依赖开发者机器上的残留数据。

22.5 配置代码质量检查

统一 make check 或等价命令执行格式、Lint、类型和快速测试,make test-all 执行全部测试。

22.6 配置 CI

Pull Request 必须通过静态检查、单元测试、集成测试、迁移检查和构建。主分支构建镜像,使用提交哈希作为不可变标签。

22.7 编写 AI 项目指令

AGENTS.md 记录模块规则、命令和修改要求,并明确:没有对应 Change 不得实现新业务能力;禁止把外部 SDK 类型泄漏进领域层;禁止跳过失败测试步骤。


23. 实现第一个完整垂直切片

23.1 创建工单的行为规格

实现者先读取 Change,逐条列出成功、验证失败和权限失败三个场景,并确认没有附件和通知。

23.2 先编写失败测试

1
2
3
4
5
6
7
8
9
10
11
def test_create_ticket_sets_reporter_and_open_status():
ticket = Ticket.create(
title="无法登录",
description="客户登录时收到 500",
priority=Priority.HIGH,
reporter_id=UserId("U-1"),
)

assert ticket.status is TicketStatus.OPEN
assert ticket.reporter_id == UserId("U-1")
assert isinstance(ticket.pull_events()[0], TicketCreated)

先运行并确认它因为 Ticket.create 尚不存在而失败,而不是因为导入路径或测试环境错误。

23.3 实现领域模型

实现标题非空、合法优先级、初始状态和事件产生。领域模型不知道 HTTP 状态码,也不直接写数据库。

23.4 实现应用服务

CreateTicketHandler 验证当前用户角色,创建聚合并调用仓储保存。事务由应用边界管理。

23.5 实现数据库仓储

集成测试验证保存后重新加载的对象保持身份、状态和值对象一致,并验证数据库唯一约束。

23.6 实现 HTTP 接口

API 把输入 DTO 转为应用命令,把领域错误映射为稳定错误码。权限不能只靠前端隐藏按钮。

23.7 实现前端页面

表单显示字段错误,成功后跳转详情页。组件只处理交互,不复制后端业务规则。

23.8 运行端到端测试

1
2
3
4
Given 客服已经登录
When 填写有效表单并提交
Then 跳转到包含工单编号的详情页
And 刷新后仍然能够读取工单

23.9 对照规格验证

审查者建立追踪表:三个 Scenario 是否有测试,代码是否增加规格外行为,迁移是否可回滚,权限是否在服务端执行。

23.10 提交并归档变更

建议提交拆分:领域测试与模型、持久化与用例、API 与页面、规格归档。合并前运行全量检查,从干净环境构建,然后归档 add-create-ticket。


24. 完成 MVP 并发布

24.1 实现工单分派

建立独立 Change,增加 AssignTicket,验证团队成员资格、关闭状态和并发更新,不顺手加入自动分派。

24.2 实现状态流转

使用领域方法保护 Open → InProgress → Resolved → Closed,非法转换返回领域错误并保持数据不变。

24.3 实现评论

明确谁能评论、内容长度、关闭后行为和审计需要。大附件仍作为非目标。

24.4 实现通知

Ticketing 发出事件,Notification 负责生成站内通知。用 Outbox 保证业务事务与事件记录一致,消费者设计为幂等。

24.5 完成安全和权限检查

验证对象级授权:工程师只能访问所属团队工单;管理员操作有审计;用户输入经过验证和输出编码;日志不记录客户敏感描述。

24.6 建立部署流水线

主分支通过检查后构建镜像,部署预发布环境运行 Smoke Test,经批准后将同一镜像部署生产。

24.7 首次发布

先向一个客服小组开放,导入少量用户,不一次替换全部现有流程。准备禁用新入口和导出数据的回退方案。

24.8 观察业务指标

监控接口错误率、任务积压、未分派比例、首次响应时间和关闭周期。指标按团队和优先级分解,避免平均值掩盖严重问题。

24.9 从反馈生成下一轮 Backlog

用户反馈“希望工单自动分配”不能直接进入实现。先确认是分派耗时、规则不清还是管理者离线,再决定 SLA、轮询规则或智能推荐哪个更有价值。


第五部分:实战二——在已有系统上二次开发

第二个案例是接手一个测试稀少的旧电商系统,为它增加“订单取消与退款”。二开与新项目最大的区别是:现有代码和运行行为本身就是约束,不能假设可以重新设计一切。

25. 接手陌生项目时不要立即修改代码

25.1 收集项目运行信息

先确认语言和运行时版本、安装命令、环境变量、数据库、外部服务、部署方式和负责人。没有本地运行条件时,应记录阻塞,而不是模拟成功。

25.2 阅读项目文档和提交历史

README 告诉你设计意图,提交历史解释某些奇怪代码为何存在,生产事件记录揭示真实风险。文档与代码冲突时,把冲突列为待验证问题。

25.3 运行现有测试和构建

记录基线:哪些测试本来就失败、耗时多少、是否有偶发失败。不能把已有失败归咎于新改动,也不能为了绿色而删除它们。

25.4 让 AI 绘制代码地图

1
2
3
4
只读分析“提交订单”到“发货”的现有调用链。
列出入口、应用服务、状态修改、数据库表、消息、外部支付接口和测试。
每条结论标注文件与行号,并把推断和事实分开。
不要提出重构或修改代码。

25.5 识别入口、数据流和外部依赖

从 HTTP、后台任务和消息消费者三个入口追踪订单状态;确认库存服务、支付网关、财务对账和通知系统的契约。

25.6 区分事实、推断和未知信息

1
2
3
事实:Order.status 存在 PAID 和 SHIPPED;发货接口会写 shipped_at。
推断:PAID 状态可能允许退款,但没有代码或文档证明。
未知:支付网关是否保证退款请求幂等。

只有事实可以直接成为设计输入,未知问题需要询问或实验。


26. 逆向理解现有系统

26.1 从用户行为追踪代码路径

以“用户支付后仓库发货”为主路径,从接口进入应用层、数据库、消息和外部系统。不要先按目录批量总结所有文件。

26.2 从数据库反推业务模型的风险

表结构显示数据形状,不一定表达业务含义。status=3 可能同时代表支付成功和等待库存,必须结合写入位置与业务人员确认。

26.3 识别现有业务规则

通过条件分支、数据库约束、错误码、测试、运营手册和日志寻找规则。将来源记录在现状文档中。

26.4 建立当前状态模型

stateDiagram-v2
    [*] --> Created
    Created --> Paid: 支付成功
    Paid --> Shipped: 仓库发货
    Shipped --> Completed: 用户确认
    Created --> Cancelled: 超时或用户取消

系统尚无“退款中”和“退款失败”状态,这是新需求必须处理的模型缺口。

26.5 补充特征测试

特征测试锁定现有行为,而不判断它是否优雅:已支付订单发货后库存扣减;重复支付回调不会重复记账;未支付订单可以取消。这些测试是安全修改的保护网。

26.6 记录技术债而不顺手全部重构

建立 Debt Log:全局事务、巨型服务、字符串状态、外部调用缺少超时。只有阻碍本次安全实施的债务进入当前范围,其余单独排期。

26.7 建立系统基线

最终得到可运行命令、测试结果、代码地图、状态模型、外部契约、已知故障和技术债列表。没有基线,不进入变更设计。


27. 为订单取消功能建立变更规格

27.1 分析原始需求

原始需求是“增加订单取消按钮”。探索后确认真实流程:用户可取消已支付但未发货订单,系统释放库存并向原支付方式退款;发货后由售后流程处理,本次不做。

27.2 识别订单、库存和支付边界

订单拥有取消状态;库存拥有释放动作;支付拥有退款记录。订单不能直接修改库存表和支付流水。

27.3 定义允许取消的订单状态

1
2
3
4
5
Created:直接取消,不退款
Paid:进入 Cancelling,释放库存并退款
Shipped:拒绝取消,引导售后
Completed:拒绝取消
Cancelled:返回已有结果,不重复执行

27.4 定义库存释放与退款行为

取消请求先记录业务意图,再异步协调库存和支付。外部退款可能需要数分钟,接口不能假装同步成功。

27.5 定义重复请求的幂等行为

相同订单重复取消返回同一取消结果;退款记录以订单和退款原因形成唯一业务键;消费者重复收到消息不重复退款。

27.6 定义失败和补偿策略

库存释放成功但退款失败时保持 Cancelling 或 RefundFailed 状态并告警,不把订单错误标记为完全取消。人工处理必须有审计入口。

27.7 使用 OpenSpec 创建 Change

Proposal 明确发货后退货、部分退款、优惠券返还和跨境支付不在范围。Specs 分别为 order-cancellation、inventory-release 和 payment-refund 编写增量。

27.8 审查对现有功能的影响

区域 影响
订单详情和列表 增加取消中、退款失败等状态
发货 必须拒绝 Cancelling 订单
财务对账 识别退款记录
客服后台 展示失败原因和人工处理入口
旧客户端 对未知状态进行兼容降级

28. 安全地修改遗留代码

28.1 先添加保护性测试

在改变状态模型前,先锁定支付、发货和原取消流程。新增测试必须在旧实现上因缺少新行为而失败。

28.2 建立最小接缝

把支付 SDK 调用包在 PaymentGateway 接口后,使退款逻辑可测试;不趁机替换整个支付模块。

28.3 用小步重构暴露业务能力

先把散落的状态判断提取为命名明确的方法并保持行为不变,单独提交;然后再增加新状态和规则。这样审查者能区分重构与功能变化。

28.4 实现取消订单状态机

使用乐观锁或条件更新防止“取消”和“发货”同时成功:只有状态仍为 Paid 时才能转为 Cancelling,更新失败后重新读取并返回冲突。

1
2
3
4
5
UPDATE orders
SET status = 'CANCELLING', version = version + 1
WHERE id = :order_id
AND status = 'PAID'
AND version = :expected_version;

受影响行数为 0 时,不允许继续释放库存或发起退款。

28.5 集成库存和支付模块

订单事务写入 Outbox 事件;库存和支付消费者各自幂等处理;协调器根据结果推进 Cancelled 或 RefundFailed。消息“至少一次”投递被视为正常情况。

28.6 处理事务与最终一致性

不要用跨数据库长事务包住支付网关。业务状态明确展示处理中,失败可重试,补偿有记录,对用户不虚假承诺即时完成。

28.7 保证旧接口兼容

新增状态先确保旧客户端能够降级显示;字段只新增不删除;新取消接口使用稳定错误码;消费者先部署兼容版本,再开始产生新事件。

28.8 完成数据迁移

新表和可空字段先上线,后台回填并校验数量,代码切换后再逐步增加非空约束。每一步都可暂停和回滚。

28.9 灰度发布和回滚

先对内部测试订单启用,再对少量用户开放;监控取消成功率、退款耗时、重复退款防护和人工介入。回滚时停止创建新取消,但继续处理已经进入 Cancelling 的订单,不能简单关闭消费者。


29. 二次开发的复盘

29.1 哪些技术债应该顺便修复

只修复阻止正确实现、无法测试或直接扩大生产风险的债。例如没有支付接口接缝会阻止可靠测试,值得先处理。

29.2 哪些重构应该单独立项

全面替换 ORM、拆微服务、重写所有状态枚举与本次取消功能没有必要关系,应建立独立 Proposal 和收益指标。

29.3 如何补齐文档和领域知识

把确认的订单状态、退款术语、外部契约和故障处理写回 Specs、ADR 和 Runbook,不让知识只留在二开人员的聊天记录里。

29.4 如何防止新功能继续恶化架构

新增代码遵守目标边界,架构测试阻止反向依赖;老代码暂未全部迁移可以接受,但新代码不能复制旧问题。

29.5 如何逐步把遗留系统纳入规范流程

不要一次为整个系统补齐规格。每次修改一个区域时,先建立该区域的现状规格和特征测试,再添加变更增量,逐步扩大可信地图。


第六部分:实战三——对线上项目持续迭代

第三个案例回到 HelpFlow。系统已经上线,团队不能为了新需求破坏现有用户、数据和服务水平。

30. 从线上反馈中识别真实需求

30.1 收集用户反馈

渠道包括访谈、客服记录、搜索词、功能请求和可用性观察。记录用户发生了什么,而不是只记录用户建议的功能。

30.2 分析业务指标和日志

数据显示高优先级工单首次响应慢,主要原因是管理员夜间不在线,而不是工程师处理速度慢。

30.3 区分用户方案与用户问题

用户说“增加 AI 自动分派”,问题其实是“工单创建后等待人工分派”。候选方案还包括轮询规则、值班表和超时升级。

30.4 识别最高价值的改进

先增加优先级和 SLA,使问题可以衡量;再引入规则分派;积累数据后才评估 AI 推荐。避免在没有标签和效果指标时直接训练模型。

30.5 评估收益、成本和风险

使用简单评分:影响用户数、业务收益、信心、开发成本和运行风险。评分用于暴露假设,不是假装得到精确数学答案。

30.6 更新产品路线图

路线按结果组织:降低未分派等待、降低高优先级超时、提高首次正确分派率,而不是按功能名称堆积。


31. 小功能迭代:增加工单优先级

31.1 判断是否需要完整设计

功能跨数据库、API、页面和排序,但业务规则简单。使用轻量 Proposal、规格场景和任务,不需要新的系统架构图。

31.2 编写轻量变更规格

定义 Low、Normal、High、Urgent 四级;默认 Normal;只有客服和管理员可修改;列表支持筛选;本次不自动计算优先级。

31.3 修改领域模型

Priority 使用值对象或枚举,工单通过 change_priority 修改并记录事件,禁止 Controller 直接赋值。

31.4 补充数据库迁移

先增加有默认值的字段并回填旧工单,再建立索引。确认数据规模下添加字段不会长时间锁表。

31.5 使用 TDD 完成实现

测试默认值、合法修改、权限不足、非法输入、事件记录和列表筛选,再实现领域、应用、API 和页面。

31.6 兼容旧数据和旧接口

旧请求不传优先级时行为不变;响应新增字段不会破坏宽松客户端;旧记录回填 Normal。

31.7 验证并发布

检查按优先级筛选结果和查询计划,小流量开放后观察字段使用率。如果所有人都选择 Urgent,说明规则和激励需要调整。


32. 中型功能迭代:增加 SLA

32.1 澄清 SLA 业务规则

需要确认首次响应和解决时限、不同优先级目标、暂停条件、工作时间、节假日、重新打开的处理和谁接收告警。

32.2 建模工作时间和值对象

BusinessCalendar 负责计算工作时间,SlaPolicy 根据优先级给出时限,SlaDeadline 保存计算结果。不要在多个定时任务中复制日期算法。

32.3 定义超时事件

FirstResponseBreached 和 ResolutionBreached 是不同事件。事件只产生一次,重复扫描不得重复告警。

32.4 设计调度和通知机制

创建或改变优先级时计算截止时间;后台任务扫描临近和已经超时的工单;通知模块订阅事件。扫描任务使用索引和分批处理。

32.5 编写规格与技术方案

规格用具体时间示例验证周末、节假日和跨时区;Design 记录日历来源、重算策略、数据迁移和故障恢复。

32.6 分阶段实施

  1. 只计算并展示截止时间;
  2. 后台记录将要产生的告警但不发送;
  3. 对内部团队发送;
  4. 全面启用并增加升级策略。

32.7 使用可观测性验证效果

监控截止时间计算错误、扫描延迟、重复告警、SLA 达成率和用户响应。影子运行阶段对比人工计算,确认正确后再触发通知。


33. 大型功能迭代:自动分派工单

33.1 从规则分派到智能分派

先实现可解释规则:产品标签、团队、值班状态和当前负载。规则已无法覆盖且积累足够历史数据后,再考虑模型推荐。

33.2 定义决策边界和人工兜底

系统可以推荐处理人,但低置信度工单进入人工队列;管理员可改派并填写原因;安全和关键客户工单始终人工确认。

33.3 建立离线评估数据集

从历史工单构建时间切分的数据集,去除泄漏字段,定义 Top-1、Top-3 命中、跨团队误分和负载公平指标。人工改派不一定代表原推荐错误,需要区分原因。

33.4 使用特性开关逐步上线

先只记录推荐不展示,再向管理员展示建议,最后对高置信度类别自动分派。每阶段使用独立开关和停止条件。

33.5 A/B 测试和业务指标

比较首次分派时间、改派率、解决时长和严重误分,不只看模型准确率。确保实验分组不会让同一团队的流程相互污染。

33.6 失败回退机制

模型超时、不可用、输出未知用户或规则校验失败时,回退到规则或人工队列。自动化不能让核心工单创建失败。

33.7 根据效果持续调整

记录模型版本、特征、决策和人工覆盖原因,定期监控数据漂移。模型更新本身也必须作为独立变更,有规格、评估和回滚。


34. 处理迭代中的架构演进

34.1 什么时候应该重构

当重复和耦合持续阻碍交付、缺陷集中在同一区域或新需求无法用当前模型清晰表达时重构。只因代码“不够漂亮”不是高优先级理由。

34.2 什么时候应该拆分模块

模块职责出现独立语言和数据所有权,且变化原因不同,可以在单体内部先拆模块。模块化是服务化之前成本更低的验证。

34.3 什么时候应该拆分服务

只有独立扩缩容、故障隔离、发布节奏或团队自治带来明确收益,同时团队能承担网络、观测、部署和一致性成本时拆分。

34.4 使用适应度函数保护架构

把依赖规则、性能预算、镜像大小、启动时间和模块循环依赖变成自动测试。架构原则只有自动反馈才能长期保持。

34.5 使用 ADR 记录演进过程

新 ADR 引用并替代旧 ADR,说明触发重新评估的证据。不要修改历史 ADR 使过去看起来从未做过不同决定。

34.6 保持规格、代码和运行状态一致

规格描述承诺,代码实现承诺,生产观测验证承诺。任何一层偏离都形成工作项:更新错误文档、修复实现或重新评估需求。


第七部分:特殊任务的处理方法

35. 如何使用大模型修复 Bug

35.1 先复现而不是猜测

将用户描述转为最小、稳定、可重复的复现步骤,记录输入、环境、期望和实际结果。无法复现时先增加观测,不要让 AI 根据错误信息猜修复。

35.2 收集证据和缩小范围

检查最近提交、日志、堆栈、指标、数据库状态和请求链。使用二分、最小输入或关闭变量逐步缩小范围。

35.3 编写回归测试

找到触发条件后,先写一个在当前代码上失败的测试。它证明团队理解了问题,也保护未来不会重现。

35.4 找到根因而不是修复表象

“空指针发生在这一行”只是故障位置。根因可能是无效状态能够被创建。优先修复产生错误状态的边界,并在必要位置增加纵深防御。

35.5 验证修复没有引入回归

运行新回归测试、相关模块测试和全量检查;复现原用户路径;查看差异中是否包含无关修改。

35.6 一个线上并发 Bug 的完整示例

现象:两个管理员同时领取工单时,后写入者覆盖前者。步骤如下:

  1. 用并发集成测试稳定复现两个请求都返回成功;
  2. 确认读取和写入之间没有并发控制;
  3. 给工单增加版本字段并使用条件更新;
  4. 一个请求成功,另一个返回可重试冲突;
  5. 验证没有丢失事件和重复通知;
  6. 在指标中增加领取冲突次数。

不要用进程内锁修复,因为多实例部署时它不能保护数据库状态。


36. 如何使用大模型进行重构

36.1 重构与功能变更分离

重构保持外部行为不变。混合新行为后,测试失败时无法判断来自结构调整还是需求实现。

36.2 建立测试保护网

先覆盖准备修改的关键行为和模块契约。测试不足的遗留系统先补特征测试,不要一边猜行为一边改结构。

36.3 定义重构目标和约束

目标应可判断,例如“订单模块不再依赖支付 SDK”“把函数圈复杂度降到阈值以下”,而不是“让代码更优雅”。

36.4 小步修改并持续验证

移动、改名、提取接口、替换调用分开进行。每一步运行相关测试并形成可审查差异。

36.5 使用架构测试防止反复退化

重构建立的依赖方向要转换为自动规则,例如 Domain 不得导入 Framework,模块不能访问另一个模块的 infrastructure。

36.6 一个模块解耦的完整示例

支付 SDK 原本散落在订单服务中。先用特征测试锁定支付结果映射,再定义 PaymentGateway 端口,创建 SDK Adapter,逐个迁移调用,最后用架构测试禁止订单模块导入 SDK。整个过程不改变用户行为。


37. 如何使用大模型处理性能问题

37.1 先测量再优化

先定义慢在哪里、影响谁、负载多少。没有数据时的“优化”通常只是引入复杂度。

37.2 建立性能基线

记录数据规模、并发、硬件、版本、P50/P95/P99 延迟、吞吐和资源使用,保证优化前后可比较。

37.3 定位瓶颈

使用追踪、Profiler、数据库执行计划和火焰图,判断时间消耗在计算、锁、I/O、网络还是下游服务。

37.4 生成并验证优化假设

让 AI 为证据提出候选解释,并为每个解释设计最小实验。例如“列表慢可能来自 N+1 查询”,先统计查询数量,再决定是否预加载。

37.5 防止以复杂度换取无效性能

缓存会带来失效、一致性和容量问题;并发会带来竞争;异步会带来状态管理。只有收益超过新增成本才保留。

37.6 一个慢查询优化示例

工单列表 P95 为 1.8 秒。追踪显示每行分别查询处理人,100 行产生 201 条 SQL。增加批量预加载后降为 3 条查询,P95 降至 180 毫秒。随后添加查询数量测试和性能预算,防止回归。


38. 如何使用大模型处理安全需求

38.1 威胁建模

围绕资产、信任边界、攻击者能力和滥用场景分析,而不是在上线前只跑一次漏洞扫描。

38.2 身份认证与授权

认证成功不代表有权访问对象。接口必须验证角色、租户、资源归属和状态,并采用默认拒绝。

38.3 输入验证

在系统边界验证长度、格式、类型和语义;数据库参数化;输出按目标上下文编码。不要只依靠前端校验。

38.4 密钥和隐私数据

密钥进入密钥管理服务,不写代码、测试、提示词和日志。发送代码给外部模型前确认数据政策并移除敏感数据。

38.5 依赖与供应链安全

锁定版本、验证来源、扫描已知漏洞、最小化依赖、保护构建凭据并生成软件物料清单。AI 建议安装的新包也必须审查。

38.6 AI 生成代码的安全审查

重点检查越权、注入、不安全反序列化、路径穿越、服务端请求伪造、弱加密、错误信息泄露和无限资源消耗。

38.7 一个越权漏洞修复示例

工单详情接口只检查用户已登录,任意用户可枚举 ID。先写对象级授权回归测试,再让查询同时限定工单 ID 和用户可见团队;对拒绝事件记录审计指标,并检查列表、附件和评论接口是否存在同类根因。


第八部分:团队落地与治理

39. 团队如何采用这套方法

39.1 从一个试点项目开始

选择业务价值明确、风险可控、周期不超过数周的项目。记录采用前后的交付时间、缺陷、返工和审查成本。

39.2 定义团队统一流程

统一最小流程和例外条件:什么任务需要 Change,谁批准规格,哪些检查必须通过,谁能发布和回滚。

39.3 建立规格和代码模板

模板提供必要问题,不强迫每节写长文。允许删除不适用部分,但非目标、验收、风险和验证不能无理由省略。

39.4 建立 AI 使用规范

明确可用模型、数据分类、允许上传的代码、外部工具权限、生成内容的责任、审查要求和安全事件处理。

39.5 代码审查责任不能转移给 AI

AI 可以提高覆盖面,最终批准者仍对合并负责。不能以“AI 已审查”替代对业务行为和生产影响的判断。

39.6 衡量效率、质量和返工率

观察需求到生产的 Lead Time、变更失败率、恢复时间、生产缺陷、返工比例和规格审查发现的问题,而不是统计生成代码行数。

39.7 避免流程形式化和文档膨胀

每个工件都应服务一次决策、实施或验证。没人读取、与代码重复、无法维护的文档应合并、自动生成或删除。


40. 根据任务复杂度裁剪流程

40.1 一行修复

复现或检查事实,修改一处,运行最相关验证,检查差异。通常不需要正式 Proposal。

40.2 小型功能

使用轻量规格、3 到 5 个验收场景、简短任务清单、相关测试和单独提交。

40.3 中型业务变更

使用完整 Proposal、规格增量、Design、Tasks、迁移方案、测试矩阵和发布观测。

40.4 大型跨模块变更

先拆多个可独立交付的 Change,补充领域建模、ADR、接口契约、灰度和回滚。避免一个包含数十项能力的巨型规格。

40.5 新项目

先做愿景、领域、MVP、架构和工程基线,再按垂直切片循环。不要一开始完整设计所有未来模块。

40.6 遗留系统改造

先建立运行和测试基线、代码地图、现状规格和保护性测试,再做最小安全变更。

40.7 不同任务需要哪些产物

任务 规格 设计 测试 发布计划
简单修复 问题说明 通常不需要 回归或相关检查 通常不需要
小功能 轻量场景 简短说明 单元/集成 简单检查
跨模块功能 完整 Change Design 与 ADR 多层测试 灰度与回滚
数据/资金/权限 正式审查 威胁和迁移设计 故障与幂等测试 演练和人工批准

41. 常见失败模式

41.1 让 AI 一次生成整个项目

结果通常表面完整、内部缺少一致模型。改用逐个垂直切片,每片独立验收。

41.2 没有规格就开始编码

AI 会用常见做法填补业务空白。先写可观察行为和非目标。

41.3 把 AI 的推测当作项目事实

要求结论附文件、日志、文档或实验依据,并明确区分事实、推断和未知。

41.4 只测试正常流程

在规格阶段主动列权限、边界、重复、并发、下游失败和恢复场景。

41.5 测试与实现共同犯错

先确认业务示例,让测试在旧代码上按预期失败,关键测试由独立审查者检查。

41.6 过度设计和过度抽象

要求每个组件说明当前需求、最简单替代和删除条件,坚持 YAGNI。

41.7 修改范围不断扩大

发现额外问题时记录为后续 Change;当前改动只有在阻塞正确性时才扩大范围。

41.8 生成大量无人维护的文档

把稳定事实放进仓库工件,把临时探索留在变更中,能从代码自动生成的信息不要手写复制。

41.9 只看代码产量,不看交付结果

最终指标是用户价值、可靠性、交付周期和维护成本。代码越少地解决问题,通常越好。


第九部分:模板与速查

42. 项目开发模板

42.1 项目愿景模板

1
2
3
4
5
6
7
8
9
10
# 项目愿景
## 问题
## 目标用户
## 用户任务
## 价值主张
## 成功指标
## MVP
## 非目标
## 约束和风险
## 未决问题

42.2 项目范围与非目标模板

1
2
3
4
5
6
7
8
9
10
11
12
## 本次范围
- 必须交付的行为:

## 非目标
- 明确不做:

## 未来候选
- 有价值但不属于当前变更:

## 边界
- 允许修改:
- 不允许修改:

42.3 领域术语表模板

术语 定义 所属上下文 不等同于 业务来源
示例 精确定义 模块边界 易混淆术语 访谈或规则

42.4 用户故事地图模板

1
2
3
4
用户活动:A → B → C → D
MVP: A1 B1 C1 D1
下一版: A2 B2 D2
未来: B3 C3

42.5 OpenSpec Proposal 模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Proposal: <变更名称>

## Why
为什么现在要做。

## What Changes
外部可观察的变化。

## Non-goals
本次明确不做什么。

## Impact
影响的规格、模块、接口、数据和外部系统。

## Risks
主要风险与缓解方式。

42.6 行为规格模板

1
2
3
4
5
6
7
8
9
10
### Requirement: <能力>

系统必须……

#### Scenario: <具体示例>
- Given 初始上下文
- And 其他前置条件
- When 用户或系统执行动作
- Then 可观察结果
- And 必须保持的不变量

42.7 ADR 模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ADR-NNN:<决策>

## 状态
Proposed / Accepted / Superseded

## 背景
约束、问题和质量属性。

## 决策
选择了什么。

## 备选方案
还考虑了什么。

## 后果
收益、成本和新风险。

## 重新评估条件
什么变化会让我们重看这个决定。

42.8 实施计划模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## Task N:可独立验收的能力

涉及文件:
- 修改:
- 新增:
- 测试:

步骤:
1. 写失败测试并确认失败原因;
2. 实现最小行为;
3. 运行相关测试;
4. 重构并运行完整检查;
5. 更新任务和文档;
6. 检查差异并提交。

完成条件:
- [ ] 对应规格场景通过
- [ ] 没有范围外修改

42.9 发布和回滚模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 发布前
- 迁移和兼容性:
- 监控和告警:
- Smoke Test:
- 审批人:

## 灰度
- 初始范围:
- 扩大条件:
- 停止条件:

## 回滚
- 应用回滚:
- 数据处理:
- 进行中任务:
- 用户沟通:

42.10 项目复盘模板

1
2
3
4
5
6
7
## 目标与结果
## 做得好的地方
## 与预期不符的地方
## 根因和证据
## 应保留的流程
## 要调整的流程
## 负责人和截止时间

43. 大模型任务提示词模板

43.1 需求探索提示词

1
2
不要写代码。一次只提出一个高价值问题,澄清用户、任务、指标、范围、
非目标、规则和风险。持续维护事实、假设和未知问题,最后输出一页愿景。

43.2 代码库调研提示词

1
2
只读调查 <功能> 的现有实现。追踪入口、调用链、数据、外部依赖和测试。
每条结论附文件位置;将事实、推断和未知分开;不要修改代码或提出无关重构。

43.3 领域建模提示词

1
2
基于已确认业务事实建立术语表、事件时间线、子域、限界上下文、
聚合和不变量。对每个模型元素标注业务依据,不要从数据库表直接推导边界。

43.4 规格编写提示词

1
2
3
为 <变更> 编写 Proposal、Requirements 和 Scenarios。
明确非目标,覆盖成功、权限、边界、重复、并发和依赖失败。
需求描述可观察行为,不预设具体技术方案。

43.5 架构设计提示词

1
2
3
基于已批准规格和质量属性,给出 2 到 3 个可行方案。
比较复杂度、运维、迁移、失败模式和团队能力,推荐最简单可演进方案。
输出 C4 图、接口、数据流、ADR 和待验证风险,不编写业务代码。

43.6 TDD 实现提示词

1
2
3
阅读规格、计划和项目规则。一次完成一个任务:
先写失败测试并运行确认失败原因,再写最少实现,运行测试后重构。
不得弱化测试或扩大范围。完成时给出差异摘要、验证命令和遗留风险。

43.7 Bug 调试提示词

1
2
先复现并收集证据,不要猜修复。建立按可能性排序的根因假设,
为每个假设设计最小实验。定位根因后先写回归测试,再实施最小修复并验证。

43.8 代码审查提示词

1
2
3
只审查当前差异与对应规格。优先找会导致错误行为、安全问题、
数据损坏、兼容性回归和缺少测试的问题。每项发现说明位置、触发条件和影响;
没有证据的问题不要报告。

43.9 发布验证提示词

1
2
3
基于变更和部署配置生成发布检查表。覆盖构建物、迁移、新旧兼容、
灰度、监控、停止条件、回滚、进行中任务和用户影响。
区分已经验证的事实与仍需人工确认的事项。

44. 开发检查清单

44.1 新项目启动检查清单

  • 问题、用户、价值和指标明确;
  • MVP 构成完整价值闭环;
  • 统一语言和核心边界明确;
  • 架构符合当前团队和规模;
  • README、AGENTS、测试和 CI 可用;
  • 首个垂直切片有规格和验收场景。

44.2 二次开发检查清单

  • 项目能够运行、测试和构建;
  • 已记录现有失败;
  • 相关调用链和数据流已经调查;
  • 现有行为有特征测试保护;
  • 兼容、迁移和回滚已经设计;
  • 无关技术债没有混入当前范围。

44.3 功能迭代检查清单

  • 需求来自真实反馈或指标;
  • 已区分用户问题和建议方案;
  • Change 足够小并有非目标;
  • 规格、测试和实现可追踪;
  • 发布后有业务和技术指标;
  • 结论会进入下一轮规划。

44.4 Bug 修复检查清单

  • 问题可以稳定复现;
  • 根因有证据;
  • 回归测试在修复前会失败;
  • 修复针对根因而非表象;
  • 相关和全量检查通过;
  • 同类问题已进行有限范围排查。

44.5 代码审查检查清单

  • 实现满足规格且没有扩大范围;
  • 领域和架构边界保持;
  • 权限、输入、隐私和错误处理正确;
  • 测试覆盖重要负面场景;
  • 数据和接口保持兼容;
  • 新依赖、配置和迁移有必要且可控。

44.6 上线发布检查清单

  • 使用经过验证的不可变构建物;
  • 迁移经过演练;
  • 新旧版本可共存;
  • 灰度范围和扩大条件明确;
  • 指标、日志和告警就绪;
  • 回滚不会破坏进行中业务;
  • 发布和回滚负责人明确。

45. 总结:大模型时代开发者的核心能力

45.1 从编写代码转向定义问题

代码越来越容易生成,准确理解用户、选择正确问题和控制范围变得更有价值。

45.2 从记忆语法转向建立约束

规格、架构规则、类型、测试、静态检查、权限和 CI 共同构成 AI 可以可靠工作的环境。

45.3 从一次生成转向小步验证

每次只交付一个可观察行为,尽快获得自动反馈和用户反馈。小步不是慢,而是减少昂贵返工。

45.4 从阅读代码转向审查系统行为

审查者要把业务场景、数据状态、外部依赖和生产影响连接起来,而不只是寻找语法问题。

45.5 从个人经验转向可复用的工程流程

优秀团队把经验写进 Specs、ADR、Tests、AGENTS、CI 和 Runbook,使新的开发者和新的模型都能复用。

最后,可以把本文方法记成一条主线:

用 DDD 理解业务,用 SDD 固化变更,用 BDD 建立共同示例,用 TDD 驱动实现,用 ADR 保存取舍,用 CI/CD 与可观测性完成交付闭环。

对三类工作分别采用不同起点:

1
2
3
4
5
6
7
8
从零到一:
愿景 → 领域 → MVP → 架构 → 工程基线 → 垂直切片 → 发布反馈

二次开发:
运行基线 → 代码地图 → 现状规格 → 特征测试 → 最小变更 → 兼容迁移

持续迭代:
线上证据 → 问题探索 → 小型 Change → 灰度发布 → 指标验证 → 下一轮

大模型可以承担越来越多的实现工作,但软件最终是否解决真实问题、是否值得上线、风险是否可以接受,仍然需要人负责。真正有效的人机协作不是“让 AI 替我开发”,而是“把目标、边界和证据组织好,让 AI 在可靠的工程系统中工作”。