Files
Docs/DevLogs/Day21.md
2025-12-31 16:18:28 +08:00

306 lines
8.0 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.
# Day 21 - 语音系统全面优化
**日期**: 2025-12-25 🎄
**主题**: 语音识别修复 + 音频系统优化 + AI 对话优化 + 轻量级 VAD
---
## 🐛 语音识别停止响应 (09:30)
**问题**:停止盲道导航后,语音指令不再被识别
**修复**:热词匹配白名单 + 客户端 RESET 处理
**状态**:✅ 已修复
### 根因
```mermaid
sequenceDiagram
participant U as 用户
participant ASR as ASR回调
participant S as 系统
U->>ASR: 说"停止导航"
ASR->>ASR: "停止" in "停止导航" ✓
ASR->>S: full_system_reset()
Note over S: ASR会话终止 → 语音不响应!
```
### 解决方案
**服务器端** (`asr_core.py`)
```python
NAV_CONTROL_WHITELIST = ["停止导航", "结束导航", "开始导航", ...]
def _has_hotword(self, text):
# 先检查白名单,匹配则不触发热词
for nav_cmd in NAV_CONTROL_WHITELIST:
if nav_cmd in text: return False
# 再检查热词
for w in INTERRUPT_KEYWORDS:
if w in text: return True
return False
```
**客户端** (`main.cpp`)
```cpp
if (msg == "RESTART" || msg == "RESET") {
ws_aud.send_text("START"); // 重新启动 ASR
}
```
---
## 🔧 音频系统优化 (10:10)
### 1. 采样率转换简化
```
修改前: 24kHz → 8kHz → 16kHz (两次转换)
修改后: 24kHz → 16kHz (一次转换)
```
**效果**:减少 50% 转换开销
### 2. 减少日志频率
- 音频接收日志100包 → 500包
### 3. 指数退避重连
```
1s → 2s → 4s → 8s → 16s (max) → 连接成功后重置
```
---
## 🔧 视觉优先级中断 (10:35)
**问题**AI 对话时检测到障碍物无法打断
**修复**:障碍物检测优先级高于 AI 对话
**状态**:✅ 已实现
```python
# app_main.py
if is_obstacle_warning and is_playing_now():
asyncio.create_task(hard_reset_audio("Obstacle priority"))
```
**触发关键词**: `前方有`, `停一下`, `注意避让`, `左侧有`, `右侧有`
---
## 🔧 AI 对话简洁化 (11:05)
**问题**AI 回答过长
**修复**:添加 system prompt 限制回答长度
**状态**:✅ 已实现
```python
# omni_client.py
system_prompt = """你是视障辅助AI助手。
请用极简短语言回答每次不超过2-3句话。
避免冗长解释,只提供最关键信息。"""
```
---
## 🔧 轻量级 VAD (11:14)
**问题**:静默时仍持续发送音频,浪费带宽
**修复**:客户端能量阈值 VAD仅语音时发送
**状态**:✅ 已实现
### 新增文件
`simple_vad.h` - 能量阈值 VADheader-only
### 参数
| 参数 | 值 | 说明 |
|------|-----|------|
| threshold | 400 | 能量阈值 |
| attack | 2帧 | 40ms确认语音开始 |
| hangover | 15帧 | 300ms避免截断 |
**效果**:静默时减少 70-80% 带宽
---
## 📁 修改文件汇总
### 服务器端
| 文件 | 修改内容 |
|------|----------|
| `asr_core.py` | 导航命令白名单,热词匹配修复 |
| `app_main.py` | 采样率优化 + 日志频率 + 视觉中断 + **新AI管道集成** |
| `audio_stream.py` | 移除多余 8k→16k 转换 |
| `omni_client.py` | AI 简洁回复 system prompt |
| `sensevoice_asr.py` | **新增** 本地 ASR (非流式) |
| `glm_client.py` | **新增** GLM-4.5-Flash 客户端 |
| `edge_tts_client.py` | **新增** EdgeTTS 流式合成 |
| `ai_voice_pipeline.py` | **新增** 统一 AI 管道 |
### 客户端 (Avaota F1)
| 文件 | 修改内容 |
|------|----------|
| `main.cpp` | RESET处理 + 指数退避 + VAD集成 + **RECOGNIZE命令** |
| `simple_vad.h` | **新增** 轻量级 VAD + 边沿检测
---
## 🚀 新 AI 管道 (13:50)
**目标**:替换付费 API 为免费方案
**状态**:✅ 已实现并测试通过
### 新架构
```
语音 → [SenseVoice] → 文本 → [GLM-4.5-Flash] → [EdgeTTS] → 播放
本地ASR 免费LLM 免费TTS
```
### 新增文件
| 文件 | 功能 |
|------|------|
| `sensevoice_asr.py` | 本地 ASR (非流式) |
| `glm_client.py` | GLM-4.5-Flash 客户端 |
| `edge_tts_client.py` | EdgeTTS 流式合成 |
| `ai_voice_pipeline.py` | 统一管道 |
### 工作流程
```mermaid
sequenceDiagram
participant C as 客户端
participant S as 服务器
participant ASR as SenseVoice
participant LLM as GLM-4.5
participant TTS as EdgeTTS
C->>S: START
S-->>C: OK:STARTED
loop 有语音时
C->>S: 音频数据 (binary)
S->>S: 收集到 audio_buffer
end
Note over C: VAD 检测到语音结束
C->>S: RECOGNIZE
S->>ASR: 一次性识别
ASR-->>S: 用户文本
S->>LLM: 调用 GLM
LLM-->>S: AI 回复
S->>TTS: 流式合成
TTS-->>S: PCM 音频块
S-->>C: 音频播放
```
### 本地测试结果
| 组件 | 状态 | 结果 |
|------|------|------|
| GLM-4.5-Flash | ✅ | "你好👋!需要帮助吗?" |
| EdgeTTS (MP3) | ✅ | 7200 bytes |
| EdgeTTS (PCM) | ✅ | 38400 bytes |
| SenseVoice 路径 | ✅ | 自动检测成功 |
### 控制开关
```bash
# 启用新管道(默认)
export USE_NEW_AI_PIPELINE=1
# 回退到旧管道
export USE_NEW_AI_PIPELINE=0
```
---
## ⏳ 待验证
### 语音修复 & 优化
- [ ] 部署服务器端修复
- [ ] 编译并部署客户端(含 VAD
- [ ] 测试语音识别恢复
- [ ] 测试 VAD 带宽节省效果
- [ ] 测试 AI 回答简洁度
### 新 AI 管道
- [x] GLM-4.5-Flash 调用测试
- [x] EdgeTTS 语音合成测试
- [ ] 部署到服务器完整测试
- [ ] SenseVoice ASR 实际语音测试
---
## 🔴 GLM API 调用问题 (17:30)
### 问题1API 调用失败 (Error 400/1210)
**日志**
```
[GLM] 调用失败: Error code: 400, with error text {"error":{"code":"1210","message":"API 调用参数有误,请检查文档。"}}
```
**尝试的修复**
1. 模型名称从 `glm-4-flash` 改为 `glm-4.5-flash`(根据官方文档)
2. 尝试安装 `zai-sdk`(官方推荐的 SDK
**结论**:由于 zai-sdk 未成功安装/配置,回退到稳定版本:
- 模型:`glm-4-flash`
- SDK纯 OpenAI SDK
**状态**:🔴 API 仍报错
### 问题2AI 回答与问题不相关
**症状**
| 用户说 | AI 回答 |
|--------|---------|
| "吧" | "天气:晴朗,温度适宜" |
| "前方是什么" | "位置:现在在市中心广场" |
| "现在看我情况是什么" | "时间晚上7点整" |
**分析**
- 语音识别结果不准确("工"、"吧" 等)
- AI 回答像是预设的状态查询模板
### 问题3语音识别不准确
**日志**
```
[SenseVoice] 识别耗时: 0.490s | 结果: 그. # 韩语字符
[SenseVoice] 识别耗时: 0.492s | 结果: 그.
```
**问题**:识别出韩语字符表明模型语言配置可能有问题
---
## 🔴 未解决问题清单
### 1. GLM API 调用失败
- **错误码**400 / 1210
- **待办**
- 确认 API Key 有效性
- 检查 messages 格式
- 尝试正确安装配置 zai-sdk
### 2. AI 回答模式异常
- **症状**:回答与问题无关,像是固定模板
- **待办**
- 检查 system prompt 是否导致问题
- 验证对话历史是否正确传递
### 3. 语音识别出韩语字符
- **症状**SenseVoice 输出韩语字符
- **待办**:检查模型语言配置
### 4. VAD 延迟过长
- **症状**:语音结束后 2-3 秒才触发识别
- **待办**:调整 `min_silence_duration_ms` 参数
---
## 📝 Day 21 总结
| 类别 | 状态 | 说明 |
|------|------|------|
| 语音识别停止响应修复 | ✅ | 热词白名单 + RESET 处理 |
| 新 AI 管道框架 | ✅ | SenseVoice + GLM + EdgeTTS |
| GLM API 调用 | 🔴 | 参数错误,需进一步调试 |
| 语音识别准确性 | 🔴 | 出现韩语字符,需检查配置 |
| VAD 延迟 | 🔴 | 2-3 秒延迟,需优化参数 |
**Day 21 状态**:⚠️ 部分完成,核心 AI 对话问题待 Day 22 继续调试