物联网中的 Node-RED(9·中):AI 协作与多工程拆分方案 · 第一阶段 Flow 拆分与 AI 协作
本篇是《AI + Node-RED 协作开发与多工程拆分统一管理方案》拆分后的第 2 篇(共 5 篇)。
- (上)背景、核心概念与总体架构
- (中)第一阶段:Flow 拆分与 AI 协作 ← 本篇
- (下壹)第二阶段:多工程拆分
- (下贰)第二阶段:统一面板升级、风险清单与实施计划
- (终)协作边界、与传统方式对比、FAQ 与检查清单
原文标题:AI + Node-RED 协作开发与多工程拆分统一管理方案
四、第一阶段:Flow 拆分与 AI 协作
本阶段产物(
split_flows.js/sync_flows.js/_reverse_sync.js/sync-panel/)是第二阶段的基础,第二阶段只是把它们改造为「按工程选端口 + 目录」,而非重写。
4.1 拆分工具 split_flows.js(前向)
作用:读取 flows.json,按 Tab / Subflow / Config 拆分为多个 YAML 文件。
工作原理:
- 读取
flows.json; - 建立 Tab、Subflow 索引(
type === "tab"/type === "subflow"); - 根据节点
z属性把每个节点分配到对应 Tab / Subflow 组; - 无
z属性的节点归为配置节点组; - 每组序列化为一个 YAML,写入
src/。
输出目录结构:
src/
├── tabs/ ← 每个 Tab 拆成一个 YAML
│ ├── <Tab 1>.yaml
│ ├── <Tab 2>.yaml
│ └── ... ← 共 N 个 Tab,N 个文件
└── config-nodes/ ← 全局配置节点(按需,见 5.5 说明)
├── <mqtt broker>.yaml
├── <数据库连接>.yaml
└── ...
文件数 = Tab 数 + 配置节点类型数;节点总数 =
flows.json内全部节点。
用法:
node tmp/split_flows.js # 全量拆分
node tmp/split_flows.js --dry # 仅预览
4.2 合并工具 sync_flows.js(反向 / 热部署)
作用:读取 src/ 下所有 YAML,组装成扁平数组并全量(或按工程)部署到 Node-RED。
工作流程:
1. 扫描 src/tabs/、src/subflows/、src/config-nodes/ 下所有 .yaml/.yml
↓
2. 用 js-yaml 解析每个文件,收集所有节点对象
↓
3. 校验每个节点必须包含 id 和 type 字段
↓
4. 组装为扁平数组 (Node-RED Admin API v1 格式)
↓
5. HTTP POST 到 http://127.0.0.1:<端口>/flows
⚠ 关键:POST body 必须是扁平数组,不能包 {flows: [...]}
因为 v1 API 会自动包装 → 包两层会导致 double-nesting 报错
↓
6. Node-RED 热重载,新逻辑立即生效
用法:
node tmp/sync_flows.js --dry # 预览模式:只读取 YAML,不部署
node tmp/sync_flows.js # 正式部署
安全机制:
| 检查项 | 说明 |
|---|---|
--dry 模式 |
先预览再部署 |
| 节点校验 | 确保每个节点都有 id 和 type |
| YAML 解析错误处理 | 跳过解析失败的文件并报错 |
| 连接超时 | 建议 10 秒超时,Node-RED 未运行时报错 |
| Git 保护 | 不修改 flows.json,只通过 API 注入 |
依赖:
{ "js-yaml": "^4.1.0" }
4.3 反向同步工具 _reverse_sync.js
作用:与上面方向相反——从 Node-RED 运行时把节点反向导出回 YAML(典型场景:你在 UI 里手动改完并 Deploy,把改动回写 src/tabs/*.yaml,交 Git 跟踪、交 AI 后续读取)。
工作原理:
- 优先
GET http://127.0.0.1:<端口>/flows拉取实时节点;API 失败时回退读取本地flows.json; - 过滤出
type === "tab"的节点作为候选; - 每个 tab 收集「tab 自身 + 所有
z指向它的子节点」,序列化为一个 YAML; - 文件名做安全化(替换非法字符、截断长度);
- 序列化格式与
split_flows.js/sync_flows.js完全一致,保证可互转。
用法:
node tmp/_reverse_sync.js # 全量反向同步(所有 tab)
node tmp/_reverse_sync.js <关键词> # 按关键词反向同步(仅名称含该词的 tab)
⚠ 覆盖警告:反向同步会覆盖
src/tabs/*.yaml。若本地有未部署的手改内容,会被运行时版本冲掉,操作前需先确认。
4.4 Web 同步面板 sync-panel/
背景:热部署 / 反向同步这俩动作重复且固定,但命令行方式有两个痛点——① 每次要给 AI 下命令、往返成本高;② 命令行传中文参数有编码问题。解决:做成独立小服务 + 网页,点按钮即执行。
文件结构:
sync-panel/
├── server.js # Node 服务(默认端口 <面板端口>,可用环境变量 PORT 覆盖)
├── index.html # 管理页面
└── start.bat # 双击启动(Windows 示例)
页面功能(第一阶段·单实例):
- 顶部两个总按钮:
⬆ 全部热部署、⬇ 全部反向同步; - 每个 tab 一张卡片:显示「NR 节点数 / 本地文件及节点数」,各带
⬆ 热部署、⬇ 反向同步按钮; - Node-RED 连接状态指示灯、搜索框(过滤 tab)、操作日志区。
服务端 API(第一阶段):
| 接口 | 方法 | 作用 |
|---|---|---|
/api/tabs |
GET | 列出全部 tab(以 NR 为准,标注本地文件与节点数) |
/api/health |
GET | Node-RED 连接状态 |
/api/deploy-all |
POST | 全部热部署 |
/api/deploy-one |
POST | 单个 tab 热部署 |
/api/reverse-all |
POST | 全部反向同步 |
/api/reverse-one |
POST | 单个 tab 反向同步 |
关键实现点:
- 合并部署
mergeFlows:本地 YAML 节点 + 运行时「不在 YAML 里」的节点(保留临时节点)。单个 tab 热部署时只替换该 tab 相关节点,其余 tab 和临时节点不动——比全量部署更安全、更快。 - 反向同步写回:复用与
_reverse_sync.js相同的序列化,保证格式一致。 - 本地无 YAML 的 tab:热部署按钮置灰(提示只能反向同步)。
4.5 AI 协作标准工作流
步骤1: 用户告诉 AI 要改什么
例: "把某解析节点的温度字段从 4 位小数改成 2 位"
步骤2: AI 读取 src/tabs/<对应 Tab>.yaml
→ 只读取该 Tab 的小文件,而非整个 flows.json
步骤3: AI 修改 YAML 中的对应节点
→ 精确定位到目标节点,修改 func 字段
步骤4: 用户 review 变更
→ git diff 清晰看到改了什么
步骤5: 部署到 Node-RED
→ 面板点击「⬆ 热部署」,或命令行 node tmp/sync_flows.js
步骤6: 验证效果
→ 浏览器打开 http://127.0.0.1:<端口>/
→ 查看 Debug 面板或注入测试数据
步骤7: 提交
→ git commit -m "<变更描述>"
4.6 注意事项
- 修改后必须 sync:YAML 的修改不会自动生效,必须运行
sync_flows.js(或面板点「热部署」)。 - 不要手动改
flows.json:拆分后flows.json仍为 Node-RED 主存储,但 AI 不应直接修改它。 - UI 内修改需反向同步回 YAML:在编辑器里改了并 Deploy,改动只存在于运行时,需运行
_reverse_sync.js(或面板「反向同步」)回写,否则下次热部署会被本地 YAML 覆盖。 - 建议闭环:AI 改 YAML → 热部署 → 验证 → 如需在 UI 微调 → Deploy → 反向同步回 YAML → 再交给 AI 下一轮修改。

浙公网安备 33010602011771号