家里有一台很旧的小爱音箱 mini,现在只负责控制空调和闹钟。我想试试:不刷机,不换硬件,能不能让它用上新的大模型聊天?
最后跑通了。现在叫一声“小爱同学”,是ChatGPT回答;小爱音箱 mini 原生已不再支持连续对话,但现在说一声“打开连续对话”后,由我的Mac接管实现了连续对话。
好的开发者不会重复造轮子,第一件事是去 github 看有哪些可以用的开源项目。
有好几个相关项目,但都停止维护了,看了看社区讨论,最后选了 MiGPT-Next,修复整理在 Autopolis/migpt-next 的 apps/local 中,继续作为开源非商业项目分享。
好的开发者现在不会自己动手的,用 Codex App(现在改名叫 ChatGPT 了)切到 gpt-6-astra,放开所有电脑操作权限,让 ChatGPT 全权接管,直到功能完成。因为是日常对话用,所以模型选了 gpt-5.6-luna。
下面是我的小爱音箱 mini 的 ChatGPT 对话接入实现记录。如果你也想改造你的小爱音箱的话可以给你的 AI agent 一些参考,当然如果你愿意自己手搓也可以参考。
先搞清楚,模型到底运行在哪里
这套方案没有把大模型装进音箱,也没有把音箱改造成一台离线 AI 设备。
它的路径是:
说话 → 小爱识别并上传到小米云
→ Mac 上的程序读取新的提问
→ 调用配置的模型 API
→ 把回复交给音箱播报
音箱继续使用原有的语音识别和播报能力,Mac 负责把问题转交给模型。
因此,免刷机确实降低了改造门槛,但也保留了几个条件:小米云接口要能用,模型 API 要能用,运行程序的电脑也要保持开机联网。
如果你把电脑关了,音箱不会继续替你运行这段程序。这个条件最好在开始折腾前就知道。
第一个坑:确认你的小爱音箱设备型号
最开始我把它叫成了 Lite。后来确认是叫 mini。
名字要填入配置的,配置填错了肯定是不管用的。
登录后查询设备列表,这台音箱返回的硬件型号是 LX01,设备模型是 xiaomi.wifispeaker.lx01。配置应该依据你的设备真实信息,而不是拿另一篇小爱音箱 Play 教程里的参数直接填进去。
上游的兼容表把 LX01 列为基本可用、但不支持其连续对话方案的型号。这个信息值得参考,不过还不能替代对眼前这台机器的测试。
我的顺序是先验证三件事:账号里能找到设备、能读取提问、音箱能接受并播放一条测试句。基础问答没跑通之前,先不碰连续对话。
第二个坑:小米音箱的登录认证需要 passToken
项目作者给出的办法是先在浏览器登录小米账号,然后从这个登录会话里取得 passToken,交给本地程序使用。
实际操作时,ChatGPT App 反馈浏览器操作出现了故障,所以我自己动手从小米网站登录成功的页面取出了 passToken。
第三个坑:表单是空的,看起来像没有保存
每次打开本地配置页,输入框都是空白。我自然以为前面填过的账号和 API key 没保存下来,又准备重填一遍。
后来 ChatGPT 把页面改成显示每一项的“已保存”状态,并明确写出:
输入框留空会保留原值,无需重复填写。
要更新哪项配置,就只填那一个字段。其他空白字段不会把旧配置清掉。
第四个坑:端口还在监听,配置网页却打不开
配置页还真出现过一次打不开。
检查发现,服务进程还在,端口也在监听,但请求一直没有响应。原来的临时页面使用了单线程 HTTP 服务,一个没有完成请求的连接就能挡住后面的访问。
浏览器会提前建立连接。对于这种场景,Python 的 ThreadingHTTPServer 文档专门提到了并发处理的必要性。
修复是改用并发服务,并给连接设置超时。验证时特意保持一个空闲连接不发送请求,再从另一个连接打开页面,确认页面仍然正常返回。
所以,“进程在”“端口开着”和“页面能用”,是三个不同的检查结果。
第五个坑:终于回答了,但回答了两次
第一次真正向音箱提问,我问的是天空为什么是蓝色的。
它有回答。但感觉答了两次,第一段还被打断了。
实际发生的是:小爱先开始回答,Mac 读到问题后再请求模型,模型回复返回时,新的播报接管了音箱。
更关键的是,上游的 abortXiaoAI() 虽然叫“打断小爱”,当时的实现却直接返回 false,没有执行暂停动作。
本地适配层做了两处调整:
- 检测新提问的间隔从 2 秒改成 1 秒。
- 收到需要模型处理的问题后,先请求暂停原生回答,再调用模型。
复测时,暂停请求被接受,但这里没有实现“实时无延迟”。免刷机方案必须等云端记录出现,小爱仍然可能先说出一两个字然后再被 ChatGPT 打断。
第六个坑:有些指令 ChatGPT 做不了,还只能依赖小爱
gpt-5.6-luna 不知道当前时钟,不会查当前天气,最主要的是不能接入米家网关控制空调。
于是 ChatGPT App 使用关键词分类,保留常见的音乐、音量、闹钟和家电控制口令,让它们继续走原生小爱。
后续可以考虑在Mac上实现时钟控制和天气的查询
第七个坑:原生连续对话没有开起来
我记得小爱有连续对话功能,于是先试了原来的口令:
小爱同学,打开连续对话
这台 mini 的回复是“好像超出我的能力范围了”。至少在这次测试的设备与固件上,不能直接依赖这个原生能力。
但设备规格里有远程唤醒指令。问题变成了:能不能在模型说完之后,再唤醒音箱一次?
ChatGPT 让音箱读一段测试文字,同时查询两种接口。播报时,MiNA 返回 playing,MIoT 的 4,1 属性返回 1;说完后,它们分别变成 idle 和 0。这次约 16 秒的采样里,能看到完整的状态变化。
有了这个结果,连续对话才有了可靠一些的触发依据:
模型回答
→ 音箱开始播报
→ 观察到播放中
→ 连续确认播放结束
→ 检查没有更新的问题或控制指令
→ 调用 LX01 的 MIoT 5,2 唤醒
→ 等待下一句
现在仍然沿用“打开连续对话”这个口令,只是接下来由 Mac 上的程序完成续听。
这里特意加了几条限制:如果没确认播报结束,就不猜时间去唤醒;如果已经有新指令,就取消旧回复的唤醒;每次说完只唤醒一次,没有人接话就不再反复唤醒。
最近 12 条消息用于上下文。退出会话或五分钟没有新问题后,清空上下文。这样可以接着追问,也不必一直带着很久以前的话题。
第八个坑:前台能跑,后台服务未必能跑
到这里,在终端里启动程序已经能用了。但我不想每次都手动打开终端。
最初把 macOS 后台服务指向 Documents 里的项目目录,启动失败,任务记录里出现 EX_CONFIG。仅凭这个退出码不能把原因说死,但把运行文件移到标准应用数据目录后,服务正常启动了。
最后采用的方式是,把程序和运行配置放到 Library/Application Support 下,再由当前用户的 LaunchAgent 启动。这样结束配置窗口或聊天后,音箱接入程序仍然运行。
电源也要单独确认。这台 Mac 已经开启“使用电源适配器供电且显示器关闭时,防止自动进入睡眠”。屏幕熄灭不等于程序休眠,合盖又是另一个条件。
如果你也想试试,建议按这个顺序
不要一上来就打开所有功能。先照着仓库里的安装说明,一步一步确认:
- 查到自己的设备,确认型号和设备编号。
- 让模型 API 单独返回一条短回复。
- 让音箱单独读出测试句,并在现场确认听到了。
- 说一个问题,核对模型调用和音箱播报是否都发生。
- 最后再开启连续对话,测试续听、追问和退出。
这次只验证了一台小米音箱 mini。不知道是不是“所有小爱都支持”,也还没有完成所有固件、所有系统和长期运行场景的验证。
代码和实测范围都放在 Autopolis/migpt-next。如果你有不同型号或固件的结果,也欢迎带着复现步骤和脱敏日志一起补充。
