当前位置:   article > 正文

利用大语言模型(KIMI)生成OPC UA 信息模型

利用大语言模型(KIMI)生成OPC UA 信息模型

       在大语言模型没有出现之前,人们更倾向使用图形化工具或者基于窗口的软件来构建信息模型,图形化工具能够直观地表达信息模型中各元素之间的相互关系。但是图形化工具也有缺点,当描述一个复杂的信息模型时,图形会变得非常复杂和庞大。而且图形通常难以修改,复制和重用。基于CAD软件设计工程模型是非常耗费精力的“体力活”,加班熬夜的工作都是在CAD 软件的界面前渡过的。

    但是,如果使用形式化语言来描述信息模型也并不轻松。形式化语言的语法有严格的规则,文档编排的主要精力都耗费在语法的检查和排错,而模型的构建只是极少的一部分。

    以chatGPT为代表的大语言模型(LLM)出现,给构建信息模型提供了新的高效率方式,使用自然语言描述信息模型描述信息模型,如同AI 生成程序设计语言一样令人向往。

     在传统计算机信息系统中,形式语言通过形式化方式描述语法,例如计算机语言使用BNF范式(巴科斯范式)描述语言,XML 使用了Schema 描述格式,而JSON 模型使用模板描述模型。

      目前chatGPT 还没有直接理解BNF 范式的能力,它通过模板来学习和生成语言的。因此,为了让chatGPT 大模型生成形式化信息模型,需要为chatGPT 提供各种模板。

     另一方面,形式化信息模型是为机器设计的,是一种相对底层的语言,为了能够使用自然语言描述模型,设计一种“高级"的中间语言更加方便。

利用大语言模型生成OPC UA 信息模型

中间语言的选择

  1. JSON
  2. XML

模型的规范

        OPC UA 信息模型的描述语言是XML语言。格式为NodeSet2.xml。NodeSet.2.xml 文件能够直接导入OPC UA 服务器。

     NodeSet2 文档十分繁琐,不适合人阅读和程序生成,为此,OPC UA 基金会开发了一个UAModelCompiler 程序,该程序使用一种DesignModel.xml 文档格式,UAModelCompiler 软件能够将DesignModel 文档转换成为NodeSet.xml 文档和C#的类定义。

例子:对象类型的定义。

  1. <opc:ObjectType SymbolicName="GenericControllerType" BaseType="ua:BaseObjectType">
  2. <opc:Description>A generic PID controller</opc:Description>
  3. <opc:Children>
  4. <opc:Property SymbolicName="Measurement" DataType="ua:Double" />
  5. <opc:Property SymbolicName="SetPoint" DataType="ua:Double" AccessLevel="ReadWrite" MinimumSamplingInterval="1" />
  6. <opc:Property SymbolicName="ControlOut" DataType="ua:Double" />
  7. </opc:Children>
  8. </opc:ObjectType>

我们在实验中选择了DesignModel 的规范来定义OPCUA 的模型。

基于ModelDesign的模型生成

模板的构建 

        为了让chatGPT 能够理解模型的规范,需要提供模型的模板(templates),而不是schema。模板的格式是有一些讲究的。

  1.    添加注释
  2.   模板中的内容也是提示

        我们 曾经尝试将UAModelCompiler 项目中的SampleDesign.xml (一个ModelDesign 的例子)上传给kimi,但是kimi无法构建模型。

模板的例子

