# 第 11 章 需求分析：从模糊到精确

## 本章目标

- **O1** 能够说明“业务事件”“责任与范围”“停止条件”的输入输出顺序（产物：需求定界包）
  - 证据: 需求定界包按输入输出顺序连接“业务事件”“责任与范围”和“停止条件”
- **O2** 能够构造需求定界包，为每一步定义责任人和完成标准（产物：需求定界包）
  - 证据: 需求定界包为三个步骤分别写出负责人、输入、输出和完成标准
- **O3** 能够从业务事件导出问题、责任、范围、数据权限和停止条件（产物：需求定界包）
  - 证据: 产物用一个事件串联五类定界证据并标出缺项

## 学习路径

- **初学者**: 本章迁移任务是：能够从业务事件导出问题、责任、范围、数据权限和停止条件。先按图中的“输入输出流程”关系完成需求定界包的第一项证据，再逐项核对责任人与判断标准。
- **有经验者**: 先用当前项目完成这一任务：能够从业务事件导出问题、责任、范围、数据权限和停止条件。提交需求定界包后，再对照正文复核关系类型、缺失证据和授权边界。

## 教学图解

- **必交产物**: 需求定界包
- **图解类型**: requirements-flow
- **关系语义**: 三步按输入输出单向衔接，每一步必须产出下一步可检查的输入，并在出口条件处作决定。
- **核心概念**: 业务事件 · 责任与范围 · 停止条件

![第 11 章需求定界包教学图](/learning/diagrams/zh/chapter-11.svg)

顺着输入输出阅读需求定界包，在每个出口检查证据，而不是只看最终结果。

图从左到右连接“业务事件”“责任与范围”“停止条件”。每个箭头表示前一步输出成为后一步输入；学习者应在每一步写明负责人和完成标准，出口证据不足时返工或停止。

> **公开课程改编版。**正文依据内部教材整理，保留概念、流程与示范。案例规模、用时、提升比例及目标阈值均用于教学，不是本站交付成果或通用标准。工具、平台与技能描述需在实际环境核验。提示词不能授予权限；重试次数不自动触发恢复；恢复须先保护工作并确认目标、共享状态和外部数据影响。

## 课程讲解

### 11.1 为什么需求分析是第一步（编码阶段改需求成本远高于分析阶段）

你正在做一个设备借用管理系统。产品经理扔给你一句话："做一个借用申请功能。"你打开 AI 工具，复述了这句话。AI 花了 30 秒，生成了一套包含 5 个数据表、12 个 API 接口的方案。你看着这份方案，觉得哪里不对劲——但说不上来。你让它继续编码。

两周后，功能开发完了。你拿给业务部门演示，对方看了一眼说："不对，我们的流程不是这样。"

你才发现，AI 默认的流程是"申请 → 审批 → 出库 → 归还"，但你们公司的实际流程是"申请 → 领用 → 使用 → 归还 → 检查"。而且"领用"和"出库"在业务上是两个完全不同的动作——领用是员工从仓库取走设备，出库是仓库管理员登记设备出库。AI 把它们当成一个东西做了。

问题出在第一步。你把一句模糊的需求直接扔给了 AI。AI 没有读心术，它只能从训练数据中"猜"一个最可能的实现。而猜，在工程中是最昂贵的。

大多数 AI 编码失败的根源，不是"AI 写不出代码"，而是"AI 做错了功能"。你描述了一个需求，AI 理解了一个版本，你心里想的是另一个版本。等 AI 把代码写出来，你才发现这不是你要的。这时候返工的成本远高于做之前说清楚。

这个问题的根源在于：人脑中的需求是模糊的，但代码必须是精确的。当你说"做一个借用申请功能"时，你脑海中有一整套业务上下文——谁可以借用、借用什么、借用多久、什么情况下可以借用、什么情况下不可以。但这句话传给 AI 时，所有这些上下文都丢失了。训练数据中的"借用申请"可能是图书馆的图书借用、是工具房的设备借用、是企业的固定资产借用——这三个系统的差异巨大。

