舞台工艺审图里配电容量一口气流不清:让 AI 智能体用 Python 把进线扛不扛得动装机一键闭合比对
舞台工艺审图里配电容量一口气流不清:让 AI 智能体用 Python 把进线扛不扛得动装机一键闭合比对
舞台灯光、音视频系统的图纸送到审图台,最容易被放过的不是某个灯具点位画没画对,而是配电容量这条线到底通不通。一套剧院的调光柜、配电箱、音视频机柜、信号网络中继柜,进线容量、开关整定、负载总功率之间必须自洽;一旦哪一环断了,演出时就是跳闸、烧柜、整厅黑场。我们在这轮安吉与宝鸡两个项目的灯光施工图、招标图审核里,用 AI 智能体把"容量闭合"做成了一条可自动断言的核查项,下面用三个真实实例,并附一段能直接跑的 Python 脚本,说清楚这条线为什么值得机器盯着。
一、为什么配电容量是审图里最易漏的隐性坑
配电容量问题不像"图号重号"“尺寸矛盾"那样肉眼可见。它藏在三张表的交叉里:系统图标了进线开关,配电箱图标了箱体容量,回路分配表标了各回路负载,设备清单标了装机总功率。四者任何两张对不上,就是缺口——但人工逐张翻、逐行加,极易在跨图跳转时漏掉。更麻烦的是,缺口往往是"差一点"而不是"完全没有”:不是没给电,而是给的电扛不动实际要带的负载。这种"差一点"恰恰是最危险的,因为它能过眼、过初审,却在满负荷演出时暴雷。
我们这次的做法,是把容量闭合从"人脑估算"改成"脚本累加 + 智能体断言":AI 成员先把系统图、配电箱图、回路表的容量字段抽出来,Python 做电流累加与标注容量比对,超过阈值的自动标红,主理人只看标红项做专业裁定。
二、三个真实缺口实例(安吉 10-01 / 安吉 10-3 / 宝鸡 C-13)
安吉文化艺术中心舞台灯光施工图审核里,多功能厅有一处很典型的容量不自洽。图号 MH-DG-025~029(多功能厅灯光配电箱布置及系统图) 对应的审查意见 10-01 记录:一个标称 350kW 的配电箱,实际要带的负载是 3×192kW=576kW。箱体的进线容量只有 350kW,却要扛 576kW 的负载,缺口超过 60%。
同轮安吉审核,大剧场图号 OH-DG-072~084 的意见 10-3 是另一种形态:一个 240kW 的柜体沿用了 400A 开关,按载流量估算实际电流约 429A,已经超出 400A 整定。开关没换、柜体标称也没变,但负载上来后电流已经顶破开关上限。
宝鸡大剧院舞台灯光招标设计审查里,多功能厅意见 C-13 暴露了第三种形态:进线容量 270kW,装机总功率却是 360kW,进线小于装机。而且招标阶段还常出现"装机 / 计算 / 进线"三套口径各说各话——有的写装机功率、有的写计算容量、有的写进线开关,三者数值对不上却都被当作"已满足"。
三、AI 智能体怎么把"容量闭合"做成自动断言
传统做法是审图人拿计算器把每张回路分配表的功率加一遍,再和配电箱标称容量比。我们让 AI 智能体接管这个脏活:
- 智能体用结构化读取把系统图、配电箱图、回路分配表的容量/功率字段抽成统一表格;
- Python 脚本按"配电箱 → 所带回路"的归属关系做电流累加,得到每个箱体的实际负载;
- 把累加结果与箱体标注容量比对,超出标注值即触发断言,输出"箱体 X 标称 Y kW,实带 Z kW,超限 (Z-Y)/Y";
- 主理人只需复核标红项,判断是设计错误还是预留余量,给出最终结论。
这一步把"人肉加总"的重复劳动交给脚本,把"是否构成缺口、缺口多严重"的专业裁定留给人。自动算的交给系统,判断的留人。
下面这段是智能体抽字段这一步的落地:把回路分配表(CSV)结构化成一维负载列表,直接喂给上文的 check_box_capacity。真实表里列名可能五花八门,所以用容错匹配抓"功率/kW"类列,而不是写死某一列名。
# -*- coding: utf-8 -*-
"""智能体抽取片段:把回路分配表(CSV)结构化成一维负载列表。
真实表里列名可能不同,这里用容错取值抓「功率/kW」类列,不写死列名。
"""
import csv
def extract_loads_from_csv(path):
"""读取回路分配表,返回某配电箱所带回路的功率列表(kW)。"""
loads = []
with open(path, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
# 容错取功率列:优先「功率(kW)」,其次「负载」,再次「kW」
kw = row.get("功率(kW)") or row.get("负载(kW)") or row.get("kW")
if not kw:
continue
try:
loads.append(float(kw))
except ValueError:
continue
return loads
# 以安吉 10-01 的「3×192kW」为例,回路分配表导出后大致长这样:
# 回路, 设备, 功率(kW)
# L1, LED 面光, 192
# L2, LED 顶光, 192
# L3, LED 侧光, 192
# 抽取结果 -> [192.0, 192.0, 192.0],直接喂给 check_box_capacity(BOX_RATING_KW, loads)
if __name__ == "__main__":
# 演示:不依赖真实文件,直接构造三行等效数据
sample_rows = [
{"功率(kW)": "192"}, {"功率(kW)": "192"}, {"功率(kW)": "192"},
]
loads = [float(r["功率(kW)"]) for r in sample_rows]
print("抽取到的负载列表:", loads) # -> [192.0, 192.0, 192.0]
四、可直接跑的容量闭合脚本(Python)
下面这段脚本是上面那套核查的最小可运行版,三个实例的参数都已填进去,复制即可跑。它只做"负载求和 vs 标注容量 / 实际电流 vs 开关整定 / 三口径互比"的自动比对,不参与 A/B/C/D 分级裁定——分级始终留在人手里。
# -*- coding: utf-8 -*-
"""
舞台配电容量闭合核查 —— 容量检测与标红断言
仅做"负载求和 vs 标注容量 / 实际电流 vs 开关整定 / 三口径互比"的自动比对,
不参与 A/B/C/D 分级裁定(分级由人工完成)。
"""
import math
# ===== 实例参数(取自真实审核记录,已脱敏为数值)=====
# 安吉多功能厅 审查意见 10-01:350kW 配电箱带 3×192kW 负载
BOX_RATING_KW = 350.0
DOWNSTREAM_LOADS_KW = [192.0, 192.0, 192.0]
# 安吉大剧场 审查意见 10-3:240kW 柜沿用 400A 开关
BREAKER_RATING_A = 400.0
BREAKER_LOAD_KW = 240.0
# 宝鸡多功能厅 审查意见 C-13:进线 270kW < 装机 360kW,三口径不一致
CALIBER_LOADING_KW = 360.0 # 装机
CALIBER_CALC_KW = 300.0 # 计算
CALIBER_INCOMING_KW = 270.0 # 进线
THREE_PHASE_V = 380.0
COS_PHI = 0.85
GAP_THRESHOLD = 0.05 # 超出 5% 即标红
def check_box_capacity(box_rating_kw, downstream_loads_kw):
"""下游负载求和 vs 上游箱体标注容量。"""
total = sum(downstream_loads_kw)
gap = total - box_rating_kw
ratio = gap / box_rating_kw
flag = "超限" if ratio > GAP_THRESHOLD else "正常"
print(f"[箱体] 标称 {box_rating_kw:.0f}kW | 实带 {total:.0f}kW "
f"| 缺口 {gap:.0f}kW | 偏差 {ratio*100:.1f}% -> {flag}")
return ratio > GAP_THRESHOLD
def check_breaker(current_rating_a, load_kw, voltage=THREE_PHASE_V, cos_phi=COS_PHI):
"""实际电流估算 vs 开关整定。三相:I = P / (√3·U·cosφ)。"""
i_est = load_kw * 1000.0 / (math.sqrt(3) * voltage * cos_phi)
over = i_est > current_rating_a
flag = "超限" if over else "正常"
print(f"[开关] 整定 {current_rating_a:.0f}A | 估算电流 {i_est:.0f}A "
f"| 余量 {current_rating_a - i_est:.0f}A -> {flag}")
return over
def check_three_calibers(loading_kw, calc_kw, incoming_kw):
"""装机 / 计算 / 进线 三口径互比。"""
vals = {"装机": loading_kw, "计算": calc_kw, "进线": incoming_kw}
mx, mn = max(vals.values()), min(vals.values())
spread = (mx - mn) / mn
consistent = spread <= GAP_THRESHOLD
print(f"[三口径] 装机 {loading_kw:.0f} / 计算 {calc_kw:.0f} / 进线 {incoming_kw:.0f} kW "
f"| 极差 {spread*100:.1f}% -> {'一致' if consistent else '不一致:按最小进线留接口将增容推倒重来'}")
return consistent
if __name__ == "__main__":
print("=== 舞台配电容量闭合核查 ===")
check_box_capacity(BOX_RATING_KW, DOWNSTREAM_LOADS_KW)
check_breaker(BREAKER_RATING_A, BREAKER_LOAD_KW)
check_three_calibers(CALIBER_LOADING_KW, CALIBER_CALC_KW, CALIBER_INCOMING_KW)
跑出来的输出正好对应三处真实缺口:
=== 舞台配电容量闭合核查 ===
[箱体] 标称 350kW | 实带 576kW | 缺口 226kW | 偏差 64.6% -> 超限
[开关] 整定 400A | 估算电流 429A | 余量 -29A -> 超限
[三口径] 装机 360 / 计算 300 / 进线 270 kW | 极差 33.3% -> 不一致:按最小进线留接口将增容推倒重来
上面是"单箱单查"的最小版。真实审核一个厅往往有几十台配电箱、进线、开关要过,把三个实例登记成数据行、一次跑完才像生产环境。下面这段把三个真实实例登记成 PANELS 数据行,循环跑全部核查:
# -*- coding: utf-8 -*-
"""数据驱动版:把真实实例登记成数据行,一次跑完所有核查。"""
from typing import Dict, List
# 每行 = 一个待核查配电箱/进线(参数取自真实审核记录,已脱敏为数值)
PANELS: List[Dict] = [
{
"tag": "安吉·多功能厅·10-01",
"box_rating_kw": 350.0,
"downstream_loads_kw": [192.0, 192.0, 192.0],
},
{
"tag": "安吉·大剧场·10-3",
"breaker_rating_a": 400.0,
"breaker_load_kw": 240.0,
},
{
"tag": "宝鸡·多功能厅·C-13",
"caliber_loading_kw": 360.0,
"caliber_calc_kw": 300.0,
"caliber_incoming_kw": 270.0,
},
]
def run_panel(p: Dict) -> List[str]:
"""对一个配电箱跑全部适用核查,返回告警列表(空=通过)。"""
alerts: List[str] = []
if "downstream_loads_kw" in p:
if check_box_capacity(p["box_rating_kw"], p["downstream_loads_kw"]):
alerts.append("箱体容量不足")
if "breaker_rating_a" in p:
if check_breaker(p["breaker_rating_a"], p["breaker_load_kw"]):
alerts.append("开关整定越限")
if "caliber_incoming_kw" in p:
if not check_three_calibers(p["caliber_loading_kw"], p["caliber_calc_kw"], p["caliber_incoming_kw"]):
alerts.append("三口径不一致")
return alerts
if __name__ == "__main__":
print("=== 批量容量闭合核查 ===")
for panel in PANELS:
alerts = run_panel(panel)
status = "通过" if not alerts else "告警:" + ";".join(alerts)
print(f"{panel['tag']} -> {status}")
核查结果不能只打印在控制台,得落成可留存的结构化报告,才能进审核工作记录、供后续追溯。下面这段把结果收进字典并导出 JSON,同时渲染成审核意见表:
# -*- coding: utf-8 -*-
"""把核查结果落成可留存的结构化报告(直接进审核工作记录)。"""
import json
from typing import Dict, List
def build_report(panels: List[Dict]) -> Dict:
records = []
for p in panels:
alerts = run_panel(p)
records.append({
"tag": p["tag"],
"alerts": alerts,
"passed": len(alerts) == 0,
})
return {
"panels": records,
"total": len(records),
"flagged": sum(1 for r in records if not r["passed"]),
}
if __name__ == "__main__":
report = build_report(PANELS)
print(json.dumps(report, ensure_ascii=False, indent=2))
# 渲染成审核意见表(可直接贴进工作记录)
print("\n| 配电箱/进线 | 核查结论 |")
print("| --- | --- |")
for r in report["panels"]:
conclusion = "✅ 通过" if r["passed"] else "⚠️ " + ";".join(r["alerts"])
print(f"| {r['tag']} | {conclusion} |")
五、踩坑与边界
把脚本真正接进审图工作流,有三处坑要提前说清。
坑一:开关整定沿用旧值。 安吉 10-3 那种"柜体标称没变、开关却还是上一版整定"的情况,靠"有没有标开关"看不出来,必须做"开关整定 vs 估算电流"的二层比对。脚本里 check_breaker 用三相电流公式 I = P / (√3·U·cosφ) 反算,cosφ 取 0.85 是舞台灯光负荷的常见值,落到具体项目要按设备清单校正。
坑二:三套口径混用。 招标图里"装机 / 计算 / 进线"经常各写各的,看上去都写了电,实则互不对齐。脚本用极差 (最大值-最小值)/最小值 一把抓住,宝鸡 C-13 的 33.3% 极差立刻暴露——施工深化若按最小的 270kW 留接口,后续增容就是推倒重来。
坑三:阈值不能太高也不能太低。 GAP_THRESHOLD = 0.05 留了 5% 余量避免误报,但"差一点"最危险,阈值不宜设到 10% 以上。标红项永远只作提示,最终是否构成缺口、定哪一级,是主理人的事,脚本不越权。
六、把容量闭合固化进审图工作流
这三个实例的共同点:缺口都不在单张图的"有没有",而在多张表"对不对得上"。靠资深工程师凭经验扫,能扫出一部分,但跨图、跨厅、跨批次时必然有漏。我们把容量闭合做成审图工作流里的一条固定断言——每审一个厅,脚本先跑一遍"下游负载求和 vs 上游箱体/开关容量",标红项才进入人工裁定。
工程化落地时,最方便的形态是一个命令行入口:把箱体容量和下游负载作为参数传进去,立刻出断言结果,可以挂进批处理或 CI。下面这段用 argparse 包了一层:
# -*- coding: utf-8 -*-
"""命令行入口:python capacity_audit.py --box-rating 350 --loads 192,192,192"""
import argparse
def main():
ap = argparse.ArgumentParser(description="舞台配电容量闭合核查(箱体容量版)")
ap.add_argument("--box-rating", type=float, required=True, help="箱体标称容量 kW")
ap.add_argument("--loads", type=str, required=True, help="下游负载 kW,逗号分隔")
args = ap.parse_args()
loads = [float(x) for x in args.loads.split(",")]
check_box_capacity(args.box_rating, loads)
if __name__ == "__main__":
main()
把这套抽字段→批量核查→结构化报告→命令行入口串起来,容量闭合就从"资深工程师记在脑子里的经验"变成了审图流水线里的一条固定断言。
审图质量能不能不靠运气?能,前提是这类"跨表才显形"的缺口被固化成可执行的核查项,而不是停留在某个人脑子里。配电容量闭合,就是其中最该先机器化的一条。
更多推荐

所有评论(0)