实验中构建了一个基于ModelDesign格式的XML模板。

  1. <! Object template -->
  2. <Object SymbolicName="Name" TypeDefinition="TypeDefinition">
  3. <Children>
  4. <! elements of The Object -->
  5. <Children>
  6. <! Property template -->
  7. <Property SymbolicName="Value">
  8. <DefaultValue>
  9. <! the 'Float' is DataType ,'0' is DefaultValue ,should replaceed By DataType and DefaultValue Of the Property -->
  10. <uax:Float>0</uax:Float>
  11. </DefaultValue>
  12. </Property>
  13. <! Variable template -->
  14. <Variable SymbolicName="Name" DataType="DataType" TypeDefinition="TypeDefinition"></Variable>
  15. <! Method template -->
  16. <Method SymbolicName="Name of Method ">
  17. <Description>Description of the Method</Description>
  18. <InputArguments>
  19. <Argument Name="Name" DataType="DataType">
  20. <Description>Description of the Argument</Description>
  21. </Argument>
  22. </InputArguments>
  23. <OutputArguments>
  24. <Argument Name="Name" DataType="DataType">
  25. <Description>Description of the Argument</Description>
  26. </Argument>
  27. </OutputArguments>
  28. </Method>
  29. <! Refernses template -->
  30. <References>
  31. <Reference>
  32. <ReferenceType>Reference Type</ReferenceType>
  33. <TargetId>Target of The reference </TargetId>
  34. </Reference>
  35. </References>
  36. <! ObjectType Template -->
  37. <ObjectType SymbolicName="Name Of The Type" BaseType="BaseType Of The Type">
  38. <Children>
  39. <! elements of The ObjectType -->
  40. </Children>
  41. </ObjectType>
  42. <! VariableType template -->
  43. <opc:VariableType SymbolicName="Name of The Type" BaseType="BaseType of The Type" DataType="DataType Of The Type">
  44. <opc:Description>Description of The VariableType</opc:Description>
  45. </opc:VariableType>

自然语言描述的模型

  1. 第一个模型:
  2. 类型:对象
  3. 名称:传感器
  4. 类型定义:BaseObject
  5. 对象成员
  6. 温度传感器
  7. 类型:对象
  8. 类型定义:SensorType
  9. 名称:温度传感器
  10. Property:
  11. 名称:Temperature
  12. 初始值:12.23
  13. 数据类型:Double
  14. Method:
  15. Name:Invert
  16. Description: Result=-Arg1
  17. InputArguments:
  18. Argument
  19. Name:"Arg1",
  20. DataType:Double
  21. OutputArguments:
  22. Argument
  23. Name:"Result",
  24. DataType:Double
  25. References:
  26. Reference:
  27. type:Connected
  28. Target:Humidity
  29. 湿度传感器
  30. 类型:对象
  31. 类型定义:SensorType
  32. 名称:湿度传感器
  33. 对象成员:
  34. 类型:Variable
  35. 名称: Humidity
  36. 数据类型 Float
  37. 初始值:90
  38. 第二个模型:
  39. 名称:控制器类型
  40. 类型:对象类型
  41. 基类型:BaseObjectType
  42. 描述:一个控制器类型
  43. Property:
  44. 名称:Voltage
  45. 初始值:0
  46. 数据类型:Double

kimi 的提示

你是一个模型构建师,请根据提供的模板,构建信息模型

kimi的回答

  1. <!-- 第一个模型:传感器 -->
  2. <Object SymbolicName="Sensors" TypeDefinition="BaseObject">
  3. <Children>
  4. <!-- 温度传感器 -->
  5. <Object SymbolicName="TemperatureSensor" TypeDefinition="SensorType">
  6. <Children>
  7. <Property SymbolicName="Temperature" DataType="Double" ValueRank="Scalar">
  8. <DefaultValue>
  9. <uax:Double>12.23</uax:Double>
  10. </DefaultValue>
  11. </Property>
  12. <Method SymbolicName="Invert">
  13. <Description>Result=-Arg1</Description>
  14. <InputArguments>
  15. <Argument Name="Arg1" DataType="Double">
  16. <Description>Input argument for the Invert method.</Description>
  17. </Argument>
  18. </InputArguments>
  19. <OutputArguments>
  20. <Argument Name="Result" DataType="Double">
  21. <Description>Output argument for the Invert method.</Description>
  22. </Argument>
  23. </OutputArguments>
  24. </Method>
  25. <References>
  26. <Reference ReferenceType="Connected">
  27. <TargetId>Humidity</TargetId>
  28. </Reference>
  29. </References>
  30. </Children>
  31. </Object>
  32. <!-- 湿度传感器 -->
  33. <Object SymbolicName="HumiditySensor" TypeDefinition="SensorType">
  34. <Children>
  35. <Variable SymbolicName="Humidity" DataType="Float" ValueRank="Scalar">
  36. <DefaultValue>
  37. <uax:Float>90</uax:Float>
  38. </DefaultValue>
  39. </Variable>
  40. </Children>
  41. </Object>
  42. </Children>
  43. </Object>
  44. <!-- 第二个模型:控制器类型 -->
  45. <ObjectType SymbolicName="ControllerType" BaseType="BaseObjectType" IsAbstract="false">
  46. <Children>
  47. <Property SymbolicName="Voltage" DataType="Double" ValueRank="Scalar">
  48. <DefaultValue>
  49. <uax:Double>0</uax:Double>
  50. </DefaultValue>
  51. </Property>
  52. </Children>
  53. </ObjectType>

