惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
Hacker News: Ask HN
Hacker News: Ask HN
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
The Exploit Database - CXSecurity.com
The Hacker News
The Hacker News
Security Latest
Security Latest
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Scott Helme
Scott Helme
H
Heimdal Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
WordPress大学
WordPress大学
雷峰网
雷峰网
L
LangChain Blog
Y
Y Combinator Blog
I
Intezer
V
Vulnerabilities – Threatpost
Apple Machine Learning Research
Apple Machine Learning Research
The Last Watchdog
The Last Watchdog
Simon Willison's Weblog
Simon Willison's Weblog
W
WeLiveSecurity
P
Privacy International News Feed
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
AI
AI
博客园 - Franky
Hacker News - Newest:
Hacker News - Newest: "LLM"
Martin Fowler
Martin Fowler
K
Kaspersky official blog
U
Unit 42
S
Schneier on Security
Webroot Blog
Webroot Blog
Know Your Adversary
Know Your Adversary
T
Tor Project blog
aimingoo的专栏
aimingoo的专栏
Engineering at Meta
Engineering at Meta
G
GRAHAM CLULEY
美团技术团队
TaoSecurity Blog
TaoSecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Google DeepMind News
Google DeepMind News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
P
Proofpoint News Feed
爱范儿
爱范儿
F
Fortinet All Blogs
有赞技术团队
有赞技术团队

元视角

