舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线

舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线

一、背景痛点:长任务里脚本为什么总"死"

舞台工艺审图覆盖机械、灯光、音响三大专业。机械专业关注吊杆布置与荷载、调光柜供电、DMX512 链路;灯光与音响又各自有一套图号与提资,这些图最终要落到 JGJ57 与 WH/T 的强制性条文上。一次完整重审,文档量轻松破两百页:机械的吊杆平面与荷载图、灯光的调光柜与 DMX512 布线图、音响的声场与提资图混在一个批次里,靠人肉翻页加手工记录,效率低且极易漏判。

后来我们把读图工具链自动化,本以为能一劳永逸,结果在长任务里踩到一个更隐蔽的坑:脚本"死"在中间。

典型死法有三种。

第一种,单页崩。一张图解析异常------比如矢量图层引用缺失、字体丢失、外部参照断链------未捕获的异常一路冒泡,整个批处理进程退出,前面跑完的几十张图全部作废,下次只能从头来。以某次灯光专业第 31 页(图号片段 ED2120K)为例,它因为矢量图层引用缺失抛异常,如果没有隔离,整批 66 张灯光图全得重跑。

第二种,假阳性洪流。自动核查把 200dpi 渲染默认值当成真实尺寸报出来,AI 智能体检查产出的信号清单里八成是噪声,人工筛一遍比自己读图还累。核查的价值不在于"报得多",而在于"报得准"。

第三种,齐套盲区。三专业图号混在一起,到底该有多少张、缺了哪张,没有人能秒答;经常是意见都写完了,才发现某个子项整页缺失,前面写的几百条意见基于一套不完整的图集。

这三种死法,本质上都不是"读图算法不准",而是"编排层没设计"------谁决定先跑谁、谁崩了怎么办、跑到一半怎么续,这些事没人管。算法再准,长任务里没有编排,脚本就活不下去。

于是我们换了一个思路------把读图工具链拆成 A(编排)→B(核查)→G(齐套)→C(成稿) 四段,用 manifest 派单+失败隔离+--resume 断点续跑,让脚本在长任务里自己活下去。

这句话是本文的灵魂,后面所有代码与实证都围绕它展开。它回答的不是"怎么读准一张图",而是"怎么让两百张图的读图任务在崩过、漏过、假阳性过之后,依然能自己跑到终点"。

需要明确边界:本文讲的是多段工具链的编排与断点续跑,属于编排层方法论,与"审图交付机器闸门"(单道闸门的逐条断言)和"多智能体审图实战"(单 agent 的对抗式审图)是明确不同的视角,请勿混读。闸门讲的是"单点判不判得过",本文讲的是"一长串任务怎么不死"。

二、四段机制:A→B→G→C 各自负责什么

四段不是四个独立脚本随意拼凑,而是一条用文件解耦、逐段落盘、彼此幂等的生产线。

A 段|编排(manifest 派单)

A 段不读图,只负责把任务摊开成可并行、可追踪的清单。manifest 是一张派工单,列出每张图要做的任务(读哪张、出什么、属于哪个专业)。A 段同时决定两个关键策略:失败隔离(单图失败不中断整批)与断点续跑(从已完成图继续不重跑)。

B 段|核查(AI 智能体检查)

B 段对每张已读图做规范核查:先过 R49 基线,再过 R28 三关------清单关(本页提资是否满足清单)、他图承载关(尺寸/荷载是否被其他图承载)、交叉矛盾关(与他图同一构件是否冲突),再叠加跨图比对。--strict 严模式用于压制假阳性,典型就是剔除 200dpi 渲染默认值带来的虚假尺寸信号。

G 段|齐套(齐全度自动比对)

G 段扫一遍所有 read.json,汇总出"实际读到的图号集合",再与"期望目录集合"比对,自动算出 EXPECTED 矩阵的齐全度百分比。缺哪张、多哪张,一眼可见。这一步必须排在成稿之前,否则写出的意见可能基于不完整的图集。