使用JSON 模板

我们也实验了使用JSON 模板构建信息模型。

模板

  1. // Object template
  2. {
  3. "Name": "The Name Of The Object",
  4. "Type": "Object",
  5. "Description": "Description of The Object",
  6. "Children": [
  7. //The Elements of the Object
  8. ]
  9. }
  10. // Property template
  11. {
  12. "Name": "The Name of Property",
  13. "DataType": "DataType of Property",
  14. }
  15. //Variable Template
  16. {
  17. "Name": "The Name of Variable",
  18. "Type": "Variable",
  19. "Description": "Description of The Variable",
  20. "DataType": "The DataType of Variable",
  21. "Value": "The Default Value of The Variable"
  22. }
  23. //Method Template
  24. {
  25. "Name": "The Name of The Method",
  26. "Type": "Method",
  27. "Arguments": {
  28. "InputArgument": [
  29. {
  30. "Name": "The Name Of the Argument",
  31. "DataType": "DataType of The Argument",
  32. }
  33. ],
  34. "OutputArgument": [
  35. {
  36. "Name": "The Name Of the Argument",
  37. "DataType": "DataType of The Argument",
  38. }
  39. ],
  40. }
  41. }
  42. //References Template
  43. {
  44. "Type": "References",
  45. "Reference": [
  46. {
  47. "Type": "Type Of the Reference",
  48. "Target": " Name of Element referenced"
  49. }
  50. ]
  51. }

自然语言的信息

  1. 第一个模型:
  2. 类型:对象
  3. 名称:Sensor
  4. 类型定义:BaseObject
  5. 对象成员
  6. 温度传感器
  7. 类型:对象
  8. 类型定义:SensorType
  9. 名称:TemperatureSensor
  10. 对象的成员:
  11. 1 属性
  12. 名称:Temperature
  13. 类型:Property
  14. 初始值:12.23
  15. 数据类型:Double
  16. 2 方法
  17. 名称:Invert
  18. Description: Result=-Arg1
  19. InputArguments:
  20. Argument
  21. Name:"Arg1",
  22. DataType:Double,
  23. OutputArguments:
  24. Argument
  25. Name:"Result",
  26. DataType:Double
  27. 3 References:
  28. type:Connected
  29. TargetHumidity
  30. 湿度传感器
  31. 类型:对象
  32. 类型定义:SensorType
  33. 名称:湿度传感器
  34. 对象成员:
  35. 类型:Variable
  36. 名称: Humidity
  37. 数据类型 Float
  38. 初始值:90
  39. 第二个模型:
  40. 名称:控制器类型
  41. 类型:对象类型
  42. 基类型:BaseObjectType
  43. 描述:一个控制器类型
  44. Property
  45. 名称:Voltage
  46. 初始值:0
  47. 数据类型:Double

kimi 的提示

