# API 参考 本节提供 AI Video Assistant 的 API 接口文档,包括 WebSocket 实时通信协议和后端 REST API。 --- ## WebSocket 实时通信 WebSocket 端点提供双向实时语音对话能力,支持音频流输入输出和文本消息交互。 ### 连接地址 ``` ws:///ws?assistant_id= ``` - `assistant_id` 为必填 query 参数,用于从数据库加载该助手的运行时配置。 ### 传输规则 - **文本帧**:JSON 格式控制消息 - **二进制帧**:PCM 音频数据(`pcm_s16le`, 16kHz, 单声道) - 帧长度必须是 640 字节的整数倍(20ms 音频 = 640 bytes) --- ### 消息流程 ``` Client -> session.start Server <- session.started Server <- config.resolved Client -> (binary pcm frames...) Server <- input.speech_started / transcript.delta / transcript.final Server <- assistant.response.delta / assistant.response.final Server <- output.audio.start Server <- (binary pcm frames...) Server <- output.audio.end Client -> session.stop Server <- session.stopped ``` --- ### 客户端 -> 服务端消息 #### 1. Session Start: `session.start` 客户端连接后发送的第一个消息,用于启动对话会话。 ```json { "type": "session.start", "audio": { "encoding": "pcm_s16le", "sample_rate_hz": 16000, "channels": 1 }, "metadata": { "channel": "web", "source": "web_debug", "history": { "userId": 1 }, "overrides": { "systemPrompt": "你是简洁助手", "greeting": "你好,我能帮你什么?", "output": { "mode": "audio" } }, "dynamicVariables": { "customer_name": "Alice", "plan_tier": "Pro" } } } ``` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `type` | string | 是 | 固定为 `"session.start"` | | `audio` | object | 否 | 音频格式描述 | | `audio.encoding` | string | 否 | 固定为 `"pcm_s16le"` | | `audio.sample_rate_hz` | number | 否 | 固定为 `16000` | | `audio.channels` | number | 否 | 固定为 `1` | | `metadata` | object | 否 | 运行时配置 | **metadata 支持的字段**: - `channel` - 渠道标识 - `source` - 来源标识 - `history.userId` - 历史记录用户 ID - `overrides` - 可覆盖字段(仅限安全白名单) - `dynamicVariables` - 动态变量(支持 `{{variable}}` 占位符) **`metadata.overrides` 白名单字段**: - `systemPrompt` - `greeting` - `firstTurnMode` - `generatedOpenerEnabled` - `output` - `bargeIn` - `knowledgeBaseId` - `knowledge` - `tools` - `openerAudio` **限制**: - `metadata.workflow` 会被忽略(不触发 workflow 事件) - 禁止提交 `metadata.services` - 禁止提交 `assistantId` / `appId` / `app_id` / `configVersionId` / `config_version_id` - 禁止提交包含密钥语义的字段(如 `apiKey` / `token` / `secret` / `password` / `authorization`) --- #### 2. Text Input: `input.text` 发送文本输入,跳过 ASR 识别,直接触发 LLM 回复。 ```json { "type": "input.text", "text": "你能做什么?" } ``` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `type` | string | 是 | 固定为 `"input.text"` | | `text` | string | 是 | 用户文本内容 | --- #### 3. Response Cancel: `response.cancel` 请求中断当前回答。 ```json { "type": "response.cancel", "graceful": false } ``` | 字段 | 类型 | 必填 | 默认值 | 说明 | |---|---|---|---|---| | `type` | string | 是 | - | 固定为 `"response.cancel"` | | `graceful` | boolean | 否 | `false` | `false` 立即打断 | --- #### 4. Tool Call Results: `tool_call.results` 回传客户端执行的工具结果。 ```json { "type": "tool_call.results", "results": [ { "tool_call_id": "call_abc123", "name": "weather", "output": { "temp_c": 21, "condition": "sunny" }, "status": { "code": 200, "message": "ok" } } ] } ``` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `type` | string | 是 | 固定为 `"tool_call.results"` | | `results` | array | 否 | 工具结果列表 | | `results[].tool_call_id` | string | 是 | 工具调用 ID | | `results[].name` | string | 是 | 工具名称 | | `results[].output` | any | 否 | 工具输出 | | `results[].status` | object | 是 | 执行状态 | --- #### 5. Session Stop: `session.stop` 结束对话会话。 ```json { "type": "session.stop", "reason": "client_disconnect" } ``` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `type` | string | 是 | 固定为 `"session.stop"` | | `reason` | string | 否 | 结束原因 | --- #### 6. Binary Audio 在 `session.started` 之后可持续发送二进制 PCM 音频。 - **格式**:`pcm_s16le` - **采样率**:16000 Hz - **声道**:1(单声道) - **帧长**:20ms = 640 bytes --- ### 服务端 -> 客户端事件 #### 事件包络 所有 JSON 事件都包含统一包络字段: ```json { "type": "event.name", "timestamp": 1730000000000, "sessionId": "sess_xxx", "seq": 42, "source": "asr", "trackId": "audio_in", "data": {} } ``` | 字段 | 类型 | 说明 | |---|---|---| | `type` | string | 事件类型 | | `timestamp` | number | 事件时间戳(毫秒) | | `sessionId` | string | 会话 ID | | `seq` | number | 递增序号 | | `source` | string | 事件来源 (`asr`/`llm`/`tts`/`tool`) | | `trackId` | string | 事件轨道 (`audio_in`/`audio_out`/`control`) | | `data` | object | 业务数据 | --- #### 会话控制类事件 | 事件 | 说明 | |---|---| | `session.started` | 会话启动成功 | | `config.resolved` | 服务端最终配置快照 | | `heartbeat` | 保活心跳(默认 50 秒间隔) | | `session.stopped` | 会话结束确认 | | `error` | 统一错误事件 | --- #### ASR 识别事件 | 事件 | 字段 | 说明 | |---|---|---| | `input.speech_started` | `probability` | 检测到语音开始 | | `input.speech_stopped` | `probability` | 检测到语音结束 | | `transcript.delta` | `text` | ASR 增量识别文本 | | `transcript.final` | `text` | ASR 最终识别文本 | --- #### LLM/TTS 输出事件 | 事件 | 字段 | 说明 | |---|---|---| | `assistant.response.delta` | `text` | 助手增量文本输出 | | `assistant.response.final` | `text` | 助手完整文本输出 | | `assistant.tool_call` | `tool_call_id`, `tool_name`, `arguments` | 工具调用通知 | | `assistant.tool_result` | `tool_call_id`, `ok`, `result` | 工具执行结果 | | `output.audio.start` | - | TTS 音频开始 | | `output.audio.end` | - | TTS 音频结束 | | `response.interrupted` | - | 回答被打断 | | `metrics.ttfb` | `latencyMs` | 首包音频时延 | --- ### 错误码 | 错误码 | 说明 | |---|---| | `protocol.invalid_json` | JSON 格式错误 | | `protocol.invalid_message` | 消息格式错误 | | `protocol.order` | 消息顺序错误 | | `protocol.assistant_id_required` | 缺少 `assistant_id` query 参数 | | `protocol.invalid_override` | metadata 覆盖字段不合法 | | `assistant.not_found` | assistant 不存在 | | `assistant.config_unavailable` | assistant 配置不可用 | | `audio.invalid_pcm` | PCM 数据无效 | | `audio.frame_size_mismatch` | 音频帧大小不匹配 | | `server.internal` | 服务端内部错误 | --- ### 心跳与超时 - **心跳间隔**:默认 50 秒(`heartbeat_interval_sec`) - **空闲超时**:默认 60 秒(`inactivity_timeout_sec`) - 客户端应持续发送音频或轻量消息避免被判定闲置