C 段|成稿(六列意见初稿)

C 段消费 B 段产出的信号清单,生成六列审查意见初稿 md:编号/位置/问题/建议/等级/复核。其中等级给建议(A-B-C-D 等级,即缺陷严重程度分级,A 最重、D 最轻),复核这一栏留空交人工终审。注意:C 段只产出 md 初稿,不展开文档排版细节。

四段之间用文件而非内存耦合:A 写 manifest 与 done.json,B 写每张图的信号 json,G 读这些 json 做集合比对,C 再读 B 的信号 json 出初稿。正因为每段都落盘、都幂等,--resume 才能成立------任何一段崩了,修好那一段重跑即可,已完成的段不动。

已落地的入口是一键串联:

bash 复制代码
python run_ab_pipeline.py --with-g --with-c --resume

这条命令按顺序跑完 A→B→G→C,并在任意中断后用 --resume 从断点续跑。

三、每段代码或伪代码

下面给出四段的核心片段,均可在工程中直接套用。

A 段:manifest 派单 + 失败隔离 + --resume

python 复制代码
# run_ab_pipeline.py 中的 A 段:编排层
import json, argparse
from pathlib import Path

MANIFEST = "manifest.json"  # manifest:派工单,列出每张图的任务

def load_manifest(p):
    return json.loads(Path(p).read_text(encoding="utf-8"))

def done_set(done_file):
    # --resume:读回已完成图集合,断点续跑不重跑
    if not Path(done_file).exists():
        return set()
    return set(json.loads(Path(done_file).read_text(encoding="utf-8")))

def read_one(img, task):
    try:
        return do_read(img, task)           # 单图失败隔离
    except Exception as e:
        print(f"[WARN] {img} 读图失败已隔离: {e}")
        return None                         # 失败隔离:返回 None,不中断整批

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--resume", action="store_true")    # --resume 断点续跑
    ap.add_argument("--with-g", action="store_true")
    ap.add_argument("--with-c", action="store_true")
    args = ap.parse_args()

    manifest = load_manifest(MANIFEST)
    done = done_set("done.json") if args.resume else set()
    finished = set()
    for item in manifest["items"]:
        img = item["img"]
        if img in done:
            print(f"[SKIP] {img} 已完成,跳过")
            continue
        r = read_one(img, item["task"])
        if r is not None:
            finished.add(img)
            # 每完成一张就落盘,保证任意时刻中断都可续
            Path("done.json").write_text(
                json.dumps(sorted(done | finished), ensure_ascii=False, indent=2))
    if args.with_g:
        run_G()
    if args.with_c:
        run_C()

配套的 manifest 派工单长这样:

json 复制代码
{
  "items": [
    {"img": "J23171.dwg", "task": "read_mechanical", "discipline": "机械"},
    {"img": "ED2120K.dwg", "task": "read_lighting", "discipline": "灯光"}
  ]
}

B 段:R49 基线 + R28 三关 + 跨图比对 + --strict

python 复制代码
# B 段:AI 智能体检查的前置核查
def check_R28(page, neighbors):
    sigs = []
    sigs += gate_checklist(page)                 # 清单关:本页提资满足清单
    sigs += gate_crossload(page, neighbors)      # 他图承载关:尺寸/荷载被他图承载
    sigs += gate_contradiction(page, neighbors)  # 交叉矛盾关:同构件跨图冲突
    return sigs

def run_B(page, neighbors, strict=False):
    base = check_R49_baseline(page)              # R49 基线:规范底线
    sigs = check_R28(page, neighbors)            # R28 三关
    if strict:
        sigs = drop_false_positive(sigs)         # --strict:剔除 200dpi 渲染默认值假阳性
    return base + sigs

G 段:齐套性自动比对

python 复制代码
# G 段:扫 read.json 汇总实际图号,与期望集合比对
def normalize(did):
    return did.strip().lower().lstrip("dwg-")    # 归一化:小写、去 dwg- 前缀

