如何用 Mermaid 画需求图
需求图(基于 SysML 需求图)用于展示需求本身、需求之间的关系,以及哪些系统元素满足或验证了这些需求,适合监管类或安全相关项目里的需求可追溯性管理。Mermaid 用 requirementDiagram 声明需求图。
为什么用需求图?
- 可视化需求结构 — 一眼看出需求之间的层级和依赖关系
- 可追溯性 — 把每条需求关联到满足它的元素、以及确认它的验证方法
- 追踪派生/细化需求 — 看清一条高层需求如何拆解成更具体的子需求
适用场景
✅ 适合:需要正式需求可追溯性(SysML 风格)的监管类或安全相关项目;记录哪些组件满足哪些需求。
❌ 不适合:不需要可追溯性的轻量级产品需求——一个普通列表或表格更简单、更容易维护。
声明图表
requirementDiagram
requirement user_auth {
id: 1
text: "系统应对用户进行身份验证"
risk: high
verifymethod: test
}
requirement 块只需要这四个字段:id、text、risk(high/medium/low)、verifymethod(analysis/inspection/test/demonstration)。不存在 type、status、priority 字段——这些听起来很合理,但在真实语法里并不存在。title 在这个图表类型里也不是有效的顶层语句——写了会直接导致渲染失败(已实测确认),这点和 architecture-beta、block-beta 不同,那两者里无效的 title只是被静默忽略。
重要:CJK(中文)文本放进 text: 字段时必须加引号,比如 text: "系统应对用户进行身份验证"。不加引号会直接渲染失败(已实测确认)——这点和英文文本不同,英文文本不加引号也没问题。
六种需求类型
除了通用的 requirement,Mermaid 还支持 5 种更具体的类型——字段结构相同,语义标签不同:
requirementDiagram
interfaceRequirement api_interface {
id: 3
text: "系统应提供 REST API"
risk: medium
verifymethod: inspection
}
physicalRequirement server_rack {
id: 4
text: "系统应运行在冗余服务器上"
risk: low
verifymethod: analysis
}
designConstraint tech_stack {
id: 5
text: "系统应使用 TypeScript"
risk: low
verifymethod: analysis
}
| 类型 | 用于 |
|---|---|
requirement |
通用兜底 |
functionalRequirement |
系统必须做什么 |
performanceRequirement |
速度/吞吐量/延迟指标 |
interfaceRequirement |
API、协议、集成点 |
physicalRequirement |
硬件、部署、物理约束 |
designConstraint |
强制指定的技术、标准或设计决策 |
元素与关系
requirementDiagram
requirement user_auth {
id: 1
text: "系统应对用户进行身份验证"
risk: high
verifymethod: test
}
element AuthService {
type: simulation
}
AuthService - satisfies -> user_auth
element id { type: ... } 定义一个参与需求关系的真实事物(服务、文档、测试用例)。关系的语法统一是 source - relationshipType -> target:
| 关系 | 含义 |
|---|---|
satisfies |
元素满足需求 |
verifies |
元素验证需求(比如测试用例) |
traces |
较弱的可追溯性关联,比 satisfies 更松散 |
contains |
需求包含子需求(层级关系) |
derives |
需求由另一条需求派生而来 |
refines |
需求细化(补充细节)另一条需求 |
copies |
需求是另一条需求的副本 |
需求之间也可以直接建立关系,不一定要通过元素:
requirementDiagram
requirement parent_req {
id: 1
text: "父需求"
risk: low
verifymethod: test
}
requirement child_req {
id: 1.1
text: "子需求"
risk: low
verifymethod: test
}
parent_req - contains -> child_req
完整示例:登录需求可追溯性
requirementDiagram
requirement user_auth {
id: 1
text: "系统应对用户进行身份验证"
risk: high
verifymethod: test
}
functionalRequirement login_flow {
id: 1.1
text: "系统应提供登录表单"
risk: medium
verifymethod: inspection
}
performanceRequirement response_time {
id: 2
text: "登录应在 2 秒内响应"
risk: low
verifymethod: demonstration
}
element AuthService {
type: simulation
}
element LoginUI {
type: simulation
}
AuthService - satisfies -> user_auth
LoginUI - satisfies -> login_flow
user_auth - contains -> login_flow
AuthService - traces -> response_time
两个元素(AuthService、LoginUI)满足两条需求,一条需求包含一条子需求,还有一个元素追溯到一条性能需求——一张完整、小巧的可追溯性关系图。
常见错误
- 用了
type、status、priority字段——这些都不存在。唯一有效的字段是id、text、risk、verifymethod。 - 用了
title——在这个图表类型里会直接导致整个图渲染失败。 - 写成
requirement "显示名称" { ... }——requirement后面紧跟的是一个裸标识符(类似变量名),不是带引号的显示字符串。应该写成requirement my_req { text: "这里放人类可读的文字" }——可读文本要放进text字段。 - CJK 文本不加引号——不像英文文本,中文文本放进
text:字段必须加引号,否则渲染失败。 - 编造关系名,比如
requires、impacts——真实存在的只有satisfies、verifies、traces、contains、derives、refines、copies。
快速参考
| 语法 | 作用 |
|---|---|
requirementDiagram |
声明需求图 |
requirement id { ... } |
通用需求 |
functionalRequirement id { ... } |
系统必须做什么 |
performanceRequirement id { ... } |
速度/吞吐量/延迟指标 |
interfaceRequirement id { ... } |
API/协议/集成点 |
physicalRequirement id { ... } |
硬件/部署约束 |
designConstraint id { ... } |
强制指定的技术/标准/设计决策 |
id、text、risk、verifymethod |
需求块内仅有的 4 个有效字段 |
element id { type: ... } |
定义一个真实世界的元素 |
a - satisfies -> b |
a 满足需求 b |
a - verifies -> b |
a 验证需求 b |
a - contains -> b |
a 包含子需求 b |
下一步
如果想用更轻量的方式展示概念间的关系、不需要 SysML 那种正式程度,请查看流程图教程。
要试运行上面的代码,点击打开编辑器并粘贴代码。