根据JSON 模板,根据提供的信息构建信息模型

 kimi 的回答

  1. //第一个模型:Sensor对象
  2. {
  3. "Name": "Sensor",
  4. "Type": "Object",
  5. "Description": "BaseObject",
  6. "Children": [
  7. {
  8. "Name": "TemperatureSensor",
  9. "Type": "Object",
  10. "Description": "SensorType",
  11. "Children": [
  12. {
  13. "Name": "Temperature",
  14. "Type": "Property",
  15. "DataType": "Double",
  16. "Value": "12.23"
  17. },
  18. {
  19. "Name": "Invert",
  20. "Type": "Method",
  21. "Arguments": {
  22. "InputArgument": [
  23. {
  24. "Name": "Arg1",
  25. "DataType": "Double"
  26. }
  27. ],
  28. "OutputArgument": [
  29. {
  30. "Name": "Result",
  31. "DataType": "Double"
  32. }
  33. ]
  34. },
  35. "Description": "Result=-Arg1"
  36. },
  37. {
  38. "Type": "References",
  39. "Reference": [
  40. {
  41. "Type": "Connected",
  42. "Target": "Humidity"
  43. }
  44. ]
  45. }
  46. ]
  47. },
  48. {
  49. "Name": "Humidity",
  50. "Type": "Variable",
  51. "Description": "Humidity Sensor",
  52. "DataType": "Float",
  53. "Value": "90"
  54. }
  55. ]
  56. }
  57. //第二个模型:控制器类型
  58. {
  59. "Name": "ControllerType",
  60. "Type": "ObjectType",
  61. "BaseType": "BaseObjectType",
  62. "Description": "A controller type",
  63. "Children": [
  64. {
  65. "Name": "Voltage",
  66. "Type": "Property",
  67. "InitialValue": "0",
  68. "DataType": "Double"
  69. }
  70. ]
  71. }

结果是正确。

第二个JSON 模板的实验

添加了Device 模板,构建一个远程IO 模块的模型

  1. // device template
  2. {
  3. "Name": "Name of device",
  4. "Type": "Device",
  5. "Description": "description of the device ",
  6. "Children": [
  7. // Components of the Device
  8. ]
  9. }
  10. //Component Template
  11. {
  12. "Name": "Name Of The Component",
  13. "Type": "ComponentType",
  14. "Description": "Description of The Component",
  15. "Children": [
  16. //FunctionGroup ,ParameterSet ,MethodSet of Component.if exist
  17. ],
  18. "References": [
  19. {
  20. "Type": "Organizes",
  21. "Target": " Name of Component referenced "
  22. }
  23. ]
  24. }
  25. //FunctionGroup Template
  26. {
  27. "Name": "Name of FunctionGroup ",
  28. "Description": "description of the FunctionGroup",
  29. "Type": "FunctionGroupType",
  30. "References": [
  31. {
  32. "Type": "Organizes",
  33. "Target": " Name of Property,Variable Method in the referenced TopologyElement "
  34. }
  35. ]
  36. },
  37. //Parameterset Template
  38. {
  39. "Name": "Parameterset",
  40. "Type": "ObjectType",
  41. "Description": "the parameters of the component",
  42. "Parameters": []
  43. }
  44. //Methodset Template
  45. {
  46. "Name": "Methodset",
  47. "Type": "ObjectType",
  48. "Description": "the methods of the component",
  49. "Methods": []
  50. }

 产品信息

