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