功能需求怎么写

你在 AI 辅助开发中一定遇到过这样的场景:需求文档写了,AI 也生成了代码,但结果和你想要的完全不同。问题往往不在 AI 的能力,而在于你的功能需求写得不够清楚。功能需求是连接「业务意图」和「技术实现」的桥梁——桥搭得越精确,AI 生成的代码就越接近预期;桥搭得模糊,AI 就只能靠「猜」来补全细节,而猜测几乎必然带来返工。

这篇文章聚焦功能需求的写法本身:用什么格式描述、怎么说明逻辑、业务规则和异常处理怎么表达、优先级怎么标注。这些内容直接决定了 AI 能不能「一次做对」。

功能需求的标准描述格式

一个清晰的功能需求,通常包含以下几个核心字段。无论你用 Markdown、Notion 还是 Jira,这些字段都应该出现在每一条功能描述中。

字段说明示例
需求编号唯一标识符,便于追溯和引用FR-AUTH-003
功能名称简短的功能描述,动宾结构用户邮箱注册
所属模块功能归属的产品模块用户认证模块
用户角色谁会使用这个功能未注册的访客
功能描述一句话说明系统应该做什么系统应允许访客通过邮箱和密码完成注册
前置条件功能触发前必须满足的状态用户未登录且不在黑名单中
触发条件什么事件触发该功能用户点击「注册」按钮
预期输出功能执行后的结果创建用户账号并发送验证邮件
验收标准如何判断功能是否正确实现邮箱格式校验通过;密码不少于 8 位;验证邮件 60 秒内发出

上面这个模板可以直接复制到你的 PRD 中使用。关键原则是:一条需求只描述一个行为。如果你发现自己在一条需求里写了「并且」「同时」,大概率需要拆分成两条。

EARS 句式模板

工业界有一种经过验证的需求写法叫 EARS(Easy Approach to Requirements Syntax),它用五个关键词模板覆盖绝大多数场景:

模式句式结构适用场景示例
通用型系统应(shall)+ 动词 + 宾语持续生效的规则系统应所有传输数据使用 TLS 1.3 加密
条件型当(WHILE)+ 状态 + 系统应…某状态下持续有效WHILE 用户处于登录状态,系统应每 5 分钟刷新 Token
事件型当(WHEN)+ 事件 + 系统应…特定事件触发WHEN 用户提交订单,系统应生成唯一订单号
可选型在(WHERE)+ 场景 + 系统应…特定功能位置WHERE 管理后台首页,系统应展示今日数据概览
异常型如果(IF)+ 条件 + 则(THEN)系统…错误和异常处理IF 支付超时 THEN 系统应释放库存并通知用户

用 EARS 句式写出来的需求,AI 解析时几乎不会产生歧义,因为每一句话都有明确的触发条件和预期行为。

功能逻辑说明:输入→处理→输出

功能需求的核心是逻辑。不管功能多复杂,都可以拆成三层:输入、处理、输出

输入(Input)

输入是功能运行所需的全部数据和状态。写输入时,要注意区分三类信息:

  • 用户输入:用户主动提供的数据,比如表单字段、搜索关键词、上传的文件
  • 系统输入:系统自动获取的数据,比如当前时间、用户 IP、设备信息
  • 外部输入:来自第三方系统的数据,比如支付回调、API 返回结果

处理(Process)

处理是业务逻辑的核心,描述系统拿到输入后要做什么。处理逻辑的说明方式取决于复杂度:

  • 简单逻辑:直接用文字步骤描述,比如「1. 校验邮箱格式 → 2. 检查邮箱是否已注册 → 3. 对密码进行哈希加密 → 4. 写入数据库 → 5. 发送验证邮件」
  • 中等逻辑:用表格列出每个步骤的输入、操作和输出
  • 复杂逻辑:用流程图或决策表,把每个判断分支画清楚

输出(Output)

输出是功能执行后产生的结果,包括:

  • 数据输出:写入数据库的记录、生成的文件、API 返回值
  • 界面输出:页面跳转、Toast 提示、弹窗、数据刷新
  • 副作用输出:发送邮件/短信、触发 Webhook、写入日志

下面用一个实际例子来展示完整的输入→处理→输出结构:

### FR-PAY-001 单次课程购买
 
**输入:**
- 用户已登录,账户状态正常
- 课程 ID(来自商品详情页)
- 支付方式(Stripe / PayPal)
- 优惠券码(可选)
 
**处理:**
1. 校验课程是否存在且可购买
2. 校验优惠券是否有效,计算最终金额
3. 调用支付网关创建支付会话
4. 等待支付回调确认
5. 若支付成功:创建订单记录、解锁课程权限、发送确认邮件
6. 若支付失败:释放锁定资源、记录失败日志
 