这一次我们使用类似技术手册的方式编写产品的信息

  1. 远程IO模块的设备
  2. 该远程IO模块的名称是ABC_Controller ,是ABC 公司生产的AT232 远程IO控制器。
  3. ABC_Controller 包含了三个组件,它们分别是DIO_16,DIN_16,DOUT_16AIN_8组件
  4. 组件
  5. 1 DIO_16 组件
  6. 该组件没有参数集,功能组和方法集,只有两个引用,引用的类型是Orgnazie,引用的对象分别是 DIN_16DOUT_16
  7. 2 DIN_16 组件
  8. 它是一个16 通道 数字输入模块,其中包含了参数集,功能组和方法集
  9. 功能组的名称是Operation,包含了两个引用,分别指向 ReadConfiguration 方法
  10. 参数集中包含了一个变量,称为DigitalRead Bool 类型
  11. 方法集中包含了两个方法,分别的 ReadConfiguration
  12. 其中
  13. Read方法 的输入参数为Index, 数据类型是Int16
  14. Configuration 方法没有输入参数,输出参数为 Status,数据类型是String
  15. 2 DOUT_16 组件
  16. 它是一个16 通道 数字输出模块,其中包含了参数集,功能组和方法集
  17. 功能组的名称是Operation,包含了两个引用,分别指向 ReadConfiguration 方法
  18. 参数集中包含了一个变量,称为DigitalOutput, Bool 类型
  19. 方法集中包含了两个方法,分别的 WriteConfiguration
  20. 其中
  21. Write方法 有两个输入参数分别为
  22. Index, 数据类型是Int16
  23. Value 数据类型是Bool
  24. Configuration 方法没有输入参数,输出参数为 Status,数据类型是String
  25. 3 AIN_8 组件
  26. 它是一个8 通道模拟量输入模块,其中包含了参数集和方法集
  27. 参数集中包含了一个变量,名称为Analog ,它是一个数组类型,数组单元的类型是Double,数组的维度是1,数组的长度为8
  28. 方法集中包含了两个方法,分别的 ReadConfiguration
  29. 其中
  30. Read方法 的输入参数为Index, 数据类型是Int16,输出参数为ReadOutDouble 类型
  31. Configuration 方法没有输入参数,输出参数为 Status,数据类型是String

