# 流式聊天 API 文档 ## 概述 该 API 提供实时流式聊天功能,支持文本对话和语音合成。API 使用 Server-Sent Events (SSE) 实现流式响应,确保实时性和高效性。 ## 基础信息 - 基础URL: `http://your-domain:8080` - 内容类型: `application/json` - 响应类型: `text/event-stream` (流式响应) ## API 端点 ### 1. 聊天接口 ``` POST /chat ``` #### 请求参数 | 参数名 | 类型 | 必填 | 描述 | |--------|------|------|------| | query | string | 是 | 用户输入的查询文本 | | response_mode | string | 是 | 响应模式,使用 "streaming" 启用流式响应 | | user | string | 是 | 用户标识符 | | conversation_id | string | 否 | 会话ID,首次对话可不传 | #### 请求示例 ```json { "query": "你好,请介绍一下自己", "response_mode": "streaming", "user": "user123", "conversation_id": "" } ``` #### 响应格式 响应使用 Server-Sent Events (SSE) 格式,每个事件包含以下字段: | 字段名 | 类型 | 描述 | |--------|------|------| | answer | string | 机器人的文本回复 | | isEnd | boolean | 是否为最后一条消息 | | conversation_id | string | 会话ID | | task_id | string | 任务ID | | audio_data | string | 语音数据(URL或十六进制编码) | #### 响应示例 ``` data: {"answer":"你好!","isEnd":false,"conversation_id":"conv_123","task_id":"task_456","audio_data":"http://example.com/audio.mp3"} data: {"answer":"我是AI助手","isEnd":false,"conversation_id":"conv_123","task_id":"task_456","audio_data":"http://example.com/audio2.mp3"} data: {"answer":"","isEnd":true,"conversation_id":"conv_123","task_id":"task_456"} ``` ### 2. 停止对话 ``` POST /chat-messages/:task_id/stop ``` #### 路径参数 | 参数名 | 类型 | 描述 | |--------|------|------| | task_id | string | 要停止的任务ID | #### 响应示例 ```json { "status": "success", "message": "Conversation stopped" } ``` ### 3. 删除对话 ``` DELETE /conversations/:conversation_id ``` #### 路径参数 | 参数名 | 类型 | 描述 | |--------|------|------| | conversation_id | string | 要删除的会话ID | #### 查询参数 | 参数名 | 类型 | 必填 | 描述 | |--------|------|------|------| | user | string | 是 | 用户标识符 | #### 响应示例 ```json { "status": "success", "message": "Conversation deleted" } ``` ## 前端集成示例 ### 1. 基本使用 ```javascript async function sendMessage(message) { const response = await fetch('/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query: message, response_mode: 'streaming', user: 'user123', conversation_id: currentConversationId }) }); const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { value, done } = await reader.read(); if (done) break; const chunk = decoder.decode(value); const lines = chunk.split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const data = JSON.parse(line.slice(6)); // 处理响应数据 handleResponse(data); } } } } ``` ### 2. 处理响应数据 ```javascript function handleResponse(data) { // 更新会话ID if (data.conversation_id) { currentConversationId = data.conversation_id; } // 处理文本回复 if (data.answer) { updateChatMessage(data.answer); } // 处理语音数据 if (data.audio_data) { playAudio(data.audio_data); } } ``` ### 3. 播放音频 ```javascript function playAudio(audioData) { // URL格式的音频 if (audioData.startsWith('http')) { const audio = new Audio(audioData); audio.play(); } // 十六进制编码的音频 else { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const audioDataArray = new Uint8Array( audioData.match(/.{1,2}/g).map(byte => parseInt(byte, 16)) ); audioContext.decodeAudioData(audioDataArray.buffer, (buffer) => { const source = audioContext.createBufferSource(); source.buffer = buffer; source.connect(audioContext.destination); source.start(0); }); } } ``` ## 错误处理 ### 常见错误码 | 状态码 | 描述 | |--------|------| | 400 | 请求参数错误 | | 401 | 未授权 | | 500 | 服务器内部错误 | ### 错误响应格式 ```json { "error": "错误描述信息" } ``` ## 最佳实践 1. **会话管理** - 保存 `conversation_id` 以维持对话上下文 - 在对话结束时清理资源 2. **错误处理** - 实现重试机制 - 优雅处理网络错误 - 提供用户友好的错误提示 3. **性能优化** - 使用缓冲通道处理流式数据 - 及时清理不需要的音频资源 - 实现消息队列避免并发问题 4. **安全性** - 验证用户身份 - 使用 HTTPS - 实现请求频率限制 ## 注意事项 1. 确保正确处理 SSE 连接的关闭 2. 实现适当的错误重试机制 3. 注意音频资源的及时释放 4. 考虑网络延迟和断线重连 5. 实现适当的加载状态提示