原始记录
来源、收到日期和原话
E001 · 解决方案
部分借鉴:Mac 做在 AgentEar 上,补语音打断。64GB 级联可做一路
返回概览 · 解决方案
来源、收到日期和原话
证据、对比和深入分析
可落地的方案、流程和基础设施
结论、工作量和建议的第一步
Mac 第一版改 AgentEar,不新起 Pipecat。模型档仍见 建议。AgentEar 的现状见 AgentEar 基线。本文不新增未标注的延迟。
学生在这台 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 里的两个函数。第一刀是让开口走同一条函数,而不是再写一套播放器。
正常回合,按今天的代码。松键之后才转写。附着时要等整句 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 计数。语音监听应调用同一套,不要另写取消。
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 自己的库保存,并遵守现有保留策略。
不新开 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 |
下面是要接到现有函数上的形状,不是新进程。
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。
人日是判断。旧列是「从零写网关」。新列是「改 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 的半双工。