如何编写和编辑 FlowZap 代码(无需技术技能!)
FlowZap 代码是可视化背后的引擎——一种精简的文本式接口,用来弥合便签式想法与专业制图之间的鸿沟。不同于复杂的编程语言,它采用自然直观的语法,让你像写待办清单一样轻松地描述流程、泳道与连接。作为单一事实来源,它同时驱动工作流与序列两种视图,让你无需重画任何元素即可瞬间切换视角。只需在编辑器中定义逻辑,点击"更新",FlowZap 就会在毫秒内把原始文本转化为精致、可上台演示的体系结构。
无论您是人类开发者还是 AI 编码助手,本指南都将帮助您生成有效的 FlowZap 代码,可保存为 `.fz` 文件并由 FlowZap.xyz 渲染。

核心输出规则
- 始终仅输出原始 FlowZap 代码,不带 Markdown 围栏、不带解释、不带任何周围文本。
- 不要添加"这是您的代码"之类的注释或 ``` 围栏;直接返回代码主体。
- 仅使用 UTF-8 纯文本;不使用表情符号,不使用不可打印字符。
FlowZap 图表的高层结构
- FlowZap 图表是由泳道、节点、边和可选循环片段组成的纯文本描述。
- 每个泳道将一个参与者或系统的相关步骤分组(如
User、Application、Server)。 - 节点定义步骤或决策;边定义节点之间的方向流。
- 循环描述重复行为(如重试),可以涉及跨泳道的节点。
全局约束(非常重要)
- 节点 ID 必须遵循
n1、n2、n3、… 的模式,并且在单个图表的所有泳道中必须全局唯一。 - 节点编号必须连续且无间隔(例如
n1、n2、n3,而不是n1、n3、n5)。始终使用从 1 开始的连续整数。 - 节点只允许四种形状:
circle、rectangle、diamond、taskbox。 - 节点属性使用
键:"值"带冒号,而边标签使用label="值"带等号在方括号内。 - 不要生成任何 Mermaid、PlantUML 或其他图表语法,如
graph TD、sequenceDiagram、participant或-->。 - 不要发明新的属性键;仅使用
label、owner、description、system和此处描述的类似英文键。
泳道(参与者/泳道)
每个泳道以泳道标识符开始,后跟左大括号和单个显示标签注释。
User { # User
...
}泳道 ID 是简单的标识符,如 User、Application、Server、flow、process、ops。每个泳道只允许一个注释,紧跟在左大括号后,使用 # 显示标签。不要在代码的其他地方放置注释。
Do:
User { # Userflow { # Flow
Don't:
// User或左大括号外的注释- 同一泳道块中有多个
#注释
节点(步骤、决策、任务)
每个节点在单独一行定义,格式为:nX: shape label:"文本" 加可选属性。
n1: circle label:"开始"
n2: rectangle label:"输入用户名和密码"
n3: diamond label:"格式有效?"
n4: taskbox owner:"Alice" description:"部署" system:"CI"允许的形状:circle(开始/结束)、rectangle(流程/动作)、diamond(决策)、taskbox(带 owner/system 的分配任务)。在节点 ID 和形状之间使用冒号(:),所有节点属性也使用冒号(如 label:"...")。节点标签必须用双引号括起来。保持节点标签简洁但具有描述性,通常少于 50 个字符。
Do:
n1: circle label:"开始"n3: diamond label:"是否有效?"n1: taskbox owner:"Alice" description:"部署" system:"CI"
Don't:
n1: circle label="开始"(错误的分隔符)n3 diamond "是否有效?"(缺少冒号)- 使用未知属性如
priority:"high"
边(节点之间的连接)
边始终将一个节点的 .handle(direction) 连接到另一个节点的 .handle(direction)。
n1.handle(right) -> n2.handle(left)
n2.handle(bottom) -> Application.n3.handle(top) [label="发送"]边的基本格式:sourceNode.handle(direction) -> targetNode.handle(direction) [label="文本"]。方向必须是:left、right、top、bottom 之一。对于跨泳道边,在目标前加上泳道名称,如 Application.n6.handle(top)。边标签使用等号加方括号,如 [label="是"],绝不使用冒号:[label:"是"]。边标签是可选的。
Do:
n1.handle(right) -> n2.handle(left) [label="前进"]n3.handle(bottom) -> laneB.n5.handle(top)n2.handle(bottom) -> Application.n6.handle(top) [label="发送"]
Don't:
n1.handle(right) -> n2.handle(left) [label:"前进"](错误的等号)n3.handle(bottom) -> n5(跨泳道边缺少泳道)n2 -> n6 [label="发送"](没有句柄)
跨泳道连接
从一个泳道的节点连接到另一个泳道的节点时,在目标节点前加上泳道 ID。
n3.handle(bottom) -> Application.n6.handle(top) [label="发送凭据"]
n8.handle(top) -> User.n2.handle(bottom) [label="否 - 错误"]将边定义保留在源泳道的大括号内。永远不要省略跨泳道目标的泳道前缀;始终写 泳道Id.nX。
序列图最佳实践
FlowZap 代码同时渲染为工作流视图和序列视图。序列视图按边定义顺序从上到下绘制消息。在编写多泳道代码时,请遵循以下规则以获得清晰、合乎逻辑的序列图。
- 请求-响应配对 — 每个跨泳道请求边都必须有对应的返回边。如果泳道 A 向泳道 B 发送消息,泳道 B 最终必须发送响应回来。缺少响应会创建不完整、误导性的图表。
- 边的时间顺序 — 按事件发生的时间顺序定义边。序列图根据边的定义顺序(而非节点 ID)从上到下渲染消息。乱序的边会产生令人困惑的箭头序列。
- 无孤立节点 — 每个节点必须参与至少一条边(作为源或目标)。没有任何边的节点在序列图中显示为断开的、无意义的步骤。
- 分离异步流 — 如果图表包含独立的流(例如主请求路径和后台监控路径),请先定义所有主流程的边,然后定义异步/后台的边。永远不要交错不相关的流。
正确做法:请求与匹配的响应
Client { # 客户端
n1: rectangle label:"发送请求"
n2: rectangle label:"接收响应"
n1.handle(bottom) -> Server.n3.handle(top) [label="HTTP GET"]
}
Server { # 服务器
n3: rectangle label:"处理请求"
n4: rectangle label:"返回数据"
n3.handle(right) -> n4.handle(left)
n4.handle(top) -> Client.n2.handle(bottom) [label="200 OK"]
}错误做法:缺少响应,孤立节点
Client { # 客户端
n1: rectangle label:"发送请求"
n2: rectangle label:"接收响应"
n1.handle(bottom) -> Server.n3.handle(top) [label="HTTP GET"]
}
Server { # 服务器
n3: rectangle label:"处理请求"
n4: rectangle label:"返回数据"
n3.handle(right) -> n4.handle(left)
}问题:n2 是孤立的(没有边),并且没有从服务器到客户端的返回边。序列图显示请求发出但从未返回。
循环(LOOP 片段)
使用 loop 关键字描述重复行为,如重试。
loop [重试直到格式有效] n2 n3 n7 n8
loop [最多重试 3 次] n2 n3 n4基本格式:loop [条件] n1 n2 n3 ...,其中条件是纯文本,后面的标记是节点 ID。条件应简短且具有描述性。按执行顺序列出循环中涉及的节点;它们可以在一个或多个泳道中。不要嵌套循环;保持它们扁平并在相关节点之后定义。
最小完整模板
从模糊提示开始时使用这些骨架;根据请求的流程调整标签和边。
Single-lane minimal flow
process { # 流程
n1: circle label:"开始"
n2: rectangle label:"步骤"
n3: circle label:"结束"
n1.handle(right) -> n2.handle(left)
n2.handle(right) -> n3.handle(left)
}Two-lane user–app interaction
user { # 用户
n1: circle label:"开始"
n2: rectangle label:"提交"
n1.handle(right) -> n2.handle(left)
n2.handle(bottom) -> app.n3.handle(top) [label="发送"]
}
app { # 应用
n3: rectangle label:"处理"
n4: circle label:"完成"
n3.handle(right) -> n4.handle(left)
}Decision branch
flow { # 流程
n1: rectangle label:"检查"
n2: diamond label:"OK?"
n3: rectangle label:"修复"
n4: rectangle label:"继续"
n1.handle(right) -> n2.handle(left)
n2.handle(bottom) -> n3.handle(top) [label="否"]
n2.handle(right) -> n4.handle(left) [label="是"]
}Simple loop
flow { # 流程
n1: rectangle label:"验证"
n2: diamond label:"有效?"
n1.handle(right) -> n2.handle(left)
loop [重试直到有效] n1 n2
}Taskbox example
ops { # 运维
n1: taskbox owner:"Alice" description:"部署" system:"CI"
}完整示例:多泳道认证流程
将此模式用作典型"认证"或"登录"流程的参考。
User { # 用户
n1: circle label:"开始"
n2: rectangle label:"输入用户名和密码"
n3: rectangle label:"提交表单"
n4: rectangle label:"收到确认"
n5: circle label:"访问已授权"
n1.handle(right) -> n2.handle(left)
n2.handle(right) -> n3.handle(left)
n3.handle(bottom) -> Application.n6.handle(top) [label="发送凭据"]
n4.handle(right) -> n5.handle(left)
loop [重试直到格式有效] n2 n3 n7 n8
}
Application { # 应用
n6: rectangle label:"接收请求"
n7: rectangle label:"验证格式"
n8: diamond label:"格式有效?"
n9: rectangle label:"转发到服务器"
n14: rectangle label:"转发确认给客户端"
n6.handle(right) -> n7.handle(left)
n7.handle(right) -> n8.handle(left)
n8.handle(right) -> n9.handle(left) [label="是"]
n9.handle(bottom) -> Server.n10.handle(top) [label="认证"]
n8.handle(top) -> User.n2.handle(bottom) [label="否 - 错误"]
n14.handle(top) -> User.n4.handle(bottom) [label="成功"]
}
Server { # 服务器
n10: rectangle label:"检查数据库"
n11: diamond label:"凭据有效?"
n12: rectangle label:"生成会话令牌"
n13: rectangle label:"返回错误"
n10.handle(right) -> n11.handle(left)
n11.handle(right) -> n12.handle(left) [label="是"]
n11.handle(bottom) -> n13.handle(bottom) [label="否"]
n12.handle(top) -> Application.n14.handle(bottom) [label="令牌"]
n13.handle(top) -> Application.n6.handle(bottom) [label="错误 401"]
}常见错误避免
- 不要将泳道注释放在单独的行上。
# 显示标签必须与左大括号在同一行:泳道名 { # 标签,而不是泳道名 {后跟下一行的# 标签。 - 不要在节点上使用
label="文本";节点标签必须是label:"文本"。 - 不要在边的方括号内使用
label:"文本";边必须是[label="文本"]。 - 不要在跨泳道边上省略泳道前缀(如跨泳道时
n3 -> n5是无效的)。 - 不要引入其他图表语法(Mermaid、UML、JSON、YAML、XML)。
- 不要在图表中重复使用节点 ID(
n1、n2、…);每个 ID 必须全局唯一。 - 不要跳过节点编号。节点 ID 必须连续且无间隔(例如
n1、n2、n3,而不是n1、n3、n5)。如果有 14 个节点,必须从n1到n14连续编号。 - 不要在每个泳道左大括号后的
# 显示标签之外添加额外注释。 - 不要在泳道的大括号之外使用循环。循环只能出现在泳道的大括号(
{...})内部。
LLM 提示技巧(面向人类开发者)
- 始终包含类似这样的指令:
参考 docs/flowzap-code-guidelines.md 并仅输出此流程的有效 FlowZap 代码。 - 提供流程的简短、清晰描述:参与者、关键步骤、决策和循环(如带重试的登录、带支付网关的结账)。
- 如果 LLM 输出包含 Markdown、解释或无效语法,重新提示:
删除所有 Markdown 和解释;仅按照指南输出 FlowZap 代码。 - 对于更新,粘贴现有的 FlowZap 代码并说:
就地修改此代码:添加 [新步骤/分支/循环],同时保持 ID 唯一和语法有效。
AI 代理的最终提醒
您的任务是生成仅遵循上述所有语法和结构规则的有效 FlowZap 代码文本,以便它可以保存为 .fz 文件并由 FlowZap 渲染,无需手动修复。