Ai_GirlFriend/xuniYou/问题定位总结.md
2026-02-28 18:04:34 +08:00

174 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 问题定位总结
## 🎯 核心问题
**卡在 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 无法处理大块数据
- **原因**:客户端一次性发送,服务器期望流式接收
- **解决**:客户端改为分片发送,模拟流式传输
- **状态**:已实现,待测试