Flow Canvas — 项目流程链路分析
把一个代码项目分析成叙事链:入口在哪、经过哪些阶段、关键决策是什么、产出什么——每一步是画布上的一个文字节点,边是阶段间的推导关系。产出是一个 flow.json,在 Flow Canvas 无限画布中浏览。
目标与边界
做:
- 阅读真实源码,产出项目工作流程的链路文件
- 用自然语言节点讲清"项目如何工作"
- 写入 Flow Canvas 的
data/目录并校验
不做:
- ❌ 代码符号图谱(类/函数级别的关系图不是目标,符号只能作为正文证据出现)
- ❌ 编造未读过的内容——每个节点必须有真实细节支撑
- ❌ 修改 flow-canvas 自身的画布代码
第零步:确认环境
- 找到 Flow Canvas 项目根目录(含
data/、docs/flow-format.md的目录,下称$FC) - 若
data/不存在则创建 - 完整格式规范见
$FC/docs/flow-format.md(本文件内含精简版,通常够用)
flow.json 精简格式
{
"project": "项目名",
"description": "一句话说明这份链路是什么",
"generatedAt": "2026-01-01T00:00:00+08:00", // ISO 8601 必填
"generator": "你的标识,如 claude-code / deepseek-agent",
"nodes": [
{
"id": "stage-entry", // kebab-case,唯一,交付后永不更改
"title": "一句话概括这个阶段",
"body": "markdown 正文,流程描述主体,100-300 字为宜",
"kind": "stage" // stage|module|decision|artifact|detail
}
],
"edges": [
{ "source": "stage-entry", "target": "stage-next", "label": "调度" }
]
}
kind 语义:stage 流程阶段(默认)· module 模块介绍 · decision 关键决策/选型 · artifact 产物 · detail 补充细节。
分析流程(五步)
1. 摸底(快,读全貌)
- README / package.json(或 Cargo.toml、go.mod 等依赖声明)→ 这是什么项目、给谁用、技术栈
- 目录树 2-3 层 → 模块划分
- 入口文件(main、index、启动脚本、CI 工作流)→ 程序从哪开始
2. 找主线(核心)
从入口追主流程:初始化 → 核心处理 → 输出/交付。沿途记录:
- 阶段:流程走到哪一步了
- 决策点:为什么这么设计(选型、架构取舍)——这类节点最有信息量
- 产物:阶段产出了什么(文件、服务、数据)
- 细节:值得单独说的机制(缓存、增量、分发方式)
3. 验证(红线所在)
对每个准备写入的节点:必须真的读过对应源码。body 里至少有一个具体证据——文件路径、真实命令、机制描述、数字("487 个文件""1072 个节点")。没把握的内容写明"推测"或删除。
4. 组织链路
- 节点数 8-15:少 = 讲不清,多 = 记不住。宁可 12 个有料的,不要 30 个凑数的
- 拓扑排序:起点 = 问题/入口,终点 = 产物/去向;
stage-*前缀标识主线 - 每条边的 label 回答"为什么连":
调度/产物传递/触发/引出技术选型/变更触发重跑 - 环是允许的(如"增量检测 → 触发重跑"回到入口),画布用与正向边平行的虚线渲染回边——这是特性不是错误
- 语言:中文正文(或遵用户指定);正文默认用文字、少用内部标识符,写法见「正文写作」
5. 写入与校验
写入 $FC/data/<name>.json,文件名用英文 kebab-case(如 my-project.json——URL 参数会过滤中文字符)。
然后强制校验:
node "$FC/skills/flow-canvas/scripts/validate.mjs" "$FC/data/<name>.json"
必须输出 ✓ valid flow file 才算完成,有 ✗ 必须修复后重跑。
正文写作:说清楚(第一位目标)
正文唯一的硬要求:把项目链路逻辑讲清楚。读者是「不了解这个项目的人」,他该看懂的是「这一步在做什么、为什么」,而不是「代码里叫什么名字」。
默认规则:用文字,少用内部标识符。 机制一律用能站住的话讲,别贴方法名 / 字段名 / 类名 / 配置键。
| 这样写(文字) | 别这样写(内部字段) |
|---|---|
| 把进程优先级提到「高」,抢 CPU 时不被拖慢 | 用 SetPriorityClass 把进程提到 HIGH |
| 红方是否机器、黑方是否机器、纯分析、联棋四种开关 | robotRed / robotBlack / robotAnalysis / linkMode |
| 识别后与内部快照逐格比对,推断出这一步变了什么 | 用 compareBoard 做差量推断 |
| 输出到一个带时间戳的日志文件,随时可查 | 写到 logs\xiangqire_*.log |
可以保留内部标识符——但只限「不写就说不清」或「读者真会去找」的地方:
- 外部可认得的名字:引擎名(皮卡鱼)、协议名(UCI/UCCI)、文件格式(.obk / .pfBook)、外部服务(chessdb.cn)
- 通用的知名工具:Maven、JDK、SQLite
- 读者要定位的产物:配置文件名、日志路径
- 数字证据:「12 节点 / 12 边」「一步 5~8.7 秒降到约半秒」
判断方法(写完自查一遍):对正文里每个标识符问两句——
- 读者会不会被它卡住?会卡住、且不影响理解链路 → 换成文字。
- 没有它说不清这个机制吗?说不清 → 保留。
清晰优先于「显得专业」。宁可正文没那么「技术味」,只要链路逻辑讲得清楚;不能一堆标识符、链路反而看不懂。
交付
- 校验通过后,启动/复用画布服务:
cd $FC && pnpm dev(端口 5273) - 给用户 URL:
http://127.0.0.1:5273/?file=<name>.json - 告知可点顶栏「导出 Markdown」拿走整链文本
质量红线(违反任何一条 = 重做)
- 真实:每个 body 有源码级证据,零编造
- 可验证:
validate.mjs通过,0 悬挂边、0 重复 id - 叙事性:节点主体是自然语言段落,符号只作证据
- 清晰:先用文字把链路讲清楚;内部标识符只在不写就说不清处保留(见「正文写作」)
- id 稳定:文件交付后不改 id(它是未来"人工标记→AI 修订"闭环的锚点)
- 诚实:不确定就标注推测,不混淆事实与猜测
常见坑
- JSON 带 BOM 或 UTF-16 编码 → 画布加载失败;写 UTF-8 无 BOM
- 文件名含中文/空格 → URL
?file=参数取不到;用英文 kebab-case - 节点正文堆砌形容词没有证据 → 用户一眼识破,重写
- 忘记
generatedAt/generator→ 元数据不完整 - 边只写"下一步"这种废话 label → label 要说明关系性质