一枚挂在脖子上、能听懂你说话的 AI 硬件。按下按钮 → 说话 → 云端转成文字 → 大模型思考 → 语音回你。
代码级颗粒度 · 三端架构(固件 / 锚点 / 宿主)· 每一行关键函数都能追溯到源码行号
跑在 ESP32-C3(8MB Flash,无 PSRAM)上。负责麦克风录音、喇叭播放、Wi-Fi / BLE 联网、把声音切成 243 字节的帧发出去、接收云端语音播出来。核心文件 9 个 wb_*.c。
一个「云端中转站」。卡片和大脑都主动连它,它负责鉴权、配对、原样转发。故意做得很「笨」——不碰音频内容,这样三端能各自独立升级。
跑在你电脑上的「大脑」。把收到的声音转成文字(ASR)、交给大模型思考、再把回答合成语音(TTS)回给卡片。同时暴露 HTTP + MCP 接口给 WorkBuddy 调用。
说人话版:你按一下、说句话,到底发生了什么?
| 步骤 | 发生了什么 | 在哪一端 |
|---|---|---|
| 1. 按住说话 | 按下按钮,麦克风开始录,音频存进内存环形缓冲区(默认约 1 秒) | 固件 wb_app.c |
| 2. 边录边发 | 每攒够 240 字节,就包成 243 字节一帧,带上序号,走网络发出去 | 固件 wb_audio.c / wb_anchor.c |
| 3. 中转 | 锚点收到帧,原样转发给已经连上来的「大脑」(网关) | 锚点 session.js |
| 4. 转文字 | 宿主把 μ-law 音频还原成 PCM,调 ASR 服务转成文字 | 宿主 session.py / asr.py |
| 5. 思考 | 文字交给大模型,生成一句回答 | 宿主(或 WorkBuddy) |
| 6. 合成语音 | 回答文字合成语音,转成 μ-law 字节流,分帧发回卡片 | 宿主 tts.py / audio.py |
| 7. 播放 | 卡片收到帧,按序号依次喂给喇叭播放出来 | 固件 wb_audio.c 播放链路 |
巴掌大的芯片,内存只有几 KB 级别可自由用,网络又可能随时断。要把连续的声音「搬」过去,得解决:断线重连、丢帧、乱序、缓冲写满等一系列问题。这占了项目绝大部分工作量。
固件、锚点、宿主是三个独立发布的软件。为了让任何一端升级都不拖累另两端,锚点被刻意设计成「只转发、不理解」,协议保持极简。
屏幕要显示中文,默认字体没有中文字形,得专门做字体方案;语音要走 ASR(听懂)和 TTS(说话)两个方向。
设备和网关用两把不同的令牌,卡片令牌泄露不等于能冒充大脑,反之亦然。
| 端 | 语言 | 主要文件 | 代码量(约) |
|---|---|---|---|
| 固件 | C(ESP-IDF 5.5.3) | wb_app.c、wb_anchor.c、wb_audio.c 等 9 个模块 | 约 24 万字节源码 |
| 锚点 | JavaScript(Worker + Durable Objects) | index.js、session.js、protocol.js、version.js | 4 个文件 |
| 宿主 | Python | bridge.py、session.py、protocol.py、transport/ 等 | 约 15 个模块 |