Add API reference documentation for WebSocket communication. Update mkdocs.yml to include new API reference section.

This commit is contained in:
Xin Wang
2026-02-28 14:37:58 +08:00
parent a7da109983
commit 0821d73e7c
2 changed files with 308 additions and 0 deletions

View File

@@ -0,0 +1,306 @@
# API 参考
本节提供 AI Video Assistant 的 API 接口文档,包括 WebSocket 实时通信协议和后端 REST API。
---
## WebSocket 实时通信
WebSocket 端点提供双向实时语音对话能力,支持音频流输入输出和文本消息交互。
### 连接地址
```
ws://<host>/ws
```
### 传输规则
- **文本帧**JSON 格式控制消息
- **二进制帧**PCM 音频数据(`pcm_s16le`, 16kHz, 单声道)
- 帧长度必须是 640 字节的整数倍20ms 音频 = 640 bytes
---
### 消息流程
```
Client -> hello
Server <- hello.ack
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. Handshake: `hello`
客户端连接后发送的第一个消息,用于协议版本协商和认证。
```json
{
"type": "hello",
"version": "v1",
"auth": {
"apiKey": "optional-api-key",
"jwt": "optional-jwt"
}
}
```
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `type` | string | 是 | 固定为 `"hello"` |
| `version` | string | 是 | 协议版本,固定为 `"v1"` |
| `auth` | object | 否 | 认证信息 |
**认证规则**
- 若配置了 `WS_API_KEY`,必须提供匹配的 `apiKey`
-`WS_REQUIRE_AUTH=true`,至少需要提供 `apiKey``jwt` 之一
---
#### 2. Session Start: `session.start`
握手成功后发送的第二个消息,用于启动对话会话。
```json
{
"type": "session.start",
"audio": {
"encoding": "pcm_s16le",
"sample_rate_hz": 16000,
"channels": 1
},
"metadata": {
"appId": "assistant_123",
"channel": "web",
"configVersionId": "cfg_20260217_01",
"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 支持的字段**
- `appId` / `app_id` - 应用 ID
- `channel` - 渠道标识
- `configVersionId` / `config_version_id` - 配置版本
- `systemPrompt` - 系统提示词
- `greeting` - 开场白
- `output.mode` - 输出模式 (`audio` / `text`)
- `dynamicVariables` - 动态变量(支持 `{{variable}}` 占位符)
---
#### 3. Text Input: `input.text`
发送文本输入,跳过 ASR 识别,直接触发 LLM 回复。
```json
{
"type": "input.text",
"text": "你能做什么?"
}
```
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `type` | string | 是 | 固定为 `"input.text"` |
| `text` | string | 是 | 用户文本内容 |
---
#### 4. Response Cancel: `response.cancel`
请求中断当前回答。
```json
{
"type": "response.cancel",
"graceful": false
}
```
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| `type` | string | 是 | - | 固定为 `"response.cancel"` |
| `graceful` | boolean | 否 | `false` | `false` 立即打断 |
---
#### 5. 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 | 是 | 执行状态 |
---
#### 6. Session Stop: `session.stop`
结束对话会话。
```json
{
"type": "session.stop",
"reason": "client_disconnect"
}
```
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `type` | string | 是 | 固定为 `"session.stop"` |
| `reason` | string | 否 | 结束原因 |
---
#### 7. 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 | 业务数据 |
---
#### 会话控制类事件
| 事件 | 说明 |
|---|---|
| `hello.ack` | 握手成功响应 |
| `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.version_unsupported` | 协议版本不支持 |
| `auth.invalid_api_key` | API Key 无效 |
| `auth.required` | 需要认证 |
| `audio.invalid_pcm` | PCM 数据无效 |
| `audio.frame_size_mismatch` | 音频帧大小不匹配 |
| `server.internal` | 服务端内部错误 |
---
### 心跳与超时
- **心跳间隔**:默认 50 秒(`heartbeat_interval_sec`
- **空闲超时**:默认 60 秒(`inactivity_timeout_sec`
- 客户端应持续发送音频或轻量消息避免被判定闲置

View File

@@ -19,3 +19,5 @@ nav:
- 自动化测试: "features/autotest.md"
- 语音合成: "features/voices.md"
- 部署指南: "deployment.md"
- API 参考:
- WebSocket: "api-reference.md"