Ai_GirlFriend/xuniYou/问题定位总结.md

174 lines
3.9 KiB
Markdown
Raw Permalink Normal View History

2026-02-28 18:04:34 +08:00
# 问题定位总结
## 🎯 核心问题
**卡在 ASR语音识别环节导致后续 LLM 和 TTS 都没有被触发。**
## 🔍 详细分析
### 问题流程
```
客户端 → 一次性发送 260KB PCM 文件
服务器 → 接收到大块数据
ASR → 无法处理(期望流式小块数据)❌
没有识别结果
LLM 不被触发 ❌
TTS 不被触发 ❌
60秒后 idle timeout
```
### 根本原因
**架构不匹配**
1. **服务器设计**
- 使用 `paraformer-realtime-v2`(实时 ASR
- 期望流式接收音频数据
- 设计用于边说边识别
2. **客户端实现**
- 录音完成后一次性发送整个文件
- 不是流式传输
- 类似"批处理"模式
这就像:
- 服务器是一个"实时翻译员",期望你一句一句说
- 但客户端把整篇文章一次性扔给他
- 翻译员不知道怎么处理
## 📊 各环节状态
| 环节 | 状态 | 说明 |
|------|------|------|
| 客户端录音 | ✅ 正常 | PCM 格式16kHz |
| 文件读取 | ✅ 正常 | 260KB |
| WebSocket 发送 | ✅ 正常 | 发送成功 |
| **ASR 识别** | ❌ **卡住** | 无法处理大块数据 |
| LLM 生成 | ⏸️ 未触发 | 因为 ASR 没有结果 |
| TTS 合成 | ⏸️ 未触发 | 因为 LLM 没有结果 |
| 返回音频 | ⏸️ 未触发 | 因为 TTS 没有结果 |
## 🔧 解决方案
### 已实现:分片发送
修改客户端,将大文件分成小块发送:
```javascript
// 每次发送 8KB
const chunkSize = 8192
// 模拟流式传输
for (let offset = 0; offset < totalSize; offset += chunkSize) {
const chunk = audioData.slice(offset, offset + chunkSize)
socketTask.send({ data: chunk })
await sleep(50) // 延迟 50ms
}
// 发送结束标记
socketTask.send({ data: 'end' })
```
### 工作原理
```
客户端 → 发送 8KB 片段 1
服务器 → ASR 开始识别
客户端 → 发送 8KB 片段 2
服务器 → ASR 继续识别
... (重复)
客户端 → 发送 "end" 标记
服务器 → ASR 完成识别
服务器 → 触发 LLM 生成
服务器 → 触发 TTS 合成
服务器 → 返回音频
```
## 📈 预期效果
### 修改前
- ❌ ASR 无法识别
- ❌ 60 秒后超时
- ❌ 没有任何响应
### 修改后
- ✅ ASR 正常识别
- ✅ LLM 生成回复
- ✅ TTS 合成语音
- ✅ 返回音频播放
## 🧪 测试步骤
1. 重新编译项目
2. 进入语音通话页面
3. 按住"按住说话"按钮
4. 说话 2-3 秒
5. 松开按钮
6. 观察日志:
- 应该看到 "开始分片发送"
- 应该看到 "第 X 片发送成功"
- 应该看到 "发送结束标记"
- 应该收到服务器的识别结果
- 应该收到 LLM 的回复
- 应该收到 TTS 的音频
## 🎓 经验总结
### 教训
1. **架构匹配很重要**
- 实时 ASR 需要流式输入
- 不能用批处理方式
2. **日志很重要**
- 通过日志快速定位问题
- 每个环节都要有日志
3. **理解服务端设计**
- 要了解服务端期望什么
- 不能想当然
### 最佳实践
1. **使用流式传输**
- 对于实时 ASR必须流式发送
- 分片大小4-8KB
- 发送间隔50-100ms
2. **添加结束标记**
- 告诉服务器数据发送完毕
- 触发最终处理
3. **完善错误处理**
- 每个环节都要有错误处理
- 超时要有提示
## 🔗 相关文档
- [Paraformer 实时 ASR 文档](https://help.aliyun.com/zh/dashscope/developer-reference/paraformer-realtime-v2)
- [WebSocket 流式传输最佳实践](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket)
## ✅ 结论
问题已定位并解决:
- **问题**ASR 无法处理大块数据
- **原因**:客户端一次性发送,服务器期望流式接收
- **解决**:客户端改为分片发送,模拟流式传输
- **状态**:已实现,待测试