作品

Vox

进行中

本地优先的语音唤醒 Agent 平台。中文唤醒 → 声纹确认 → 本地识别 → 派发给外部 agent → 本地合成朗读,全链路不上传音频。

Windows 上的语音唤醒对话平台,我现在花时间最多的东西。

和这个站一样:代码由编程 agent 写,架构、契约、方案取舍和验收口径由我定。

链路

说出唤醒词 → 声纹确认是本人 → 唤醒球弹出 → 本地识别语音 → 简单的事平台自己做(读文件、搜索、终端、记忆),复杂的事派发给外部 agent → 流式回复 → 本地合成朗读 → 继续多轮,随时打断。

唤醒、端点检测、识别、合成、声纹校验全部在本机跑。项目代码不保存、不上传音频。

三条红线

  • 本地优先 —— 记忆只存文本:records 表每一列都是 TEXT 或 INTEGER,没有 BLOB,音频没有列可以落。
  • 组件可替换 —— 唤醒、识别、合成、会话传输、agent 后端都在版本化契约之后,第三方 SDK 的类型不许泄漏进公开事件结构。
  • 验证等级诚实 —— 每条结论都要标注证据来源,自动化测试不许冒充真机验收。

真正做过决定的几个地方

FTS5 搜不到中文,是先测出来才动手的。SQLite 默认的 unicode61 分词器把连续汉字当成一个 token:一行 用户喜欢用中文交流 and english too,MATCH 'english' 命中,MATCH '中文' 不命中。解法是索引派生 token 而不是原文 —— 索引侧存单字加相邻双字,查询侧只用双字。

向量检索被主动否决。单人语料这个量级,换不来额外 200 MB 本地嵌入模型的代价。

路由五维打分,能力是门不是权重。能力匹配、成本、预期延迟、历史成功率、当前负载。声明了做不了图像的 agent,不能靠又便宜又快赢下一个图像任务。加了连续失败熔断,否则故障 agent 会靠过期统计持续赢得路由,每一轮都付一次超时。

多路并发不做默认。聚合必须等最慢的那个成员,首字延迟会退化成集合里最差的那个值。

shell.run 出厂即关。说一句话就能在本机执行命令,这是全项目最大的风险面。默认关闭、白名单外拒绝而非询问、白名单内仍要在球上显示原文并确认、13 条危险模式硬拦截 —— 而且危险模式写在代码里不在配置里,配置能关掉的硬拦截不是硬拦截。

一个被改正的数字

唤醒命中原先对每次命中都报 score=1.0。核实之后发现 sherpa-onnx 1.13.4 的 KeywordResult 根本不暴露置信度,那个 1.0 是个看起来像测量值的常量。现在改成返回 None,进事件的数字换成声纹余弦相似度 —— 那个是真测出来的。

写下来是因为它已经进过一次真机记录。发现之后能做的只有把它标出来。

现在到哪儿了

核心 47 个模块 9,443 行,pytest 669 passed, 3 skipped(2026-08-26 实跑)。五份架构决策记录,十二份任务单。

没到发布标准,也不打算假装到了。真实外部 agent 跑通一轮、真实透明窗口验收、多场景真机唤醒统计,这三项还是空的。声纹的判别力有自动化背书(同人簇内 0.736、异人簇间 0.370,阈值 0.5 落在间隙里),但真机通过率没测过。