结果

  1. {
  2. "Name": "ABC_Controller",
  3. "Type": "Device",
  4. "Description": "AT232 Remote IO Controller by ABC Company",
  5. "Children": [
  6. {
  7. "Name": "DIO_16",
  8. "Type": "ComponentType",
  9. "Description": "Virtual Component including DIN_16 and DOUT_16",
  10. "Children": [
  11. {
  12. "Name": "Operation",
  13. "Description": "Function group for DIO_16 component",
  14. "Type": "FunctionGroupType",
  15. "References": [
  16. {
  17. "Type": "Organizes",
  18. "Target": "Read"
  19. },
  20. {
  21. "Type": "Organizes",
  22. "Target": "Configuration"
  23. }
  24. ]
  25. },
  26. {
  27. "Name": "Parameterset",
  28. "Type": "ObjectType",
  29. "Description": "Parameters of DIO_16 component",
  30. "Parameters": [
  31. {
  32. "Name": "DigitalRead",
  33. "DataType": "Bool"
  34. }
  35. ]
  36. },
  37. {
  38. "Name": "Methodset",
  39. "Type": "ObjectType",
  40. "Description": "Methods of DIO_16 component",
  41. "Methods": [
  42. {
  43. "Name": "Read",
  44. "Arguments": {
  45. "InputArgument": [
  46. {
  47. "Name": "Index",
  48. "DataType": "Int16"
  49. }
  50. ]
  51. }
  52. },
  53. {
  54. "Name": "Configuration",
  55. "Arguments": {
  56. "OutputArgument": [
  57. {
  58. "Name": "Status",
  59. "DataType": "String"
  60. }
  61. ]
  62. }
  63. }
  64. ]
  65. }
  66. ],
  67. "References": [
  68. {
  69. "Type": "Organizes",
  70. "Target": "DIN_16"
  71. },
  72. {
  73. "Type": "Organizes",
  74. "Target": "DOUT_16"
  75. }
  76. ]
  77. },
  78. {
  79. "Name": "DIN_16",
  80. "Type": "ComponentType",
  81. "Description": "16-channel Digital Input Module",
  82. "Children": [
  83. {
  84. "Name": "Operation",
  85. "Description": "Function group for DIN_16 component",
  86. "Type": "FunctionGroupType",
  87. "References": [
  88. {
  89. "Type": "Organizes",
  90. "Target": "Read"
  91. },
  92. {
  93. "Type": "Organizes",
  94. "Target": "Configuration"
  95. }
  96. ]
  97. },
  98. {
  99. "Name": "Parameterset",
  100. "Type": "ObjectType",
  101. "Description": "Parameters of DIN_16 component",
  102. "Parameters": [
  103. {
  104. "Name": "DigitalRead",
  105. "DataType": "Bool"
  106. }
  107. ]
  108. },
  109. {
  110. "Name": "Methodset",
  111. "Type": "ObjectType",
  112. "Description": "Methods of DIN_16 component",
  113. "Methods": [
  114. {
  115. "Name": "Read",
  116. "Arguments": {
  117. "InputArgument": [
  118. {
  119. "Name": "Index",
  120. "DataType": "Int16"
  121. }
  122. ]
  123. }
  124. },
  125. {
  126. "Name": "Configuration",
  127. "Arguments": {
  128. "OutputArgument": [
  129. {
  130. "Name": "Status",
  131. "DataType": "String"
  132. }
  133. ]
  134. }
  135. }
  136. ]
  137. }
  138. ]
  139. },
  140. {
  141. "Name": "DOUT_16",
  142. "Type": "ComponentType",
  143. "Description": "16-channel Digital Output Module",
  144. "Children": [
  145. {
  146. "Name": "Operation",
  147. "Description": "Function group for DOUT_16 component",
  148. "Type": "FunctionGroupType",
  149. "References": [
  150. {
  151. "Type": "Organizes",
  152. "Target": "Write"
  153. },
  154. {
  155. "Type": "Organizes",
  156. "Target": "Configuration"
  157. }
  158. ]
  159. },
  160. {
  161. "Name": "Parameterset",
  162. "Type": "ObjectType",
  163. "Description": "Parameters of DOUT_16 component",
  164. "Parameters": [
  165. {
  166. "Name": "DigitalOutput",
  167. "DataType": "Bool"
  168. }
  169. ]
  170. },
  171. {
  172. "Name": "Methodset",
  173. "Type": "ObjectType",
  174. "Description": "Methods of DOUT_16 component",
  175. "Methods": [
  176. {
  177. "Name": "Write",
  178. "Arguments": {
  179. "InputArgument": [
  180. {
  181. "Name": "Index",
  182. "DataType": "Int16"
  183. },
  184. {
  185. "Name": "Value",
  186. "DataType": "Bool"
  187. }
  188. ]
  189. }
  190. },
  191. {
  192. "Name": "Configuration",
  193. "Arguments": {
  194. "OutputArgument": [
  195. {
  196. "Name": "Status",
  197. "DataType": "String"
  198. }
  199. ]
  200. }
  201. }
  202. ]
  203. }
  204. ]
  205. },
  206. {
  207. "Name": "AIN_8",
  208. "Type": "ComponentType",
  209. "Description": "8-channel Analog Input Module",
  210. "Children": [
  211. {
  212. "Name": "Parameterset",
  213. "Type": "ObjectType",
  214. "Description": "Parameters of AIN_8 component",
  215. "Parameters": [
  216. {
  217. "Name": "Analog",
  218. "DataType": "Double[8]"
  219. }
  220. ]
  221. },
  222. {
  223. "Name": "Methodset",
  224. "Type": "ObjectType",
  225. "Description": "Methods of AIN_8 component",
  226. "Methods": [
  227. {
  228. "Name": "Read",
  229. "Arguments": {
  230. "InputArgument": [
  231. {
  232. "Name": "Index",
  233. "DataType": "Int16"
  234. }
  235. ],
  236. "OutputArgument": [
  237. {
  238. "Name": "ReadOut",
  239. "DataType": "Double"
  240. }
  241. ]
  242. }
  243. },
  244. {
  245. "Name": "Configuration",
  246. "Arguments": {
  247. "OutputArgument": [
  248. {
  249. "Name": "Status",
  250. "DataType": "String"
  251. }
  252. ]
  253. }
  254. }
  255. ]
  256. }
  257. ]
  258. }
  259. ]
  260. }

 感觉大模型更加理解文本描述的内容。

结论

   自然语言生成形式化语言是令人兴奋的课题,具体实现过程中,设计模板是关键。模板中应该包含描述和提示信息。设计模板的工作需要对OPC UA 的信息模型有十分详细的了解。

  实验表明,XML 的模板看来要比JSON 模板更好一点。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/580017
推荐阅读
相关标签
  

闽ICP备14008679号