与当下热门的AI类似,曾几何时,物联网(Internet of thing)实现“万物互联"给人类带来了无限的遐想。但是往往事与愿违,美好的愿景并没有如约而至。十几年来,物联网远没有实现”万物互联“的美好愿景。
随着chatGPT 为主的AI热潮,人们又一次提出了 AIoT (artificial intelligence of thing) 的新概念。AI 会给IoT 带来新的生机么?这是有趣的话题。
多年的实践表明,IoT 实现的难点在于没有广泛被接纳的IoT 协议,目前只有各个公司内部形成的各种IoT 生态,比如小米,华为,苹果的智能设备,它们自成一体。 它们成为了一个又一个信息孤岛,令人沮丧。
哪怕是不同公司的遥控器都互不兼容。出于各自的商业利益,人类难以达成共识。
各种自主无人系统的快速发展,增加了机器的内生智能,使智能机器之间的功能协作成为可能。然而,传统的智能机器协作协议在功能、效率和可扩展性方面存在局限性。此外,现有的智能机器协作研究尚未接近一种统一的范式,以促进机器之间以及机器与人类之间的交互。
在我看来,chatGPT 的出现,为IoT 行业打开了另一条道路-”让机器说人话“.
在人类文明进步过程中,自然语言成为人类最为广泛接纳的交流语言,相比于机器语言而言,人类语言非常丰富,对语法和语义的要求并严格。如果让设备采用人类的语言来交流,能够最大程度地实现设备之间的相互交流和理解。
自然语言的通信仍然需要底层的协议承载,最简单和普及的通信协议莫过于TCP/IP 协议了,但是考虑到物联网设备需要点对多点通信,所以使用基于MQTT 的PUB/SUB 通信协议最为合适。
本文记录了如何使用自然语言/MQTT作为物联网设备的通信协议。
实验的主要内容
- MQTT Broker :mosquitto
- 大语言模型:本地部署ollama/llama-3 ,远程调用kimi。
- 程序设计语言 :Python
准备工作
安装mosquitto
要在 Windows 上安装 Mosquitto,请从 mosquitto.org(64 位或 32 位)中选择所需的安装文件,下载并运行它。
具体过程请参考:
How to Install Mosquitto MQTT Broker on Windows
运行
PS C:\Windows\system32> mosquitto
订阅
PS C:\Users\Yao> mosquitto_sub -i mosq_sub1 -t "Test topic" -d
发布
PS C:\Users\Yao> mosquitto_pub -i mosq_pub1 -t "Test topic" -m "Test message" -d
python MQTT Client
安装 paho-mqtt
pip3 install -i https://pypi.doubanio.com/simple paho-mqtt
发布
# python 3.6
import random
import time
from paho.mqtt import client as mqtt
broker = '127.0.0.1'
port = 1883
topic = "python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'
def connect_mqtt():
def on_connect(client, userdata, flags, rc,properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client):
msg_count = 0
while True:
time.sleep(1)
msg = f"messages: {msg_count}"
result = client.publish(topic, msg)
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
msg_count += 1
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
if __name__ == '__main__':
run()
订阅
# python3.6
import random
from paho.mqtt import client as mqtt
broker = '127.0.0.1'
port = 1883
topic = "/python/mqtt"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
def connect_mqtt() -> mqtt:
def on_connect(client, userdata, flags, rc,properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def subscribe(client: mqtt):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
client.subscribe(topic)
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()
实验
Device1 通过自然语言控制 Device2。
GPTAgent 调用大语言模型,完成语言的理解,调用本地llama-3 或者远程调用kimi大模型。
Device2 模仿一个空调设备。
topic 定义
Device To ChatGPT | Device/GPT |
chatGPT to Device | GPT/Device |
Device to Device | Device/Device |
仿真程序
为了做实验,编写了两个设备和一个Chat GPT Agent的仿真软件.使用Python 编写。
Device1 传感器
定时地采集温度,并向Device2 发送控制命令。
Devices2 控制器
接收Device 1 发送的控制命令,控制空调。
具体的方法
- TurnOn- 开启空调
- TurnOff-关闭空调
- Up-调高温度
- Down-调低温度
控制流程
- 订阅Device/Device 主题的信息
- 订阅Device/GPT 主题的信息
- 当接收到 Device1 发送来的消息后,组织大语言模型的Prompt ,发送给chatGPT IoT Agent(主题为Device/GPT),chatGPT 解析自然语言,将结果发布给Device 2 设备(主题为GPT/Device )
- Device2 根据chatGPT 解析的结果,控制设备。
chatGPT Agent
订阅 Device/GPT 主题的信息,做出自然语言命令的解释,然后将结果返回给发送的设备。
为了提高大语言模型服务的实时性,在PC 机上部署了ollama /llama-3 大模型。
源代码
GPTAgent
# python3.6
import random
from openai import OpenAI
from paho.mqtt import client as mqtt
broker = '127.0.0.1'
port = 1883
topic = "Device/GPT"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
#LLM = OpenAI(base_url="http://localhost:11434/v1", api_key="lm-studio")
LLM=OpenAI(
api_key="sk-xxxxxxx",
base_url="https://api.moonshot.cn/v1",
)
def connect_mqtt() -> mqtt:
def on_connect(client, userdata, flags, rc,properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def subscribe(client: mqtt):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
history = [
{"role": "system", "content": "你是一个聪明的助手。你总是提供合理、准确且有帮助的答案。总是用中文简体回答"},
{"role": "user", "content": msg.payload.decode()},
]
completion = LLM.chat.completions.create(
model="moonshot-v1-8k",
messages=history,
temperature=0,
)
Response=completion.choices[0].message.content
print(Response)
result = client.publish("GPT/Device", Response.encode('utf-8'))
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
client.subscribe(topic)
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()
Device2
# python3.6
import random
import json
from paho.mqtt import client as mqtt
broker = '127.0.0.1'
port = 1883
#topic = "GPT/Device"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
def connect_mqtt() -> mqtt:
def on_connect(client, userdata, flags, rc,properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def subscribe(client: mqtt):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
if msg.topic=="Device/Device":
print("Device to Device")
Prefix='''针对下面的命令,判断应该调用哪个工具执行:
工具:
TurnOn:打开空调
TurnOff:关闭空调
Up: 调高温度
Down:调低空调
命令:
'''
Suffix='''请以JSON 格式输出,格式为:
/`/`/`json
{"ToolName":"The Name Of Tool"}
/`/`/`
'''
Prompt=Prefix+msg.payload.decode()+ Suffix
client.publish("Device/GPT", Prompt)
else:
if msg.topic=="GPT/Device":
print("GPT/Device")
Result=msg.payload.decode()
p=Result.find("```json")
print(p)
if p>=0:
Temp=Result.replace("```json","")
e=Temp.find("```")
print(e)
print(Temp[p:e])
JsonContent=json.loads(Temp[p:e])
print(JsonContent)
if JsonContent["ToolName"]=="TurnOn":
print("打开空调!")
else:
if JsonContent["ToolName"]=="TurnOff":
print("关闭空调!")
else:
if JsonContent["ToolName"]=="Up":
print("调高空调温度!")
else:
if JsonContent["ToolName"]=="Down":
print("调低空调温度!")
client.subscribe("GPT/Device")
client.subscribe("Device/Device")
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()
Device1
# python 3.6
import random
import time
from paho.mqtt import client as mqtt
broker = '127.0.0.1'
port = 1883
topic = "Device/Device"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'
def connect_mqtt():
def on_connect(client, userdata, flags, rc,properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client):
msg_count = 0
while True:
time.sleep(5)
#msg = f"messages: {msg_count}"
if (msg_count & 1) == 0:
msg="请打开空调!"
else:
msg="请关闭空调!"
result = client.publish(topic, msg.encode('utf-8'))
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
msg_count += 1
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
if __name__ == '__main__':
run()
结果
Device1 的发送周期为5秒钟,kimi 大模型响应自如。而本地llama-3 速度还是不行。
应用场景
使用自然语言作为物联网的通信语言的缺点是
- 延时长
- 成本高
对于实时性要求不高的应用场景,有一定的应用场景。
设备添加一个维护接口
为设备添加一个自然语言的维护接口,具有很大的好处,以前的设备通常也保留了一个字符终端的命令行接口,当设备发生故障,或者需要配置,维护时,使用命令行控制设备,现在可以转换成自然语言来维护。自然语言适合远程操作。不需要记忆各种命令的格式。
另一个好处是当设备发生故障时,可以手动操作。
自然语言命令接口也有利于与上层软件的兼容。使上层软件更加灵活,并且与各种厂商的设备互联互通。
不同生态系统的互联
例如小米的设备与华为的设备互联互通,可以采用自然语言通信。
进一步的思考
实现IoT 设备的自然语言通信,只需要一个小型的语言模型就可以实现,并且在IoT 领域增强,这种小型的IoTModel 部署在云端,或者边缘。随着AI 成本的下降,也许很快能够出现IoT GPT 服务器产品出现。基于自然语言的IoT 通信将会流行起来。他们将会在智慧城市,工业,智能家居,农业,环境等行业流行起来。
笔者相信,除了物联网应用之外,自然语言通信协议的另一个巨大的潜在市场是政府,大企业之间异构系统的互联互通。比如在一个医院信息管理系统中,医生的电脑要调用各种检查报告,查询病例,床位信息。这都要通过复杂的API 实现,当需要更新API,或者添加一项新的数据科目时,所有相关的软件都需要做相应的更新。除了医院信息管理系统的厂商能够做软件的更新之外,别的厂商难以介入。这就人为地设置了各种“数据墙”,难以挖掘医学数据。使用“自然语言”协议能够解决异构系统的信息共享。
信息共享是人们朝思暮想的目标,但是长期以来难以实现,为此还不断地推广类似DDS,OPCUA 等统一的协议,老实说,许多年过去了,收效甚微。也许,自然语言将成为异种机互联的终结协议,我们将迎来“让机器说人话”的时候了!