返回概览 · 解决方案

原始记录

来源、收到日期和原话

深入分析

证据、对比和深入分析

解决方案

可落地的方案、流程和基础设施

建议

结论、工作量和建议的第一步

E001 部署设计

Mac 第一版改 AgentEar,不新起 Pipecat。模型档仍见 建议。AgentEar 的现状见 AgentEar 基线。本文不新增未标注的延迟。

1. 组件

学生在这台 Mac 上说话。AgentEar 已经占着麦克风、识别和 VoxCPM2。agent24d 只在同一台机器上通过 A3 回答。浏览器和 TURN 留到 P2。

flowchart LR
  mic[cpal 麦克风] --> rec[按键录音]
  rec --> asr[SenseVoice 整段转写]
  asr --> route{附着?}
  route -->|否| side[本机 LLM 边车流式]
  route -->|是| a3["_a24/model/complete"]
  side --> sent[按句切开]
  a3 --> sent
  sent --> tts["POST /speak VoxCPM2"]
  tts --> play[本机播放]
  vad[播放时的监听] -->|开口| stop["stop_playback 加 on_barge_in"]
  stop --> play
  stop --> a3

vad 那条今天不存在。按键路径已经会调用 stop 里的两个函数。第一刀是让开口走同一条函数,而不是再写一套播放器。

2. 时序

正常回合,按今天的代码。松键之后才转写。附着时要等整句 model_complete 才开始合成。

sequenceDiagram
  participant U as 用户按键
  participant E as AgentEar
  participant A as agent24d
  participant T as VoxCPM2
  U->>E: 开始录音
  U->>E: 停止
  E->>E: SenseVoice 整段转写
  E->>A: _a24/model/complete
  A-->>E: 整段文本
  E->>T: POST /speak 逐句
  T-->>E: 整段 wav
  E->>U: 播放

要补的打断。播放期间开口,不等下一次按键。

sequenceDiagram
  participant U as 用户开口
  participant E as AgentEar
  participant A as agent24d
  participant T as VoxCPM2
  Note over E,T: Speaking
  U->>E: 监听判定为开口
  E->>E: stop_playback
  E->>E: on_barge_in
  E->>A: $/cancelRequest
  E->>T: 不再发下一句
  E->>U: 开始下一轮录音

$/cancelRequest 今天只在 Conn::call 超时里发送。开口路径要补一次主动发送。本机边车流式已经有 abort 标志,按键会增加 interrupt 计数。语音监听应调用同一套,不要另写取消。

3. 各档要装什么

Mac 各档共用 AgentEar。Windows 和服务器不跑这份二进制,模型服务仍按分析稿的 S2 到 S5,那是以后的移植。

档 模型服务 进程 网络 客户端 硬件清单
Mac 64GB AgentEar 现成进程。TTS 默认 VoxCPM2-4bit。识别先用 SenseVoice。LLM 在附着时走 A3,不附着时走本机边车 已有菜单栏进程加 agent24d。不新增网关进程 本机回环。daemon 保持 127.0.0.1。不上浏览器端口 AgentEar.app。耳机优先 M 系列,64GB 统一内存
Mac 128GB 同上,ASR 可换 1.7B,VoxCPM2-8bit 常驻 同上 同上 同上 128GB 统一内存
Mac 256GB 产品进程仍是上一行。Moshi MLX 单独进程,只在英语模式启动 多一个可选进程,不用时退出 同上 同上 256GB 统一内存
Windows 64GB + 24GB GPU VoxCPM2 走官方 vLLM-Omni 或原仓库。ASR 与 LLM 用 llama.cpp 或 vLLM,视剩余显存 Windows 服务或 NSSM。GPU 进程和 daemon 分开 同上 浏览器 64GB 内存,RTX 4090 级 24GB GPU,SSD 放模型
Windows 128GB + 48GB GPU MOSS-TTS-Realtime 用 vLLM-Omni。配方写 talker 约 6 GB、codec 约 8 GB 同上 同上 同上 128GB 内存,48GB 级 GPU
Windows 256GB + 80GB GPU,或 1 张 H200 SGLang-Omni 级联配置。TTS 仍可换 VoxCPM2 systemd 机房到教室的内网。仍不把 daemon 暴露到公网 浏览器 按该档 GPU。H200 是服务器对照,不是教室主机的前提
2 张 H100 仅当选择 S5 时用 SGLang 的 Qwen3-Omni 配置 systemd 同上 浏览器 两张 H100。短对话槽位见分析稿