**输出:**
- 成功:跳转课程详情页,Toast 提示「购买成功」,发送订单确认邮件
- 失败:停留在支付页,展示错误信息和重试按钮

这种结构对 AI 非常友好——它能清晰地知道数据从哪来、经过什么逻辑、结果到哪去。

业务规则怎么写

业务规则(Business Rules)和功能需求是两个不同层面的东西。功能需求描述系统「做什么」,业务规则描述系统「遵循什么约束」。Karl Wiegers 在讨论业务规则时特别指出:业务规则不仅适用于软件系统,手动流程同样受其约束——正因如此,把它们从功能需求中分离出来,能让需求文档更清晰。

业务规则的分类

规则类型说明示例
事实规则定义业务领域的客观事实每个课程最多包含 50 个课时
约束规则限制某些行为或状态免费用户每月最多导出 10 次
动作规则定义触发条件和执行动作订单超过 30 分钟未支付,自动取消
计算规则定义计算方式和公式会员价格 = 原价 × 0.8(保留两位小数)
权限规则定义谁能做什么只有管理员可以删除评论

业务规则的写法

写业务规则时,遵循以下原则:

1. 一条规则只表达一个约束。 不要写「用户密码不少于 8 位且必须包含数字和字母」,而是拆成两条:

  • BR-001:用户密码长度不得少于 8 位
  • BR-002:用户密码必须同时包含数字和字母

2. 使用「必须 / 不得 / 应当」等明确措辞。 避免使用「最好」「尽量」「建议」这类模糊词——AI 无法判断这些词的优先级。

3. 规则要可验证。 每条规则都应该能通过测试来确认是否满足。如果一条规则写出来后你无法想象测试用例,说明它还不够具体。

4. 注明规则来源。 如果规则来自法律法规、商业合同或运营策略,标注来源能帮助开发和测试理解规则的优先级和变更频率。

### 业务规则清单
 
| 编号 | 规则描述 | 类型 | 来源 | 验证方式 |
|------|----------|------|------|----------|
| BR-001 | 密码长度不得少于 8 位 | 约束 | GDPR 安全基线 | 注册接口单元测试 |
| BR-002 | 免费用户每月导出上限 10 次 | 约束 | 产品商业化策略 | 导出功能集成测试 |
| BR-003 | 订单超时 30 分钟未支付自动取消 | 动作 | 运营策略 v2.3 | 定时任务测试 |
| BR-004 | 会员价 = 原价 × 0.8,保留两位小数 | 计算 | 定价策略文档 | 价格计算单元测试 |

异常处理怎么写

异常处理是功能需求中最容易被忽略、却最影响用户体验的部分。很多需求文档只写了「正常流程」,把异常情况留给开发「自行判断」——这在 AI 辅助开发中尤其危险,因为 AI 没有你的业务上下文,它会选择最通用的处理方式,而不是最适合你产品的方式。

异常处理的三层结构

层级说明具体动作
预防层在问题发生前拦截输入校验、权限检查、状态检查
处理层在问题发生时响应错误提示、降级方案、重试机制
恢复层在问题发生后恢复数据回滚、状态重置、通知管理员

异常场景清单模板

写异常处理时,可以从以下维度逐一排查:

异常类别需要覆盖的场景示例
输入异常空值、格式错误、超长、非法字符邮箱格式不正确
状态异常前置条件不满足、资源不存在课程已下架但仍有人购买
权限异常未登录、无权限、Token 过期普通用户访问管理后台
网络异常超时、断连、第三方服务不可用支付网关超时
并发异常重复提交、库存超卖、数据冲突同一座位被两人同时购买
业务异常违反业务规则、达到上限免费用户超出导出次数限制

异常处理的写法

对每一个异常场景,需求文档应包含以下信息:

### 异常处理:FR-PAY-001 单次课程购买
 
| 异常场景 | 触发条件 | 系统行为 | 用户提示 | 日志级别 |
|----------|----------|----------|----------|----------|
| 课程不存在 | 课程 ID 无效或已删除 | 返回 404,不创建订单 | 「该课程不存在或已下架」 | WARN |
| 库存不足 | 课程名额已满 | 禁用购买按钮,展示候补入口 | 「该课程已售罄,可加入候补名单」 | INFO |
| 支付超时 | 支付网关 30 秒未响应 | 释放锁定资源,记录待确认订单 | 「支付处理超时,请检查支付状态或重试」 | ERROR |
| 重复提交 | 同一用户 5 秒内重复点击购买 | 幂等处理,返回首次请求结果 | 不展示新提示,复用首次响应 | WARN |
| 优惠券失效 | 结算时优惠券被其他人先用完 | 重新计算价格,提示优惠券变化 | 「优惠券已被领完,已恢复原价」 | INFO |