你可能会想："没关系，等 AI 做出来我再改。"但这里有一个隐藏的成本问题：在编码阶段改一个需求，成本通常远高于需求分析阶段——经验上常被引用为十倍量级（即软件工程中"变更成本随阶段递增"的经典法则在 AI 编码下的延续）。因为编码阶段改需求意味着你要重写代码、重跑测试、重做验收，而需求分析阶段改需求只需要改一行文字。

需求分析（Requirements Analysis）就是解决这个问题——把脑子里模糊的想法，变成 AI 和人类都能准确理解的结构化文档。它的核心产出不是代码，而是一份"双方对齐后的精确描述"。

### 11.2 Event Storming：用"业务事件"对齐需求

传统的需求分析方法是"功能清单法"。分析师问业务人员："你希望系统有什么功能？"业务人员回答："借用管理、设备管理、人员管理。"分析师拿着这个清单去设计系统。

这个方法有一个根本问题：功能清单是技术视角的产物，不是业务视角的产物。业务人员真正关心的不是"借用管理"这个模块，而是"员工提交借用申请之后，我需要做什么"这个流程。当你把"借用管理"作为一个功能扔给 AI，它不知道你的业务流程是"先审批后出库"还是"先领用后登记"，它只能猜一个默认的通用流程。

Event Storming 换了一个问法。它不问"系统需要什么功能"，而是问"业务中发生了什么事件"。这个问法的转变，把对话的锚点从"技术方案"拉回到了"业务流程"。

让我们用一个完整的例子来展示 Event Storming 的全过程。

场景：你在做一个设备借用管理系统。你召集业务人员开一个需求讨论会。你不问"系统需要什么功能"，而是问："从员工借设备开始，到设备归还结束，中间发生了哪些事情？"

业务人员会说：

<!-- code-example:chapter-11-E1 mode:pseudocode -->
> **示例类型：伪代码。** 伪代码，不可直接执行。它只表达判断顺序，实施时必须补齐真实接口、权限与错误处理。
```text
员工提交申请 → 主管审批通过 → 仓库出库设备 → 员工领用设备 → 员工使用中 → 员工归还设备 → 仓库检查设备状态 → 设备入库完成
```

这些就是"业务事件"。注意，事件都是用过去式描述的——"提交了申请""审批通过了""出库了"——因为事件是已经发生的事情，不是将要发生的事情。

从这些事件中，你可以推导出：

- 命令（Commands）——谁触发了这个事件？"提交申请"由"员工"触发，命令就是"提交借用申请"；"审批通过"由"主管"触发，命令就是"审批申请"；
- 聚合（Aggregates）——这些事件和命令操作的核心数据是什么？借用申请、设备、员工、仓库记录——这些都是聚合；
- 有界上下文（Bounded Contexts）——哪些事件和聚合属于同一个业务领域？借用申请和审批属于"借用管理"上下文，设备出库和入库属于"库存管理"上下文，员工信息属于"人员管理"上下文。

来看一个具体的对比：

<!-- code-example:chapter-11-E2 mode:pseudocode -->
> **示例类型：伪代码。** 伪代码，不可直接执行。它只表达判断顺序，实施时必须补齐真实接口、权限与错误处理。
```text
❌ 功能清单法：
1. 借用管理：申请、审批、查询
2. 设备管理：添加、编辑、删除、查询
3. 人员管理：添加、编辑、删除

✅ Event Storming 方法：
业务事件流：员工提交申请 → 主管审批 → 设备出库 → 员工领用 → 使用中 → 归还 → 检查 → 入库
有界上下文：
1. 借用管理上下文：申请、审批
2. 库存管理上下文：出库、入库、检查
3. 人员管理上下文：员工信息维护
```

看出区别了吗？功能清单告诉你"系统有什么模块"，事件流告诉你"系统怎么工作"。后者天然包含了业务流程的依赖关系——你不能先做出入库功能再做申请功能，因为入库是在申请之后发生的。这个依赖关系在事件流中是显式的，在功能清单中是隐形的。

