配智平台2.0六大决策地图技术方案
配智平台 V2.0 六大决策地图:基于电网图计算与业务数据穿透的完整技术方案
我检查了你上传的 ZIP,包括 OutageCalculator.pm、GridDefectMatcher.pm、OutageAPI.pm 和 MySQL 8.0 的 smartdms-table-difine.sql。结合我们之前关于配智平台 V2.0、单线图解析引擎和 AI Agent 的讨论,我认为,V2.0 不应该开发六套独立的穿透算法,而应该把 V1.0 已经验证的拓扑计算能力提炼为一个统一的电网图穿透引擎,再在上面构建六个业务决策模块。
这既能复用现有资产,也能控制研发规模。更重要的是,同一段电网,无论用户从停电地图、故障地图还是风险地图进入,都应该得到一致的杆塔、设备、区段和馈线范围,避免六套程序出现六种计算结果。
一、先看 V1.0:已经具备了哪些关键技术能力?
你的 V1.0 并不是简单地根据开关名称或杆号查询数据库,而是已经实现了一个具有实际工程价值的拓扑穿透机制。
1. 电网拓扑索引
OutageCalculator.pm 把 JSON 拓扑转换为 equipment_cns、cn_equipment 两组邻接索引,建立设备与 ConnectivityNode(连接节点)之间的双向关联。这相当于一张适合 BFS 遍历的电网图。
2. 区域识别与边界穿透
calculate_outage() 从馈线电源侧执行 BFS,排除用户指定的断开开关,再依据电源可达性识别停电区段;calculate_switch_range() 则从起始开关的下游侧出发,在指定边界开关处停止扩展。
3. 从电网图穿透到业务数据
GridDefectMatcher.pm 通过 PoleSite、Pole 和连接节点识别对应杆塔,再查询 defects 表匹配未消除缺陷。也就是说,代码已经具备了“拓扑范围 → 杆塔 → 缺陷”的基本业务穿透链路。
这三项能力,就是 V2.0 最值得保留的技术资产。需要强调的是,图算法只负责正确识别电网区域,业务数据映射负责找到区域内的资产、缺陷、故障、项目和指标。二者必须分层,不能继续把业务匹配逻辑直接堆进停电算法。
我还注意到三个需要在 V2.0 处理的问题:
- 拓扑需要统一。 当前停电计算读 JSON,而缺陷匹配又解析 XML。两者的拓扑版本和连接节点标识必须一致,否则线路范围正确,也可能匹配出错误的杆塔或缺陷。
- 多开关语义必须明确。 现有 API 在只有一个开关时调用
calculate_outage();多个开关时调用calculate_switch_range(),后者实际上把第一个开关解释为起点,其余开关解释为边界。这不是任意多个开关同时断开的同一种语义。V2.0 应将这两种操作明确区分。 - 业务数据关联需要规范化。 当前缺陷匹配包含文本杆号解析、区间扩展和字符串匹配。这个机制可以兼容历史存量数据,但不适合作为六大地图长期共享的唯一关联方式。
附件里没有实际的 CIM XML 和拓扑 JSON 样本,因此以下方案可以针对现有代码与表结构进行工程设计,但还不能据此验证某条真实馈线的计算结果和性能。
二、V2.0 的总体架构:一个穿透引擎,六个业务模块
我建议采用以下分层架构。
自然语言 / 单线图交互 / 条件筛选
│
┌─────────▼─────────┐
│ Agent 工具调用层 │
│ 意图解析、实体定位 │
└─────────┬─────────┘
│
统一业务 API / 权限校验
│
┌────────────────▼────────────────┐
│ 电网图穿透引擎 │
│ │
│ 可达性 BFS / 下游区间 / 边界搜索│
│ 设备、区段、杆塔、馈线范围识别 │
│ 拓扑版本、开关状态、遍历规则 │
└────────────────┬────────────────┘
│
统一 ScopeResult
│
┌──────────┬──────────┬─┴────────┬──────────┐
▼ ▼ ▼ ▼ ▼
停电地图 故障地图 资产地图 项目地图 风险地图
│
▼
经营地图
所有业务模块共用 MySQL 8.0 及业务语义与关联层
所有结果返回统一的设备 ID、区段 ID、馈线 ID
上图的核心是 ScopeResult,即一份标准化的电网区域计算结果。
例如,用户选择某个分段开关后,图引擎返回一个区域,其中包含 12 个线路区段、38 个杆塔位置、若干开关,以及这些对象与馈线的关系。这里的数字只是说明数据结构的示例,不是附件中的真实计算结果。
停电模块可以用它找出未带电区段;资产模块可以找出区段里的设备;风险模块可以汇总区段风险;项目模块可以检查哪些项目覆盖该区域。
图引擎计算一次,多个业务模块复用同一个区域结果。 这比在六个业务模块内分别实现 BFS、杆号匹配和馈线过滤,更容易保证正确性与可维护性。
需要补充一点:经营地图不应该为了使用图引擎而强行执行拓扑 BFS。它应该复用图引擎识别出来的馈线、区段和组织范围,再做指标计算与汇总。这是统一架构,不是要求每张地图都执行相同的遍历。
三、核心穿透引擎应该如何实现?
3.1 保留 V1.0 的 ConnectivityNode 图模型
我不建议 V2.0 一开始就引入 Neo4j,也不建议立即推倒重写现有 Perl 代码。
对于你们目前的核心场景——基于单线图识别配电网区段,再穿透到业务数据——MySQL 8.0 加内存中的邻接索引,完全可以作为首期的技术路线。真正决定正确性的,是图模型、遍历规则、数据映射和拓扑版本管理,而不是是否使用图数据库。
V1.0 的图结构可以概括为:
ConnectivityNode A
│
开关 S1
│
ConnectivityNode B
│
线路 L1
│
ConnectivityNode C
│
开关 S2
│
ConnectivityNode D
在内部索引中,既保存设备对应哪些连接节点,也保存连接节点关联哪些设备。
例如:
equipment_cns[S1] = { CN_A, CN_B }
cn_equipment[CN_A] = { S1, ... }
cn_equipment[CN_B] = { S1, L1, ... }
这类模型优于直接根据线路名称、开关编号或杆号判断上下游关系,因为它基于实际拓扑中的连接关系进行遍历。
但是,V2.0 应补充一个十分重要的机制:设备类型对应的穿越规则(Traversal Policy)。
不能一概认为所有具有多个 ConnectivityNode 的设备都应该把这些节点连通。线路、闭合开关、隔离开关、变压器、母线和负荷的电气作用不同。尤其是涉及不同电压等级、变压器绕组以及跨馈线联络时,应该明确设备是否允许穿越、哪些端子能够互通,以及在哪种分析场景下可以穿越。
建议定义一份可版本化的规则:
| 设备类别 | 典型穿越规则 |
|---|---|
| 架空线、电缆 | 在有效端点之间连通 |
| 闭合的分段开关、联络开关 | 按开关状态连通 |
| 断开的隔离开关、故障隔离边界 | 不允许穿越 |
| 母线、同电气连接节点设备 | 按电压等级和连接模型处理 |
| 变压器、多绕组设备 | 不得无条件跨端子连通;按电压等级和分析场景处理 |
| 台区负荷、终端负载设备 | 通常作为叶节点,不应把低压侧错误地接回中压图 |
具体规则需要按照你们 CIM/XML 的设备类型、端子模型和实际图模校验后定稿,不能仅凭设备名称猜测。
3.2 将图算法提炼为五类通用操作
V1.0 已经实现了前两类。V2.0 不需要创造六套算法,而应将其抽象为稳定、可测试的图操作。
A. 电源可达性计算 source_reachability
从指定电源集合出发,根据拓扑、设备穿越规则及开关状态计算可达节点。用于识别模拟停电范围和实际失电范围。
B. 两开关之间的区间 range_between_switches
根据起始开关识别下游侧,在一个或多个边界开关处终止扩展。主要用于停电消缺、区段检修和精确的区间穿透。
C. 上下游边界搜索 upstream_downstream
查找某设备最近的上游保护开关、下游分段开关及其关联区域,供故障定位和影响范围分析使用。
D. 电气连通分量 connected_component
识别在当前拓扑和开关状态下相互连通的设备集合,用于分析联络关系、孤立区段和拓扑异常。
E. 范围扩展与聚合 expand_scope
从一组设备、区段、杆塔或馈线出发,按指定关系扩展,并返回可供业务查询、统计和地图渲染的统一对象集合。
3.3 必须明确三种不同的电网状态
这是 V1.0 向 V2.0 升级时最重要的计算语义之一。
第一种:模拟停电。 用户在单线图上选择开关,系统假设这些开关已经断开,计算由此形成的停电范围。这就是当前消缺场景最接近的模式。
第二种:实际运行状态。 系统根据最新有效的开关遥信、设备状态和当前拓扑,计算实际电源可达性。不能把用户在界面上的选择当成真实的开关动作。
第三种:历史时刻状态。 用户查询某次历史故障或历史停电时,需要采用对应时间的拓扑和开关状态,不能直接拿今天的运行状态重算昨天的故障。
因此,图引擎至少需要三类输入:
拓扑版本 + 电源集合 + 开关状态快照
│
图遍历规则
│
目标范围
实际运行状态和模拟操作应该采用不同的请求模式。对于有联络开关或环网转供的场景,还需要考虑其他有效电源,不能永远只从当前馈线的单一电源侧判断是否失电。
3.4 统一计算接口与结果结构
建议把图引擎封装成独立的内部服务,不再由六个模块直接调用 Perl 类的内部方法。
例如,统一入口:
POST /api/v2/graph/scopes/compute
输入参数:
{
"operation": "range_between_switches",
"feeder_id": "FEEDER_ID",
"start_switch_id": "SWITCH_A",
"boundary_switch_ids": ["SWITCH_B"],
"topology_version": "active",
"traversal_policy": "distribution_10kv_v1"
}
这里的 ID 是接口示例,并非附件中的实际设备编号。
输出的设计重点不是一次性返回所有详细业务记录,而是生成一个可以重复引用的区域结果:
{
"success": true,
"scope_id": "SCOPE_ID",
"scope_type": "section",
"topology_version": "TOPOLOGY_VERSION",
"members_summary": {
"segments": 12,
"pole_sites": 38,
"switches": 3
},
"provenance": {
"operation": "range_between_switches",
"traversal_policy": "distribution_10kv_v1"
}
}
业务模块再使用 scope_id 获取缺陷、资产、故障、风险或项目。这样既能减少重复计算,也能避免把几千个电网对象 ID 全部塞进大模型上下文。
为了保证可追溯,每一份区域结果都应记录所用拓扑版本、状态时间、起始设备、边界设备和遍历规则。对于重要的风险及故障分析,还应保存使用的业务规则版本。
四、V2.0 必须增加的基础设施:统一对象身份和业务关联
我认为,这是整个 V2.0 中与图算法同样重要的一项工程工作,甚至更容易成为项目成败的关键。
你上传的 SQL 中已经有不少可以复用的业务表,例如:
- 馈线信息:
accounting - 缺陷:
defects - 故障记录:
fault_records、faults_list、dispatch_logs - 遥信、事件和遥控:
telesignaling_data、soe_data、telecontrol_data - 设备台账:
dev_accounting、arrester_equipment_ledger、device_data - 项目和计划:
power_restoration_effectiveness_projects、automatic_analysis、outage_plans、work_plans - 风险相关:
high_risk_feeders、lightning_prone_sections、lightning_strike_fault、arrester_health_scores
这些表已有不少有用的数据,但它们并不天然构成统一的电网对象模型。
例如,同一个设备在 CIM 中可能以设备 ID 或 mRID 标识,在调度事件表中使用 dev_oid,在 DMS 文件中使用 switch_gis_id 或 switch_oid,而资产台账可能使用 device_id。即使字段名称看起来相似,也必须验证数据来源和 ID 语义,不能直接假定它们相等。
4.1 建立统一电网对象身份层
建议为每一个纳入穿透范围的设备或区段分配统一的内部 object_id,作为跨业务域的关联锚点。
基础对象至少涵盖:
| 对象类型 | 用途 |
|---|---|
| FEEDER | 馈线、线路级聚合和组织归属 |
| SWITCH | 分段、联络、保护和隔离设备 |
| SEGMENT | 架空线、电缆等线路区段 |
| POLE_SITE / POLE | 杆塔位置与具体杆号 |
| TRANSFORMER | 配变和相关负荷范围 |
| DEVICE | 终端、避雷器及其他设备 |
| STATION / BUS | 厂站、变电站及母线相关对象 |
同一个业务对象可以对应多个源系统标识,但只能通过经过校验的映射关系归并为统一对象。
建议新增以下几张基础表。
| 表名 | 职责 |
|---|---|
grid_topology_version |
管理每次拓扑解析的版本、来源、校验状态和发布时间 |
grid_object |
保存统一电网对象及其类型、名称、馈线归属等基本信息 |
grid_object_alias |
保存设备别名、历史名称、源系统编码等实体检索信息 |
source_object_mapping |
将各源系统的记录 ID 映射到统一的电网对象 ID |
grid_scope_run |
保存一次区域穿透计算的条件与结果元数据 |
grid_scope_member |
保存某个区域内的设备、区段、杆塔等成员关系 |
grid_business_link |
保存缺陷、故障、资产、项目等业务记录与电网对象的关联证据 |
这些表的逻辑关系如下:
源系统记录
│
▼
source_object_mapping
│
▼
grid_object ◄──── 电网拓扑关系
│
▼
grid_scope_member
│
▼
停电 / 故障 / 资产 / 项目 / 风险 / 经营
这里不必一开始就把所有旧表迁移进新表。源业务表仍作为原始数据来源,新表只保存规范化身份、映射、拓扑版本和穿透结果。
针对高频查询,可以按实际数据量为缺陷、项目和故障建立专用关联表或物化关联表,以免所有热点业务都依赖一个通用关联表做复杂查询。
4.2 拓扑版本表与缓存机制
建议每次图模解析成功后,为对应馈线生成一个新的拓扑版本,至少记录:
feeder_id、拓扑版本号、源文件标识或哈希值;- 节点数、连接数、解析时间;
- 设备端子缺失、开关端子异常、跨馈线引用等校验结果;
- 版本状态,例如构建中、已校验、已发布、已停用。
发布新版本时,不能让正在计算的请求混用新旧拓扑。应先构建、校验,再原子切换到新版本;历史结果仍能引用旧版本。
当前每次 API 请求都会重新创建计算对象,并加载相关拓扑和数据库连接。V2.0 应优化为:拓扑在后台解析与校验,运行时按版本加载缓存,业务请求共享缓存结果。
这并不意味着所有进程共享一个内存对象。若继续使用 Apache/mod_perl,缓存通常需要考虑多进程工作模式;也可以把图计算封装为独立服务,由服务内部维护按馈线和拓扑版本管理的缓存。
4.3 杆塔与缺陷关联:保留兼容,逐步替换文本匹配
现有 GridDefectMatcher.pm 会从 PoleSite 及其 Pole 子对象提取杆号,再通过 defects.problem_section 中的支线名称与编号匹配缺陷。
这对历史数据有实用价值,但其中的杆号区间扩展逻辑不能作为生产级的最终关联依据。比如根据已出现的杆号自动把中间所有数字扩展出来,就可能将不存在的杆号或不属于该区段的缺陷匹配进来。
建议采用分级关联策略:
- 精确关联: 缺陷记录有准确的设备 ID、杆号或电网对象 ID 时,直接关联。
- 规范化关联: 根据经过校验的线路 ID、杆塔编码、区段边界及别名映射关联。
- 历史文本匹配: 对只有自然语言区段描述的旧缺陷继续采用现有算法,但明确标注其匹配方式与可信度。
- 待核实关联: 多个候选对象均符合条件时,不强行确定唯一设备,应由用户确认或纳入数据治理工作。
因此,缺陷记录最终最好形成类似以下关系:
defect_id → grid_object_id → pole/segment/switch
每条关联都记录匹配依据、关联方式、可信度以及是否经过人工确认。六大地图就不需要重复解析 problem_section 中的杆号文本。
五、六大地图分别怎么做?
六张地图应该采用同一套技术骨架:
输入业务对象或查询条件 → 计算电网区域 → 关联该区域内的业务数据 → 执行业务规则或指标计算 → 返回地图高亮、列表与统计。
区别在于它们选择不同的范围计算方式、业务表、判断规则以及展示内容。
5.1 停电地图:以 V1.0 为基线,完成统一穿透
这是最适合优先完善的地图,因为你们已经有经过实际业务验证的功能。
输入
用户选择一个或多个需要模拟断开的开关,或者指定一个起始开关与若干边界开关。
Power Distribution Network Reconfiguration Techniques: A Thorough Review
图计算
根据选定的操作模式进行电源可达性计算或边界区间搜索,生成受影响的 scope_id。
业务穿透
关联区段、杆塔、设备、未消除缺陷以及已有计划,输出可供生技部安排停电消缺的明细。
前端继续保留现有的区域高亮、弹窗和杆号展示方式,但底层不再直接调用某个特定的停电模块。
建议给停电地图明确三个业务入口:
| 模式 | 含义 | 关键计算 |
|---|---|---|
| 模拟停电 | 假设指定开关断开 | 重新计算电源可达性 |
| 区段消缺 | 选择起点及一个或多个边界开关 | 计算指定区间 |
| 实际失电 | 根据有效运行状态识别失电范围 | 使用真实开关状态和有效电源集合 |
三种模式共用图内核,但输入参数和结果语义必须分别定义。特别是模拟停电,结果不能被误认为调度系统下发的真实停电命令。
停电地图最终不仅展示绿色区段,还应回答三个实用问题:
- 这个区段内有哪些杆塔和设备?
- 有哪些尚未消除的缺陷,具体位于何处?
- 当前区段能否与已有工作计划或其他消缺任务合并安排?
这也是从单纯的拓扑展示升级为决策地图的关键。
5.2 故障地图:从故障事件定位到故障区段
故障地图和停电地图有关联,但不能简单地把故障地图做成另一张停电地图。
停电地图的核心问题是“如果这些开关断开,哪些区域失电”;故障地图需要回答的是“故障在哪里、哪些设备受到影响、有哪些证据支持这个判断”。
建议采用以下处理流程:
第一步:识别故障事件
故障单、跳闸记录、SOE 事件、遥信变位及相关设备
第二步:映射到统一电网对象
利用设备 ID、GIS ID、别名与馈线映射定位设备和事件所属馈线
第三步:重建故障时刻及开关动作
结合事件时间、信号质量、保护动作、开关状态及历史拓扑
第四步:图穿透与候选区段识别
从故障候选设备搜索上游保护边界和下游分段边界
第五步:故障地图输出
候选故障区段、相关开关、影响范围、历史故障、证据与判断可信度
附件中的现有表可以作为故障模块的数据入口:
fault_records:设备故障记录,含dev_oid、故障时间、故障类型等。faults_list:故障单,含馈线名称、故障时间、类型、状态与描述。dispatch_logs、outage_log:运行事件及故障处置记录。soe_data、telesignaling_data、telecontrol_data:可用于还原事件、信号和操作过程。dms_data_gzdy、breaker_data、remote_signaling_data:可作为开关状态和运行信息来源,具体采用哪张表取决于数据的时间覆盖、质量和来源权威性。
这里有两项必须严格处理的技术要求。
第一,故障记录中的某个设备名称只能作为线索,必须尽可能映射到真实的电网对象。不能直接用名称包含关系确定故障区段。
第二,必须区分“已确认故障设备”和“算法推断出的候选区段”。当事件时间、保护信息或拓扑信息不完整时,系统应该返回候选范围、支持证据和不确定性,而不是把推断结果展示成确定事实。
建议第一阶段优先做好“已知故障记录 → 精确设备定位 → 图穿透影响范围 → 历史事件查看”。基于 SOE 与保护动作进行更复杂的自动故障定位,可在数据校验后逐步增强。
5.3 资产地图:让电网拓扑成为资产查询的入口
资产地图最关键的不是把台账放到单线图上,而是解决资产台账与电网实际对象之间的对应关系。
例如,用户在单线图选中一个开关或一段线路,系统应该能查出该对象所属区域内的设备清单、投运日期、设备状态、生产厂家、运维单位、健康分数等信息,并能够识别缺失台账的设备。
建议以以下表为主要来源:
| 表 | 主要用途 |
|---|---|
dev_accounting |
通用设备台账、资产身份编码、投运日期、产权及功能位置 |
arrester_equipment_ledger |
避雷器专项资产属性、型号、投运情况及位置 |
device_data |
DTU/FTU 等设备信息及健康分数 |
automation_switch_ledger、automation_switch_ledger_new |
自动化开关本体、终端、通信及运行维护信息 |
automated_gis_devices |
自动化设备与线路、开关 GIS 标识的关联 |
穿透逻辑应为:
用户选择的开关 / 区段 / 馈线
│
▼
图引擎计算区域
│
▼
获取统一电网对象 ID
│
▼
关联资产台账与设备表
│
▼
台账明细 / 健康状况 / 缺失及重复关联
这里还可以实现两个有价值的功能。
资产完整性检查: 拓扑中有设备,但台账中找不到对应记录;或者台账中存在设备,却无法映射到任何有效的电网对象。这些问题可以形成资产治理清单。
资产全景穿透: 从一个馈线向下查询开关、杆塔、线路设备和避雷器,并按设备类别、运行状态、投运年限和管理单位进行汇总。
但要注意,资产不一定全部是有电气连通关系的节点。某些资产需要通过 parent_gis_id、功能位置或其他资产层级关系找到,不能仅依赖电气 BFS。
5.4 项目地图:建立项目与电网区段之间的明确关联
项目地图面临的核心问题,与资产地图类似,但映射难度往往更大。
现有数据库已经有:
power_restoration_effectiveness_projects:复电成效相关项目。automatic_analysis:自动化分析、问题区段和相关项目编号。outage_plans:停电方案及影响范围。work_plans:工作计划、计划时间、工作地点和线路 ID。lightning_arrester_maintenance_plan:避雷器运维与更换计划。high_risk_feeders:高风险馈线及其重点管控、整治和抢修项目相关字段。
但这些表的项目编码、关联字段、区段表达方式及状态语义并不统一,暂时不能假定存在一个完整的通用项目模型。
建议新增一套规范化项目主数据和关联关系:
project_id
├── 项目基本信息
├── 项目类型、投资及批次
├── 计划时间与进度
├── 责任单位与实施班组
└── 关联电网对象
├── 馈线
├── 区段
├── 开关
└── 设备
其中最重要的是最后一层:建立项目与电网对象的明确关联,并保存关联依据。
当用户选择停电区段时,项目地图据此查出已覆盖该区段的项目、尚未覆盖的缺陷,以及可能重复安排的工作。反过来,从某个项目进入地图时,也能高亮对应馈线与施工区域。
如果旧表只有文字形式的 project_name、outage_section 或 work_location,应先进行规范化匹配;没有可靠证据时,将结果标记为候选关联,而不是强行认定项目覆盖整个馈线。
这样,项目地图才能回答:哪些项目真正解决了当前区段的问题,哪些缺陷仍然悬空,以及不同项目之间是否存在实施冲突或工作重叠。
5.5 风险地图:图穿透负责定位,规则引擎负责定量
风险地图最容易出现的错误,是把“图算法”和“风险评分”混成同一件事情。
图引擎可以告诉系统某个区段包含哪些设备、杆塔以及历史故障对象;但风险分值必须由明确的业务规则计算,不能由大模型随意判断。
建议先定义风险对象的三个层级:
- 设备级风险: 某个开关、避雷器、自动化终端的健康状况或故障风险。
- 区段级风险: 某个线路区段的缺陷集中度、历史故障和环境暴露情况。
- 馈线级风险: 汇总整条馈线的区段风险、重复故障、重要负荷影响等信息。
可以使用以下数据源:
| 数据源 | 可提供的风险证据 |
|---|---|
high_risk_feeders |
高风险馈线名单及既有管控措施 |
defects |
未闭环缺陷、缺陷类型及发现时间 |
fault_records、faults_list、dispatch_logs |
历史故障次数、类型和处置情况 |
arrester_health_scores |
避雷器健康评分及匹配状态 |
lightning_prone_sections、lightning_strike_fault |
易雷击区段与历史雷击故障 |
device_abnormal_state、anomaly_records |
设备异常及其处置状态 |
accounting、资产台账 |
设备与馈线属性、投运时间及线路基础数据 |
建议把风险引擎做成一个可配置、可审计的规则体系。
例如:
风险结果 =
历史故障风险
+ 未消除缺陷风险
+ 设备健康与老化风险
+ 雷击等环境风险
+ 供电影响及运行可靠性风险
这只是风险因子结构,并不意味着可以把这些项目直接相加。实际评分需要定义指标的归一化方式、时间窗口、数据缺失处理、各类因素的权重,以及不同风险等级的阈值。初始权重应该由供电专业人员依据历史数据确定,并通过历史事件回测校准。
风险结果还必须保存可解释的证据,例如“最近两年发生过若干次故障”“存在若干条未消缺缺陷”“避雷器健康分低于设定阈值”。用户点击一个高风险区段,应能看到分值是怎么来的。
对于地图展示,建议风险图层可以同时显示风险等级、主要风险因素以及尚未执行的整治项目。这样它不仅能识别风险,还能帮助安排治理优先级。
5.6 经营地图:统一指标定义,不把 SQL 交给大模型自由生成
经营地图的核心是指标,而不是单线图遍历。
例如,用户在馈线或区域上点击后,可以查看线路长度、配变数量、计划与故障停电情况、影响用户数、复电表现、项目投资和治理进度等。
数据来源主要包括:
accounting:馈线长度、配变数量、容量、自动化开关数量等。outage_analysis、outage_info_system、noplan_outage:停电事件、时长、影响配变或用户、复电相关数据。outage_plans、work_plans:计划性停电及工作计划。- 项目和资产相关表:投资、进度、资产状况和治理结果。
不过,不能简单地把上述各表的数据相加。不同表可能包含重复的停电事件,也可能使用不同的统计口径。比如,同一故障在调度记录、故障单和停电分析表中可能出现多次;有效复电率也不应直接对逐条记录做不加权的简单平均。
因此,V2.0 应建立统一指标目录(Metric Registry)。每个指标至少定义:
| 属性 | 示例 |
|---|---|
| 指标编码 | feeder_outage_count |
| 指标含义 | 选定期间内符合统计条件的停电事件数量 |
| 统计粒度 | 馈线 / 区县 / 地市 / 时间 |
| 统计口径 | 事件去重、排除规则和状态定义 |
| 数据来源 | 经核定的业务表及字段 |
| 刷新方式 | 实时查询或定时汇总 |
| 适用范围 | 哪些组织、线路和时间条件可以使用 |
具体的统计口径需要按照供电局现有业务规定确认,不能仅凭表名或字段名推定。
技术实现上,对于低频的明细查询,直接使用 MySQL 参数化 SQL 即可;对于较大时间跨度、较多馈线的统计,建议建立日级馈线指标汇总表,再按区县和地市聚合。
例如:
metric_feeder_daily
日期
馈线 ID
停电事件数
累计停电时长
影响用户数
影响时户数
已核定的复电指标
字段是否纳入最终表,应由已确认的指标清单决定。实时遥信、设备健康等即时值则继续走对应的数据入口。
这样,经营地图可以与其他五张地图打通:用户从高风险馈线进入经营地图后,可以直接查看该馈线近年的故障和停电指标、治理项目投入,以及已有治理工作的执行情况。
六、让自然语言智能体真正调用这六大地图
这部分我建议沿用你之前提出的路线:大模型负责理解用户意图、抽取条件和选择工具,业务运行时负责校验参数、执行确定性的图计算和数据库查询。
没有必要让大模型理解整张电网,也没有必要让它自己写出复杂 SQL,更不能依靠大模型自由生成设备间的拓扑关系。
6.1 智能体调用链
用户自然语言
│
▼
大模型:识别意图、实体、时间与过滤条件
│
▼
运行时:实体解析、上下文解析、权限校验
│
▼
调用登记过的业务工具
│
├── 图穿透工具
├── 停电查询工具
├── 故障查询工具
├── 资产查询工具
├── 项目查询工具
├── 风险查询工具
└── 经营指标工具
│
▼
业务服务:图计算 + 结构化 SQL + 业务规则
│
▼
证据、数据及 scope_id
│
▼
大模型组织回答,前端显示地图与明细
这套架构的关键是将大模型的灵活性与电网计算的确定性结合起来。大模型可以理解“帮我把金银支线这个开关后面尚未处理的缺陷找出来”,但它不能自行决定哪条线路与哪段区间存在电气连通关系。
6.2 建议提供给 Agent 的工具
不需要一次为每张地图设计很多零碎工具。建议先提供共用基础工具,再提供六个业务查询入口。
| 工具 | 作用 |
|---|---|
resolve_grid_entity |
根据名称、别名、编号解析馈线、开关、区段或设备 |
compute_grid_scope |
执行标准图穿透操作,生成 scope_id |
query_outage_map |
查询停电范围、杆塔、缺陷与计划 |
query_fault_map |
查询故障事件、候选区段、证据与影响范围 |
query_asset_map |
查询区域设备与资产台账 |
query_project_map |
查询项目覆盖、状态及对应电网对象 |
query_risk_map |
查询风险分值、风险因素与治理状态 |
query_metric |
按登记的指标编码查询经营数据 |
工具参数应该有明确的 JSON Schema、字段类型、必选条件、允许的操作及返回结构。运行时可以根据意图调用一个业务工具,或按顺序组合多个工具。
举个例子:
用户提问:
都匀局金银支线 FZ0010 开关后面有哪些没消除的缺陷?这些缺陷涉及哪些资产?
智能体首先识别这是一个停电消缺相关的区段查询,并解析 FZ0010 对应的开关 ID。随后调用图穿透工具,获取对应区域的杆塔、区段及设备 ID,再使用相同的 scope_id 查询未消除缺陷与资产信息。
最终输出应该包含明确的设备、杆号、缺陷详情和台账记录,而不只是由大模型总结出来的一段话。
注意,以上是对调用流程的示例,不代表目前数据库一定已有该开关的有效映射或该区段的真实数据。
6.3 上下文必须使用结果引用,而不是只靠聊天文本
你之前讨论过连续提问中的上下文问题。这里可以将它直接纳入 V2.0 的工具设计。
例如:
- 用户问:“查询今天都匀局有多少条停电记录。”
- 用户接着问:“其中有多少条已经复电?”
- 用户再问:“把未复电的列出来。”
对于第二、第三轮,不应该重新从头理解所有实体和条件。第一轮工具可以返回 result_ref 或 scope_id,并保存查询时间、组织范围、指标和筛选条件。
后续请求由大模型识别为“基于前一次结果继续筛选”或“继续查询相关字段”,运行时将前一次的结果引用传递给工具。
系统应保存的上下文包括:
- 当前对话中相关的查询实体和业务范围;
- 前一次工具调用的参数与结果引用;
- 用户最近一次筛选条件;
- 当前选中的地图对象;
- 时间范围、组织范围及尚未确认的实体候选。
大模型负责判断用户是在延续前面的查询,还是提出全新的问题;运行时负责验证引用是否有效、条件是否兼容。不能只依靠关键字规则,也不能让模型随意改变上一次查询的组织范围。
6.4 生产环境中的安全边界
智能体初期建议只开放经过授权的只读查询工具。
所有数据库访问必须经过运行时执行层,采用参数化 SQL、白名单、数据范围校验和行级或业务级权限控制。模型返回的工具参数不应直接决定用户能访问哪些馈线,也不应允许模型自行拼装任意 SQL。
如果未来需要把“创建停电方案”“生成工作计划”或“提交缺陷处置”等操作开放给 Agent,应另外设置权限、确认机制、审计日志和业务审批流程。图计算结果本身不能代替调度操作或安全审批。
七、MySQL 8.0 与运行时的工程落地细节
前面定义了业务架构,接下来要保证它能在你们现有的数据环境里运行,而不是只停留在概念图。
7.1 不建议让六张地图分别遍历数据库
所有地图应通过统一区域结果访问关联对象。对于同一查询,如果多个业务模块需要相同区段,就复用同一个 scope_id。
推荐的调用结构:
Scope Engine
│
├── 计算图成员
├── 保存 scope_id 与版本
└── 缓存或持久化区域成员
│
▼
业务 SQL 查询层
│
┌──────┴──────┐
▼ ▼
资产 / 缺陷 故障 / 项目
│ │
└──────┬──────┘
▼
结果聚合层
实现时不应把几万条设备 ID 拼接为一个超长的 SQL IN (...) 条件。中小范围可以分批查询;规模较大或需要多次复用时,可以把成员放入 grid_scope_member 等关联表,通过索引关联到业务记录。
7.2 为热点业务查询增加合适的索引
从附件中的 SQL 定义可以看出,一些业务表已经有时间、设备或馈线的单列索引,但对“按线路定位未消除缺陷”“按设备与时间查询事件”这种组合查询,还可以优化。
例如,defects 当前对 line_id 没有显式索引,而 V1.0 的缺陷查询正是按线路筛选,再过滤闭环状态。可考虑用生成列和联合索引支持这一查询:
ALTER TABLE defects
ADD COLUMN is_open TINYINT
GENERATED ALWAYS AS (
CASE
WHEN COALESCE(fixed, 0) = 1
OR COALESCE(fixed_sw, 0) = 1
OR COALESCE(fixed_verbal, 0) = 1
THEN 0
ELSE 1
END
) STORED,
ADD INDEX idx_defects_line_open_time
(line_id, is_open, discovery_time);
这里的 is_open 沿用当前代码“任一闭环标记为 1 就视为已消除”的逻辑。上线前应先核实三种闭环字段在实际业务中的含义,并排查该生成列及索引是否已经存在。
还建议在检查现有索引后,评估以下组合索引:
| 表 | 候选索引 | 支持的查询 |
|---|---|---|
fault_records |
(dev_oid, time) |
按设备查询某个时间段的故障 |
soe_data |
(dev_oid, soe_time) |
按设备、事件时间重建动作序列 |
telemetry_data |
(dev_oid, collection_time) |
按设备查询历史遥测 |
outage_analysis |
(feeder_id, outage_start_time) |
按馈线查询历史停电 |
outage_info_system |
(line_id, outage_time) |
按线路及时间查询停电记录 |
这不是要求不加分析地执行全部 DDL。应先用真实 SQL 的 EXPLAIN ANALYZE 检查执行计划,确认扫描量、选择性和收益后再建立索引,避免重复索引增加写入开销。
对于百万级的 SOE、遥测或其他高频数据,还需要区分实时查询和历史分析:实时页面读取最新值或有限时间窗口;风险评分与经营指标优先使用定时聚合结果,必要时再研究历史归档和分区,而不是让每一次问答都扫描全量事件。
7.3 用统一数据快照保证结果可信
每份穿透结果都应该能够回答以下问题:
- 用的是哪个版本的单线图?
- 使用的开关状态来自哪个时刻?
- 设备、缺陷和项目数据分别刷新到什么时候?
- 关联对象时采用了精确 ID 还是历史文本匹配?
- 本次风险分值使用的是哪个规则版本?
当拓扑有效而业务台账已经过期时,图引擎的计算可能正确,但业务结果仍不一定完整。因此,地图需要同时展示计算时间、拓扑版本及相关数据的更新时间;对于关键数据缺失或拓扑校验失败的请求,应明确提示,不能静默生成一个看似完整的结果。
八、建议的实施顺序:先打通一条完整业务链,再扩展六大地图
结合现有 V1.0 代码、SQL 结构和 V2.0 目标,我建议按以下顺序实施。
01
统一图引擎和区域结果
保留现有 BFS 及上下游区间算法,将其封装成独立接口;补充拓扑版本、遍历策略、状态快照与标准化的 scope_id。先使用已验证的馈线开展回归测试。
02
完善停电地图与资产、缺陷关联
将现有停电区域计算与杆塔、资产和缺陷统一到标准对象身份层。明确精确关联与历史文本匹配的区别,确保一个图区域在不同模块得到相同的设备集合。
03
建设故障地图
优先打通现有故障记录、SOE、开关及拓扑关系;先支持已知故障设备与影响范围穿透,再逐步建设自动故障区段识别和事件关联。
04
建设项目地图和风险地图
建立项目与电网对象的关联;建立版本化风险规则、证据链与多层级风险聚合。先让规则清晰、数据可追溯,再追求更复杂的风险模型。
05
建设经营指标与自然语言 Agent
建立指标目录和日级汇总;为六张地图登记统一工具接口,并实现实体解析、查询上下文延续、权限校验和结果引用。
06
验证生产质量和性能
对拓扑、业务关联、跨馈线范围、数据新鲜度和智能体调用开展回归测试,记录每次查询的计算耗时、错误类型、规则版本和结果来源。
这条路线有一个重要的研发管理原则:不要先把六张地图的页面全部做出来,再补底层关联关系。 应先确保穿透区域和对象关联的正确性,再让地图复用这些能力。
每个阶段应设置哪些验收条件?
最初阶段不必追求所有业务场景都自动化。建议先建立一套可重复执行的标准测试集,至少覆盖以下情形:
- 单开关模拟停电、多个开关组成的指定区间,以及不同支线之间的边界情况。
- 开关断开后,联络供电或其他电源是否会使部分区域仍然带电。
- 同一区域在停电、资产和缺陷查询中得到的设备与杆塔集合是否一致。
- 拓扑节点缺失、开关端子异常、源系统 ID 无法关联时,系统能否明确返回错误或不确定状态。
- 故障区段识别是否区分确定结果与候选结果;风险地图是否能提供分值依据。
- 自然语言提问能否准确选择工具,并在“其中还有多少”“把未处理的列出来”等连续追问中沿用正确的查询结果。
对已有 V1.0 场景,应以原系统的已验证结果作为基线。V2.0 的拓扑改造必须能解释结果变化,不能只凭画面看起来正确就验收。
九、最终技术决策:哪些应当沿用,哪些必须新增?
| 技术组件 | 建议 |
|---|---|
| V1.0 BFS / ConnectivityNode 拓扑模型 | 沿用核心算法,补齐设备类型穿越规则 |
| ModPerl 实现 | 首期保留并封装标准接口,经过回归测试后再决定是否迁移语言 |
| MySQL 8.0 | 继续作为业务数据与规范化关联数据的主要存储 |
| 单线图解析引擎 | 增加拓扑版本、校验、原子发布及缓存机制 |
| 资产、缺陷、故障、项目等原表 | 继续作为业务数据源,通过统一对象身份层关联 |
| 六大地图算法 | 不分别开发六套图算法,改用统一图引擎与独立业务模块 |
| 风险计算 | 新建可配置、可解释、可回测的规则体系 |
| 经营分析 | 建立指标目录与汇总数据层,不依赖大模型临时拼装 SQL |
| AI Agent | 通过固定的工具 Schema 调用图引擎及业务 API,保留完整权限与审计机制 |
还有一个值得明确的工程细节:我不建议为了架构上的统一而立即将现有 Perl 代码重写成另一种语言。先把现有图计算模块与 Apache 请求处理、数据库访问、拓扑加载解耦;等标准接口和回归测试建立之后,再根据开发维护成本、实际吞吐量和团队技术栈决定是否迁移。这能最大程度地减少对 V1.0 已有业务效果的影响。
我的核心判断是:配智平台 V2.0 的技术核心,不是六张地图,也不是大模型本身,而是“统一电网图计算引擎 + 统一电网对象身份 + 业务语义与规则层”。
图引擎解决“这个区域究竟包含哪些电网对象”;统一身份层解决“其他系统里的哪些记录对应这些对象”;业务模块解决“这些对象有哪些缺陷、故障、资产、项目和风险”;Agent 解决“用户如何通过自然语言方便地调用这些能力”。
这四层形成稳定架构后,新增一张地图主要是补充业务关联、计算规则、指标和展示,不必重新实现拓扑穿透。也只有这样,六大地图才能真正成为同一个配电网决策平台的六个观察和分析入口,而不是六套相互独立的应用。