关键原则:每个异常场景都要明确写出系统行为和用户提示。不要只写「给出错误提示」——具体提示什么内容,要写清楚。这对 AI 生成代码的帮助极大,因为它可以直接使用你提供的提示文案。

功能优先级标注方法

不是所有功能都同等重要。优先级标注帮助团队决定开发顺序,也帮助 AI 理解哪些功能是核心路径、哪些可以降级处理。

MoSCoW 方法

MoSCoW 是最常用的优先级标注框架:

优先级含义说明示例
Must Have必须有没有这个功能产品无法上线用户注册登录、支付功能
Should Have应该有重要但可以延后一个版本优惠券系统、邮件通知
Could Have可以有锦上添花,资源允许时再做社交分享、个性化推荐
Won't Have暂不做本期明确不做的功能多语言支持(v2 再做)

价值-成本矩阵

对于需要更精细排序的场景,可以使用价值-成本矩阵:

低成本高成本
高价值优先做(P0)重点规划(P1)
低价值顺手做(P2)不做(P3)

优先级在需求文档中的标注方式

### FR-AUTH-003 用户邮箱注册
- **优先级**:Must Have(P0)
- **所属模块**:用户认证
- **预计工时**:3 人日
- **依赖项**:FR-AUTH-001(邮箱格式校验服务)
- **风险项**:第三方邮件服务可用性

把优先级、依赖关系和风险项一起写清楚,AI 在生成代码时就能更好地安排模块的加载顺序和降级策略。

案例:两个真实场景的功能需求

案例一:AI 脚本生成工具的「重新生成」功能

这是一个 AI 产品常见的功能需求,看起来简单,但如果不写清楚,AI 生成的代码会问题百出。

### FR-GEN-012 脚本重新生成
 
**功能描述:**
用户可以对已生成的脚本发起重新生成请求,系统使用新的随机种子重新调用 AI 模型。
 
**优先级:** Should Have(P1)
 
**前置条件:**
- 用户已登录
- 当前页面存在至少一次成功生成的脚本结果
- 用户账户有足够的生成额度
 
**触发条件:**
用户点击「重新生成」按钮
 
**输入:**
- 原始 prompt(从上一次生成请求中获取)
- 原始参数(语言、风格、时长等)
- 新的随机种子(系统自动生成)
 
**处理逻辑:**
1. 校验用户生成额度是否充足
2. 若额度不足,终止流程并提示
3. 调用 AI 模型,传入原始 prompt + 参数 + 新种子
4. 等待模型返回结果(超时时间 60 秒)
5. 生成成功:保存新结果,追加到历史记录中(不覆盖旧结果)
6. 生成失败:保留旧结果,展示失败提示
 
**业务规则:**
- BR-GEN-001:同一脚本 24 小时内最多重新生成 5 次
- BR-GEN-002:重新生成消耗一次生成额度,与首次生成相同
- BR-GEN-003:重新生成的结果不得与最近一次结果完全相同(比对 hash)
 
**异常处理:**
| 异常场景 | 系统行为 | 用户提示 |
|----------|----------|----------|
| 额度不足 | 禁用按钮,展示充值入口 | 「生成额度不足,请充值后重试」 |
| 达到次数上限 | 禁用按钮,展示剩余次数 | 「今日重新生成次数已用完,明天再试」 |
| AI 模型超时 | 60 秒后中断,保留旧结果 | 「生成超时,请稍后重试」 |
| AI 模型返回错误 | 保留旧结果,记录错误日志 | 「生成失败,请重试。若问题持续,请联系支持」 |
| 网络中断 | 展示离线提示 | 「网络连接已断开,请检查网络后重试」 |
 
**验收标准:**
- [ ] 点击按钮后 3 秒内显示加载状态
- [ ] 生成成功后新结果展示在页面上,旧结果保留在历史中
- [ ] 达到次数上限后按钮变为灰色且展示提示
- [ ] 超时时旧结果不受影响

这个案例覆盖了功能描述、逻辑说明、业务规则、异常处理和验收标准。注意每个异常场景都有明确的系统行为和用户提示文案——这是 AI 能否一次生成正确代码的关键。

案例二:SaaS 平台的「团队成员邀请」功能

### FR-TEAM-005 邀请团队成员
 
**功能描述:**
管理员可以通过邮箱邀请新成员加入团队,受邀者收到邮件后完成注册和加入。
 
**优先级:** Must Have(P0)
 
**前置条件:**
- 当前用户是团队管理员或 Owner
- 团队未达到成员上限
 
**触发条件:**
管理员在团队设置页点击「邀请成员」并填写邮箱
 
**输入:**
- 受邀者邮箱(支持批量,逗号分隔,最多 10 个)
- 角色分配(Viewer / Editor / Admin)
- 邀请人 ID(自动获取)
- 团队 ID(自动获取)
 
