-
Notifications
You must be signed in to change notification settings - Fork 3
Voice Chat.zh CN
phinn edited this page Sep 18, 2026
·
1 revision
🌐 Language: English | 中文
基于火山引擎(豆包)实时语音大模型的双向语音对话。自然说话——AI 听、转写、用自然 TTS 回复,同时可触发 Agent 工具执行。
- ⚙ 设置 → 语音对话 — 填入火山引擎 App ID + Access Token。
- 点击输入栏的 🎤 打开语音浮层。
- 说话——实时显示转写文本。
- AI 用自然语音回复(豆包 TTS)。
- 再点 🎤(或关闭按钮)结束会话。
用户说话 → 麦克风(AudioWorklet 16kHz PCM)
→ WebSocket 二进制帧(event 200)
→ 火山 ASR(event 451: 增量转写)
→ ASR 结束(event 459: 完整发言)
↓
┌─────┴─────┐
↓ ↓
豆包 LLM 本地 Agent
(event 453/550) (taskManager.send)
↓ ↓
豆包 TTS Agent 结果
(event 352) → WS 502 注入
↓ → 豆包 TTS
AI 音频 Agent 音频
会话运行在全链路对话模式:豆包负责完整的 ASR → LLM → TTS 管道。同时,识别到的文本被转发给本地 Agent 引擎执行工具(shell、文件操作等)。Agent 结果通过 WS 通道(event 502)注入,由豆包 TTS 朗读。
语音对话绑定到按下 🎤 时的当前活跃频道。所有 Agent 结果发送到该频道的主聊天窗口——会话中途切换频道不会重定向消息。
语音启动时读取当前项目的 cwd 和最近 3 轮对话,注入为 system_role。问"这个项目用了什么框架"——AI 知道。
-
agentBusy锁 — Agent 任务执行期间,新的 ASR 发言会被丢弃(防止交错回复)。 -
双重检查 — VoiceChat 在 event 459 加锁,TaskManager 再检查
conv.status === 'running'作为第二道防线。 - TTS 串行化 — Agent TTS 等豆包 TTS 播完再注入(最长等 15 秒)。
Agent 结果出现在主聊天窗口(通过 agent-event 流式推送),不在语音浮层中独立显示。语音浮层只管实时转写和豆包对话——保持聊天记录干净,与文字输入行为一致。
| 字段 | 说明 |
|---|---|
| App ID | 火山引擎语音应用标识 |
| Access Token | WS 端点认证密钥 |
| Voice Type | TTS 说话人音色(默认:zh_female_vv_jupiter_bigtts) |
WS 端点为 wss://openspeech.bytedance.com/api/v3/realtime/dialog,资源 ID 为 volc.speech.dialog。
WS 连接使用自定义二进制帧协议(不是 JSON-over-text):
-
4 字节 header:
0x11 0x14 0x10 0x00(协议版本、header 大小、消息类型、flags) - 4 字节 event ID(大端)
- Session/Connection ID(长度前缀)
- Payload(长度前缀的 JSON 或原始音频)
关键事件:
| Event | 方向 | 说明 |
|---|---|---|
| 1 | C→S | StartConnection |
| 50 | S→C | ConnectionStarted |
| 100 | C→S | StartSession(ASR + Dialog + TTS 配置) |
| 150 | S→C | SessionStarted — 可以说话 |
| 200 | C→S | 音频数据(16kHz PCM) |
| 451 | S→C | ASR 增量结果 |
| 459 | S→C | ASR 结束 — 触发 Agent |
| 453/550 | S→C | AI 对话文本 |
| 352 | S→C | TTS 音频回复 |
| 359 | S→C | TTS 结束 |
| 502 | C→S | ChatRequest — 注入文本供 TTS 朗读 |
| 102 | C→S | FinishSession |
- 采集:AudioWorklet 16kHz 单声道 PCM → base64 → WS event 200
- 播放:event 352 音频块排队 → 串行播放(drainPlayQueue)24kHz
- 打断:speaking → listening 状态切换由 event 359(TTSEnded)触发
| 症状 | 可能原因 |
|---|---|
| WS 立即关闭(code 1006) | App ID / Access Token 不对,或服务未开通 |
| 没有 ASR 转写(451/459 不来) | StartSession 配置为全链路模式 — 豆包内部处理一切 |
| Agent 结果没有语音播放 | WS 可能已断开;查看 agentResult 日志 |
| 音频重叠 | 不应发生 — agentBusy + TTS 串行化防止 |
-
src/main/VoiceChat.ts— WS 管理器、二进制协议、会话生命周期、Agent 桥接 -
src/main/main.ts:~1948—voice-chat-startIPC handler、上下文注入、onUserMessage回调 -
src/renderer/app.ts:~4189—onVoiceChatEvent监听、浮层 UI、音频采集/播放 -
src/preload/preload.ts—voiceChatStart(convId)/voiceChatStopIPC 桥接