def check_completeness(read_dir, expected):
    actual = set()
    for f in Path(read_dir).glob("**/read.json"):
        data = json.loads(f.read_text(encoding="utf-8"))
        actual.update(normalize(d) for d in data.get("drawing_ids", []))
    exp = set(normalize(d) for d in expected)
    missing = exp - actual
    ratio = len(actual & exp) / max(len(exp), 1) * 100   # 齐全度%
    return {"actual": actual, "missing": missing, "ratio": round(ratio, 1)}

expected = set(json.loads(Path("expected.json").read_text())["ids"])
report = check_completeness("out/", expected)
print(f"齐全度 {report['ratio']}%,缺失:{sorted(report['missing'])}")

C 段:消费 B 信号清单产出六列初稿

python 复制代码
# C 段:B 的信号清单 -> 六列审查意见初稿 md
def draft_opinion(signals):
    lines = ["| 编号 | 位置 | 问题 | 建议 | 等级 | 复核 |",
             "| --- | --- | --- | --- | --- | --- |"]
    for i, s in enumerate(signals, 1):
        level = suggest_level(s)                # 等级建议:A-B-C-D 等级
        lines.append(f"| {i} | {s['loc']} | {s['issue']} | {s['fix']} | {level} |  |")
        # 复核这一栏留空,由人工终审填写
    return "\n".join(lines)

def suggest_level(s):
    # A-B-C-D 等级:结构/安全类给 A,一般违规给 B,提示类给 C/D
    return {"critical": "A", "major": "B", "minor": "C", "tip": "D"}.get(s["sev"], "C")

C 段只到 md 初稿为止;六列表格后续的文档化排版不属于本篇范围,本文不展开。

四、实证数据:某城市交响音乐厅 218 页三专业重审

最近一次实战落地的场景是一家城市交响音乐厅(项目名已泛化,不出现真实地名与编制单位)的三专业重审。读图工具链被工程化编排后,单批处理规模达到 218 页:机械专业 99 页、灯光专业 66 页、音响专业 53 页(图号仅保留技术性片段如 J23171、ED2120K 作教学样本,不具身份识别性)。

这次重审有几个可被验证的结果。

第一,断点续跑真正救了场。重审当日,灯光专业第 31 页(图号片段 ED2120K)因矢量图层引用缺失抛异常。由于 A 段做了失败隔离,该页被标记为隔离、其余 217 页正常跑完;修复该页字体引用后用 --resume 续跑,仅重跑了 1 页,没有让整批 218 页推倒重来。

第二,齐套性比对提前暴露缺口。G 段跑完,齐全度显示为 96.3%,缺失 8 个图号;人工核对后发现其中 3 个属于本轮暂不交付、5 个确实漏提。意见成稿前就把缺口摆到桌面上,避免了"写完两百多页意见才发现少了 8 张"的尴尬。

第三,精力从"救火"转向"编排"。重审团队当日的轮次权重相对估算(注意:这是相对权重,非绝对工时;AI 智能体的处理时长本身不可证伪,本段数字仅作方法演示,不代表真实人日)显示,用于"修脚本/救崩批"的时间占比从以往的约 40% 降到约 12%,腾出的权重转向 manifest 设计与信号清单的精读------也就是从"让脚本别死"升级到"让脚本跑得对"。

需要强调的是:上述"轮次权重"是相对估算,不是可审计的工时;AI 智能体的处理时长不可证伪,任何号称"省了 N 人日"的绝对表述都应打问号。本文只承诺方法可被复现,不承诺具体节省数字。

五、踩坑:四个最值得记的坑

下面按"现象 / 成因 / 解法"记录实战里踩过的坑。

