Files
life-echo/api/docs/WebSocket测试文档.md
徐在坤 ebfd705b93 feat: 添加Docker和部署配置
- 添加Dockerfile用于容器化部署
- 添加docker-compose.yml用于本地开发环境
- 添加build.sh构建脚本
- 添加README.md项目文档
- 添加API文档
2026-01-18 15:58:05 +08:00

15 KiB
Raw Blame History

Life Echo WebSocket 对话接口测试文档

1. 接口信息

1.1 连接地址

ws://localhost:8000/ws/conversation/{conversation_id}

参数说明:

  • conversation_id: 对话IDUUID格式例如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)

{
  "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)

{
  "type": "end_conversation",
  "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2024-01-15T10:35:00.000Z"
}

3.2 服务端消息格式

3.2.1 连接确认 (connect)

{
  "type": "connect",
  "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "status": "connected"
  },
  "timestamp": "2024-01-15T10:30:00.000Z"
}

3.2.2 语音转文字结果 (transcript)

{
  "type": "transcript",
  "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "text": "我小时候住在北京"
  },
  "timestamp": "2024-01-15T10:30:05.000Z"
}

3.2.3 Agent 回应 (agent_response)

{
  "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)

{
  "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)

{
  "type": "end_conversation",
  "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "status": "ended"
  },
  "timestamp": "2024-01-15T10:35:00.000Z"
}

3.2.6 错误信息 (error)

{
  "type": "error",
  "data": {
    "message": "ASR服务暂时不可用请稍后重试"
  },
  "timestamp": "2024-01-15T10:30:05.000Z"
}

4. 在 Apifox 中测试步骤

4.1 准备工作

  1. 启动后端服务

    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. 发送音频块

    {
      "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. 结束对话

    {
      "type": "end_conversation",
      "conversation_id": "550e8400-e29b-41d4-a716-446655440000"
    }
    
    • 预期收到:end_conversation 确认消息
    • 连接自动断开

场景 2错误处理测试

测试无效的音频数据:

{
  "type": "audio_chunk",
  "data": {
    "audio_base64": "invalid_base64_data"
  }
}
  • 预期收到:error 消息,包含错误描述

测试缺少必需字段:

{
  "type": "audio_chunk"
}
  • 预期收到:error 消息或连接断开

场景 3连接断开测试

  1. 正常断开

    • 发送 end_conversation 消息
    • 连接正常关闭
  2. 异常断开

    • 直接关闭连接(不发送 end_conversation
    • 服务端应清理资源

场景 4多轮对话测试

测试对话阶段切换:

  1. 发送童年相关话题

    {
      "type": "audio_chunk",
      "data": {
        "audio_base64": "{童年相关音频的base64}"
      }
    }
    
    • 预期Agent 回应关于童年的话题
  2. 发送教育相关话题

    {
      "type": "audio_chunk",
      "data": {
        "audio_base64": "{教育相关音频的base64}"
      }
    }
    
    • 预期Agent 自动切换到教育阶段,回应教育相关话题
  3. 发送工作相关话题

    • 预期Agent 切换到职业阶段

5. 测试用例清单

5.1 基础功能测试

用例ID 测试场景 输入 预期结果 状态
TC-001 建立连接 连接 WebSocket 收到 connect 消息
TC-002 发送音频块 发送 audio_chunk 收到 transcriptagent_responsetts_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使用在线工具

方法2使用命令行

# Python
python -c "import uuid; print(uuid.uuid4())"

# Node.js
node -e "console.log(require('crypto').randomUUID())"

6.2 准备测试音频

方法1使用文本转Base64模拟

# 创建一个简单的测试音频文件WAV格式
# 然后转换为Base64
base64 -i test_audio.wav

方法2使用在线工具

方法3使用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 对话测试
    • URLws://localhost:8000/ws/conversation/{conversation_id}
    • 方法WebSocket (自动识别)
  3. 添加参数

    • 在 URL 中直接替换 {conversation_id} 为实际值
    • 或使用变量:ws://localhost:8000/ws/conversation/{{conversation_id}}

7.2 发送消息

  1. 连接成功后

    • 在消息输入框中输入 JSON 格式的消息
    • 或使用"消息模板"
  2. 创建消息模板

    {
      "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. 添加变量

    {
      "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 测试脚本示例:

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 参考链接


文档版本v1.0
最后更新2024-01-15
维护人员Life Echo 开发团队