模型文件放在主机的固定目录,文件名带 Hugging Face revision。上课期间不自动下载。更新在维护窗口做,先拉到新目录,校验后再切换软链。

日志记会话 id、轮次 id、VAD、ASR 完成、首个音频块、取消是否赶上播放。默认不落原始学生音频。排错用的环形缓冲在会话结束时删除。指标里不要出现提示词和转写全文,转写进 agent24 的 run 时由 daemon 自己的库保存,并遵守现有保留策略。

4. 教室安全

5. 改哪里

不新开 school-voice-gateway。改 AgentEar 自己的源码。agent24 内核先不动。

src/main.rs          按键打断已经在这里。播放时的监听接到同一分支
src/session.rs       Speaking 期间允许进入 Listening
src/talk.rs          开口时置上已有的 abort,停掉下一句合成
src/a3.rs            开口时对当前 model_complete 发 $/cancelRequest
src/host.rs          HostLlm 仍是整句。流式要等 agent24 的推理回调,或闲聊改回本机边车
services/tts/        VoxCPM2 已是默认。第一刀不换模型

Windows 和浏览器若以后要做,再单独开仓库。那时候才用 Pipecat。要对照的上游:

用途 仓库
编排 https://github.com/pipecat-ai/pipecat
Apple 上的 ASR/TTS https://github.com/Neywa-Labs/mlx-audio
VoxCPM2 https://github.com/OpenBMB/VoxCPM
MOSS 实时 TTS https://github.com/OpenMOSS/MOSS-TTS
Qwen3-ASR / Qwen3-TTS https://github.com/QwenLM/Qwen3-ASR 与 https://github.com/QwenLM/Qwen3-TTS
服务器级联与 Omni https://github.com/sgl-project/sglang
以后的 WebRTC https://github.com/livekit/agents
英语全双工旁路 https://github.com/kyutai-labs/moshi
内核 https://github.com/iDoris-ai/agent24 ,提交 bc923205

6. 集成草稿

下面是要接到现有函数上的形状,不是新进程。

fn on_voice_open() {
    let stopped = talk::stop_playback();
    host::on_barge_in();
    talk::note_recording_started();
    a3::cancel_inflight_model_complete();
    if stopped {
        log::info!("语音打断,停播并取消本轮推理");
    }
}

cancel_inflight_model_complete 今天没有这个名字。Conn::call 只有超时才写 $/cancelRequest。第一刀可以先只停播放。第二刀再让开口走同一条取消帧,避免整句回答在用户已经开口之后才开始播。

附着时若要首字更快,闲聊不要进 HostLlm::reply。answer_and_speak_streamed 看到 streams() 为 false 会退回整句。本机边车的 streams() 为 true,句子级路径已经能重叠合成。工具回合再 model_complete。

7. 分阶段

人日是判断。旧列是「从零写网关」。新列是「改 AgentEar」。

阶段 做什么 旧 新 过关
P0 播放时开口即停。耳机。不改模型 5 到 8 3 到 5 输入法按键仍能录音。误打断有记录。AEC 仍未做就不许用扬声器
P1 开口取消飞行中的 model_complete。闲聊可继续走本机流式 4 到 6 2 到 4 开口之后不再开始念旧回答。A3 配对仍在
P2 浏览器多学生,或 Windows 移植 6 到 10 6 到 10 没有现成代码可复用,数字不降
Mac 试点 P0 加 P1 9 到 14 5 到 9 一台 64GB Mac,一路
含浏览器 再加 P2 20 到 30 11 到 19

P3 原生全双工仍另计,规模 L,不替换 AgentEar 的半双工。