esp32-thinks - 让 ESP32 小硬件用上你自己的模型栈
esp32-thinks 是维护者 raullenchai 发布的 ESP32 固件补丁项目,基于 Meta 开源的 muse-gadget-sdk,把语音识别、对话与语音合成拆成三个独立的 OpenAI 兼容端点,让带麦克风、扬声器和圆形屏的小硬件按自己的配置说话。采用 MIT 许可,最新版本 v0.2.12。
esp32-thinks 是一个面向 ESP32-S3 硬件的固件项目,目标是让一台带麦克风、扬声器和圆形显示屏的小设备成为可自定义的语音助手。据项目自述,它的核心主张是「不把大脑锁在某个厂商手里」:语音识别(STT)、对话(chat)和语音合成(TTS)是三个彼此独立的端点,每个都可以指向任意 OpenAI 兼容服务,可以三家共用一个供应商,也可以每项各用一家。它适合愿意自己编译固件、手里有对应开发板、并且希望把语音链路指向自建或第三方兼容服务的开发者。
维护者与状态
项目由 raullenchai 维护,仓库创建于 2026-10-12,最后一次提交在 2026-10-19。最新正式版本为 v0.2.12,发布于 2026-10-19。截至 2026-10-22,仓库获得 246 个星标。从时间线看,这是一个非常年轻的项目,创建到最新版本之间只有一周左右,迭代节奏较快,接口与配置方式仍可能变动。
主要能力
以下能力均来自项目 README 的自述,未经独立验证:
- 唤醒词与按键双入口:说「Hi, ESP」或按住旋钮都能开始一轮对话。唤醒词使用 esp-sr WakeNet10,在芯片上本地运行;唤醒触发的录音以语音活动检测计时结束,按键则沿用原有逻辑。
- 自带模型栈:在一个配置文件里填写三个独立的 OpenAI 兼容端点(STT / chat / TTS),可自由混用供应商,并提供
openai、quicksilver、openmuse、custom四种预设。 - 可选 agent 层:仓库内的
openmuse/目录提供位置、时钟、天气、持久记忆和可选网页搜索能力,掌管系统提示词,并代理 STT,使 STT 与 chat 共用一条 TLS 会话;TTS 仍直连供应商。 - 流式语音回复:对话流按句子边界切分(同时处理 ASCII 与中日韩标点),每句话一落地就合成并追加到正在播放的音频之后,因此模型还在生成时第一句就已经出声。
- 长连接维护:TLS 在提问前预先准备,空闲时每 180 秒探测一次,空闲断开后可用会话票据恢复。探测失败会触发后台重新准备;两次探测之间的断连仍可能需要在对话时重连。
- 打断(barge-in):助手说话时按下旋钮,回复立即中止,进行中的请求被取消,下一句话马上开始新一轮。
- 静音保护:过于安静的录音(被打断的一轮、口袋里误触)会被丢弃,而不是变成一段凭空编造的答案。
- 卡死自动恢复:未完成的 I2S 或 LCD 任务有 20 秒期限,超时后做零分配的任务转储并重启;v0.2.11 起,I2C 扩展器持续失败一分钟后也会重启。正常休眠和较慢的云端响应不计入卡死。
- 语言跟随:按用户语言作答,无法判断时默认英文。项目称英语、中文、韩语经过测试,STT 自动检测语言;回复目标是一到两句,约 40 个英文单词或 60 个汉字。
- 语言感知音色:中文和韩文回复会选用可选的多语种 TTS 模型;QuickSilver 预设对这两类回复使用 qwen3-tts,英文使用 chatterbox-turbo。
- 无头配网:把 Wi-Fi 写进配置,设备开机自行完成配网,不需要手机 App、蓝牙配对或厂商账号。
- 串口打字测试:串口控制台路径可以走同一套推理与解码流程,但不经过麦克风采集,便于单独验证 chat 与 TTS。
使用入口
仓库地址:esp32-thinks。
据项目说明,使用前需要准备 ESP-IDF v6.0.x(面向 esp32s3),并克隆固定提交的 muse-gadget-sdk 作为底座,然后把本项目作为补丁应用上去。README 给出的流程大致是三步:先备份一次出厂 NVS 分区,作为出问题时的恢复路径;再运行 apply.sh 应用补丁并选择预设、填写密钥与 Wi-Fi;最后运行 build-and-flash.sh 编译并烧录。项目提醒烧录过程不要中断。
./scripts/backup-nvs.sh ../muse-gadget-sdk /dev/ttyACM1 ./apply.sh ../muse-gadget-sdk --preset quicksilver ./build-and-flash.sh ../muse-gadget-sdk /dev/ttyACM1
如果希望设备知道所在城市与时间、回答天气问题、跨轮记住事情,可以额外运行仓库内的 agent:./openmuse/run.sh 首次运行会生成 openmuse/.env 后退出,填好上游 API key 与 token 后再次启动,并用 --preset openmuse 重新应用配置。项目称该 agent 支持 Docker 或 Node 运行,--funnel 参数可通过 Tailscale 暴露 HTTPS,因此不需要自有域名。记忆保存在 openmuse/data/memories.json。
许可与限制
许可证为 MIT。项目自述中提到的已知边界包括:
- 硬件方面,README 明确列出 Seeed SenseCAP Watcher W1-B(ESP32-S3、1.45 英寸 412×412 圆形 LCD、ES8311 扬声器编解码、ES7243E 麦克风、PTT 旋钮),并表示 SDK 支持的其他板子属于候选,并未承诺可直接使用。
- 延迟方面,项目给出的是个别采样而非保证:QuickSilver 预设下打字输入的热启动一轮,英文与韩文约 2.2–2.5 秒,中文约 6.8 秒;语音轮次还要加上录音与 VAD,从说完到第一声大约 3–5 秒;前面挂 openmuse agent 时,打字轮次约 3.9 秒、语音轮次约 4.7 秒,开机后第一轮可能因 DNS/TLS 预热更慢。项目自己强调这些数字受供应商负载与回复长度影响很大。
- 连接行为上,若连接准备尚未完成,或较长回复需要单独建立语音连接,第一个问题仍可能付出建连开销。
- 项目以补丁形式作用于固定提交的上游 SDK,升级 SDK 时需要重新适配。
总体而言,esp32-thinks 把「换供应商」这件事从固件层面变成了配置层面,代价是需要自己完成工具链准备、编译与烧录,并接受一个仍在快速变动中的年轻项目。