物联网中的 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 文件。

工作原理:

  1. 读取 flows.json;
  2. 建立 Tab、Subflow 索引(type === "tab" / type === "subflow");
  3. 根据节点 z 属性把每个节点分配到对应 Tab / Subflow 组;
  4. 无 z 属性的节点归为配置节点组;
  5. 每组序列化为一个 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 后续读取)。

工作原理:

  1. 优先 GET http://127.0.0.1:<端口>/flows 拉取实时节点;API 失败时回退读取本地 flows.json;
  2. 过滤出 type === "tab" 的节点作为候选;
  3. 每个 tab 收集「tab 自身 + 所有 z 指向它的子节点」,序列化为一个 YAML;
  4. 文件名做安全化(替换非法字符、截断长度);
  5. 序列化格式与 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 注意事项

  1. 修改后必须 sync:YAML 的修改不会自动生效,必须运行 sync_flows.js(或面板点「热部署」)。
  2. 不要手动改 flows.json:拆分后 flows.json 仍为 Node-RED 主存储,但 AI 不应直接修改它。
  3. UI 内修改需反向同步回 YAML:在编辑器里改了并 Deploy,改动只存在于运行时,需运行 _reverse_sync.js(或面板「反向同步」)回写,否则下次热部署会被本地 YAML 覆盖。
  4. 建议闭环:AI 改 YAML → 热部署 → 验证 → 如需在 UI 微调 → Deploy → 反向同步回 YAML → 再交给 AI 下一轮修改。
posted @ 2026-09-29 09:15  星辰手  阅读(3)  评论(0)    收藏  举报