.NET 生态下的 Agent 框架选型:从 ReAct 到原生推理 - 元视角 从「能用」到「好用」:LLM 流式响应实现方式的探索之路 - 元视角 当我用 2000 条聊天记录,让 AI 为我画一幅自画像 - 元视角 基于 Supabase 的 AI 应用开发探索 - 元视角 微博 × MCP:社交媒体新玩法解锁 - 元视角 四点钟海棠花未眠 - 元视角 Semantic Kernel × MCP:智能体的上下文增强探索 - 元视角 基于 K-Means 聚类分析实现人脸照片的快速分类 - 元视角 容器技术驱动下的代码沙箱实践与思考 - 元视角 温故而知新:后端通用查询方案的再思考 - 元视角 浅议 CancellationToken 在前后端协同取消场景中的应用 - 元视角 Semantic Kernel 视角下的 Text2SQL 实践与思考 - 元视角 关于 ChatGPT 的流式传输,你需要知道的一切 - 元视角 RAG 的是与非、Rewrite 和 Rerank - 元视角 使用 EFCore 和 PostgreSQL 实现向量存储及检索 - 元视角 基于 LLaMA 和 LangChain 实践本地 AI 知识库 - 元视角 使用 llama.cpp 在本地部署 AI 大模型的一次尝试 - 元视角 如何为 Git 配置多个 SSH Key - 元视角 C# 使用 LibUsbDotNet 实现 USB 设备检测 - 元视角 基于 C# 实现样式与数据分离的打印方案 - 元视角 基于 SVG 的图形交互方案实践 - 元视角 前端视频播放技术概览 - 元视角 温故而知新,再话 Python 动态导入 - 元视角 后 GPT 时代,NLP 不存在了? - 元视角 视频是不能 P 的系列:使用 Milvus 实现海量人脸快速检索 - 元视角 GDI+下字体大小自适应方案初探 - 元视角 程序员视角下的三体世界随想 - 元视角 关于 Docker 容器配置信息的渐进式思考 - 元视角 在 Docker 容器内集成 Crontab 定时任务 - 元视角 为你的服务器集成 LDAP 认证 - 元视角 似花还似非花 - 元视角 视频是不能 P 的系列:使用 Dlib 实现人脸识别 - 元视角 浅议分布式链路追踪与日志的整合 - 元视角 关于 Git 大文件上传这件小事 - 元视角 .NET 进程内队列 Channel 的入门与应用 - 元视角 使用 Fody 实现 .NET 的静态编织 - 元视角 .NET Core + ELK 搭建可视化日志分析平台(下) - 元视角 聊一聊前端图片懒加载背后的故事 - 元视角 支持外部链接跳转的 Vue Router 扩展实现 - 元视角 视频是不能 P 的系列:OpenCV 和 Dlib 实现表情包 - 元视角 不得不说的 ASP.NET Core 集成测试 - 元视角 再议 DDD 视角下的 EFCore 与 领域事件 - 元视角 Vue.js 前端项目容器化部署实践极简教程 - 元视角 再见,人间四月天 - 元视角 Python 图像风格化迁移助力画家梦想 - 元视角 利用 ASP.NET Core 中的标头传播实现分布式链路追踪 - 元视角 利用 gRPC 实现文件的上传与下载 - 元视角 七种武器:延迟队列的原理和实现总结 - 元视角 gRPC 流式传输极简入门指南 - 元视角 Envoy 集成 Jaeger 实现分布式链路追踪 - 元视角 浅议非典型 Web 应用场景下的身份认证 - 元视角 gRPC 借助 Any 类型实现接口的泛化调用 - 元视角 分布式丛林探险系列之 Redis 集群模式 - 元视角 分布式丛林探险系列之 Redis 主从复制模式 - 元视角 通过 Python 预测 2021 年双十一交易额 - 元视角 gRPC 搭配 Swagger 实现微服务文档化 - 元视角 SSL/TLS 加密传输与数字证书的前世今生 - 元视角 使用 Python 自动识别防疫健康码 - 元视角 你不可不知的容器编排进阶技巧 - 元视角 ASP.NET Core 搭载 Envoy 实现 gRPC 服务代理 - 元视角 再话 AOP,从简化缓存操作说起 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT) - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的监控预警 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的反向代理 - 元视角 ASP.NET Core gRPC 打通前端世界的尝试 - 元视角 EFCore 实体命名约定库:EFCore.NamingConventions - 元视角 ASP.NET Core gRPC 集成 Polly 实现优雅重试 - 元视角 ASP.NET Core gRPC 健康检查的探索与实现 - 元视角 ASP.NET Core gRPC 拦截器的使用技巧分享 - 元视角 SnowNLP 使用自定义语料进行模型训练 - 元视角 使用 HttpMessageHandler 实现 HttpClient 请求管道自定义 - 元视角 ABP vNext 的实体与服务扩展技巧分享 - 元视角 ABP vNext 对接 Ant Design Vue 实现分页查询 - 元视角 源代码探案系列之 .NET Core 跨域中间件 CORS - 元视角 源代码探案系列之 .NET Core 限流中间件 AspNetCoreRateLimit - 元视角 源代码探案系列之 .NET Core 并发限制中间件 ConcurrencyLimiter - 元视角 通过 EmbededFileProvider 实现 Blazor 的静态文件访问 - 元视角 低代码,想说爱你不容易 - 元视角 记一次失败的 ThoughtWorks 面试经历 - 元视角 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览 - 元视角 通过 Python 分析 2020 年全年微博热搜数据 - 元视角 基于 Python 和 Selenium 实现 CSDN 一键三连自动化 - 元视角 使用多线程为你的 Python 爬虫提速的 N 种姿势,你会几种? - 元视角 实现网页长截图的常见思路总结 - 元视角 温故而知新,由 ADO.NET 与 Dapper 所联想到的 - 元视角 视频是不能 P 的系列:OpenCV 人脸检测 - 元视角 作为技术宅的我,是这样追鬼滅の刃的 - 元视角 使用 Python 抽取《半泽直树》原著小说人物关系 - 元视角 厉害了!打工人用 Python 分析西安市职位信息 - 元视角 使用 dotTrace 对 .NET 应用进行性能分析与优化 - 元视角 一道 HashSet 面试题引发的蝴蝶效应 - 元视角 基于选项模式实现.NET Core 的配置热更新 - 元视角 Dapper.Contrib 在 Oracle 环境下引发 ORA-00928 异常问题的解决 - 元视角 .NET Core 中对象池(Object Pool)的使用 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(下):EventBus 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(中):RabbitMQ 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(上):基础篇 - 元视角 记一次从已损坏的 Git 仓库中找回代码的经历 - 元视角 .NET Core 原生 DI 扩展之属性注入实现 - 元视角 .NET Core 原生 DI 扩展之基于名称的注入实现 - 元视角
小爱音箱集成 ChatGPT 的不完全教程 - 元视角
飞鸿踏雪 · 2023-03-20 · via 元视角