坑一:失败隔离不做落盘,--resume 就成摆设

  • 现象:加了 try/except 单图失败不崩了,但崩在中间断电或手动杀进程后,done.json 没更新,--resume 从头跑。
  • 成因:done 集合只在进程末尾写盘,中途退出全部丢失。
  • 解法:每完成一张就追加写盘(见 A 段代码 Path("done.json").write_text(...) 在循环内),保证任意时刻中断都可续。

坑二:--strict 不开,信号清单被 200dpi 假阳性淹没

  • 现象:B 段不开启严模式时,把 200dpi 默认渲染分辨率当成真实像素尺寸,报出大量"尺寸不符",人工筛信号比自己读图还累。
  • 成因:栅格化渲染默认值被误当作矢量真实尺寸。
  • 解法:重审场景默认开 --strict,先压假阳性;确需保留疑似项的,单独建宽松通道复核,不混进主信号清单。

坑三:G 段图号大小写/前缀不一致,齐全度算错

  • 现象:期望目录写的是 J23171,read.json 里是 j23171 或带前缀 DWG-J23171,集合比对直接判缺。
  • 成因:图号字符串未归一化。
  • 解法:比对前统一小写、剥离 dwg- 前缀再入集合(见 G 段 normalize);EXPECTED 矩阵与 read.json 用同一归一化函数,避免"同图不同名"。

坑四:C 段等级建议过严,A 级泛滥

  • 现象:suggest_level 初版把"提示类"也标 A,意见初稿满屏 A 级,失去了分级意义。
  • 成因:严重度映射阈值没校准。
  • 解法:A 级只留给结构/安全类硬冲突,提示类落到 C/D;等级是建议,复核这一栏始终留空交人工终审。

六、可迁移结论:让脚本"活下去"的四条通则

第一条,长任务先设计编排层,再谈算法精度。任何会跑几百次的批处理,第一件事不是"读准",而是"崩了怎么办、断了怎么续"。manifest 派单+失败隔离+--resume 是三件套,缺一不可。

第二条,段间用文件解耦,幂等落盘。A/B/G/C 每段都落盘、都幂等,--resume 才能成立。内存里传对象看似快,崩一次全没。

第三条,严模式默认开,假阳性是长任务最大的隐性成本。AI 智能体检查的价值不在"报得多",而在"报得准"。--strict 压住 200dpi 这类默认值假阳性,信号清单才有人愿意读。

第四条,齐套性要前置到成稿前。G 段不跑,C 段写得再漂亮也可能基于不完整的图集。齐全度百分比是最便宜的"你漏了没"提醒。

把这四条放回舞台工艺审图:机械的吊杆荷载、灯光的调光柜与 DMX512 链路、音响的声场提资,三专业图号混在一起时,编排层比任何单点算法都更能决定一次重审能不能在当天收口。脚本自己活下去,审图团队才能把精力从"救火"挪到"编排"------这正是 A+B+C+G 四段流水线想交付的东西。

相关推荐
小奶包他干奶奶2 小时前
AI学习——1、机器学习概念
人工智能·机器学习
展讯快报2 小时前
悬浮提词器免费App评估报告:说得AI的免费策略与可用性分析
人工智能
Yuzhiyuxia2 小时前
【AI Agent面试系列】AI Agent记忆机制知识点1
人工智能·面试·职场和发展
2601_965448872 小时前
AI视频制作:做系列历史人物视频音色不搭,AI 音色克隆的方法实测
人工智能·音视频
2分钟速写快排2 小时前
ggg! 潜行摸鱼被 Trae 爆改成 3D!
人工智能·程序员·数据可视化
“AI国潮设计-小江”2 小时前
【AIGC实战】Python+Stable Diffusion打造“英歌舞财神”IP,解锁“马到成功”等爆款情绪营销文案设计
开发语言·人工智能·python·prompt·aigc
明志数科2 小时前
实景数据与训练场数据的分布差异:机器人操作数据的分层采集与工程边界
人工智能
zhippt_10142 小时前
汇报总结PPT怎么做更快?5款AI生成PPT工具实测横评
人工智能·powerpoint