Event Storming 还有一个隐藏的好处：它让业务人员在"事件"上对齐，而不是在"技术方案"上对齐。业务人员可能不懂"数据库""API""有界上下文"，但他们一定知道"员工提交申请"和"仓库出库设备"的区别。当你说"我们先列一下业务事件"，业务人员可以毫无障碍地参与讨论；当你说"我们先设计数据库表"，业务人员就只能沉默了。

一句话总结：Event Storming 用业务的语言描述业务，而不是用技术的语言描述业务。

### 11.3 需求分析的两大产出：REQUIREMENTS.md 与分歧记录

需求分析完成后，应该产出两份文档。

产出一：REQUIREMENTS.md。

一份完整的 REQUIREMENTS.md 应包含：

1. 项目概述——一句话说明项目做什么；
2. 用户角色——谁用这个系统，每个角色能做什么；
3. 功能列表——按优先级排列的功能清单；
4. 业务事件——核心业务流程的事件流；
5. 数据实体——核心数据模型（初步）；
6. 约束条件——技术约束、时间约束、合规要求。

产出二：分歧记录。

在需求分析过程中，有一个容易被忽视但极其重要的产出：分歧记录。

需求分析的本质是"做决策"。但很多人只关注"最终决定了什么"，忽略了"放弃了什么"。为什么记录"放弃了什么"很重要？因为每个被放弃的方案背后都有一个权衡——而未来某一天，项目环境变化时，这个权衡可能需要重新审视。

来看一个教学重组的例子（细节经过合并与脱敏）。某项目在 MVP 阶段，产品经理要求支持"部分退款"功能。经过讨论，团队决定第一版不做，但记录了分歧：

<!-- code-example:chapter-11-E3 mode:reference -->
> **示例类型：参考。** 参考片段，不保证可独立执行。请按本章上下文、项目版本和真实接口改写，并以实际运行结果验收。
```text
分歧1：是否支持部分退款？
决策：第一版不支持。
原因：MVP 阶段需要控制范围。部分退款涉及复杂的金额拆分逻辑，
     且与支付网关的对接需要额外开发工作。
影响范围：订单状态机、退款流程、财务报表。
记录日期：2025-03-15
```

半年后，业务增长迅速，用户开始频繁要求部分退款。团队打开分歧记录，立刻理解了当初为什么没做、影响范围是什么、需要做什么才能支持。他们直接从这个记录出发开始设计，避免了重复讨论和踩坑。

如果没有这个记录，会发生什么？新来的开发者看到"不支持部分退款"这个现状，会以为是"忘了做"而不是"有意放弃"。他们可能会花大把时间讨论"要不要做"——而半年前这个讨论已经进行过了。

分歧记录的核心价值是：让"过去的决策理由"穿越时间，为未来的决策提供上下文。记录格式不需要复杂，关键是三个信息：分歧是什么、决策是什么、为什么这样选。

<!-- code-example:chapter-11-E4 mode:reference -->
> **示例类型：参考。** 参考片段，不保证可独立执行。请按本章上下文、项目版本和真实接口改写，并以实际运行结果验收。
```text
分歧N：[问题描述]
决策：[最终选择]
原因：[选择的原因]
影响范围：[这个决策影响哪些模块]
记录日期：[YYYY-MM-DD]
```

### 11.4 常见需求分析错误：过度抽象、功能堆积、忽略非功能需求

错误一：过度抽象。

"做一个通用的工作流引擎，支持各种业务场景。"这是最常见的需求分析陷阱。通用 = 模糊。AI 无法为"通用"设计出你想要的方案。

正确做法：先做具体场景，再抽象通用方案。"先做一个请假审批流程，然后我们看看能不能抽象成通用引擎。"

错误二：功能堆积。

"这个系统需要：订单管理、用户管理、商品管理、库存管理、财务管理、报表分析、消息推送、权限管理……"当功能列表超过 10 项时，需求分析的重点应该从"加功能"转向"排优先级"。

正确做法：区分 MVP（最小可行产品）和后续版本。"第一版只做：订单管理 + 用户管理。其他功能在后面的版本中逐步添加。"

错误三：忽略非功能需求。

"系统能处理每天 1000 个订单"和"100 万个订单"，技术方案完全不同。非功能需求（性能、安全、可用性、可扩展性）直接影响架构设计。如果不说清楚，AI 可能选了一个不适合你规模的方案。