2023年三月对于金融和科技领域来说,可谓是“冰火两重天”。硅谷银行倒闭事件像一枚深水炸弹一样在金融领域扩散开来,而 OpenAI 则凭借 ChatGPT 这款产品一路“狂飙”,成为当下最负盛名的爆款话题。就在百度推出同类产品“文心一言”的前夕,OpenAI 正式发布了 GPT-4,直至微软高调宣布在 Office 全家桶中集成了 GPT-4,将这场技术狂欢推向高潮。作为一个关注聊天机器人的人,我从大学时期就开始通过 AIML 标记语言构建语料库,并逐渐接触 NLP 领域的知识。我认为这一波人工智能的热度代表了 OpenAI 主张的大语言模型(LLM)的胜利。ChatGPT 虽然始于聊天机器人,但绝不会止于聊天机器人。它的最终形态或许会是钢铁侠的智能管家“贾维斯”,抑或是《流浪地球》里超级人工智能 MOSS。事实上,我日常会用 ChatGPT 写程序原型、翻译文本、提取主题/关键词,这段时间更是尝鲜了智能家居。因此,我想和大家分享一下小爱音箱集成 ChatGPT 的过程。

基本原理

如果你像博主一样是一名智能家居新手玩家,那么在正式接触智能家居之前,你应该至少听说过 WIFI、ZigBee、BLE 这些名词。这些是指智能家居中的通信协议,例如小爱音箱可以作为蓝牙 Mesh 网关去连接那些使用蓝牙通信的设备,而 ZigBee 则是一种短距离、低功耗、支持自组网的无线通信协议。虽然 ZigBee 对外宣称是一个开放标准,但不同的厂商出于利益考虑,并不完全兼容彼此的设备,离真正的万物互联始终还有一段距离。因此,你会发现米家有类似多模网关这样的产品,现阶段的智能家居是一个多种协议混合使用的局面,2C 市场更青睐蓝牙和 WIFI 方案,2B 市场更青睐 ZigBee 方案。为了让更多的设备加入整个智能家居生态,开源的智能家居方案 HomeAssistant 就此诞生。其中的 IFTTT 组件可以扩展出更多的智能玩法;为了让设备加入苹果公司的 HomeKit 生态,HomeBridge 这样一个“曲线救国”的方案就此诞生。可以说,现阶段智能家居的高阶玩法,基本都是围绕这两个平台展开。作为一名普通的消费者,你并没有机会去选择使用哪种协议,更多的是去选择使用哪一个平台。

Smart Home Protocols: WiFi vs Bluetooth vs ZigBee vs Z-Wave Smart Home Protocols: WiFi vs Bluetooth vs ZigBee vs Z-Wave

前面提到 ZigBee 的自组网具有离线可用的特性。与 WIFI 不同,WIFI 需要接入互联网,一旦断网就无法对设备进行有效控制,而蓝牙和 ZigBee 就没有这种烦恼。唯一的问题是它们都需要对应的网关。目前,米家的设备控制主要有远程控制和本地控制两种方式。远程控制需要发送指令到米家的服务器,这种方式对小米来说更有利,唯独不利于实现“万物互联”这一伟大远景。本地控制至少需要一个智能家庭屏或中枢网关,其好处是延迟低、离线可用、保障隐私。从某种角度来说,这与人们开始使用 NAS 搭建私有云的初衷一致,都是为了更好地保护隐私和数据安全。由于博主不具备本地控制的条件,所以,我们还是采用远程控制的方案,即通过向米家的服务器发送指令来达到控制设备的目的。在这个过程中,接入 ChatGPT 的 API,再控制小爱音箱将其响应内容朗读出来。这个方案可以实现远程控制的同时,利用 ChatGPT 弥补小爱同学“智能”上的不足。如图所示,下面是一个简单的示意图:

米家远程控制及 ChatGPT 接入示意图 米家远程控制及 ChatGPT 接入示意图

如何控制米家

接下来,我们来探讨如何控制米家设备。米家通过 HTTP 协议实现远程控制,为此,我们推荐使用两个非常实用的库:MiServicepython-miio。这两个库各有优缺点。如果你对米家物联网协议更感兴趣,我们建议使用 python-miio;如果你希望更快、更容易地上手米家智能家居,我们则推荐使用 MiService。从使用方式上来看,MiService 使用 DID 来区分不同的设备,而 python-miio 使用 TokenIP 来区分不同的设备。下面,我们以 MiService 为例来演示如何通过编程控制米家设备。