**处理逻辑:**
1. 校验所有邮箱格式
2. 批量检查邮箱是否已在团队中
3. 检查团队剩余名额是否足够
4. 为每个有效邮箱生成唯一邀请 Token(有效期 72 小时)
5. 发送邀请邮件
6. 在邀请管理页展示待接受列表
 
**业务规则:**
- BR-TEAM-001:单次邀请最多 10 个邮箱
- BR-TEAM-002:邀请链接有效期 72 小时,过期自动失效
- BR-TEAM-003:同一邮箱 24 小时内不能重复邀请
- BR-TEAM-004:Free 计划团队最多 5 名成员
- BR-TEAM-005:被移除的成员 30 天内不能重新邀请同一邮箱
 
**异常处理:**
| 异常场景 | 系统行为 | 用户提示 |
|----------|----------|----------|
| 邮箱格式错误 | 标记错误邮箱,不发送 | 「以下邮箱格式有误:xxx@abc,请修正后重试」 |
| 邮箱已在团队中 | 跳过该邮箱,继续处理其余 | 「[email protected] 已是团队成员」 |
| 超出团队名额 | 全部取消,不发送任何邮件 | 「团队名额不足(剩余 0/5),请升级计划或移除成员」 |
| 重复邀请 | 跳过该邮箱,继续处理其余 | 「[email protected] 已收到邀请,无需重复发送」 |
| 邮件发送失败 | 记录失败,展示重试入口 | 「邀请邮件发送失败,请在邀请管理中重试」 |
| 团队已被删除 | 终止操作 | 「团队不存在」 |
 
**验收标准:**
- [ ] 批量输入 10 个有效邮箱,全部收到邀请邮件
- [ ] 包含无效邮箱时,有效邮箱正常发送,无效邮箱标红提示
- [ ] 超出名额时不发送任何邮件
- [ ] 邀请链接 72 小时后失效
- [ ] 被移除成员 30 天内无法通过邀请链接加入

写功能需求的流程

下面这张图展示了从拿到一个功能想法到产出完整功能需求文档的全过程:

流程图画布 · 115%
Mermaid 流程图加载中...

这个流程的核心思路是:先写正常路径,再补异常路径;先写业务规则,再定验收标准。很多人习惯从头写到尾,结果异常处理总是草草收场。把异常排查作为独立步骤,能确保不遗漏关键场景。

功能需求检查清单

在提交需求文档前,逐项检查以下内容:

  • 每条需求有唯一编号(如 FR-XXX-NNN)
  • 每条需求只描述一个功能行为,没有「并且」「同时」连接多个动作
  • 使用了 EARS 句式或等价的明确表述(触发条件 + 系统行为 + 预期结果)
  • 输入、处理、输出三层结构完整
  • 业务规则与功能需求分开列出,每条规则可验证
  • 异常场景覆盖了输入异常、状态异常、权限异常、网络异常、并发异常
  • 每个异常场景都写明了系统行为和用户提示文案
  • 优先级已标注(MoSCoW 或 P0-P3),且有排序依据
  • 依赖关系已注明(哪些功能必须先完成)
  • 验收标准具体、可测试,不包含模糊表述
  • 没有使用「最好」「尽量」「建议」等模糊词
  • 所有业务术语已在文档开头的术语表中定义
  • 涉及 UI 的需求附有原型图或线框图引用
  • 涉及数据的需求注明了数据格式、长度限制和校验规则

小结

  1. 格式决定清晰度——使用统一的需求模板,每条需求包含编号、描述、前置条件、触发条件、预期输出和验收标准。
  2. 逻辑分三层写——输入、处理、输出。不管功能多复杂,拆成这三层都能理清楚。
  3. 业务规则单独列——约束规则、计算规则、权限规则从功能描述中分离,每条可独立验证。
  4. 异常处理要具体——不是「给出错误提示」,而是写清楚什么异常、什么行为、什么文案。
  5. 优先级要量化——MoSCoW 或价值-成本矩阵,让团队和 AI 都知道先做什么。
  6. 检查清单是最后防线——提交前逐项核对,避免遗漏关键信息。

功能需求写得越精确,AI 生成的代码就越准确。这不是「多花时间写文档」,而是「用前置投入减少后期返工」。在 AI 辅助开发时代,写好功能需求已经从一个「PM 的专业技能」变成了「每个做 AI 产品的人都必须掌握的基本功」。

参考资料

  1. Jama Software — Functional Requirements Examples and Templates
  2. LogRocket Blog — An Overview of Functional Requirements
  3. Karl Wiegers — Identifying and Documenting Business Rules
  4. Atlassian — 如何创建产品需求文档(PRD)
  5. IEEE — Software Requirements Specification Template
  6. GitHub — SRS Markdown Template (IEEE 830)
  7. Ohio State — 10 Best Practices in Writing Requirements (PDF)
  8. IBM — What Are Business Rules?