语义架构重构计划 (2026-06-02)
背景:在讨论"设备语义管理"与"空间语义管理"的映射配置问题时,发现当前设备级映射存在大量重复配置、LLM 上下文过重等问题。基于自控平台"产品品类→产品→设备实例"三层继承结构,在 AI 侧建立对应语义映射体系。
场景举例:某实验室装了同一型号 4 盏灯,归属同一个产品(灯),对应 4 个设备实例(灯-01~灯-04)。按设备级映射,每盏灯都要独立配置
light_power、light_brightness等点位——4 盏灯 × 2 个通用点位 = 8 行完全相同的配置。推广到 50 盏灯、20 台空调、30 个窗帘的空间场景,重复配置量线性膨胀,LLM 上下文轻松破万 token。更棘手的是设备自建信号(区别于产品继承的标准点位):灯-04 额外挂了一个"闪烁模式"信号。这类信号不属于产品级定义的通用点位,设备级模式下每个实例各自维护,无法纳入产品复用体系。而自控平台的同产品映射一致约束仅覆盖继承类型信号(来自产品的标准点位),对设备自建信号无约束力——即使人工硬扛维护,也天然容易产生数据不一致。
为此,与自控平台技术负责人达成以下约定,为标准点位(继承类型)的产品级聚合提供基础:
- 同产品 100% 继承:产品层配置的映射(value label / range / step 等)强制下发到所有设备实例,设备层不可修改。即同一产品的不同设备实例,点位映射完全一致
- 同品类放行:同一产品品类下的不同产品,允许差异(如灯产品和灯带产品的 brightness range 可不同)
注:自控平台信号链(品类→产品→设备)当前无硬约束,每一层均可修改。上述规则为 AI 侧与自控侧的管理约定,后续需在自控平台落实为校验规则。
本次重构不做完美方案:将标准点位的映射配置从设备级上提到产品级,设备级只存极少量差异(别名 +
disabled_signals),LLM 上下文从"全设备展开"压缩为"按产品聚合 + 仅 enabled 点位"。其中disabled_signals仅作用于标准点位(同一产品下各设备实例对标准点位的启停差异),与设备自建信号无关。对于"闪烁模式"等设备自建信号,AI 侧完全无感,不纳入语义映射体系、不出现在 LLM 上下文中——以此换取 Agent 效率提升和逻辑处理复杂度的显著降低。
1. 总体架构变更一览
1.1 角色重新定义
| 层级 | 当前职责 | 重构后职责 | 对应页面 |
|---|---|---|---|
| 🧬 标准语义管理 | 定义 Key+品类+default_props | 不变,定义 Key 是什么 + 品类级自动对账建议 | iot-semantics.html(已有) |
| 📦 产品管理 | ❌ 不存在 | 新增,定义 Key 的映射配置:label/range/step/AI指引 | iot-products.html(新增) |
| 💡 设备语义管理 | 设备级完整 Capability Mapping | 精简,引用产品映射 + 别名 + 生效开关 | iot-devices.html(改造) |
| 🏢 空间逻辑映射 | 统一齿轮配置 | 分流:设备升维→👁️只读;群控点位→⚙️可编辑 | iot-assets.html(改造) |
1.2 数据链路
设备语义继承链(品类→产品→设备):
产品品类 (Category) ← 标准语义 default_props("接入时建议")
└── 产品 (Product) ← 产品级映射配置(label/range/step/AI指引)【新增】
└── 设备实例 (Device) ← 继承产品映射 + 别名 + disabled_signals
空间逻辑映射(独立,不挂在设备下):
├── 设备升维行 → 来源:设备实例 → 引用其产品映射(👁️ 只读)
└── 群控点位行 → 来源:空间级独立定义,自行配置映射(⚙️ 可编辑)2. 新增:产品管理页面 (iot-products.html)
✅ 已实现:
- PRD:
docs/02_设计/01_管理后台/2026_AI空间智能体_产品语义管理.md(v1.1)- 原型:
iot-products.html+js/products/(store.js / main.js / drawer-view.js / drawer.js)详细交互、数据模型、UI 原型等请直接查阅上述 PRD 文件,以下仅列出新增文件清单与快捷新建语义功能说明。
2.1 快捷新建标准语义
产品抽屉的点位映射卡片中,标准语义下拉列表底部增加 + 新建标准语义 选项。选中后弹出创建弹窗,支持在配置流程中直接创建新语义,无需跳转至 iot-semantics.html。
产品侧特性:
- 数据类型 / 业务角色从当前点位
data_type+access自动推导并置灰(不可修改) - 创建后自动选中新建项,无需二次操作
- 取消时恢复到之前的下拉值
弹窗交互详见 PRD 2026_AI空间智能体_产品语义管理.md §3.3.2。
2.2 新增文件
| 文件 | 说明 |
|---|---|
iot-products.html | 产品管理页面(三栏布局) |
js/products/store.js | 产品数据 mock + state |
js/products/main.js | 列表渲染 + 导入逻辑 |
js/products/drawer-view.js | 配置抽屉渲染 |
js/products/drawer.js | 抽屉业务逻辑 |
3. 改造:设备语义管理 (iot-devices.html)
✅ 已实现:
- PRD:
docs/02_设计/01_管理后台/2026_AI空间智能体_设备语义管理.md(v4.0)- 原型:
iot-devices.html+js/devices/(drawer-view.js / drawer.js / store.js / drawer-validation.js / main.js / import.js)- Agent 设计:
docs/02_设计/02_Space_Agent_SA/SA_设备控制/SA_设备控制_Agent设计.md(L3 改为产品级聚合,新增跨产品推理、共享量程、LLM 输出示例 §4.2~4.6)- 物理执行逻辑:
docs/02_设计/02_Space_Agent_SA/SA_设备控制/SA_设备控制_物理执行逻辑.md(get_full_caps → get_product_caps,新增产品级指令拆解表)详细交互、数据模型、UI 原型等请直接查阅上述 PRD 文件,以下仅列出核心变更与文件清单。
3.1 核心变更
| 维度 | 改前 (v3.1) | 改后 (v4.0) |
|---|---|---|
| 映射配置位置 | 设备级完整 Capability Mapping(选择标准语义 + 绑定逻辑信号 + label/range/step/AI指引) | 上移至产品级,设备级继承产品映射 |
| 设备抽屉内容 | 基础信息 + 别名 + 完整映射卡片(齿轮可编辑) | 基础信息 + 别名 + 产品映射继承展示 + per-signal switch 启用/禁用(👁️只读查看) |
| 映射编辑方式 | 设备级任意编辑 label/range/step/AI指引 | 设备级不可编辑,仅通过 disabled_signals[] 控制点位开关 |
| 设备自建信号 | 支持 | ❌ 放弃支持 |
| 列表页 | 原始名称、归属空间、别名、状态、异常 | 新增:产品品类、产品名称、总点位、已启用列 |
| 列表搜索 | 设备名称 | 新增:产品品类下拉筛选 |
| 数据模型 | capabilities.mappings[] 存完整映射 | product_id + disabled_signals[] 仅存差异 |
3.2 三态 switch 逻辑
为什么设备层还需要 ON/OFF 开关:同一产品部署在不同空间时,管理策略不同。例如三台大金空调是同一产品,但:
- CEO 办公室:开关 + 温度 + 风速 + 模式(全部开启)
- 开放办公区:仅开关(禁用温度/风速/模式)
- 会议室:开关 + 温度(禁用风速/模式)
不可能为每个空间建一个产品 SKU,因此靠
disabled_signals[]在设备级做差异化开关控制。
3.3 修改文件清单
| 文件 | 改动说明 |
|---|---|
iot-devices.html | 移除 Capability Mapping 配置区,改为产品映射继承 + per-signal switch 展示 |
js/devices/drawer-view.js | 精简视图模板,移除语义选择+信号绑定+齿轮详情,改为产品映射只读列表 + switch + 👁️ |
js/devices/drawer.js | 移除映射编辑逻辑,改为展示产品引用 + 开关切换 + disabled_signals 维护 |
js/devices/drawer-validation.js | 移除设备级映射校验,改为校验 disabled_signals 合法性 |
js/devices/store.js | 数据结构精简:capabilities.mappings → product_id + disabled_signals |
js/devices/main.js | 列表增加产品品类/产品名称/总点位/已启用列及筛选逻辑 |
js/devices/import.js | 引入弹窗增加产品品类 + 产品名称过滤条件 |
4. 改造:空间逻辑映射 (iot-assets.html drawer-caps)
✅ 已完成:
- PRD:
docs/02_设计/01_管理后台/2026_AI空间智能体_空间语义管理.md§9~§10 已更新- 原型:
iot-assets.html+js/assets/(drawer-caps-view.js / drawer-caps.js / drawer-actions.js / store.js)- 设备能力透视卡片改为按产品分组;空间逻辑映射按 signal_source 分流(👁️只读 / ⚙️可编辑)
4.1 核心变更:按来源分流
数据模型新增字段:
{
"semantic_key": "light_power",
"signal_name": "灯具-照明开关 (LightSwitch)",
"signal_source": "device", // "device" | "space_logic"
"source_device_id": "dev_1", // 仅 source="device" 时
"source_product_id": "prod_light", // 仅 source="device" 时
// 以下仅 source="space_logic" 时有意义
"mapping_config": {
"values": { "0": "关闭", "1": "开启" },
"range": [0, 100],
"step": 1,
"ai_instruction": "群控开关,控制空间内所有灯"
}
}4.2 UI 分流展示
设备升维行(👁️ 只读查看):
┌──────────────────────────────────────────────────────────────┐
│ [灯具开关] [📎 灯-开关信号 (RW)] [👁️] [ 🗑️ ] │
│ ════════════════════════════════════════════════════════════ │
│ 查看详情:点击后展开只读面板,展示继承自"灯产品"的映射配置 │
│ 0 → 关闭(只读) │
│ 1 → 开启(只读) │
│ AI指引:控制灯具开关(只读) │
│ 💡 如需修改,请前往 产品管理 → 灯产品 → 点位映射配置 │
└──────────────────────────────────────────────────────────────┘群控点位行(⚙️ 可编辑):
┌──────────────────────────────────────────────────────────────┐
│ [灯具开关] [🔄 空间群控开关 (RW)] [⚙️] [ 🗑️ ] │
│ ════════════════════════════════════════════════════════════ │
│ 详情配置:点击后展开可编辑面板 │
│ 0 → [关闭] ← 必填 │
│ 1 → [开启] ← 必填 │
│ AI指引:[空间群控开关,控制所有灯] │
└──────────────────────────────────────────────────────────────┘4.3 行为变更
| 场景 | 当前行为 | 改后行为 |
|---|---|---|
| 点击设备升维行的齿轮 | 打开可编辑详情 | 改为 👁️ 图标,展开只读详情 |
| 点击群控点位行的齿轮 | 同左 | 不变 |
| 保存逻辑 | 所有映射行完整序列化 | 设备升维行只存 signal_source + device_id,不存 mapping_config |
| 重新扫描装载 | Case A 自动升维,详情可编辑 | Case A 自动升维,标记 signal_source=device,详情只读 |
4.4 空间逻辑映射已有字段调整
PRD §10.4 数据 Schema,新增字段:
| 字段 | 类型 | 说明 |
|---|---|---|
semantic_key | String | 不变 |
signal_name | String | 不变 |
signal_source | Enum | 新增:device / space_logic |
is_auto_promoted | Boolean | 保留(标记是否自动生成) |
source_device_id | String | 新增,仅 signal_source=device 时 |
source_product_id | String | 新增,仅 signal_source=device 时 |
mapping_config | JSON | 仅 signal_source=space_logic 时有效 |
4.5 映射行快捷新建标准语义
空间逻辑映射的语义下拉(.m-key)底部同样增加 `+ 新建标准语义 选项,与产品抽屉共享同一套底层组件。
与产品侧的区别:
- 空间逻辑映射没有点位上下文,数据类型 / 业务角色不作为自动推导,显示为可编辑的下拉选择框,由管理员手动指定
- 底层统一通过
SemanticUtils.openNewSemanticDialog()弹窗实现
详见 PRD 2026_AI空间智能体_空间语义管理.md §10.1.2。
4.6 修复:SVG data URI 双引号导致 select onchange 失效
问题:drawer-caps-view.js 中语义下拉 <select> 的 style 属性内嵌 SVG data URI,包含未转义的双引号(\" 在模板字面量中渲染为 "),导致 HTML 解析器认为 style 属性提前结束,onchange 等后续属性被丢弃。
修复:将 SVG data URI 改为单引号属性 + URL 编码,消除 HTML 属性定界符冲突。
影响范围:js/assets/drawer-caps-view.js → .m-key 下拉的 background:url() 样式。
5. 快捷新建标准语义
本次新增的通用交互能力:在标准语义下拉列表底部统一增加 "+ 新建标准语义" 按钮,允许管理员在配置点位映射、空间映射时,无需跳转到 iot-semantics.html,直接现场创建新语义。
5.1 覆盖入口
| 页面 | 具体位置 | 触发方式 |
|---|---|---|
产品管理(iot-products.html) | 产品抽屉 → 点位映射卡片 → 标准语义下拉 | 选中下拉底部"+ 新建标准语义" |
空间语义管理(iot-assets.html) | 空间逻辑映射 → 映射行 → 语义下拉(.m-key) | 同上 |
5.2 两处入口的行为差异
| 维度 | 产品抽屉入口 | 空间映射入口 |
|---|---|---|
| 数据类型 / 业务角色 | 从当前点位自动推导,弹窗内置灰不可修改 | 弹窗内显示为可编辑下拉框,管理员手动指定 |
| 创建后 | 新建的语义自动回填到下拉并选中 | 同左 |
| 取消 | 恢复到创建前的下拉选中值 | 同左 |
5.3 弹窗样式
新建弹窗对齐 iot-semantics.html 右侧抽屉的字段布局,统一使用语义管理页的品类分类(暖通空调 / 照明系统 / 遮阳与幕布 / 环境感知,不含设备运行状态 FA)。
6. LLM 上下文数据结构(L3 产品级聚合描述)
设备控制 Agent 在 Stage 3 通过 get_product_caps 按需注入的产品级聚合 JSON。每个 capability 独立挂 enabled_device_count 和 current_values[],同产品设备共享一份 mapping,LLM 无需看到逐设备 ID 列表:
[
{
"product_id": "prod_light",
"product": "灯产品",
"category": "照明",
"capabilities": [
{
"key": "light_power",
"name": "灯具开关",
"data_type": "bool",
"access": "rw",
"semantic_desc": "控制灯具的通断电状态",
"mapping": {
"values": { "0": "关闭", "1": "开启" },
"ai_instruction": "控制灯具开关"
},
"enabled_device_count": 5,
"current_values": [1, 0, 1, 1, 0]
},
{
"key": "light_brightness",
"name": "亮度调节",
"data_type": "number",
"access": "rw",
"semantic_desc": "调节灯具的亮度输出",
"mapping": {
"min": 0,
"max": 100,
"step": 1,
"unit": "%",
"ai_instruction": "数值越大越亮"
},
"enabled_device_count": 3,
"current_values": [80, 50, 100]
}
]
},
{
"product_id": "prod_strip",
"product": "灯带产品",
"category": "照明",
"capabilities": [
{
"key": "light_power",
"name": "灯带开关",
"data_type": "bool",
"access": "rw",
"semantic_desc": "控制灯带的通断电状态",
"mapping": {
"values": { "0": "关闭", "1": "开启" },
"ai_instruction": "控制灯带开关"
},
"enabled_device_count": 4,
"current_values": [1, 1, 1, 0]
}
]
}
]设计要点:
enabled_device_count与current_values.length对齐——灯产品 5 台设备全都启用了 light_power,但只有 3 台启用了亮度调节,LLM 可直接感知- 每个 capability 独立挂
current_values(不含设备 ID),结构紧凑- 控制执行时 Engine 根据
product_id+ 语义值拆解为逐设备物理指令
空间级群控点位的映射配置视为"特殊产品"(空间号_群控),补充在同一结构或单独段中。
7. 文件修改清单
7.1 新增文件
| 文件 | 优先级 |
|---|---|
iot-products.html | P0 |
js/products/store.js | P0 |
js/products/main.js | P0 |
js/products/drawer-view.js | P0 |
js/products/drawer.js | P0 |
7.2 修改文件
| 文件 | 改动说明 | 状态 |
|---|---|---|
iot-devices.html | 移除 Capability Mapping 配置区,改为产品映射继承 + per-signal switch | ✅ 已完成 |
js/devices/drawer-view.js | 精简视图模板,移除语义选择+信号绑定+齿轮详情 | ✅ 已完成 |
js/devices/drawer.js | 移除映射编辑逻辑,改为展示产品引用 + 开关切换 | ✅ 已完成 |
js/devices/drawer-validation.js | 移除设备级映射校验,改为 disabled_signals 合法性校验 | ✅ 已完成 |
js/devices/store.js | 数据结构精简 | ✅ 已完成 |
js/devices/main.js | 列表增加产品品类/产品名称/总点位/已启用列 | ✅ 已完成 |
js/devices/import.js | 引入弹窗增加产品品类+产品名称过滤 | ✅ 已完成 |
iot-assets.html | 空间逻辑映射分流展示 | ✅ 已完成 |
js/assets/drawer-caps-view.js | buildMappingRowHtml 增加 signal_source 分支;语义下拉委托 SemanticUtils.generateOptions();修复 SVG data URI 双引号导致 onchange 失效 | ✅ 已完成 |
js/assets/drawer-caps.js | toggleDetail、_renderMappingDetail 增加分流逻辑;refreshMappingRow 拦截 __new__ 调共享弹窗 | ✅ 已完成 |
js/assets/drawer-actions.js | 映射行保存/读取逻辑适配分流 | ✅ 已完成 |
js/assets/store.js | 空间映射数据模型增加 signal_source | ✅ 已完成 |
js/common/ui-mapping-utils.js | 新增 SemanticUtils._catMeta、generateOptions()、openNewSemanticDialog() 共享组件 | ✅ 已完成 |
js/products/drawer-view.js | _filteredSemanticOptions 委托 SemanticUtils.generateOptions() | ✅ 已完成 |
js/products/drawer.js | onSemanticChange 拦截 __new__ 委托共享弹窗;删除私有 _openNewSemanticDialog(减 152 行) | ✅ 已完成 |
7.3 修改 PRD 文档
| 文档 | 改动说明 |
|---|---|
2026_AI空间智能体_标准语义管理.md | 补充产品管理页面的入口说明 |
2026_AI空间智能体_设备语义管理.md | 映射配置上移至产品级,精简设备级内容 |
2026_AI空间智能体_空间语义管理.md | 空间逻辑映射分流改造(§10);新增 §10.1.2 快捷新建标准语义 |
新增 2026_AI空间智能体_产品语义管理.md | 产品管理页面 PRD;§3.3.2 新增快捷新建标准语义 |
文档终