网关在整个智能家居中的地位 网关在整个智能家居中的地位

在开始前,请确保你安装了 MiService , 你可以选择下面两种方式之一进行安装:

# 从包管理器安装
python -m pip install MiService
# 从源代码安装
git clone git@github.com:Yonsm/MiService.git
cd MiService
python -m pip install .

安装后,你会在 Python 主目录下的 Scipts 目录看到一个叫做 micli 的命令行工具。如果你的 Scripts 目录在全局环境变量中 Path 中,那么,恭喜你,你可以直接在终端中使用该命令。为了向该工具表明身份,我们需要在终端中导出下面两个环境变量:

export MI_USER=<小米账号>
export MI_PASS=<小米密码>

此时,我们在终端中输入命令 micli list,我们就可以得到当前账号下所有的米家设备信息:

[{
    "name": "客厅主灯",
    "model": "yeelink.light.ceil31",
    "did": "",
    "token": ""
}, 
{
    "name": "小爱同学",
    "model": "xiaomi.wifispeaker.x08e",
    "did": "",
    "token": ""
}, 
{
    "name": "温湿度计",
    "model": "miaomiaoce.sensor_ht.t2",
    "did": "",
    "token": ""
}]

可以注意到,在这个列表中有我们想要的小爱同学,在获得关键信息 DID 后,我们将其在终端中导出:

export MI_DID=<请替换为你的DID>

通过上述信息,我们了解到小爱音箱的型号为 X08E,你可以在音箱底部找到这个信息。接下来,我们需要访问 https://home.miot-spec.com/ 这个网站,以获取更多控制小爱音箱的信息。在该网站中,输入当前型号,你将会看到如下页面:

米家产品规范截图-1 米家产品规范截图-1

点击页面中标有链接的部分,你将看到小爱音箱拥有各种控制指令,如下图所示:

米家产品规范截图-2 米家产品规范截图-2

针对我们最关心的语音部分,你会发现它整体上分为三个级别:分类、属性(Properties) 和动作(Actions)。每个分类都有唯一的 SIID,每个属性都有唯一的 PIID,每个动作都有唯一的 AIID。参考 MiService 的文档,我们可以轻松编写以下指令:

# 获取小爱音箱播放状态 1:Playing, 0:Stop, 2:Pause
micli 3-1 
# 播放文本内容
micli 7-3 Hello
# 执行文本指令
micli 7-4 为我点亮世界
# 播放
micli action '{"did":"<你的DID>","siid":3,"aiid":2,"in":[]}'
# 暂停
micli action '{"did":"<你的DID>","siid":3,"aiid":3,"in":[]}'
# 停止
micli action '{"did":"<你的DID>","siid":3,"aiid":4,"in":[]}'
# 设置音量
micli 2-1=#60

以上演示以小爱音箱为例,事实上,只要掌握了这种方法,大多数米家设备都可以通过编程实现控制。例如,智能门锁和门窗传感器可以通过程序获取电池耗电量的信息,以便提醒及时更换电池。目前,第三方物联网平台如 巴法云 采用发布/订阅模式来控制单片机,这使得像 ESP32 这样的开发板可以快速接入米家生态。我个人认为,这些技术都非常有趣,值得我们做进一步的深入探索。

如何接入 ChatGPT

对于 Python,接入 ChatGPT 非常方便,因为 OpenAI 官方提供了 SDK。首先,我们需要使用 pip 安装 openai 包:

python -m pip install openai

接下来,我们只需导入 openai 模块,并设置 API 密钥:

import openai
openai.api_key = "<YOUR_API_KEY>"

现在,我们可以调用 OpenAI 的 API,输入对话文本,获取机器生成的回复,如下所示:

completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo", 
    messages=[{"role": "user", "content":"Hi,ChatGPT!"}]
)

当然,鉴于 OpenAI 在国内的可访问性问题,笔者通过 Vercel 搭建了一个代理服务。此时,你可以使用下面的 API 接口,如下所示。虽然这只是对官方 SDK 进行了二次封装,但是考虑到国情如此,我们只能说聊胜于无:

