摘要VibeStick 把 M5Stack StickS3 变成桌面 AI Agent 的状态屏和语音遥控器。本文从源码出发拆解固件、Python Bridge、Agent 观察器、ASR 与桌面粘贴的完整链路。建议标签ESP32-S3PythonLVGLAI Agent物联网很多“AI 硬件”的架构图喜欢画一朵云再画一道闪电仿佛多画几个箭头智能就会自己从纸里长出来。VibeStick 的思路朴素得多让小设备做它擅长的事让电脑做它不得不做的事。StickS3 有屏幕、按键、麦克风、扬声器和 Wi-Fi但没有必要保管 Codex 会话、Claude 凭据和 ASR Key。电脑看得到本地 Agent 的活动也有能力访问云端或本地语音模型。因此项目被拆成两大运行时Codex / Claude 本地活动 | v Python Bridge ----HTTP/UDP---- StickS3 | | -- ASR -- LVGL 屏幕 -- 剪贴板与按键注入 -- 麦克风/扬声器/按键 -- HUD 与诊断对应源码并不捉迷藏firmware/sticks3/src/main.c固件主流程、LVGL UI、HTTP、按键和状态渲染firmware/sticks3/src/vibe_audio.c16 kHz、16 bit、单声道 PCM 录音与提示音firmware/sticks3/src/vibe_provisioning.cSoftAP、Captive Portal、Wi-Fi 扫描和 NVSbridge/src/vibe_stick/server/app.pyBridge HTTP API 和状态汇总bridge/src/vibe_stick/providers/Codex、Claude 观察器适配层bridge/src/vibe_stick/audio/WAV 写入磁盘、ASR 与重试bridge/src/vibe_stick/paste/input_injector.pymacOS/Windows 粘贴注入。一、为什么不是让 StickS3 直连 AI 服务这不是“ESP32 性能不够”一句话就能概括的问题。真正的约束至少有四层。第一Agent 状态来自电脑本地。Codex 的运行状态和配额来自本地进程、会话 JSONL 中的事件与rate_limitsClaude 的状态也要结合进程和本地项目日志判断。StickS3 隔着 Wi-Fi 再努力也不会突然长出读取电脑文件系统的超能力。第二凭据边界更清楚。固件只保存 Wi-Fi、Bridge 地址、端口和共享 TokenASR Key 与 Agent 凭据都留在电脑端。这样设备丢了损失至少不会自动升级成“云账户也跟着丢失”。第三跨平台能力集中在 Bridge。剪贴板注入在 macOS 使用pbcopy/pbpaste osascript在 Windows 使用 PowerShell、System.Windows.Forms.SendKeys。这些差异放进固件只会把 C 项目炖成一锅操作系统火锅。第四服务可替换。TranscriptionAdapter可以走本地命令也可以调用 OpenAI-compatible/audio/transcriptions。固件只上传 PCM不关心后面坐着 SiliconFlow、Groq、faster-whisper还是未来的新模型。二、状态链路两秒一次的“你忙完了吗”固件常量VIBE_STICK_STATE_POLL_MS为 2000。设备通过GET /state拉取状态Bridge 返回统一的VibeStickStatedataclassclassVibeStickState:time:strwifi:boolble:boolbattery:int|Noneactive_provider:strprovider:ProviderState codex:CodexState alert:AlertStateprovider是当前活动 Agent 的统一视图codex则保留兼容字段。状态包含IDLE、RUNNING、DONE、APPROVAL、ERROR、OFFLINE等值。固件用 cJSON 解析后更新屏幕上的状态点、项目名和 5H/7D 配额。值得注意的是电池值由设备本地 PMIC 读取而不是信任 Bridge。Bridge 的to_jsonable()甚至明确把battery置为None。谁离电池近谁说了算架构上没有安排远程电脑隔空把脉。告警也不是每两秒响一次。Bridge 为完成、审批和错误生成稳定event_id固件记住上一次播放的事件。只有事件发生变化才播放提示音否则一个完成事件能把工位变成电子门铃体验区。三、语音链路按住说话松开发送语音流程跨越硬件、网络、ASR 和桌面输入长按正面蓝键固件启动麦克风并调用/recording/startI2S 以 16 kHz、16 bit、单声道采集 PCM最长 45 秒松开按键设备显示UPLOADING并向/recording/audio上传二进制音频数据Bridge 将 PCM 封装为 WAV进行时长、静音和削峰检查TranscriptionAdapter调用本地命令或 OpenAI-compatible ASR成功后PasteInjector将文本粘贴进当前焦点应用设备显示SENT失败时保留 PCM并允许短按重试。这条链路里最有产品味的不是“支持语音”而是失败以后怎么办。固件保留录音缓冲区Bridge 返回retryable和尝试次数默认每段录音最多处理 3 次。网络临时抽风时用户不用把同一句需求重新表演三遍。四、配网与发现IP 地址不应成为入门考试首次启动时设备创建VibeStick-XXXXSoftAP并在192.168.4.1提供配置页。Wi-Fi、Bridge 地址和 Token 被写入 NVS。Captive Portal DNS 会把常见探测请求引到配置页附近 2.4 GHz 网络也可以直接扫描。如果电脑 DHCP 地址变化固件会向 UDP8766广播发现请求。Bridge 校验 Token 后返回服务端口设备从 UDP 源地址获取新主机地址并更新 NVS。这比要求用户背诵ipconfig的输出友好多了毕竟产品说明书不该兼任网络管理员招聘试卷。五、安全边界够用但还没到高枕无忧Bridge 在非 loopback 地址监听时要求提供有效 Token受保护接口使用X-Vibe-Stick-Token服务端通过hmac.compare_digest比较。管理页只允许本机 loopback 访问录音上传大小默认限制为 2 MB。但当前传输仍是局域网内的 HTTP不是 HTTPSSoftAP 的安全配对、Token 轮换、NVS 加密和设备解绑还在未来规划中。因此它适合受信任的家庭或办公局域网不应被描述成已经完成零信任加固的商业硬件。六、这套架构最值得借鉴什么VibeStick 的价值不只是一块会显示百分比的小屏幕。它演示了一种实用的 AI 外设架构硬件负责确定性的输入输出Bridge 吸收不稳定的 Agent、模型和操作系统差异协议只传递稳定的状态与音频。这种分层让后续演进有路可走加新 Agent 时扩展 provider换 ASR 时替换 adapter支持新设备时围绕协议做硬件抽象。反过来如果一开始就让固件直接登录各种服务版本 0.1 可能还没发布证书、OAuth 和内存占用已经先开完三轮需求评审。下一篇将钻进main.c和vibe_audio.c看看 135×240 的屏幕、两个按键、一颗麦克风和一只扬声器如何在资源有限的设备里协同工作。本文基于 VibeStick 当前工作区0.1.4源码。VibeStick 是社区项目不是 M5Stack、OpenAI 或 Anthropic 官方产品Codex/Claude 名称仅用于说明兼容能力。