[全双工规格补齐]:完成完整Agent语音助手OpenSpec,包含真实运行边界和自测标准

This commit is contained in:
mkbk
2026-06-19 12:17:08 +08:00
parent 7c6797aeb0
commit 504dd2cbf2
5 changed files with 389 additions and 0 deletions
@@ -0,0 +1,63 @@
# 完整全双工 Agent 运行时设计
## 背景
当前 `run-agent-live` 通过 `build_live_runtime(config).run_agent()` 复用旧 `VoiceAssistantPipeline`。这条路径只在 TTS 播放时启动临时监听,无法满足持续监听、持续识别、全局可取消和 WebRTC APM 音频底座要求。本设计新增独立 `FullDuplexAgentRuntime`,将旧 pipeline 降级为 `run-live` 专用稳定路径。
## 数据流
1. `SoundDeviceAudioTransport` 只负责设备 I/O。
2. `AudioHub` 读取麦克风 raw frame,写 raw capture ring。
3. `WebRtcAudioProcessingStage` 使用 render reference 处理 raw capture,写 processed capture ring。
4. `ContinuousVadWorker` 消费 processed capture,发布 speech_start/speech_end。
5. `StreamingSttWorker` 消费同一 processed capture,发布 partial/stable/final transcript。
6. `InterruptController` 订阅 VAD 事件和 state machine,在 thinking/speaking/tool_running 中触发 cancellation。
7. `ConversationManager` 收到 final transcript 后构建短期上下文、memory context、LLM request。
8. LLM streaming delta 进入 sentence segmenter。
9. Streaming TTS 产出 PCM chunk`InterruptiblePlaybackQueue` 播放并写 render reference。
10. Tool calls 进入 `ToolRouter`,结果回注入 LLM。
## 并发模型
后台任务:
1. `audio_capture_task`
2. `apm_process_task`
3. `vad_task`
4. `streaming_stt_task`
5. `conversation_task`
6. `playback_task`
7. `tool_task`,按需创建
所有任务使用 `CancellationGraph` 管理。用户打断时取消当前 response 子图,不关闭 audio hub;进程退出时取消 root token 并关闭所有订阅。
## 状态管理
状态机使用现有 `PipelineState` 枚举,不再在 `run-agent-live` 中用隐式 list 记录状态。每个转移必须发 event。非法转移在测试中失败。
## Provider 策略
1. APM`webrtc` 为完整模式默认且 required`fake` 仅 self-test`disabled` 只允许开发降级,不算完整验收。
2. STT`faster_whisper` 为开发默认;`sherpa_onnx` fallback`sensevoice` 预留。
3. TTS`cosyvoice` 为默认目标;缺失时完整模式失败,除非显式配置 fallback。
4. Memory`faiss_sqlite` 默认;如果 FAISS 不可用则 memory health error,基本对话可继续但 self-test 标记失败。
5. Tools:默认启用 ToolRouter,但高风险 adapter 默认 disabled。
## 错误处理
1. 音频设备错误:启动失败或 recovery 到 idle。
2. APM 不可用:完整模式启动失败。
3. STT final 空文本:丢弃 utterance,回 listening。
4. LLM/TTS 错误:取消 response,发 stage_error,回 listening。
5. Tool high-risk:发 confirmation_required;第一版终端拒绝自动执行。
6. Memory health error:禁用 memory context,继续基本对话并报告诊断。
## 自测设计
`agent-self-test` 使用 fake AudioHub/APM/STT/TTS/LLM/tool/memory,必须模拟三轮:
1. 正常问答。
2. 播放时用户打断。
3. memory.search tool call。
`audio-self-test` 检查真实设备、APM provider health、fake echo suppression、interrupt latency 统计。无真实 WebRTC binding 时输出失败 JSON,不伪造通过。