炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会!
(来源:科技行者)
2023年,某家做工业自动化研究的团队做了一件挺较真的事:他们把市面上几种号称能自动生成PLC控制代码的AI方法拿来测,结果发现一个扎心的事实——这些代码在静态检查阶段全都"看起来差不多",分数差距不超过10分。可一旦真的把代码部署到PLC硬件上跑起来,差距瞬间从10分拉大到接近30分。
这意味着什么?意味着那些被认为"写得还不错"的代码,有相当一部分根本经不起真实运行的考验。
这就是今天要聊的这篇论文,来自美的AIRC联合库卡、上海交大、浙江大学的团队,他们做了一个叫SemaPLC的系统,专门解决这个问题。
工厂的大脑,谁来写代码
先说说PLC是什么。
可编程逻辑控制器*:一种专门用来控制工厂设备的小型计算机,负责让传送带该转的时候转、阀门该开的时候开、温度超标了就报警停机。工厂里几乎所有自动化设备背后都有一个PLC在盯着。
PLC的代码主要用一种叫Structured Text(结构化文本,简称ST)的语言写,这是IEC 61131-3标准里的一种编程语言,长得有点像Pascal。过去几年,大语言模型(LLM)已经能写出不错的独立程序单元了,行话叫POU。
POU(Program Organization Unit,程序组织单元)*:PLC程序里最小的功能模块,类似于普通编程里的一个函数或类,比如"电机控制模块""阀门控制模块"。
问题是,现实中的PLC代码从来不是孤零零地存在的。一个真实的工厂项目,可能有几十个模块相互调用,共享变量,遵守着这个项目自己的一套命名规则和安全约定。AI写出一个能独立编译通过的POU相对容易,但要把这段代码塞进一个已经运行了很多年的老项目里,让它和周围的代码和睦相处、正确协作,这是完全不同量级的难题。
打个比方。让一个新来的实习生独立写一份报告,你审核一下格式和逻辑,基本能判断合格不合格。但如果让这个实习生往一份正在运行的财务系统里插入一段新代码,这段代码要读取系统里已有的变量、调用已有的函数、还不能破坏系统原有的运算逻辑,那审核的难度完全不是一个级别。你不能只看这段代码本身写得好不好,还得看它跟整个系统"处不处得来",更要紧的是,得真正跑起来试试,不然表面上兼容,实际跑起来可能哪个环节就崩了。
如果不做这后一步验证会怎样?论文里给出了答案:那些静态检查阶段看起来相安无事的方法,真正跑起来的时候,动态表现分数最低只有22.4分(满分100),而最好的基线方法也只有31.4分。差了将近10分,这背后可能就是某个定时器配置错了,某个联锁条件漏判了,某个复位逻辑没触发。这些错误在纸面审查时根本看不出来。
三道关卡:说明书、编译器、真实运行
SemaPLC这套系统的核心思路,说白了就一句话:不许AI自己说"我写完了",必须拿出外部证据证明写完了。
这句话听起来简单,但背后有一整套设计。
这套系统设立了三层验证关卡。第一层是规格检查,第二层是编译检查,第三层是活体运行时验证。
规格检查(Specification Check)*:把生成的代码逐条对照原始需求文档来审查,检查每个提到的设备信号有没有被处理、边界条件对不对、互锁逻辑有没有漏掉。这一步专门抓那些"编译器不报错,但压根不符合需求"的问题。
编译检查(Compilation Check)*:常规的语法、类型、符号、接口检查,看代码能不能正常编译通过,能不能整合进已有项目的构建流程里。
活体运行时验证(Live Runtime Validation)*:把生成的代码真正部署到一个PLC运行环境里,注入模拟的输入信号(比如"温度传感器读数是30度"),然后观察输出信号的变化轨迹,跟一份"标准答案"的运行轨迹做比对。
**这三层验证不是并列关系,而是层层递进的过滤网,能编译不代表符合需求,符合静态检查不代表运行正确。**
论文里举了一个特别典型的案例。任务要求是这样:当某个流量计读数低于50kg/hr时,某个设定值要变成500;但如果这个流量计本身坏了(故障状态),设定值要变成2500,而且故障情况的优先级更高。
结果呢,一个叫Agents4PLC的对比方法写出的代码能编译通过,逻辑上看起来也说得过去,它先写了"如果故障,设为2500",然后又写了一段独立的"如果流量低于50,设为500"。问题是,如果故障发生的同时流量恰好也低于50,这两段代码会先后执行,后面那句就把前面的2500覆盖掉了,最终结果变成500,跟需求要求的2500正好相反。
这种错误,肉眼看代码几乎发现不了,编译器更不会报错,因为语法完全正确。只有真正跑一遍,让流量计"坏一次",观察输出到底是500还是2500,才能揪出这个bug。
SemaPLC自己写的第一版候选代码其实也犯了类似的错误,用一个静态值同时服务两种情况。但因为有运行时验证这一关,系统强行模拟了"流量降到30kg/hr"这个场景,发现期望值是500,实际输出却是2500,立刻定位到问题,把代码改成按故障原因分别赋值,重新验证后才通过。
**只有SemaPLC的方案在最后真正做到了运行时验证通过,其余几个基线方法要么编译都过不了,要么编译通过但行为是错的。**
这个案例其实揭示了一个更深的道理:代码审查能抓住"写得对不对",但抓不住"跑得对不对"。这两者的差距,恰恰是工业控制系统里最要命的部分,因为PLC控制的是真实的机器、真实的阀门、真实的电流,一旦逻辑在某个边界条件下失灵,后果可能是设备损坏甚至安全事故。
编辑一次,所有验证结果全部作废
光有三层检查还不够,SemaPLC还设计了一套很严格的"生效机制",这套机制里有三条铁律。
第一条叫有限重试。每一项检查最多允许两轮修复尝试,不能无限循环下去耗资源。
第二条叫编辑作废,这是我觉得设计得最巧妙的一条。系统规定,只要代码被修改了哪怕一个字节,之前所有检查结果全部失效,必须重新跑一遍全部检查流程。
想象你在给一份重要合同做审核,法务、财务、业务三个部门分别签字确认没问题。这时候有人偷偷改了合同里的一个数字,如果不重新走一遍三个部门的审核流程,直接用之前的签字盖章,这份合同的"合规"就是假的,那三个签字对应的根本不是现在这份文件。SemaPLC的编辑作废机制,就是不允许这种"偷梁换柱"式的信任延续,任何改动都必须重新挣得每一项验证结果。如果不设这条规则,系统很可能在修复某个bug的同时引入新bug,而这个新bug因为绕开了重新验证,永远不会被发现。
第三条叫"挣得的证明"。每一个通过的验证结果,都必须有工具日志作为证据,日志里记录的字节内容要跟最终交付的代码完全对得上。如果AI自己声称"这项检查通过了"但日志里找不到对应记录,这个声明会被直接降级为"未检查"。
**这三条规则合起来,保证了交付的代码就是真正拿到全部通过验证的那份代码,不存在AI自我夸大战绩的空间。**
这套机制的设计哲学,其实反映了一种对AI系统的不信任态度,但这种不信任是有道理的。大语言模型天然有一种倾向,倾向于觉得自己完成的任务是完成了的,这种自我评估的可靠性在工业场景里是不够的。SemaPLC的做法相当于把"你自己觉得对不对"这件事,完全交给外部的、客观的、可复现的工具日志来判断,AI的角色从"裁判自己的比赛"变成了"必须拿到裁判签字才能离场的选手"。
项目落地:不是从零写一个工厂,而是往老项目里插代码
前面提到的独立POU生成,论文里称为"函数轨道"(function track),用的是117个独立任务,方便跟已有的研究成果做对比。但研究团队还搭建了另一条更贴近现实的评测轨道,叫"项目上下文轨道"(project-context track),一共65个任务,来自十个真实工业厂区的控制场景,数据来源于一个叫Spec2Control的项目转换库。
这条轨道要求生成的代码不是凭空造一个新系统,而是要理解已有项目的结构,找到自己该往哪个模块插入代码,重用已经定义好的变量和功能块,不能随意重新定义已有的接口,还得遵守整个项目原有的构建、复位、初始化、安全惯例。
这就好比一个新装修工人接手一套已经住了十年的老房子,要在厨房加装一个新的智能插座。你不能把整面墙拆了重新布线,你得搞清楚原有的电路走向,找到合适的接入点,还得保证新插座跟原有的跳闸保护、漏电保护是兼容的,不能因为加了个插座导致整个房子的用电系统出问题。如果图省事直接从零布一套新电路,虽然新插座本身能用,但极可能跟老房子的其他电路产生冲突,甚至埋下火灾隐患。
这条轨道用三个独立的分数来衡量结果:能不能编译整合进项目(整合编译)、静态断言检查通不通过(静态行为)、真实部署运行后跟标准答案对不对得上(动态行为)。
结果非常能说明问题。
| 方法 | 整合编译均值 | 静态行为均值 | 动态行为均值 |
| LLM4PLC | 58.7 | 75.7 | 22.4 |
| AutoPLC | 81.5 | 74.0 | 31.4 |
| Agents4PLC | 71.2 | 71.7 | 30.3 |
| **SemaPLC** | **89.4** | **81.6** | **52.2** |
看这张表,静态行为那一列,四个方法的分数挤在71.7到81.6之间,差距不算特别夸张。但动态行为那一列,差距瞬间拉开:三个基线方法都在22到31之间徘徊,SemaPLC却达到了52.2,几乎是最好基线的1.7倍。
这个结果印证了论文标题里那句话的分量:静态打分和真实运行,测的根本是两码事。一个方法在静态审查里表现平平,不代表它在真实运行里必然差,但反过来,静态审查表现好也完全不能保证真实运行没问题。评测如果只停在"能不能编译""看起来符不符合规范"这一层,是没办法把真正靠谱的方法和金玉其外的方法区分开的。
验证的钱花在哪儿了
有人可能会问,做这么多验证,会不会特别费时间费资源?
论文里专门算了这笔账,而且答案还挺反直觉。
在独立POU的函数轨道上,SemaPLC用的模型请求次数跟最强基线Agents4PLC差不多(6.5次 vs 6.3次每任务),但耗时反而更短(71秒 vs 454秒)。原因是Agents4PLC每一轮迭代都要调用一次很重的形式化验证工具(PLCverif配合nuXmv模型检测引擎),这个过程本身极其耗时,拖慢了整体节奏。
但在项目上下文轨道上,情况反过来了。总耗时两者接近(347秒 vs 344秒),可SemaPLC用的请求次数是对方的近5倍(34.1次 vs 6.9次)。这是因为Agents4PLC采用的是固定流程的多智能体架构,不管遇到什么情况,迭代轮数基本是设定死的,跨模型波动很小(6.8到7.0之间)。而SemaPLC采用的是开放式循环,每一次要不要继续调用工具、要不要继续修复,都是模型自己临场判断的,验证关卡会一直逼着它交互,直到真的通过检查为止,所以不同能力的模型消耗的请求数差异很大(16.4到60.4之间)。
这其实揭示了一个设计取舍:固定流程省心省钱,但对复杂场景的适应力有限;开放式循环能根据任务难度自动调整投入,但代价是消耗更难预测。SemaPLC选择了后者,因为它更看重"确保交付质量"这个目标,愿意为难啃的任务多花几轮交互。
定时器,是模型检测工具的软肋
论文里还有一个挺有意思的技术细节,值得单独说说。
研究团队分析了独立POU评测里使用的形式化验证工具(PLCverif配合nuXmv),发现这套工具在处理不同类型的代码时,能给出确定结论的比例差异巨大。
不含实数变量和定时器的普通程序,916个里有75.7%能得到确定的验证结论(满足或者违反)。含有实数变量的程序,确定结论的比例升到87.0%。但一旦程序里包含TON定时器(PLC里最常用的一种延时定时器),32个程序、174条待验证属性,确定结论的比例是——0%。全部都是"无法判断"。
TON定时器*:Timer On Delay的缩写,一种延时接通定时器,常用于"按下按钮后延迟5秒再启动电机"这类场景,在工业控制里极为常见。
这个数字挺惊人的。也就是说,只要你的PLC代码里用到了最常见的定时器逻辑,现有的形式化验证工具基本就帮不上忙了,因为定时器涉及跨多个扫描周期的状态演变,这种时间维度上的复杂性超出了当前模型检测工具的处理能力。
这恰恰是论文强调运行时验证价值的地方。**形式化验证在理论上很优雅,但遇到定时器这类跨时间的状态逻辑就会大面积失效,而这些正是运行时验证最擅长直接观测的部分。**
这就好比理论物理学家可以用公式精确推导一个球从斜坡滚下的轨迹,但如果这个球滚进了一片布满不确定障碍物的树林,公式推导就不管用了,你只能真的把球放进去,看它到底怎么滚。定时器逻辑就是PLC世界里那片"树林",跨越时间的状态变化太复杂,数学证明束手无策,只能靠真刀真枪地跑一遍来验证。
换了模型,结论还成立吗
这套系统会不会只对某一个特定的AI模型有效?
研究团队在七个不同的大模型上都做了测试,包括MiniMax、Qwen、DeepSeek、GLM、GPT等主流模型家族,覆盖了不同能力档位。
在独立POU的函数轨道上,SemaPLC在全部七个模型上都拿到了最高的严格验证通过率,平均72.6%,比最强基线Agents4PLC的63.9%高出8.8个百分点。更关键的是稳定性:SemaPLC表现最差的那个模型(67.5%),依然超过了所有基线方法的平均分。基线方法的分数跨度在25到31分之间波动,而SemaPLC的跨度只有14.6分,说明这套验证机制确实起到了"托底"的作用,不管底层模型强弱,都能把结果拉到一个较高的水平线之上。
论文还专门做了一个"裸奔对照"实验,把SemaPLC身上的技能库和工具全部拆掉,只留下最基础的循环框架,叫作bare配置。结果显示,每个模型接上完整版SemaPLC之后都有明显提升,提升幅度在8.5到33.3个百分点之间,而且提升最大的往往是原本能力较弱的模型,比如DeepSeek-V4-Flash直接从裸奔状态提升了33.3个百分点。这说明这套验证机制更像是一层通用的可靠性保障,而不是针对某一个模型精心调过的提示词技巧。
不过论文也很坦诚地指出了一个局限:在最强的模型GPT-5.5上,SemaPLC的领先优势会明显收窄。在项目上下文轨道的动态行为得分上,SemaPLC领先Agents4PLC只有1.8分(65.4 vs 63.6),甚至在静态行为得分上还落后于部分基线方法。这说明当底层模型足够强的时候,它自己写出靠谱代码的能力已经比较高了,验证机制能补上的短板相应变小。这也侧面证明了这套系统的价值定位:它是补足模型能力短板的保险机制,模型越弱,这份保险的价值越大。
这篇论文的评测数据从哪儿来的
一个容易被忽略但其实很重要的细节是,研究团队在数据准备阶段做了不少扎实的基础工作。
独立POU任务用的117道题,来自另一篇叫Agents4PLC的论文公开的评测基准。但研究团队发现,原始的验证标准(oracle)里存在不少缺陷,包括错误的常数或极性、自相矛盾的断言、跟设计意图相悖的属性、凭空捏造的阈值、复制粘贴导致的重复项。他们组织PLC工程师做了三轮审核:第一轮独立并行审查标出可疑问题,第二轮从零重新推导每一个标记项(布尔逻辑用真值表暴力验证,状态机用逐步模拟验证),第三轮盲审裁定分歧。最终在117个任务里确认了43个存在缺陷,修复了53个样本。
项目上下文轨道的65个任务,数据来自Spec2Control项目里的十个真实工厂场景。研究团队专门做了一次查重审计,确认AI生成的任务包和各方法的运行记录里,没有出现跟隐藏参考答案逐字重复的内容,排除了"AI偷看答案"的可能性。
这种对基准数据本身较真的态度,其实反映了一种研究伦理:如果评测标准本身有bug,那么无论方法多先进,测出来的分数都是不可信的。这个细节虽然不算论文的核心贡献,但恰恰是让整篇论文的结论站得住脚的地基工作。
Q&A
Q1:SemaPLC是什么?
A:SemaPLC是一个由美的AIRC、库卡等机构联合研发的AI代码生成系统,专门用来给PLC(可编程逻辑控制器)生成控制代码。它最大的特点是不允许AI自己判断代码写完了,必须通过规格检查、编译检查、真实运行时验证这三层外部关卡确认通过,才算任务完成。
Q2:SemaPLC和其他PLC代码生成方法相比,优势在哪?
A:最大的优势体现在真实运行环节。论文实验显示,静态检查阶段各方法分数差距不到10分,但真实部署到PLC上运行后,SemaPLC的动态行为得分达到52.2分,而其他基线方法最高只有31.4分,差距接近一倍,说明其他方法生成的代码有不少在实际运行时会出错。
Q3:为什么PLC代码光靠编译通过还不够,一定要做运行时验证?
A:因为很多逻辑错误编译器根本发现不了,比如两段代码执行顺序导致某个赋值被意外覆盖,这种问题只有让代码真正跑起来、模拟各种输入场景(比如传感器故障)才能暴露出来。论文中的案例显示,一段能正常编译、逻辑看似合理的代码,在故障场景下输出了完全相反的结果,只有运行时验证才抓住了这个bug。