5.5 KiB
5.5 KiB
语音对话接口交互文档
本文档详细描述了前端 webUI 与后端 server 之间关于语音对话功能(/voice-chat)的交互流程、参数传递及返回值结构。
1. 概述
语音对话功能允许用户录制一段语音,前端将其上传至后端。后端依次执行以下操作:
- STT (Speech-to-Text):将语音转换为文本。
- LLM (Large Language Model):将识别出的文本作为输入,获取 AI 的文本回复。
- TTS (Text-to-Speech):将 AI 的文本回复转换为语音。
最终,后端将用户识别文本、AI 回复文本及合成的语音数据一次性返回给前端。
2. 前端调用 (WebUI)
前端主要涉及的文件为 webUI/src/components/ChatBox.vue 和 webUI/src/utils/api.js。
2.1 调用方式
在 ChatBox.vue 中,当用户完成录音后,调用 handleVoiceModeMessage 方法,进而调用 voiceAPI.voiceChat。
底层通过 uni.uploadFile 发起 multipart/form-data 类型的 POST 请求。
2.2 请求参数
前端向后端发送的请求包含 文件 和 表单数据 (FormData)。
-
URL:
/api/chat/voice-chat(由config.js中的VOICE_CHAT常量定义) -
Method:
POST -
Header:
Authorization: Bearer <token> -
文件部分:
name:"audio"filePath: 录音文件的本地路径 (e.g.,.aac或.wav)
-
表单数据 (FormData):
| 参数名 | 类型 | 必填 | 说明 | 来源 |
|---|---|---|---|---|
sessionId |
String | 否 | 会话 ID,用于保持上下文 | conversationId.value |
modelId |
Integer | 否 | 模型 ID | characterConfig.modelId |
templateId |
Integer | 否 | 模板 ID | characterConfig.templateId |
voiceStyle |
String | 否 | 语音风格 (用于 TTS) | options.voiceStyle |
ttsConfigId |
Integer | 否 | TTS 配置 ID | aiConfig.ttsId |
sttConfigId |
Integer | 否 | STT 配置 ID | aiConfig.sttId |
useFunctionCall |
Boolean | 否 | 是否使用函数调用 | 默认为 false |
2.3 响应处理
前端接收到后端返回的 JSON 数据后,进行如下解析:
- 用户文本: 从
sttResult.text获取,显示在聊天界面右侧。 - AI 回复: 从
llmResult.response获取,显示在聊天界面左侧。 - 语音播放: 优先使用
ttsResult.audioBase64(Base64 编码音频),如果没有则使用ttsResult.audioPath(音频 URL) 进行播放。
3. 后端处理 (Server)
后端入口为 server/src/main/java/com/xiaozhi/controller/ChatController.java,核心逻辑在 ChatSessionServiceImpl.java。
3.1 接口定义
- Controller:
ChatController - Path:
/api/chat/voice-chat - Consumes:
multipart/form-data
3.2 处理流程
- 接收文件: 后端支持字段名为
audioFile,file, 或audio的文件上传 (前端使用audio)。 - 参数解析: 解析
sessionId,modelId等参数。 - 文件验证: 检查文件大小 (1KB - 50MB)、格式 (支持 mp3, wav, m4a, aac 等) 和 MIME 类型。
- 音频处理:
- 将上传的音频文件保存为临时文件。
- 使用
AudioUtils将音频转换为 PCM 16k 单声道 格式(适配 STT 引擎)。
- 业务逻辑 (
ChatSessionService.voiceChat):- STT: 调用配置的 STT 服务识别语音,得到
recognizedText。 - LLM: 如果识别到文本,调用
syncChat获取 AI 回复chatResponse。 - TTS: 调用 TTS 服务将 AI 回复转换为语音,生成音频文件并读取为 Base64。
- STT: 调用配置的 STT 服务识别语音,得到
- 结果封装: 将 STT、LLM、TTS 的结果封装到 Map 中返回。
4. 接口规范
4.1 请求结构
POST /api/chat/voice-chat
Content-Type: multipart/form-data
Body:
audio: [二进制文件数据]sessionId: "session_12345"modelId: 10templateId: 6- ...
4.2 响应结构
Content-Type: application/json
{
"code": 200,
"message": "语音对话成功",
"data": {
"sessionId": "session_12345",
"timestamp": 1717660000000,
// 1. STT 结果
"sttResult": {
"text": "你好,请介绍一下你自己。", // 用户语音识别结果
"audioSize": 32000,
"sttProvider": "vosk"
},
// 2. LLM 结果
"llmResult": {
"response": "你好!我是蔚AI,很高兴为你服务。", // AI 回复文本
"inputText": "你好,请介绍一下你自己。"
},
// 3. TTS 结果
"ttsResult": {
"audioBase64": "UklGRi...", // Base64 编码的音频数据 (用于直接播放)
"audioPath": "audio/output/...", // 服务器音频文件路径
"timestamp": 1717660005000
},
// 性能统计 (耗时: ms)
"sttDuration": 500,
"llmDuration": 1200,
"ttsDuration": 800,
// 文件元数据
"originalFileName": "temp_audio.aac",
"fileSize": 15000,
"contentType": "audio/aac",
"description": null
}
}
4.3 错误响应
{
"code": 400, // 或 500
"message": "请求参数错误: 音频文件不能为空",
"data": null
}
5. 总结
- 交互模式: 同步一次性交互。前端发送音频,等待后端完成所有处理(识别+对话+合成)后,一次性接收所有数据。
- 音频格式: 前端通常录制
aac或wav,后端统一转码为pcm进行处理。 - 回退机制: 如果后端处理失败,前端
ChatBox.vue会捕获异常并提示用户,或使用本地模拟回复(在未登录等特定情况下)。