利用大语言模型(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#的类定义。

例子:对象类型的定义。

XML 复制代码
  <opc:ObjectType SymbolicName="GenericControllerType" BaseType="ua:BaseObjectType">
        <opc:Description>A generic PID controller</opc:Description>
        <opc:Children>
            <opc:Property SymbolicName="Measurement" DataType="ua:Double" />
            <opc:Property SymbolicName="SetPoint" DataType="ua:Double" AccessLevel="ReadWrite" MinimumSamplingInterval="1" />
            <opc:Property SymbolicName="ControlOut" DataType="ua:Double" />
        </opc:Children>
    </opc:ObjectType>

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

基于ModelDesign的模型生成

模板的构建

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

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

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

模板的例子

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

XML 复制代码
<! Object template -->
<Object SymbolicName="Name" TypeDefinition="TypeDefinition">
    <Children>
<! elements of The Object -->    
        <Children>
 <! Property template -->
            <Property SymbolicName="Value">
                <DefaultValue>
                  <!  the 'Float' is DataType  ,'0' is  DefaultValue ,should replaceed By DataType and DefaultValue Of the Property -->
                    <uax:Float>0</uax:Float>
                </DefaultValue>
            </Property>
<! Variable template -->
<Variable SymbolicName="Name" DataType="DataType" TypeDefinition="TypeDefinition"></Variable>

<! Method template -->
<Method SymbolicName="Name of Method ">
    <Description>Description of the Method</Description>
    <InputArguments>
      <Argument Name="Name" DataType="DataType">
        <Description>Description of the Argument</Description>
      </Argument>
    </InputArguments>
    <OutputArguments>
      <Argument Name="Name" DataType="DataType">
        <Description>Description of the Argument</Description>
      </Argument>
    </OutputArguments>
  </Method>
<! Refernses template -->
    <References>
      <Reference>
        <ReferenceType>Reference Type</ReferenceType>
        <TargetId>Target  of The reference </TargetId>
      </Reference>
    </References>
<! ObjectType Template -->
  <ObjectType SymbolicName="Name Of The Type" BaseType="BaseType Of The Type">
    <Children>
 <! elements of The ObjectType --> 
    </Children>
  </ObjectType> 

  <! VariableType template -->
    <opc:VariableType SymbolicName="Name of The Type" BaseType="BaseType of The Type" DataType="DataType Of The Type">
    <opc:Description>Description of The VariableType</opc:Description>
  </opc:VariableType>   

自然语言描述的模型

XML 复制代码
第一个模型:
    类型:对象
    名称:传感器
    类型定义:BaseObject
    对象成员
        温度传感器
                类型:对象
                类型定义:SensorType
                名称:温度传感器
                Property:
                    名称:Temperature
                    初始值:12.23
                    数据类型:Double
                Method:
                    Name:Invert
                    Description: Result=-Arg1
                    InputArguments:
                        Argument
                            Name:"Arg1",
                            DataType:Double
                    OutputArguments:
                        Argument
                            Name:"Result",
                            DataType:Double
                References:
                Reference:
                        type:Connected
                        Target:Humidity
        湿度传感器
            类型:对象
            类型定义:SensorType
            名称:湿度传感器
            对象成员:
                类型:Variable   
                名称: Humidity
                数据类型  Float
                初始值:90

 
第二个模型: 
        名称:控制器类型
        类型:对象类型
        基类型:BaseObjectType
        描述:一个控制器类型
        Property:
                名称:Voltage
                初始值:0
                数据类型:Double

kimi 的提示

XML 复制代码
你是一个模型构建师,请根据提供的模板,构建信息模型

kimi的回答

XML 复制代码
<!-- 第一个模型:传感器 -->
<Object SymbolicName="Sensors" TypeDefinition="BaseObject">
    <Children>
        <!-- 温度传感器 -->
        <Object SymbolicName="TemperatureSensor" TypeDefinition="SensorType">
            <Children>
                <Property SymbolicName="Temperature" DataType="Double" ValueRank="Scalar">
                    <DefaultValue>
                        <uax:Double>12.23</uax:Double>
                    </DefaultValue>
                </Property>
                <Method SymbolicName="Invert">
                    <Description>Result=-Arg1</Description>
                    <InputArguments>
                        <Argument Name="Arg1" DataType="Double">
                            <Description>Input argument for the Invert method.</Description>
                        </Argument>
                    </InputArguments>
                    <OutputArguments>
                        <Argument Name="Result" DataType="Double">
                            <Description>Output argument for the Invert method.</Description>
                        </Argument>
                    </OutputArguments>
                </Method>
                <References>
                    <Reference ReferenceType="Connected">
                        <TargetId>Humidity</TargetId>
                    </Reference>
                </References>
            </Children>
        </Object>
        <!-- 湿度传感器 -->
        <Object SymbolicName="HumiditySensor" TypeDefinition="SensorType">
            <Children>
                <Variable SymbolicName="Humidity" DataType="Float" ValueRank="Scalar">
                    <DefaultValue>
                        <uax:Float>90</uax:Float>
                    </DefaultValue>
                </Variable>
            </Children>
        </Object>
    </Children>
</Object>

<!-- 第二个模型:控制器类型 -->
<ObjectType SymbolicName="ControllerType" BaseType="BaseObjectType" IsAbstract="false">
    <Children>
        <Property SymbolicName="Voltage" DataType="Double" ValueRank="Scalar">
            <DefaultValue>
                <uax:Double>0</uax:Double>
            </DefaultValue>
        </Property>
    </Children>
</ObjectType>

使用JSON 模板

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

模板

javascript 复制代码
// Object template
{
    "Name": "The Name Of The Object",
    "Type": "Object",
    "Description": "Description of The Object",
    "Children": [
        //The Elements of the Object
    ]
}
// Property template 
{
    "Name": "The Name of Property",
    "DataType": "DataType of Property",
}
//Variable Template
{
    "Name": "The Name of Variable",
    "Type": "Variable",
    "Description": "Description of The Variable",
    "DataType": "The DataType of Variable",
    "Value": "The Default Value of The Variable"
}
//Method Template
{
    "Name": "The Name of The Method",
    "Type": "Method",
    "Arguments": {
        "InputArgument": [
            {
                "Name": "The Name Of the Argument",
                "DataType": "DataType of The Argument",
            }
        ],
        "OutputArgument": [
            {
                "Name": "The Name Of the Argument",
                "DataType": "DataType of The Argument",
            }
        ],
    }
}
//References Template
{
    "Type": "References",
    "Reference": [
        {
            "Type": "Type Of the Reference",
            "Target": " Name of Element  referenced"
        }
    ]
}

自然语言的信息

javascript 复制代码
第一个模型:
    类型:对象
    名称:Sensor
    类型定义:BaseObject
    对象成员
        温度传感器
                类型:对象
                类型定义:SensorType
                名称:TemperatureSensor
                对象的成员:
                  1 属性
                    名称:Temperature
                    类型:Property
                    初始值:12.23
                    数据类型:Double
                  2 方法
                        名称:Invert
                        Description: Result=-Arg1
                        InputArguments:
                            Argument
                                Name:"Arg1",
                                DataType:Double,
                        OutputArguments:
                            Argument
                                Name:"Result",
                                DataType:Double
                   3 References:
                            type:Connected
                            Target:Humidity
        湿度传感器
            类型:对象
            类型定义:SensorType
            名称:湿度传感器
            对象成员:
                类型:Variable   
                名称: Humidity
                数据类型  Float
                初始值:90

 
第二个模型: 
        名称:控制器类型
        类型:对象类型
        基类型:BaseObjectType
        描述:一个控制器类型
        Property:
                名称:Voltage
                初始值:0
                数据类型:Double

kimi 的提示

javascript 复制代码
根据JSON 模板,根据提供的信息构建信息模型

kimi 的回答

javascript 复制代码
//第一个模型:Sensor对象
{
    "Name": "Sensor",
    "Type": "Object",
    "Description": "BaseObject",
    "Children": [
        {
            "Name": "TemperatureSensor",
            "Type": "Object",
            "Description": "SensorType",
            "Children": [
                {
                    "Name": "Temperature",
                    "Type": "Property",
                    "DataType": "Double",
                    "Value": "12.23"
                },
                {
                    "Name": "Invert",
                    "Type": "Method",
                    "Arguments": {
                        "InputArgument": [
                            {
                                "Name": "Arg1",
                                "DataType": "Double"
                            }
                        ],
                        "OutputArgument": [
                            {
                                "Name": "Result",
                                "DataType": "Double"
                            }
                        ]
                    },
                    "Description": "Result=-Arg1"
                },
                {
                    "Type": "References",
                    "Reference": [
                        {
                            "Type": "Connected",
                            "Target": "Humidity"
                        }
                    ]
                }
            ]
        },
        {
            "Name": "Humidity",
            "Type": "Variable",
            "Description": "Humidity Sensor",
            "DataType": "Float",
            "Value": "90"
        }
    ]
}
//第二个模型:控制器类型
{
    "Name": "ControllerType",
    "Type": "ObjectType",
    "BaseType": "BaseObjectType",
    "Description": "A controller type",
    "Children": [
        {
            "Name": "Voltage",
            "Type": "Property",
            "InitialValue": "0",
            "DataType": "Double"
        }
    ]
}

结果是正确。

第二个JSON 模板的实验

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

javascript 复制代码
// device template
{
    "Name": "Name of device",
    "Type": "Device",
    "Description": "description of the device ",
    "Children": [
        // Components of the Device
    ]
}
//Component Template
{
    "Name": "Name Of The Component",
    "Type": "ComponentType",
    "Description": "Description of The Component",
    "Children": [
        //FunctionGroup ,ParameterSet ,MethodSet of Component.if exist
    ],
    "References": [
        {
            "Type": "Organizes",
            "Target": " Name of Component  referenced "
        }
    ]
}
//FunctionGroup Template
{
    "Name": "Name of FunctionGroup ",
    "Description": "description of the FunctionGroup",
    "Type": "FunctionGroupType",
    "References": [
        {
            "Type": "Organizes",
            "Target": " Name of Property,Variable Method in the referenced  TopologyElement "
        }
    ]
},
//Parameterset Template
{
    "Name": "Parameterset",
    "Type": "ObjectType",
    "Description": "the parameters of the component",
    "Parameters": []
}
//Methodset Template
{
    "Name": "Methodset",
    "Type": "ObjectType",
    "Description": "the methods of the component",
    "Methods": []
}

产品信息

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

javascript 复制代码
远程IO模块的设备
该远程IO模块的名称是ABC_Controller ,是ABC 公司生产的AT232 远程IO控制器。
ABC_Controller 包含了三个组件,它们分别是DIO_16,DIN_16,DOUT_16和AIN_8组件
组件
1 DIO_16 组件
  该组件没有参数集,功能组和方法集,只有两个引用,引用的类型是Orgnazie,引用的对象分别是 DIN_16 和DOUT_16
2 DIN_16 组件
  它是一个16 通道 数字输入模块,其中包含了参数集,功能组和方法集
  功能组的名称是Operation,包含了两个引用,分别指向 Read和Configuration 方法
  参数集中包含了一个变量,称为DigitalRead Bool 类型
  方法集中包含了两个方法,分别的 Read和Configuration。
  其中
   Read方法 的输入参数为Index, 数据类型是Int16
   Configuration 方法没有输入参数,输出参数为 Status,数据类型是String
 2 DOUT_16 组件
  它是一个16 通道 数字输出模块,其中包含了参数集,功能组和方法集
  功能组的名称是Operation,包含了两个引用,分别指向 Read和Configuration 方法
  参数集中包含了一个变量,称为DigitalOutput, Bool 类型
  方法集中包含了两个方法,分别的 Write和Configuration。
  其中
   Write方法 有两个输入参数分别为
       Index, 数据类型是Int16
       Value   数据类型是Bool
   Configuration 方法没有输入参数,输出参数为 Status,数据类型是String  
3 AIN_8 组件
   它是一个8 通道模拟量输入模块,其中包含了参数集和方法集
   参数集中包含了一个变量,名称为Analog ,它是一个数组类型,数组单元的类型是Double,数组的维度是1,数组的长度为8
   方法集中包含了两个方法,分别的 Read和Configuration。
     其中
   Read方法 的输入参数为Index, 数据类型是Int16,输出参数为ReadOut,Double 类型
   Configuration 方法没有输入参数,输出参数为 Status,数据类型是String

结果

javascript 复制代码
{
  "Name": "ABC_Controller",
  "Type": "Device",
  "Description": "AT232 Remote IO Controller by ABC Company",
  "Children": [
    {
      "Name": "DIO_16",
      "Type": "ComponentType",
      "Description": "Virtual Component including DIN_16 and DOUT_16",
      "Children": [
        {
          "Name": "Operation",
          "Description": "Function group for DIO_16 component",
          "Type": "FunctionGroupType",
          "References": [
            {
              "Type": "Organizes",
              "Target": "Read"
            },
            {
              "Type": "Organizes",
              "Target": "Configuration"
            }
          ]
        },
        {
          "Name": "Parameterset",
          "Type": "ObjectType",
          "Description": "Parameters of DIO_16 component",
          "Parameters": [
            {
              "Name": "DigitalRead",
              "DataType": "Bool"
            }
          ]
        },
        {
          "Name": "Methodset",
          "Type": "ObjectType",
          "Description": "Methods of DIO_16 component",
          "Methods": [
            {
              "Name": "Read",
              "Arguments": {
                "InputArgument": [
                  {
                    "Name": "Index",
                    "DataType": "Int16"
                  }
                ]
              }
            },
            {
              "Name": "Configuration",
              "Arguments": {
                "OutputArgument": [
                  {
                    "Name": "Status",
                    "DataType": "String"
                  }
                ]
              }
            }
          ]
        }
      ],
      "References": [
        {
          "Type": "Organizes",
          "Target": "DIN_16"
        },
        {
          "Type": "Organizes",
          "Target": "DOUT_16"
        }
      ]
    },
    {
      "Name": "DIN_16",
      "Type": "ComponentType",
      "Description": "16-channel Digital Input Module",
      "Children": [
        {
          "Name": "Operation",
          "Description": "Function group for DIN_16 component",
          "Type": "FunctionGroupType",
          "References": [
            {
              "Type": "Organizes",
              "Target": "Read"
            },
            {
              "Type": "Organizes",
              "Target": "Configuration"
            }
          ]
        },
        {
          "Name": "Parameterset",
          "Type": "ObjectType",
          "Description": "Parameters of DIN_16 component",
          "Parameters": [
            {
              "Name": "DigitalRead",
              "DataType": "Bool"
            }
          ]
        },
        {
          "Name": "Methodset",
          "Type": "ObjectType",
          "Description": "Methods of DIN_16 component",
          "Methods": [
            {
              "Name": "Read",
              "Arguments": {
                "InputArgument": [
                  {
                    "Name": "Index",
                    "DataType": "Int16"
                  }
                ]
              }
            },
            {
              "Name": "Configuration",
              "Arguments": {
                "OutputArgument": [
                  {
                    "Name": "Status",
                    "DataType": "String"
                  }
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "Name": "DOUT_16",
      "Type": "ComponentType",
      "Description": "16-channel Digital Output Module",
      "Children": [
        {
          "Name": "Operation",
          "Description": "Function group for DOUT_16 component",
          "Type": "FunctionGroupType",
          "References": [
            {
              "Type": "Organizes",
              "Target": "Write"
            },
            {
              "Type": "Organizes",
              "Target": "Configuration"
            }
          ]
        },
        {
          "Name": "Parameterset",
          "Type": "ObjectType",
          "Description": "Parameters of DOUT_16 component",
          "Parameters": [
            {
              "Name": "DigitalOutput",
              "DataType": "Bool"
            }
          ]
        },
        {
          "Name": "Methodset",
          "Type": "ObjectType",
          "Description": "Methods of DOUT_16 component",
          "Methods": [
            {
              "Name": "Write",
              "Arguments": {
                "InputArgument": [
                  {
                    "Name": "Index",
                    "DataType": "Int16"
                  },
                  {
                    "Name": "Value",
                    "DataType": "Bool"
                  }
                ]
              }
            },
            {
              "Name": "Configuration",
              "Arguments": {
                "OutputArgument": [
                  {
                    "Name": "Status",
                    "DataType": "String"
                  }
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "Name": "AIN_8",
      "Type": "ComponentType",
      "Description": "8-channel Analog Input Module",
      "Children": [
        {
          "Name": "Parameterset",
          "Type": "ObjectType",
          "Description": "Parameters of AIN_8 component",
          "Parameters": [
            {
              "Name": "Analog",
              "DataType": "Double[8]"
            }
          ]
        },
        {
          "Name": "Methodset",
          "Type": "ObjectType",
          "Description": "Methods of AIN_8 component",
          "Methods": [
            {
              "Name": "Read",
              "Arguments": {
                "InputArgument": [
                  {
                    "Name": "Index",
                    "DataType": "Int16"
                  }
                ],
                "OutputArgument": [
                  {
                    "Name": "ReadOut",
                    "DataType": "Double"
                  }
                ]
              }
            },
            {
              "Name": "Configuration",
              "Arguments": {
                "OutputArgument": [
                  {
                    "Name": "Status",
                    "DataType": "String"
                  }
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}

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

结论

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

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

相关推荐
打码人的日常分享29 分钟前
基于信创体系政务服务信息化建设方案(PPT)
大数据·服务器·人工智能·信息可视化·架构·政务
硬汉嵌入式1 小时前
专为 MATLAB 优化的 AI 助手MATLAB Copilot
人工智能·matlab·copilot
北京盛世宏博1 小时前
如何利用技术手段来甄选一套档案馆库房安全温湿度监控系统
服务器·网络·人工智能·选择·档案温湿度
搞科研的小刘选手1 小时前
【EI稳定】检索第六届大数据经济与信息化管理国际学术会议(BDEIM 2025)
大数据·人工智能·经济
半吊子全栈工匠1 小时前
软件产品的10个UI设计技巧及AI 辅助
人工智能·ui
机器之心2 小时前
真机RL!最强VLA模型π*0.6来了,机器人在办公室开起咖啡厅
人工智能·openai
机器之心2 小时前
马斯克Grok 4.1低调发布!通用能力碾压其他一切模型
人工智能·openai
一水鉴天2 小时前
整体设计 全面梳理复盘 之39 生态工具链 到顶级表征及其完全公理化
大数据·人工智能·算法
小和尚同志2 小时前
本地 AI Code Review 探索及落地
人工智能·aigc
Juchecar3 小时前
视觉分层,对人工神经网络的启示
人工智能