这一切始于几年前,当我想到“能否用Alexa来管理物理设备?”我做了一个简单的演示项目,展示给我的业余无线电朋友们看。你可以这样说,“Alexa,把我的天线转90度,”我的模型天线就会神奇般地转动起来。这是一个有趣的周末项目,使用了树莓派、步进电机和一个小模型天线。如果你想看,我把它发布在了YouTube上,有兴趣可以去看看。
Alexa天线应用程序
智能小屋模型Alexa的实验很棒,但也遇到了一些问题。使用Alexa时,你需要非常精确地表达你的指令。在我的应用中,Alexa要求你说“Alexa,将我的天线转XX度”,只有这句话能被识别。随着大型语言模型(LLM)变得越来越普遍,我开始考虑利用它们来控制电机、设备和传感器。
“如果我弄个玩具屋,再加上一堆传感器和微控制器,然后为它们写一个 REST API 服务器呢?”然后,我会让一个大模型把人类语言转换成 REST API 请求并发送给服务器。此外,我还想要一个看起来逼真的东西,而不是一堆传感器随意摆在我桌子上。
幸运的是,我在亚马逊找到了我需要的东西:一个附有许多传感器和一个微控制器的木屋。我要赞扬我从Keyestudio购买的套件的质量:它非常容易组装和连接传感器,而且软件一运行就成功了!这在同类套件中其实不常见。
图片来自Keyestudio.com
这个套件包括了一个简单的Arduino控制器,以及一个包含了一些业务逻辑的示例程序:比如,当屋顶的雨传感器检测到信号时,伺服电机就会把窗户关闭。
它运作得很好,但是我还需要一个服务器来处理远程来的请求。
IoT服务器我决定换到树莓派Pico W(Raspberry Pi Pico W)和MicroPython。Pico W提供了我需要的连接功能,我打算用MicroPython来搭建一个简单的REST API服务器。
关于使用AI助手
随着这种情况越来越普遍,我请Claude.ai帮我搞定这个项目。
我想用MicroPython为树莓派Pico编写一个程序。程序应该运行一个连接到WiFi的web服务器。这个web服务器应该接受REST请求,并对Pico执行相应的操作,例如:从传感器获取信息,开启和关闭LED,开启和关闭电机(伺服电机和步进电机)等。请帮我为这个应用创建一个API。
克劳德回复了一串可以用于我们计划中的API接口的curl
命令。我喜欢这种做法:我先定义了用户体验(在我们这里,就是REST API,),然后开始实现。
它创建了一个非常简单的Web服务器,没有使用任何框架,仅仅通过套接字来实现。我问是否可以用像Flask这样的框架,Claude建议说,用MicroPython的话,Microdot更常用,因为它占用的资源更少,所以更适合。我得知Microdot是由Miguel Grinberg开发的,Miguel Grinberg也是撰写关于Flask最流行书籍的作者之一。这确实是个不错的建议,我请Claude用Microdot重新编写web服务器。
做完那事后,我在Pico上测试了服务器,一切正常!但我还有个想法,就问了。
请帮我写一个 Microdot 的 GET 函数,当访问
/sensors
时返回传感器列表,当访问/sensors/id
时返回传感器的值。我觉得这会有所帮助。
而且这里还有一个有趣的发现!这个概念听起来很奇怪,但实际上它指的是“HATEOAS”(超媒体作为应用状态引擎)。克劳德向我解释了这一概念及其背后的思想,并通过示例代码向我展示了如何响应类似 /sensors
或 /leds
路由的服务器代码。这些代码返回了关于传感器和 LED 位置(如屋顶、花园、门)的信息,以及它们的参数(例如 LED 的颜色、传感器的校准),最关键的是,返回了我应该用来与它们交互的链接。
那和我需要的差不多。
使用LLM来生成REST API调用现在,多亏了克劳德的帮助,我有了一个这样的服务器,它对如 curl http://server/leds
的请求返回如下 JSON 数据:
{
"_links": {
"filter_by_color": {
"href": "/leds/filter?color={color}",
"templated": true
},
"self": {
"href": "/leds"
},
"filter_by_location": {
"href": "/leds/filter?location={location}",
"templated": true
}
},
"data": {
"1": {
"color": "黄色",
"location": "屋顶",
"状态": 0,
"_links": {
"on": {
"href": "/leds/1/on"
},
"self": {
"href": "/leds/1"
},
"off": {
"href": "/leds/1/off"
},
"toggle": {
"href": "/leds/1/切换"
}
}
},
"2": {
"color": "白色",
"location": "花园里",
"状态": 0,
"_links": {
"on": {
"href": "/leds/2/on"
},
"self": {
"href": "/leds/2"
},
"off": {
"href": "/leds/2/off"
},
"toggle": {
"href": "/leds/2/切换"
}
}
}
}
}
如果我从其他路由(比如 /sensors
和 /motors
)获取类似的 JSON 数据,并让它将人类的请求转换成 curl
命令,然后我就可以把这些命令通过 requests
Python 库发送到服务器,并操作设备了。
编写一个简单的Python脚本来从服务器的根路径(/
)获取初始链接,并遍历所有链接以从中获取相同的JSON。
在脚本收集了服务器的 API 描述之后,我创建了一个系统提示,其中包括了整个 JSON,该 JSON 包含了服务器上的所有链接,并在其中添加了请求:
你是一个物联网API助手。
将用户命令转换为IoT服务器使用的curl命令。
API结构: {json.dumps(self.api_structure, indent=2)}
服务器URL: {self.server_url}
仅回复curl命令,不作任何解释。
然后,我创建了一个简单的对话框,该对话框从用户那里获取自然语言输入的命令,将其添加到提示中,然后将其发送给大模型。
在这个应用中,我使用了来自Anthropic的Haiku-3.5,因为它比那些更复杂的模型更快更便宜。
将 JSON 响应转换为人类可读的语言
现在,系统已经开始运作了。我会发送消息如“打开黄色的LED”,然后它就会亮起来。或者发送“打开花园的LED”,花园中的白色LED就会亮起。我可以用正常的话来问“屋顶的灯光情况怎么样?”,它会用一个包含大量信息的JSON回应。
{
"_links": {
"config": {
"href": "/sensors/2/config"
},
"self": {
"href": "/sensors/2/值"
},
"all_sensors": {
"href": "/sensors"
},
"传感器": {
"href": "/sensors/2"
}
},
"data": {
"unit": "lux",
"type": "光照类型",
"calibrated_value": 4114.6,
"location": "屋顶位置",
"id": "2",
"raw_value": 41146
}
}
那不错,但我想要更像人类的语言,而不是那些JSON!LLM 又来帮忙了!这里又有俳句的提示:
只需提取最重要的信息,转换成简洁易懂的语言。
现在我服务器上的回答看起来像:
位于屋顶的光传感器2测得的照度是4,109.8勒克斯,显示照明条件很亮。
首次公开演示(Demo)最近我去亚特兰大的本地 Python 会议,准备一个关于这个项目的演讲并进行演示。不用说,我很紧张。
我在手机上开启了一个热点,将笔记本电脑连接到热点上,然后启动了Pico程序。它显示已成功连接到热点并获取了一个IP地址。现在,我得调整对话程序,让它指向那个地址。
对话开始了。
IoT 控制器已启动。输入 'quit' 以退出。
>>> 打开黄色 LED
LED 1 当前是黄色的,并位于屋顶上。
>>> 打开电机
当前电机 1(直流类型)位于屋顶上,并且已开启。
>>> 关闭电机
关闭电机
>>> 关闭电机
位于屋顶上的直流电机 #1 当前已关闭。
到目前为止还不错。螺旋桨一转起来,观众都很喜欢,为我鼓掌。
我把键盘切换成了西里尔文,然后打了这些字。
>>> 关掉黄色的 LED
“哇哦,是俄语吗?”我听到观众中有人在小声说。
然后,神奇的事情发生了,LED灯灭了,我收到了这条消息:
屋顶上的LED 1是黄色的,当前是关的(状态0)。
我问组织者帕布罗(Pablo),他能不能用西班牙语讲讲怎么点亮LED灯。
保罗拿起键盘,然后开始打字了:
>>> 请把那黄色的LED打开
LED 1 当前开启,黄色,位于顶部。
>>> 关掉那个该死的黄色LED
LED 1 当前关闭,位于顶部,黄色。
>>>
“哇!”观众惊叹道。
我解释说:“这个功能完全是LLM完成的。我没有编写任何相关代码。它能轻松理解和翻译多种语言,包括REST和JSON。注意,当我用俄语与它交流时,我说了‘LED(发光二极管)’这个英文单词,它完全理解了我的意思。”
经验教训
这个项目竟然变成了一段意想不到的学习之旅。我最初只是想控制一个模型屋子,最后却学到了很多东西,远远超出了最初的预期。
- MicroPython及其与常规Python的区别
- Microdot——适用于微控制器的轻量级Web框架
- HATEOAS——一个REST API设计原则,名字听起来像是在打喷嚏
- 大语言模型在自然语言处理中的惊人多用途性
最重要的是,我意识到像克莱奥这样的AI助手可以成为优秀的编程伙伴。它们不仅帮助编写代码,还能引入你可能未曾了解的最佳实践和概念。
瑞典译为: 瑞典未来计划最终修改后的翻译应为:
未来计划当然,我开始寻找扩展项目的方法。当然,我找到了一个包含42个组件的巨大Keyestudio套件,有很多传感器和致动器。
你说的话就能在LCD屏幕上显示,这不是很酷吗?气体感应器、加速度传感器、蜂鸣器和电动机都在等着我来连接。
越来越认真了当然,这只是为学习目的而创建的一个玩具项目。如果你想在真实的家庭环境中使用物联网,当然你应该了解一下Home Assistant。我也是这么做的,心想:“我能否用相同的方法来创建Home Assistant的API请求呢?”不用说,该项目已经实现了LLM的API功能。“果然,英雄所见略同,”我得意地想。嘿,真是太巧了!😉
代码如果你对搭建自己的多语言智能小屋感兴趣(或者只是想看看它是怎么工作的),可以在这里查看该项目(Geekhouse:https://github.com/pavelanni/geekhouse)。欢迎贡献代码或提出问题,或者分享你的物联网冒险。
试着用你懂的任何语言,看看LLM能否将这句话翻译成REST API调用!试试其他的LLM,试试在你家里的实验室里运行的本地LLM。很有可能,使用本地LLM会使LED的开关速度更快。
结束语我喜欢这个项目从我早期对像Alexa这样的语音助手的实验,逐渐发展到在物联网中使用LLM的过程。在这个项目里,我不仅利用LLM把人类语言翻译成JSON,还帮我编写代码和学习新知识。LLM确实是非常棒的助手!
共同學習,寫下你的評論
評論加載中...
作者其他優質文章