# Life Echo WebSocket 对话接口测试文档 ## 1. 接口信息 ### 1.1 连接地址 ``` ws://localhost:8000/ws/conversation/{conversation_id} ``` **参数说明:** - `conversation_id`: 对话ID(UUID格式,例如:`550e8400-e29b-41d4-a716-446655440000`) **示例:** ``` ws://localhost:8000/ws/conversation/550e8400-e29b-41d4-a716-446655440000 ``` ### 1.2 协议 - 协议类型:WebSocket (WS) - 消息格式:JSON - 编码:UTF-8 --- ## 2. 消息类型定义 ### 2.1 客户端 → 服务端消息类型 | 消息类型 | 说明 | 必需字段 | |---------|------|---------| | `audio_chunk` | 发送音频数据块 | `type`, `data.audio_base64` | | `end_conversation` | 结束对话 | `type` | ### 2.2 服务端 → 客户端消息类型 | 消息类型 | 说明 | 包含字段 | |---------|------|---------| | `connect` | 连接确认 | `type`, `conversation_id`, `data.status`, `timestamp` | | `transcript` | 语音转文字结果 | `type`, `conversation_id`, `data.text`, `timestamp` | | `agent_response` | Agent 回应文本 | `type`, `conversation_id`, `data.text`, `timestamp` | | `tts_audio` | TTS 生成的音频 | `type`, `conversation_id`, `data.audio_base64`, `timestamp` | | `end_conversation` | 对话结束确认 | `type`, `conversation_id`, `data.status`, `timestamp` | | `error` | 错误信息 | `type`, `data.message`, `timestamp` | --- ## 3. 消息格式规范 ### 3.1 客户端消息格式 #### 3.1.1 发送音频块 (audio_chunk) ```json { "type": "audio_chunk", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "audio_base64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQAAAAA=" }, "timestamp": "2024-01-15T10:30:00.000Z" } ``` **字段说明:** - `type`: 固定值 `"audio_chunk"` - `conversation_id`: 对话ID(可选,建议包含) - `data.audio_base64`: Base64编码的音频数据(必需) - `timestamp`: ISO 8601格式的时间戳(可选) #### 3.1.2 结束对话 (end_conversation) ```json { "type": "end_conversation", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "timestamp": "2024-01-15T10:35:00.000Z" } ``` ### 3.2 服务端消息格式 #### 3.2.1 连接确认 (connect) ```json { "type": "connect", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "status": "connected" }, "timestamp": "2024-01-15T10:30:00.000Z" } ``` #### 3.2.2 语音转文字结果 (transcript) ```json { "type": "transcript", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "text": "我小时候住在北京" }, "timestamp": "2024-01-15T10:30:05.000Z" } ``` #### 3.2.3 Agent 回应 (agent_response) ```json { "type": "agent_response", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "text": "听起来很有趣!能告诉我更多关于你在北京的生活吗?比如你最喜欢那里的什么地方?" }, "timestamp": "2024-01-15T10:30:06.000Z" } ``` #### 3.2.4 TTS 音频 (tts_audio) ```json { "type": "tts_audio", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "audio_base64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQAAAAA=" }, "timestamp": "2024-01-15T10:30:07.000Z" } ``` #### 3.2.5 对话结束 (end_conversation) ```json { "type": "end_conversation", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "status": "ended" }, "timestamp": "2024-01-15T10:35:00.000Z" } ``` #### 3.2.6 错误信息 (error) ```json { "type": "error", "data": { "message": "ASR服务暂时不可用,请稍后重试" }, "timestamp": "2024-01-15T10:30:05.000Z" } ``` --- ## 4. 在 Apifox 中测试步骤 ### 4.1 准备工作 1. **启动后端服务** ```bash cd api uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` 2. **准备测试数据** - 生成一个 UUID 作为 `conversation_id`(可以使用在线工具或命令行) - 准备一段 Base64 编码的音频数据(用于测试) ### 4.2 创建 WebSocket 连接 1. **打开 Apifox** - 创建新请求 - 选择协议类型:**WebSocket** 2. **配置连接地址** ``` ws://localhost:8000/ws/conversation/550e8400-e29b-41d4-a716-446655440000 ``` - 将 `550e8400-e29b-41d4-a716-446655440000` 替换为你的对话ID 3. **点击"连接"按钮** - 连接成功后,应该立即收到 `connect` 类型的消息 ### 4.3 测试场景 #### 场景 1:完整对话流程测试 **步骤:** 1. **连接 WebSocket** - 地址:`ws://localhost:8000/ws/conversation/{conversation_id}` - 预期收到:`connect` 消息 2. **发送音频块** ```json { "type": "audio_chunk", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "data": { "audio_base64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQAAAAA=" } } ``` - 预期收到(按顺序): 1. `transcript` - 语音转文字结果 2. `agent_response` - Agent 回应文本 3. `tts_audio` - TTS 生成的音频 3. **继续发送多个音频块** - 重复步骤 2,模拟连续对话 4. **结束对话** ```json { "type": "end_conversation", "conversation_id": "550e8400-e29b-41d4-a716-446655440000" } ``` - 预期收到:`end_conversation` 确认消息 - 连接自动断开 #### 场景 2:错误处理测试 **测试无效的音频数据:** ```json { "type": "audio_chunk", "data": { "audio_base64": "invalid_base64_data" } } ``` - 预期收到:`error` 消息,包含错误描述 **测试缺少必需字段:** ```json { "type": "audio_chunk" } ``` - 预期收到:`error` 消息或连接断开 #### 场景 3:连接断开测试 1. **正常断开** - 发送 `end_conversation` 消息 - 连接正常关闭 2. **异常断开** - 直接关闭连接(不发送 `end_conversation`) - 服务端应清理资源 #### 场景 4:多轮对话测试 **测试对话阶段切换:** 1. **发送童年相关话题** ```json { "type": "audio_chunk", "data": { "audio_base64": "{童年相关音频的base64}" } } ``` - 预期:Agent 回应关于童年的话题 2. **发送教育相关话题** ```json { "type": "audio_chunk", "data": { "audio_base64": "{教育相关音频的base64}" } } ``` - 预期:Agent 自动切换到教育阶段,回应教育相关话题 3. **发送工作相关话题** - 预期:Agent 切换到职业阶段 --- ## 5. 测试用例清单 ### 5.1 基础功能测试 | 用例ID | 测试场景 | 输入 | 预期结果 | 状态 | |--------|---------|------|---------|------| | TC-001 | 建立连接 | 连接 WebSocket | 收到 `connect` 消息 | ⬜ | | TC-002 | 发送音频块 | 发送 `audio_chunk` | 收到 `transcript`、`agent_response`、`tts_audio` | ⬜ | | TC-003 | 结束对话 | 发送 `end_conversation` | 收到 `end_conversation` 确认,连接断开 | ⬜ | | TC-004 | 多轮对话 | 连续发送多个音频块 | 每轮都收到完整响应 | ⬜ | ### 5.2 异常场景测试 | 用例ID | 测试场景 | 输入 | 预期结果 | 状态 | |--------|---------|------|---------|------| | TC-101 | 无效音频数据 | 发送无效 base64 | 收到 `error` 消息 | ⬜ | | TC-102 | 缺少必需字段 | 发送不完整的消息 | 收到 `error` 或连接断开 | ⬜ | | TC-103 | 无效对话ID | 使用不存在的 conversation_id | 连接成功但创建新对话 | ⬜ | | TC-104 | 连接超时 | 长时间不发送消息 | 连接保持或超时断开 | ⬜ | | TC-105 | 异常断开 | 直接关闭连接 | 服务端清理资源 | ⬜ | ### 5.3 性能测试 | 用例ID | 测试场景 | 输入 | 预期结果 | 状态 | |--------|---------|------|---------|------| | TC-201 | 快速连续发送 | 1秒内发送10个音频块 | 所有请求都能正常处理 | ⬜ | | TC-202 | 大音频块 | 发送较大的音频数据 | 正常处理,响应时间在可接受范围 | ⬜ | | TC-203 | 长时间连接 | 保持连接30分钟 | 连接稳定,无内存泄漏 | ⬜ | --- ## 6. 测试数据准备 ### 6.1 生成对话ID **方法1:使用在线工具** - 访问:https://www.uuidgenerator.net/ - 生成 UUID v4 **方法2:使用命令行** ```bash # Python python -c "import uuid; print(uuid.uuid4())" # Node.js node -e "console.log(require('crypto').randomUUID())" ``` ### 6.2 准备测试音频 **方法1:使用文本转Base64(模拟)** ```bash # 创建一个简单的测试音频文件(WAV格式) # 然后转换为Base64 base64 -i test_audio.wav ``` **方法2:使用在线工具** - 访问:https://base64.guru/converter/encode/audio - 上传音频文件,获取Base64编码 **方法3:使用Python脚本** ```python import base64 with open("test_audio.wav", "rb") as f: audio_base64 = base64.b64encode(f.read()).decode('utf-8') print(audio_base64) ``` ### 6.3 测试音频建议 - **格式**:WAV、MP3、M4A - **时长**:3-10秒 - **内容**:清晰的中文语音 - **示例话题**: - 童年:"我小时候住在北京" - 教育:"我在清华大学读书" - 工作:"我在一家科技公司工作" - 家庭:"我有一个幸福的家庭" --- ## 7. 在 Apifox 中的详细操作 ### 7.1 创建 WebSocket 请求 1. **新建请求** - 点击"新建" → "WebSocket" - 或使用快捷键 `Ctrl+N` (Windows) / `Cmd+N` (Mac) 2. **配置连接** - **名称**:Life Echo 对话测试 - **URL**:`ws://localhost:8000/ws/conversation/{conversation_id}` - **方法**:WebSocket (自动识别) 3. **添加参数** - 在 URL 中直接替换 `{conversation_id}` 为实际值 - 或使用变量:`ws://localhost:8000/ws/conversation/{{conversation_id}}` ### 7.2 发送消息 1. **连接成功后** - 在消息输入框中输入 JSON 格式的消息 - 或使用"消息模板" 2. **创建消息模板** ```json { "type": "audio_chunk", "conversation_id": "{{conversation_id}}", "data": { "audio_base64": "{{audio_base64}}" }, "timestamp": "{{$timestamp}}" } ``` 3. **发送消息** - 点击"发送"按钮 - 或使用快捷键 `Ctrl+Enter` ### 7.3 查看响应 1. **实时消息** - 在"消息"面板查看收到的消息 - 消息按时间顺序显示 2. **消息详情** - 点击消息查看详细信息 - 可以查看 JSON 格式、时间戳等 3. **保存响应** - 右键消息 → "保存为示例" - 用于后续对比测试 ### 7.4 使用环境变量 1. **创建环境** - 点击"环境" → "新建环境" - 名称:Local Development 2. **添加变量** ```json { "base_url": "ws://localhost:8000", "conversation_id": "550e8400-e29b-41d4-a716-446655440000", "audio_base64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQAAAAA=" } ``` 3. **在请求中使用** - URL: `{{base_url}}/ws/conversation/{{conversation_id}}` - 消息中使用 `{{audio_base64}}` --- ## 8. 常见问题排查 ### 8.1 连接失败 **问题**:无法建立 WebSocket 连接 **排查步骤:** 1. 检查后端服务是否运行:`curl http://localhost:8000/health` 2. 检查端口是否正确:默认 8000 3. 检查防火墙设置 4. 检查 URL 格式是否正确(`ws://` 不是 `http://`) ### 8.2 收不到响应 **问题**:发送消息后没有收到响应 **排查步骤:** 1. 检查消息格式是否正确(JSON 格式) 2. 检查必需字段是否包含(`type`, `data.audio_base64`) 3. 检查后端日志是否有错误 4. 检查 LLM 服务是否配置(DEEPSEEK_API_KEY 或 LLM_API_KEY) ### 8.3 收到错误消息 **问题**:收到 `error` 类型的消息 **排查步骤:** 1. 查看错误消息内容:`data.message` 2. 检查 ASR 服务配置(OPENAI_API_KEY) 3. 检查 TTS 服务配置(OPENAI_API_KEY) 4. 检查 LLM 服务配置(DEEPSEEK_API_KEY 或 LLM_API_KEY) ### 8.4 音频处理失败 **问题**:音频转文字失败 **排查步骤:** 1. 检查音频格式是否支持(WAV、MP3、M4A) 2. 检查 Base64 编码是否正确 3. 检查音频文件大小(建议 < 10MB) 4. 检查 ASR 服务是否可用 --- ## 9. 测试检查清单 ### 9.1 连接测试 - [ ] 能够成功建立 WebSocket 连接 - [ ] 连接后立即收到 `connect` 消息 - [ ] 连接信息包含正确的 `conversation_id` ### 9.2 消息发送测试 - [ ] 能够发送 `audio_chunk` 消息 - [ ] 能够发送 `end_conversation` 消息 - [ ] 消息格式符合规范 ### 9.3 消息接收测试 - [ ] 发送音频后收到 `transcript` 消息 - [ ] 收到 `agent_response` 消息 - [ ] 收到 `tts_audio` 消息 - [ ] 消息顺序正确(transcript → agent_response → tts_audio) ### 9.4 功能测试 - [ ] 语音转文字功能正常 - [ ] Agent 回应内容合理 - [ ] TTS 音频生成正常 - [ ] 对话阶段自动切换 ### 9.5 异常处理测试 - [ ] 无效消息返回错误 - [ ] 连接断开时资源清理 - [ ] 错误消息格式正确 --- ## 10. 性能指标 ### 10.1 响应时间 | 操作 | 目标响应时间 | 实际响应时间 | 状态 | |------|------------|------------|------| | 连接建立 | < 1s | - | ⬜ | | 音频转文字 | < 3s | - | ⬜ | | Agent 回应 | < 5s | - | ⬜ | | TTS 生成 | < 3s | - | ⬜ | | 完整流程 | < 15s | - | ⬜ | ### 10.2 并发测试 - [ ] 支持 10 个并发连接 - [ ] 支持 50 个并发连接 - [ ] 支持 100 个并发连接 --- ## 11. 测试报告模板 ### 测试信息 - **测试日期**:2024-XX-XX - **测试人员**:XXX - **测试环境**:Local Development - **后端版本**:1.0.0 ### 测试结果 - **总用例数**:XX - **通过数**:XX - **失败数**:XX - **通过率**:XX% ### 问题记录 1. **问题描述**:XXX - **严重程度**:高/中/低 - **复现步骤**:XXX - **预期结果**:XXX - **实际结果**:XXX --- ## 12. 附录 ### 12.1 快速测试脚本 **Python 测试脚本示例:** ```python import asyncio import websockets import json import uuid import base64 async def test_websocket(): conversation_id = str(uuid.uuid4()) uri = f"ws://localhost:8000/ws/conversation/{conversation_id}" async with websockets.connect(uri) as websocket: # 接收连接确认 response = await websocket.recv() print("收到连接确认:", response) # 发送音频块(模拟) message = { "type": "audio_chunk", "conversation_id": conversation_id, "data": { "audio_base64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQAAAAA=" } } await websocket.send(json.dumps(message)) # 接收响应 for i in range(3): response = await websocket.recv() print(f"收到响应 {i+1}:", response) # 结束对话 end_message = { "type": "end_conversation", "conversation_id": conversation_id } await websocket.send(json.dumps(end_message)) # 接收结束确认 response = await websocket.recv() print("收到结束确认:", response) asyncio.run(test_websocket()) ``` ### 12.2 参考链接 - FastAPI WebSocket 文档:https://fastapi.tiangolo.com/advanced/websockets/ - Apifox WebSocket 测试:https://apifox.com/help/app/web-socket - UUID 生成器:https://www.uuidgenerator.net/ - Base64 编码工具:https://base64.guru/converter/encode/audio --- **文档版本**:v1.0 **最后更新**:2024-01-15 **维护人员**:Life Echo 开发团队