curl -X POST 'https://openai-proxy.yuanpei.me/openai/v1/completions' \
-H 'Authorization: Bearer <Your-OpenAI-API-KEY>' \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content":"Hello ChatGPT!"}]
}'

更多的细节,大家可以参考这里:https://github.com/qinyuanpei/openai-proxy

风云合璧

到目前为止,整个思路非常清晰。当我们使用米家 App 时,可以注意到米家存储了我们和小爱同学的对话内容。因此,我们的思路是通过接口获取对话记录,每一组对话中的第一句话,就是我们对小爱同学的提问。此时,我们可以用这个问题去询问 ChatGPT,等待 ChatGPT 给出回应后,再利用上述技巧将文本转化为语音输出。然而,这个方案最大的弊端是,无法完全屏蔽小爱同学自身的交互逻辑。因此,在下面的演示视频中,我们不得不通过程序来强行打断小爱同学的发言,这其实是一种无奈的做法:

当然,我们还有另一种思路,即通过蓝牙连接到小爱音箱。在这种情况下,小爱同学就完全成为一个输出设备,甚至无需介入米家。但这样做会失去与小爱同学互动的乐趣,除非你想创建类似于“贾维斯”的人工智能程序,否则请不要轻易尝试这条注定艰辛的道路。下面是一个针对这种方案的简化实现:

import speech_recognition as sr
import pyttsx3

# 初始化语音识别 & 语音合成
r = sr.Recognizer()
engine = pyttsx3.init()

# 语音识别函数
def recognize_speech():
    with sr.Microphone() as source:
        print('Please speak:')
        audio = r.listen(source)
    try:
        text = r.recognize_google(audio, language='zh-CN')
        print('You said:', text)
        return text
    except Exception as e:
        print('Error:', e)
        return ''

# 语音合成函数
def speak(text):
    engine.say(text)
    engine.runAndWait()

# 主程序
speak('你好,请问有什么可以帮助您的?')
while True:
    text = recognize_speech()
    if text == '退出':
        break
    elif text.startswith('帮我')
        # todo:在这里调用 ChatGPT
        pass
    else:
        speak('对不起,我不明白您的意思,请您再说一遍。')

视频中的演示程序源自 Github 上的一个开源项目 https://github.com/yihong0618/xiaogpt。在此基础上,我做了一些微不足道的工作。首先,将对小爱的控制方式完全替换为上文中的指令,因为我感觉 MiNAService 这个类不是特别稳定;其次,将 OpenAI 的 API 替换为我自己架设的代理接口,这样就解决了科学上网的烦恼;最后,将 MI_USERMI_PASSMI_DIDOPENAI_API_KEY 四个参数放入 .env 文件中,简化了程序启动时的参数。我已将这些工作提交到了我的 Github 上,对此感兴趣的朋友可以自行下载:https://github.com/Regularly-Archive/2023/tree/main/XiaoiGPT

本文小结

在这个过程中,我最大的收获是学会了如何用编程控制米家设备。尽管现在智能家居的交互场景还相对有限,但就像 ChatGPT 一样,当你意识到 AI 正式进入一个新阶段的时候,一切都显得为时已晚。百度的文心一言发布后,陆续有人拿到了内测资格,一时间好像没有人再去讨论 ChatGPT 了,因为大家的精力都放在戏谑文心一言生成的图片上面。我经常思考未来是否会出现一种职业叫做“魔法吟唱师”,负责为各种 AI 模型输入提示词。去年 Stable Diffusion 开始流行时,我就意识到提示词对结果产生影响。遗憾的是,此时此刻,人类仍然为比 AI 多懂几个成语、多吃过几道菜而沾沾自喜。作为一名技术人员,我对科技的未来一直抱有乐观的态度,因为我认为技术日新月异,真正拖累人心的始终是那些非技术因素。人们总以为 AI 能帮助解决各种各样的问题,但问题是我们是否能清晰地表达出我们的想法呢?我们总是太过痴迷于华丽的言辞,而忽略了简单直接的表达方式。人们实在太享受口是心非的感觉,就像今天这篇博客,其实是由我和 ChatGPT 一起完成的,但你是否能分清其中的真假吗?