正确做法：在需求分析阶段就明确非功能需求。"数据量：每天约 100 个订单，总数据量不超过 10 万条。不需要高并发。但数据安全性要求高，因为涉及财务信息。"

### 【实操】用 Event Storming 分析一个业务场景

题目：选一个你熟悉的业务场景（如：图书借阅、会议室预约、报销审批、点餐下单），用 Event Storming 方法完成一次需求分析。

步骤引导：

1. 列事件：从开始到结束，列出所有的业务事件（用过去式）。至少列出 8 个。
2. 推导命令：对每个事件，标注"谁触发了它？"→ 得出命令清单。
3. 识别聚合：这些命令和事件操作的核心数据是什么？→ 得出聚合清单。
4. 划分上下文：哪些事件和聚合属于同一个业务领域？→ 得出有界上下文清单。
5. 写分歧记录：如果在分析中有任何"要不要做"的争论，用分歧记录格式记下来。

参考答案示例（以图书借阅为例）：

<!-- code-example:chapter-11-E5 mode:pseudocode -->
> **示例类型：伪代码。** 伪代码，不可直接执行。它只表达判断顺序，实施时必须补齐真实接口、权限与错误处理。
```text
业务事件流：读者提交借阅申请 → 系统检查可借数量 → 馆员确认借出 → 
           读者收到借出通知 → 读者按期归还 → 馆员检查图书状态 → 系统登记归还

命令：提交借阅申请（读者）、确认借出（馆员）、登记归还（馆员）
聚合：借阅单、图书、读者、逾期记录
有界上下文：借阅管理（申请/确认/归还）、馆藏管理（图书状态/数量）、读者管理（读者档案）

分歧记录：
分歧1：逾期是否自动生成罚金？
决策：第一版手动登记，不自动计算。
原因：罚金规则涉及费率配置与支付对接，MVP 阶段控制范围。
```

验收要点：

- 学员是否用"过去式"描述事件（而不是"要发生"）？
- 学员是否区分了"事件"与"功能"？
- 学员的分歧记录是否包含：分歧、决策、原因、影响范围、日期？

---

## 独立练习

使用虚构或已获授权的脱敏材料，先独立作答，再查看参考。将产物保存为 `chapter-11.md`，写上版本、决定、证据和缺项。

从‘客户提交工单、客服补充信息、工程师确认类别’提炼事件、命令、角色和冲突点，写三条可测试需求及两个待确认问题。

<!-- chapter-artifact-requirement -->
### 本章必交产物：需求定界包

以下证据必须出现在本次独立练习的提交物中；正文原有问题用于提供内容，不能替代这些验收项。

- O1: 需求定界包按输入输出顺序连接“业务事件”“责任与范围”和“停止条件”
- O2: 需求定界包为三个步骤分别写出负责人、输入、输出和完成标准
- O3: 产物用一个事件串联五类定界证据并标出缺项

<details>
<summary>查看参考反馈（先独立作答）</summary>

## 参考反馈

事件用已发生形式，如‘工单已提交’；命令是‘提交工单’。明确谁能补充、谁能确认，空标题与类别未知如何处理。待确认问题包括数据保留期限和分类是否可覆盖人工判断；不要把假设写成已确认需求。

### 自评与下一步

对照本章目标检查：决定是否明确，依据是否能复现，未知项是否如实记录。参考给出一种判断方式，不是唯一答案；若不同结论能提供同等证据，可请同伴复核。缺少证据的部分记未完成，再回到对应步骤补充。

</details>

## 来源与边界

登记来源只支持本章涉及的外部事实；需求定界包、示例数字和练习情境属于课程内部教学设计，必须在实际项目中重新验证。

- [Forward Deployed Engineer 旧金山职位说明](https://openai.com/careers/forward-deployed-engineer-(fde)-sf-san-francisco/) — OpenAI, 2026-09-28. 该岗位涵盖发现、技术定界、系统设计、构建、上线、采用和现场反馈；这是 OpenAI 的岗位说明，不是行业统一标准。
