【文献笔记】LLM-based and retrieval-augmented control code generation
LLM-based and retrieval-augmented control code generation
原文代码
标题翻译:基于语言模型与检索增强的控制代码生成
1. 内容介绍
1.1. 背景
- 工业自动化中的控制代码:
- 控制代码:在工业自动化中,控制代码用于管理如发电厂、化工过程或钢铁生产等复杂系统。这些系统依赖传感器采集数据(如温度、压力、流量),通过可编程逻辑控制器(PLC)周期性执行控制逻辑(例如每250毫秒一次),并向执行器(如泵、电机、阀门)发送控制信号。
- 编程语言:控制逻辑通常使用IEC 61131-3标准中的Structured Text(ST)语言编写。ST类似于Pascal和C,支持条件语句、循环、面向对象编程等特性。
- 功能块(Function Blocks)库:控制工程师常使用功能块库(如OSCAT库),这些库包含数百个预定义的功能块,用于数学运算、逻辑处理、信号处理等。功能块提高了代码复用性,但其具体实现通常是专有的,工程师只能通过参考文档了解其接口和功能。
一个用于数学函数计算的简单功能块规范示例
1.2. 现有挑战
- 手动编程耗时:控制工程师需要根据过程工程师提供的控制叙述(Control Narratives,自然语言描述的控制策略)手动编写代码,涉及从叙述中提取需求、选择合适功能块并实现逻辑。这个过程效率低下。
- LLM的局限性:虽然大型语言模型(如GPT-4)能够生成通用ST代码,但它们对专有功能块库缺乏了解,无法直接生成整合这些功能块的代码。
1.3. 目标
作者提出了一种自动化方法,利用LLM和RAG技术,从控制叙述生成整合专有功能块的IEC 61131-3 ST代码,以提高编程效率。
2. 检索增强控制代码生成方法
2.1. 概览
2.1.1. 方法概述
- 输入:功能块规格说明(Function Block Specifications,通常为PDF或HTML文档)和控制叙述(自然语言描述的需求)
- 输出:符合IEC 61131-3 ST标准的控制代码,可导入PLC开发环境(如CODESYS、OpenPLC)
- 核心思想:利用RAG技术,将功能块规格说明嵌入向量存储库中,通过相似性搜索增强LLM的生成提示,从而生成整合功能块的代码
2.1.2. 详细步骤拆分
2.1.2.1. 向量库构建
- 步骤a:文档加载(Document Loader):
从功能块规范库(PDF、HTML)中提取内容,使用LangChain等框架支持的加载器(如PyPDF、PDFPlumber)处理不同格式的文件;大多数功能块库分为多个模块,每个模块有单独的文档,在这种情况下,文档加载程序会遍历每一个文件 - 步骤b:文档分块(Document Chunker):
将文档分割成小块,每块包含单个功能块的完整描述(包括输入输出参数、功能说明),同时保证内容适合LLM的上下文窗口(有语义完整性) - 步骤c:文本嵌入与向量存储(Text Embedder & Vector Store):
使用文本嵌入模型将分块后的文档编码为浮点数向量,存储在向量数据库(如FAISS、Pinecone)中,优化相似性搜索,支持基于余弦相似度或欧几里得距离的查询
2.1.2.2. 控制代码生成
-
1:控制叙述提取(Control Narrative Extractor)
从控制叙述中提取简洁的代码生成提示词,通常针对单个控制回路,包含设定点、报警限值、控制序列等信息。(提示词示例:“编写一个IEC 61131-3 ST程序,使用PID控制器,设定点为5.0,整合预定义功能块。”)
-
2:向量存储检索(Vector Store Retriever)
将提示词编码为向量,使用向量存储进行相似性搜索,检索相关的功能块规格说明;使用了不同的搜索技术(如最大边际相关性MMR)提高结果多样性,避免冗余(提示词向量化示例)
-
3:提示增强与代码生成
将检索到的功能块规格说明附加到原始提示中,形成增强的提示词;然后根据提示词使用LLM生成包含功能块实例化的控制代码(示例输出:包含功能块声明、参数配置和逻辑连接的ST代码)
- 4:代码导入
将生成的代码导入对应的集成开发环境(如OpenPLC),支持进一步编辑、编译、模拟和部署
3. 原型实现
3.1. 配置选择
- 框架:LangChain,用于管理LLM、文档处理和检索链。
- 功能块库:OSCAT BASIC(开源,496页PDF,含400+功能块),因其复杂性接近商业库且未包含在GPT-4训练集中,确保实验透明性和可重复性。
- 文档加载器:PDFPlumberLoader,将PDF页面加载为字符串,支持元数据提取。
- 文档分块器:基于正则表达式的自定义分块器,按OSCAT文档的编号结构分割功能块描述。
- 文本嵌入模型:OpenAI的text-embedding-ada-002,能生成1536维向量,上下文窗口达到8192个token 。
- 向量存储:FAISS-CPU 1.7.4,本地向量数据库,存储4.5MB嵌入数据,支持高效相似性搜索。
- LLM:GPT-4-32k(版本0613),温度设为0以确保输出确定性。
- PLC开发环境:OpenPLC-Editor,支持ST代码编辑、编译和调试。
- 用户界面:Streamlit,显示生成代码和相关功能块文档的缩略图,便于验证。
3.2. 通用提示词模板
提示模板可根据不同PLC开发环境调整,以支持特定IEC 61131-3特性,基本包含:
- 要求生成功能块而非完整程序,便于嵌入其他代码
- <query>放所需逻辑的描述
- 要求使用增强的功能块规格说明,忽略注释,并且遵循标准输出结构
4. 实验
作者通过三个测试评估了方法的有效性,目标是验证生成代码的正确性和功能性
4.1. 测试1:采样和平均
- 提示词<query>: 对输入信号每秒采样一次,计算最近8个采样点的均值
- OSCAT库提供的功能块(RAG的内容):SH_1(采样功能块),FT_AVG(均值计算功能块)
-
代码生成结果
- 正确调用SH_1,并设置1秒采样间隔
- 调用FT_AVG计算均值
- 问题:由于OSCAT文档未明确列出SH_1的输出参数“OUT”,GPT-4错误使用了OUT_MAX;FT_AVG输出变量命名错误
修正:手动将OUT_MAX改为OUT,调整FT_AVG输出变量为AVG
-
验证:修正后导入OpenPLC,编译成功且结果正确
- 导入OpenPLC,包含依赖功能块(TPLC_MS、DELAY、INC1)
- 编译成功,模拟运行100秒
- 输入信号从10.0变为20.0,输出均值在8个间隔后正确达到20.0
4.2. 测试2:正弦波与阶梯函数
- 提示词<query>:“生成周期10秒、幅度10、偏移5、延迟0的正弦波,将其输出作为阶梯函数的输入,阶梯步长2.3。”(想测试一下能不能集成更复杂的功能块)
- 功能块库:有两种正弦波生成器和阶梯函数,想看看最后生成的代码会选择哪一个
-
代码生成结果
- 正确选择并实例化GEN_SIN。
- 问题:错误将STAIR视为功能块而非函数。
修正:手动移除STAIR实例化,改为函数调用
-
验证:修正后导入OpenPLC,编译成功且结果正确
- 导入OpenPLC,包含依赖函数(GCNT、FLOOR2、SIGN)
- 编译成功,模拟显示正弦波和阶梯函数输出
4.3. 测试3:PID控制器
- 提示词<query>:“为硝酸铵反应器创建带动态防饱和和手动控制的PID控制器,设定点180.0,Kp=50.0,Ki=1.2,Kd=10.0,限值-100到+100,10秒后切换到自动模式。”
- 功能块库:CTRL_PID(PID控制器),TON(IEC 61131-3标准定时器)
-
代码生成结果
- 正确选择CTRL_PID和TON,设置参数。
- 正确地将提示中的kd、kp和ki参数转换为CTRL_PID块所需的参数
- 正确连接定时器和PID控制器
-
验证:
- 导入OpenPLC,添加模拟温度曲线逻辑
- 编译成功,模拟运行
- PID控制器在10秒后切换到自动模式,温度稳定在180°C,调整设定点到100°C后正确响应
5.1. 实验结论
- 成功点:方法能够正确检索复杂功能块,生成整合功能块的代码,代码可编译并通过模拟验证。
- 局限性:
- 文档不完整(如参数未明确列出)可能导致生成错误,需手动修正。
- 测试为点样本(Spot Samples),未全面评估生成质量或效率。
6. 有效性探讨
6.1. 内部有效性
内部有效性是指确立对自变量的操控(即控制叙述、功能块规格和内部系统参数)与因变量变化(即生成的控制代码质量)之间的因果关系。
- 问题:LLM的非确定性输出可能影响代码一致性;未识别的干扰变量可能影响结果
- 缓解措施:
- 设置温度为0,减少随机性
- 编译和执行代码,初步验证质量
6.2. 构造有效性
实验中的测试在多大程度上能够准确评估此方法
- 问题:提示较为简单,未完全代表复杂控制逻辑;OSCAT库和OpenPLC可能不完全反映商业环境
- 解释:OSCAT库复杂性接近商业库,OpenPLC包含必要功能
6.3. 外部有效性
外部有效性指的是将该方法转移到其他背景和环境的潜力
-
可推广性:
- 方法独立于OSCAT库,适用于其他功能块库
- 支持多种工业自动化领域(如化工、电力)
- 可通过转换工具支持其他IEC 61131-3编程语言
-
未来工作:验证更复杂库和功能块,测试不同领域应用
7. 结论
这篇文献展示了一种创新的控制代码生成方法,结合了LLM的生成能力和RAG的知识检索能力,解决了传统LLM无法处理专有功能块的问题。实验结果表明,该方法在生成可编译、可运行的ST代码方面具有潜力,尽管仍需手动修正某些错误。未来通过更广泛的测试和优化,该方法有望在工业自动化中得到实际应用。
7.1. 主要贡献
- 方法创新:提出了一种RAG-based方法,自动化生成整合功能块的IEC 61131-3 ST代码。填补了LLM在工业控制代码生成中的空白,特别是在整合专有功能块方面。
- 效率提升:通过自然语言提示快速生成代码,减少手动编程时间,支持批量生成代码,工程师仅需专注于验证和优化。
- 灵活性:支持专有功能块库,兼容现有PLC开发环境,适用于化工、电力、制造等多个工业领域。
- 实验验证:通过开源工具(OSCAT、OpenPLC)和原型实现,证明方法可行性,提供了可重复的实验框架(开源代码、OSCAT库),推动后续研究。
7.2. 未来工作
计划将该方法应用于商业功能块库和PLC编程环境,将通过更全面的实验测试该方法的代码生成能力,包括不同类型控制逻辑生成提示及多样功能块的测试。若实验成功,将进一步探究该方法在非交互式批量运行中的潜力与局限性。