AI Passport

AI Passport 项目总览

一枚挂在脖子上、能听懂你说话的 AI 硬件。按下按钮 → 说话 → 云端转成文字 → 大模型思考 → 语音回你。

代码级颗粒度 · 三端架构(固件 / 锚点 / 宿主)· 每一行关键函数都能追溯到源码行号

#一句话说清楚它是什么

这是一个 「会说人话的 AI 随身挂件」:你对着它讲话,它把声音传到一个云端大脑,大脑听懂后给你一段语音回答。中间最麻烦的「怎么把声音稳定地从巴掌大的芯片传到电脑 / 服务器」这件事,就是这个项目的核心工程。它的难点不是 AI,而是「可靠地把声音搬过去」。

#三个角色(三端)

📟 固件
ESP32-C3 芯片
录音 / 播放 / 联网
◀─▶音频帧 + 控制
☁️ 锚点
Cloudflare Worker
配对 + 转发
◀─▶原样转发
🧠 宿主
Python 服务
转写 / 推理 / 合成
ai-passport/

固件层(C / ESP-IDF)

跑在 ESP32-C3(8MB Flash,无 PSRAM)上。负责麦克风录音、喇叭播放、Wi-Fi / BLE 联网、把声音切成 243 字节的帧发出去、接收云端语音播出来。核心文件 9 个 wb_*.c。

anchor/

锚点层(Cloudflare Worker + DO)

一个「云端中转站」。卡片和大脑都主动连它,它负责鉴权、配对、原样转发。故意做得很「笨」——不碰音频内容,这样三端能各自独立升级。

passport-companion/

宿主层(Python)

跑在你电脑上的「大脑」。把收到的声音转成文字(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.js4 个文件
宿主Pythonbridge.py、session.py、protocol.py、transport/ 等约 15 个模块