SDD 2.0:用户故事的Prompt工程化重构
TL;DR
本文核心观点:
- 传统用户故事过时 — “作为X我想要Y”格式无法承载AI需要的上下文
- 三元组新结构 — 上下文-约束-验收标准成为最小完备单元
- Prompt即故事 — 精心设计的Prompt就是可执行的需求文档
- 需求工程升级 — 从文本描述到结构化意图表达的范式转移
📋 本文结构
- 用户故事的局限 — 为什么经典格式不再够用
- 三元组新范式 — 上下文-约束-验收标准
- Prompt即需求 — 从自然语言到结构化表达
- 实战模板 — 可直接使用的SDD 2.0模板
- 工具链演进 — 需求管理系统的AI-Native改造
- 结论 — 产品经理的新核心能力
用户故事的局限
💡 Key Insight
“作为用户,我想要登录功能”这种格式诞生于2001年,目的是促进对话。但在AI时代,我们需要的是可执行的需求,而不仅仅是谈话起点。
经典用户故事格式:
作为 [角色]
我想要 [功能]
以便 [价值]
这个格式在敏捷初期是革命性的——它强迫产品经理思考”为谁”和”为什么”,而不仅仅是”做什么”。
但它有三个致命缺陷:
| 缺陷 | 说明 | 后果 |
|---|---|---|
| 上下文缺失 | 不知道用户当前状态、环境、前置条件 | AI生成代码频繁假设错误 |
| 约束模糊 | 性能、安全、合规要求难以表达 | 生成的代码需要反复修改 |
| 验收游离 | AC与故事分离,容易不一致 | 实现与期望偏差大 |
真实案例:
一个团队让AI实现”作为顾客,我想要查看订单历史”。AI生成了一个简单的列表页面。
但实际需求包括:
- 分页(每页20条)
- 按时间倒序
- 支持按状态筛选
- 移动端适配
- 3秒内响应
- 只显示近2年数据
这些约束散落在邮件、会议记录、口头沟通中——AI读不到。
三元组新范式
💡 Key Insight
AI需要的最小完备信息单元是三元组:上下文(Context)+ 约束(Constraints)+ 验收标准(Acceptance Criteria)。缺少任何一项,生成都可能偏离目标。
结构对比
传统用户故事:
作为顾客,
我想要查看订单历史,
以便了解我的购买记录。
验收标准:
- 显示订单列表
- 支持分页
SDD 2.0 三元组:
context:
actor: 已登录的注册顾客
state: 在我的账户页面
goal: 查看历史订单以追踪物流或申请售后
constraints:
- 每页显示20条,按时间倒序
- 支持按状态筛选(待发货/运输中/已完成/已取消)
- 移动端优先响应式布局
- 页面加载时间 < 3秒(P95)
- 只显示近24个月数据
- 符合GDPR数据访问要求
acceptance_criteria:
- 无订单时显示友好空状态
- 点击订单进入详情页
- 下拉刷新加载更多
- 筛选后URL可分享
为什么三元组更优?
| 维度 | 传统格式 | SDD 2.0 |
|---|---|---|
| 完整性 | 需人工补充 | 自包含 |
| AI可消费性 | 低(需解析) | 高(结构化) |
| 可验证性 | 模糊 | 明确 |
| 可追溯性 | 弱 | 强 |
| 版本管理 | 文本diff难读 | 结构diff清晰 |
Prompt即需求
💡 Key Insight> 当Prompt可以被版本控制、被测试、被验证时,它就不再是”提示”,而是可执行的规格说明书。
Prompt作为需求的演进
阶段1: 临时提示(Ad-hoc Prompt)
"帮我写一个订单查询功能"
↓ 问题:每次都从零开始,无法复用
阶段2: 模板化Prompt(Template)
"作为[角色],我想要[功能],要求[约束]"
↓ 问题:仍然是文本,AI理解不稳定
阶段3: 结构化Prompt(Structured Spec)
YAML/JSON格式的三元组
↓ 优势:可解析、可验证、可继承
阶段4: 可执行规格(Executable Spec)
Prompt → AI生成 → 自动验证AC
↓ 优势:需求即测试,测试即文档
Prompt工程 = 需求工程
传统需求工程的产出:PRD文档
AI-Native需求工程的产出:可执行Prompt
# 这是一个可执行的规格
spec_version: "1.0"
title: 订单历史查询功能
context:
system: 电商APP
module: 用户中心
actor: 已认证顾客
input:
user_id: UUID
filters:
status: enum[all, pending, shipping, completed, cancelled]
date_range: optional[DateRange]
pagination:
page: integer >= 1
page_size: integer, default 20, max 50
output:
orders: array[OrderSummary]
total_count: integer
has_more: boolean
constraints:
performance: "P95 < 3s"
data_retention: "24 months"
compliance: ["GDPR", "PCI-DSS"]
acceptance_tests:
- name: 无订单时显示空状态
given: 用户从未下单
when: 访问订单历史
then: 显示"还没有订单"提示和购物引导
- name: 分页加载更多
given: 用户有50个订单
when: 滚动到列表底部
then: 自动加载第2页(订单21-40)
这个YAML可以直接:
- 被AI消费生成代码
- 被测试框架解析生成测试用例
- 被文档工具渲染为需求文档
- 被验证工具检查完整性
一份来源,多处使用。
实战模板
💡 Key Insight> 好的模板不是限制,而是思维的脚手架。它确保你不遗漏关键信息,同时保持表达的灵活性。
SDD 2.0 标准模板
## 需求规格
### 1. 上下文(Context)
**系统边界:**
- 所属系统:
- 相关模块:
- 触发场景:
**用户状态:**
- 前置条件:
- 当前位置:
- 目标意图:
**业务背景:**
- 为什么现在做:
- 不做会怎样:
- 成功指标:
### 2. 约束(Constraints)
**功能约束:**
- [ ] 必须支持...
- [ ] 必须限制...
**非功能约束:**
| 类型 | 要求 | 优先级 |
|------|------|--------|
| 性能 | | |
| 安全 | | |
| 合规 | | |
| 兼容性 | | |
**依赖约束:**
- 外部系统:
- 数据依赖:
- 发布顺序:
### 3. 验收标准(Acceptance Criteria)
**正常路径:**
```gherkin
Given [初始状态]
When [用户操作]
Then [预期结果]
And [附加验证]
异常路径: | 场景 | 输入 | 预期行为 | |——|——|———-| | 场景1 | | | | 场景2 | | |
边界条件:
- 空数据
- 最大值
- 并发访问
- 网络异常 ```
完整示例
## 需求规格:优惠券领取功能
### 1. 上下文
**系统边界:**
- 所属系统:营销系统
- 相关模块:用户中心、优惠券系统、消息通知
- 触发场景:用户在商品详情页看到"领券"按钮
**用户状态:**
- 前置条件:已登录、账户正常、未被风控
- 当前位置:商品详情页 / 购物车 / 个人中心
- 目标意图:获取可用优惠券以降低支付金额
**业务背景:**
- 为什么现在做:大促活动需要提升转化率
- 不做会怎样:用户流失到竞品平台
- 成功指标:领券率>30%,用券率>50%
### 2. 约束
**功能约束:**
- [x] 每人每券限领1张
- [x] 库存为0时按钮变灰显示"已领完"
- [x] 领取成功后推送APP通知
**非功能约束:**
| 类型 | 要求 | 优先级 |
|------|------|--------|
| 性能 | 领取接口P99 < 500ms | P0 |
| 安全 | 防刷券(同设备/IP限制) | P0 |
| 合规 | 记录领取日志用于审计 | P1 |
**依赖约束:**
- 外部系统:优惠券库存服务
- 数据依赖:用户实名认证状态
- 发布顺序:需先上线库存预热功能
### 3. 验收标准
**正常路径 - 领取成功:**
```gherkin
Given 用户已登录且优惠券有库存
When 用户点击"立即领取"
Then 优惠券添加到用户卡包
And 显示"领取成功"提示
And 按钮状态变为"已领取"
And 发送APP推送通知
异常路径: | 场景 | 输入 | 预期行为 | |——|——|———-| | 库存不足 | 剩余0张 | 按钮变灰,提示”已领完” | | 已领取过 | 用户已持有该券 | 提示”您已领取”,跳转卡包 | | 风控拦截 | 同IP领取超10次 | 提示”操作频繁”,要求验证码 | | 未登录 | 游客点击 | 弹出登录框,登录后继续 |
边界条件:
- 并发领取:1000人同时点击,不超卖
- 网络中断:领取中断网,支持重试
- 服务端错误:返回500时友好提示 ```
工具链演进
💡 Key Insight> 003e 需求管理工具的下一个形态不是更好的看板,而是结构化意图编辑器——让产品经理以三元组格式工作。
传统工具 vs AI-Native工具
| 功能 | JIRA/Confluence | AI-Native需求工具 |
|---|---|---|
| 需求格式 | 富文本 | 结构化三元组 |
| AI消费 | 需NLP解析 | 原生支持 |
| 版本对比 | 文本diff | 结构diff |
| 可验证性 | 人工检查 | 自动完整性检查 |
| 生成代码 | 不支持 | 一键生成 |
| 生成测试 | 不支持 | 自动生成AC测试 |
需求工具新形态
┌─────────────────────────────────────────────────┐
│ 意图编辑器(Intent Editor) │
├─────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ Context │ │ Constraints │ │ AC │ │
│ │ 面板 │ │ 面板 │ │ 面板 │ │
│ └─────────────┘ └─────────────┘ └──────────┘ │
├─────────────────────────────────────────────────┤
│ 辅助功能: │
│ [AI补全] [约束检查] [AC生成] [影响分析] │
├─────────────────────────────────────────────────┤
│ 输出选项: │
│ [生成代码] [生成测试] [生成文档] [导出Prompt] │
└─────────────────────────────────────────────────┘
开源实现思路
基于现有工具的改造路径:
- JIRA插件:自定义字段实现三元组
- Notion模板:结构化数据库
- GitHub Issues:YAML frontmatter
- 专用DSL:开发新的需求描述语言
结论
🎯 Takeaway
| 传统需求工程 | AI-Native需求工程 |
|---|---|
| 目标是文档 | 目标是可执行规格 |
| 格式自由文本 | 格式结构化三元组 |
| 验收标准手工写 | 验收标准自动生成 |
| 需求与实现分离 | 需求即Prompt即代码 |
| 产品经理写PRD | 产品经理设计意图架构 |
用户故事从”促进对话的工具”演变成了”驱动AI的指令”。
这个转变要求我们:
- 更结构化 — 告别自由文本,拥抱结构化表达
- 更精确 — 每个约束都要明确、可验证
- 更工程化 — 需求像代码一样被版本管理、被测试
SDD 2.0不是新方法论,而是旧方法论在AI时代的自然演化。
“需求的本质是消除不确定性。在AI时代,不确定性主要来自意图传达——结构化表达就是答案。”
📚 延伸阅读
经典案例
- Atlassian的JIRA AI插件:如何将传统用户故事转换为AI可消费的格式
- Stripe的API设计文档:工程化需求表达的典范
本系列相关
- TDD的死亡与重生 (第1篇)
- DDD meets LLM:领域模型与Embedding空间 (第3篇)
- BDD语义化升级 (第4篇)
学术理论
- 《User Stories Applied》(Mike Cohn): 用户故事经典教材,理解起源
- 《Specification by Example》(Gojko Adzic): 实例化需求的系统方法
- 《Domain-Driven Design》(Eric Evans): 领域建模与语言表达
AI-Native软件工程系列 #2 深度阅读时间:约 10 分钟
💬 评论
💡 使用 GitHub 账号登录 即可参与讨论