362 lines
16 KiB
Plaintext
362 lines
16 KiB
Plaintext
---
|
||
title: 单租户生产化开发计划
|
||
description: 以标准接口、实时可观测性、运行可靠性和全链路质量门禁为主线的建设计划。
|
||
icon: list-checks
|
||
---
|
||
|
||
# 单租户生产化开发计划
|
||
|
||
## 目标
|
||
|
||
本计划把当前平台从“功能完整的单租户 MVP”推进到“可以稳定对外提供服务的单租户生产平台”。建设顺序固定为:
|
||
|
||
1. 标准接口契约;
|
||
2. 实时可观测性与 SLO;
|
||
3. 生产运行可靠性;
|
||
4. 全链路质量门禁。
|
||
|
||
顺序不能颠倒:先确定平台对调用方承诺的行为,再测量真实质量,然后根据数据加固运行时,最后用自动化门禁持续证明质量。
|
||
|
||
## 范围
|
||
|
||
本计划包含:
|
||
|
||
- OpenAI-compatible Responses 和 Realtime 公开接口;
|
||
- HTTP、SSE、WebSocket 和 WebRTC 的协议契约;
|
||
- Pipecat Pipeline、Provider、工具、知识库和后台任务的指标与追踪;
|
||
- 单实例优先的生产部署、优雅停机、任务恢复和资源保护;
|
||
- 协议、浏览器媒体链路、弱网、故障和负载测试。
|
||
|
||
本计划暂不包含:
|
||
|
||
- 多用户、组织、工作空间和 RBAC;
|
||
- `/v1/chat/completions` 兼容层;
|
||
- 完整实现 OpenAI Responses 的所有可选能力;
|
||
- SIP、跨区域部署和 Realtime 断线续传;
|
||
- 助手草稿、发布版本和环境晋级体系。
|
||
|
||
<Note>
|
||
即使暂不建设完整权限体系,公网部署前仍必须移除默认凭证、分离签名密钥、启用 TLS,并设置基本的请求与并发限制。
|
||
</Note>
|
||
|
||
## 当前基线
|
||
|
||
- `POST /v1/responses` 和 `GET /v1/responses/{response_id}` 已支持持久化状态、`previous_response_id`、SSE 和 Client Tool 续传。
|
||
- `/v1/realtime/client_secrets`、`/v1/realtime/calls` 和 `/v1/realtime` WebSocket 已支持标准事件与项目扩展事件。
|
||
- Realtime 已支持 WebRTC、WebSocket、Server VAD、PTT、打断、函数调用和条件视觉输入。
|
||
- 后端现有 342 个自动化测试,并通过统一入口处理本地 NLTK 运行环境。
|
||
- 前端可以通过构建和 lint,已增加官方 SDK 契约测试,但尚无系统性的组件测试和浏览器端到端测试。
|
||
- Responses 已启用 Provider token usage 采集;延迟等 Pipecat metrics 尚未启用,健康检查仍只有进程存活语义。
|
||
- 知识库处理、通话后分析、Webhook 和批量测试仍有进程内任务或 Worker。
|
||
|
||
## 里程碑一:标准接口契约
|
||
|
||
### 目标
|
||
|
||
让第三方调用方只依赖公开文档、OpenAPI 和标准 SDK 即可完成接入,并清楚知道哪些 OpenAI 能力受支持、哪些能力被平台锁定或尚未实现。
|
||
|
||
### 1.1 建立兼容性规范
|
||
|
||
- [x] 将公开协议命名为 `OpenAI-compatible subset v1`。
|
||
- [x] 为 Responses 请求字段、返回对象、SSE 事件和错误码维护兼容矩阵。
|
||
- [x] 为 Realtime 客户端事件、服务端事件、传输限制和扩展事件维护兼容矩阵。
|
||
- [x] 区分三种字段状态:支持、平台锁定、不支持。
|
||
- [x] 为 `x.interactive_media.*` 扩展增加独立版本号和能力协商说明。
|
||
- [x] 规定新增字段向后兼容、废弃字段通知和破坏性变更升级规则。
|
||
|
||
### 1.2 补全公开 API Schema
|
||
|
||
- [x] 为 Responses create、retrieve 和错误对象建立 Pydantic 模型。
|
||
- [x] 使用判别联合描述 `message`、`function_call` 和 `function_call_output`。
|
||
- [x] 在 OpenAPI 中声明 JSON、multipart/form-data、application/sdp 和 text/event-stream。
|
||
- [x] 为 Realtime JSON 事件维护可校验的 JSON Schema。
|
||
- [x] 为所有公开响应声明状态码、错误结构和示例。
|
||
- [x] 生成并提交稳定的 OpenAPI snapshot,CI 检查未审查的契约变化。
|
||
|
||
### 1.3 完善 Responses 资源接口
|
||
|
||
- [x] 增加 `GET /v1/responses/{response_id}/input_items`,支持稳定排序和分页。
|
||
- [x] 增加 `DELETE /v1/responses/{response_id}`。
|
||
- [x] 删除 Response 时使用逻辑删除或内部 tombstone,不能破坏已有子 Response 的祖先链。
|
||
- [x] 增加 `Idempotency-Key`:同 Key、同请求返回原结果;同 Key、不同请求返回冲突。
|
||
- [x] Provider 可以提供 Token 统计时返回真实 `usage`;无法提供时保持 `null` 并写入兼容说明。
|
||
- [x] 暂不实现 background 时,明确拒绝 `/cancel`,而不是静默接受。
|
||
|
||
### 1.4 增加模型发现与统一错误
|
||
|
||
- [x] 增加 `GET /v1/models`,列出当前可以通过公开接口调用的助手。
|
||
- [x] 第一版继续返回 `assistant:asst_xxx`;响应结构为未来稳定助手别名保留字段。
|
||
- [x] 所有公开 HTTP 错误统一为 OpenAI 风格的 `error` 对象。
|
||
- [x] 所有 HTTP 响应返回或透传 `X-Request-ID`。
|
||
- [x] Realtime `error.event_id` 必须关联原客户端事件。
|
||
- [x] 401、404、409、422、429、503 的使用规则写入协议文档。
|
||
|
||
### 1.5 SDK 契约测试
|
||
|
||
- [x] 使用官方 OpenAI Python SDK 测试 Responses 非流式、多轮和 SSE。
|
||
- [x] 使用官方 OpenAI JavaScript SDK 测试相同场景。
|
||
- [x] 测试 Client Tool 调用及 `function_call_output` 续传。
|
||
- [x] 测试跨 API Key 隐藏、重复幂等键和不支持字段。
|
||
- [x] 对 Realtime WebSocket 事件运行 JSON Schema 与事件顺序测试。
|
||
|
||
### 验收标准
|
||
|
||
- OpenAPI 中所有公开 HTTP 接口都有请求体、响应体和错误 schema。
|
||
- 官方 Python 和 JavaScript SDK 可以通过自定义 `base_url` 完成三轮 Responses 对话。
|
||
- 非流式结果、SSE 最终结果和 GET 查询结果语义一致。
|
||
- 公开兼容矩阵与代码自动化测试一一对应。
|
||
- 调用方不阅读项目源码也能完成首次接入。
|
||
|
||
## 里程碑二:实时可观测性与 SLO
|
||
|
||
### 目标
|
||
|
||
能够回答“慢在哪里、错在哪里、影响了多少会话”,并用可量化指标定义实时对话质量。
|
||
|
||
### 2.1 建立统一关联标识
|
||
|
||
每次执行使用以下层级:
|
||
|
||
```text
|
||
request_id
|
||
└─ session_id / response_id
|
||
└─ conversation_id
|
||
└─ turn_id
|
||
├─ asr span
|
||
├─ llm span
|
||
├─ tts span
|
||
├─ knowledge span
|
||
└─ tool span
|
||
```
|
||
|
||
- [ ] 使用 `contextvars` 在异步任务中传播关联标识。
|
||
- [ ] HTTP、SSE、WebSocket、WebRTC、后台任务和 Webhook 使用同一套标识命名。
|
||
- [ ] 日志中输出关联标识,但不把提示词、转写、密钥或动态变量作为默认日志字段。
|
||
- [ ] 指标标签禁止使用 response ID、session ID 等高基数字段。
|
||
|
||
### 2.2 接入 Metrics 和 Tracing
|
||
|
||
- [ ] 启用 Pipecat Pipeline metrics。
|
||
- [ ] 接入 Prometheus 指标端点。
|
||
- [ ] 接入 OpenTelemetry SDK,并允许通过 OTLP 环境变量配置 exporter。
|
||
- [ ] 为 FastAPI、HTTP Provider 调用和 PostgreSQL 增加基础自动插桩。
|
||
- [ ] 为 Pipeline 阶段、工具、知识库、SSE 和后台任务增加业务 span。
|
||
- [ ] exporter 不可用时不得阻塞或终止实时对话。
|
||
|
||
### 2.3 第一批指标
|
||
|
||
| 指标 | 类型 | 推荐标签 |
|
||
| --- | --- | --- |
|
||
| 活跃 Realtime 会话 | Gauge | channel、runtime_mode |
|
||
| 会话建立和结束 | Counter | channel、status、reason |
|
||
| 用户停说到首音频 | Histogram | runtime_mode、provider |
|
||
| ASR final 延迟 | Histogram | interface_type、status |
|
||
| LLM 首 Token 延迟 | Histogram | interface_type、status |
|
||
| TTS 首音频延迟 | Histogram | interface_type、status |
|
||
| 打断处理延迟 | Histogram | channel、status |
|
||
| 工具调用延迟 | Histogram | tool_type、status |
|
||
| 知识库检索延迟 | Histogram | mode、status |
|
||
| Responses 请求 | Counter/Histogram | stream、status |
|
||
| 后台任务 | Counter/Histogram | kind、status |
|
||
|
||
- [ ] 统一定义成功、取消、客户端断开、超时和内部失败状态。
|
||
- [ ] Provider 错误按鉴权、限流、超时、网络和服务端错误分类。
|
||
- [ ] WebRTC 首版从服务端可见统计开始;浏览器 `getStats()` 上报作为后续增强。
|
||
|
||
### 2.4 仪表盘与初始 SLO
|
||
|
||
- [ ] 建立 Realtime 总览、Provider、Responses、工具与后台任务仪表盘。
|
||
- [ ] 至少展示 p50、p95、p99 和最近错误样本。
|
||
- [ ] 先采集基线,再确认正式阈值。
|
||
- [ ] 为会话建立失败率、首音频延迟、Provider 错误率和任务积压设置告警。
|
||
|
||
初始候选目标:
|
||
|
||
| 项目 | 候选目标 |
|
||
| --- | --- |
|
||
| Realtime 会话建立成功率 | ≥ 99.5% |
|
||
| 用户停说到首音频 | p95 ≤ 2 秒 |
|
||
| 服务端打断处理 | p95 ≤ 250 ms |
|
||
| 平台自身导致的 turn 失败率 | ≤ 0.5% |
|
||
| Responses 非流式成功率 | ≥ 99.5% |
|
||
|
||
正式 SLO 必须在目标部署环境和真实 Provider 上取得基线后确认。
|
||
|
||
### 验收标准
|
||
|
||
- 可以从一次失败的会话追踪到具体 Provider、工具或存储阶段。
|
||
- 仪表盘能展示首音频延迟、错误率、活跃会话和任务积压。
|
||
- 关闭监控后端不会影响对话主链路。
|
||
- 日志和指标不泄漏用户内容或密钥。
|
||
|
||
## 里程碑三:生产运行可靠性
|
||
|
||
### 目标
|
||
|
||
在单租户、单区域、单个 Realtime API 进程优先的约束下,实现可恢复、可排空、有限流和可备份的生产运行方式。
|
||
|
||
### 3.1 Realtime 进程生命周期
|
||
|
||
- [ ] 增加服务状态:starting、ready、draining、stopped。
|
||
- [ ] draining 后停止签发 Client Secret,并拒绝新 Calls 和 WebSocket 会话。
|
||
- [ ] 已建立会话在可配置的宽限期内继续运行。
|
||
- [ ] 宽限期结束后取消剩余 Pipeline,并持久化明确终态。
|
||
- [ ] 统一 WebRTC、WebSocket、RTVI 和 Responses 的关闭及取消路径。
|
||
- [ ] 为 Pipeline 启动、关闭和资源释放增加超时保护。
|
||
|
||
Realtime Pipeline 与媒体连接绑定,继续保留在 API 进程内,不迁移到普通任务队列。
|
||
|
||
### 3.2 健康检查和资源保护
|
||
|
||
- [ ] 增加 `/health/live`,只判断事件循环和进程是否存活。
|
||
- [ ] 增加 `/health/ready`,检查数据库、迁移版本、必要配置和对象存储。
|
||
- [ ] readiness 失败时不接收新会话,但 liveness 不应因此触发无限重启。
|
||
- [ ] 设置全局活跃会话上限和每 API Key 并发上限。
|
||
- [ ] 为请求体、音频缓冲、SSE 队列和工具结果设置大小上限。
|
||
- [ ] 数据库连接池、HTTP 连接池和线程池使用显式上限。
|
||
- [ ] 达到容量上限时返回可识别的 429 或 503。
|
||
|
||
### 3.3 Provider 可靠性策略
|
||
|
||
- [ ] 统一 Provider 错误分类和超时配置。
|
||
- [ ] 只有在尚未向客户端输出内容时才允许自动重试。
|
||
- [ ] 流式输出开始后禁止透明重试,避免重复文字、音频或工具调用。
|
||
- [ ] 对新会话实现轻量熔断和恢复探测。
|
||
- [ ] 模型资源测试与生产请求共享同一套连接和错误分类逻辑。
|
||
- [ ] 备用 Provider 或模型作为后续可选能力,不在第一批强制实现。
|
||
|
||
### 3.4 迁移后台任务
|
||
|
||
第一批迁移以下任务:
|
||
|
||
- 知识库文档解析与向量化;
|
||
- 通话后分析;
|
||
- Webhook 投递;
|
||
- 批量测试和 Prompt 改进。
|
||
|
||
实现约束:
|
||
|
||
- [ ] 使用 Redis + ARQ 作为单租户 MVP 队列。
|
||
- [ ] PostgreSQL 保存任务业务状态,Redis 只负责投递、租约和重试。
|
||
- [ ] 每类任务都有幂等键、最大重试次数和明确终态。
|
||
- [ ] Worker 崩溃后任务可以重新领取。
|
||
- [ ] 重复执行不能重复发送 Webhook 或写入重复结果。
|
||
- [ ] API 能查询任务状态,服务启动不再直接恢复和执行全部后台工作。
|
||
|
||
### 3.5 生产部署和恢复
|
||
|
||
- [ ] 增加生产 API 镜像,移除 `--reload`。
|
||
- [ ] 前端使用 `next build` 与 `next start` 或静态生产部署。
|
||
- [ ] 数据库迁移作为独立部署步骤,不能由多个 API 实例同时执行。
|
||
- [ ] 为 PostgreSQL 和对象存储编写备份、恢复和校验步骤。
|
||
- [ ] 设置日志轮转、磁盘水位和录音/Response 保留策略。
|
||
- [ ] 完成一次从备份恢复到新环境的演练。
|
||
|
||
### 验收标准
|
||
|
||
- 服务进入 draining 后不接收新会话,已有会话可以正常结束或在超时后被正确取消。
|
||
- Worker 被强制终止后,未完成任务可以恢复且不会重复产生副作用。
|
||
- Provider 超时不会无限占用 Pipeline 或连接。
|
||
- 数据库或对象存储不可用时 readiness 会失败并给出可诊断原因。
|
||
- 生产部署不运行开发热更新服务。
|
||
|
||
## 里程碑四:全链路质量门禁
|
||
|
||
### 目标
|
||
|
||
把协议正确性、实时体验和故障恢复变成每次变更都能重复验证的发布条件。
|
||
|
||
### 4.1 测试分层
|
||
|
||
| 层级 | 运行时机 | 内容 |
|
||
| --- | --- | --- |
|
||
| 单元和组件测试 | 每次提交 | 协议解析、状态机、工具、工作流、指标 |
|
||
| 契约测试 | 每次提交 | OpenAPI、JSON Schema、Python/JS SDK |
|
||
| 服务集成测试 | 每次提交 | PostgreSQL、Redis、对象存储、Fake Provider |
|
||
| 浏览器媒体测试 | 主分支或发布前 | WebRTC、假麦克风、DataChannel、打断 |
|
||
| 基础设施测试 | 每日或发布前 | TURN、弱网、故障注入 |
|
||
| 真实 Provider smoke | 每日或发布前 | 限量 ASR、LLM、TTS、Realtime 调用 |
|
||
| 负载和长稳测试 | 发布前 | 并发、容量、内存、连接和任务泄漏 |
|
||
|
||
### 4.2 每次提交门禁
|
||
|
||
- [ ] 提供一个无需隐藏环境变量的后端测试命令。
|
||
- [ ] 运行后端全部测试、前端 lint 和 production build。
|
||
- [ ] 从空数据库执行所有 Alembic migrations。
|
||
- [ ] 校验 OpenAPI snapshot 和 Realtime JSON Schema。
|
||
- [ ] 使用 Fake Provider 完成 Responses 三轮对话、分支和 Client Tool 续传。
|
||
- [ ] 测试 SSE 断开、Pipeline 失败、超时和取消后的数据库终态。
|
||
- [ ] 测试 Worker 幂等、重试和任务恢复。
|
||
|
||
### 4.3 浏览器和媒体链路
|
||
|
||
- [ ] 使用 Playwright Chromium 假麦克风输入固定音频文件。
|
||
- [ ] 验证 WebRTC SDP、远端音频轨道和 `oai-events` DataChannel。
|
||
- [ ] 验证 Server VAD、PTT、打断和 Client Tool。
|
||
- [ ] 使用固定 PCM fixture 测试 Realtime WebSocket。
|
||
- [ ] 在独立环境中强制只走 TURN,避免测试误用直连路径。
|
||
- [ ] 保存失败时的浏览器日志、协议事件和服务端 trace。
|
||
|
||
### 4.4 弱网、故障和负载
|
||
|
||
- [ ] 使用 Linux `tc netem` 注入延迟、抖动、丢包和短时断网。
|
||
- [ ] 注入 ASR、LLM、TTS、工具、数据库、Redis 和对象存储超时。
|
||
- [ ] 验证客户端断开后 Pipeline 与资源及时释放。
|
||
- [ ] 对 Responses HTTP/SSE 和 Realtime WebSocket 运行并发测试。
|
||
- [ ] 使用 aiortc 测试客户端运行 WebRTC 并发场景。
|
||
- [ ] 运行 30 至 60 分钟长连接 soak test,观察内存、Task 和连接数量。
|
||
|
||
### 4.5 发布判定
|
||
|
||
一次生产发布至少满足:
|
||
|
||
- [ ] 单元、契约、集成和浏览器关键路径全部通过。
|
||
- [ ] 没有未审查的公开协议变化。
|
||
- [ ] p95 首音频延迟未超过允许回归范围。
|
||
- [ ] 错误率、超时率和异常断开率未超过阈值。
|
||
- [ ] 没有持续增长的 Pipeline、asyncio Task、数据库连接或 WebRTC peer。
|
||
- [ ] 备份恢复和 Worker 恢复机制在当前版本仍然有效。
|
||
|
||
## 推荐交付批次
|
||
|
||
### 批次 A:契约与工程入口
|
||
|
||
- 修复统一测试命令;
|
||
- 建立后端、前端和 migration CI;
|
||
- 为 Responses 增加 Pydantic/OpenAPI schema;
|
||
- 增加统一错误对象、Request ID 和 OpenAPI snapshot;
|
||
- 增加 Python SDK Responses 契约测试。
|
||
|
||
### 批次 B:Realtime 契约与观测基础
|
||
|
||
- 建立 Realtime 事件 JSON Schema;
|
||
- 增加 JavaScript SDK 和 WebSocket 契约测试;
|
||
- 建立关联 ID 和结构化日志;
|
||
- 接入 Prometheus 与 OpenTelemetry;
|
||
- 输出第一版运行基线仪表盘。
|
||
|
||
### 批次 C:生命周期与 Worker
|
||
|
||
- 增加 live、ready 和 draining;
|
||
- 增加会话、缓冲和连接池上限;
|
||
- 统一 Provider 超时和重试边界;
|
||
- 引入 ARQ Worker 并逐类迁移后台任务;
|
||
- 增加生产镜像与备份恢复说明。
|
||
|
||
### 批次 D:全链路发布门禁
|
||
|
||
- 建立 PostgreSQL、Redis、对象存储和 Fake Provider 集成环境;
|
||
- 增加 Playwright WebRTC 与 PCM WebSocket 测试;
|
||
- 增加 TURN、弱网、故障注入和真实 Provider smoke;
|
||
- 建立负载、长稳测试和发布阈值。
|
||
|
||
## 总体验收
|
||
|
||
完成本计划后,平台应满足以下定义:
|
||
|
||
1. 对外接口有明确、可生成、可测试的稳定契约;
|
||
2. 每个请求、会话和对话轮次都可以被测量和追踪;
|
||
3. 服务、Provider 或 Worker 故障不会留下无法恢复的模糊状态;
|
||
4. 发布前可以自动证明标准接口、实时媒体链路和核心 SLO 没有回归;
|
||
5. 无需引入多用户体系,也能作为单租户生产服务安全、稳定地运行。
|