Files
Xin Wang deaf3d7730 Add dynamic variable support to Assistant model and related components
- Introduce dynamic variable definitions in AssistantConfig and Assistant models, allowing for flexible prompt customization.
- Implement validation for dynamic variable names and types in the schema.
- Update backend services and routes to handle dynamic variables in assistant configurations and runtime processing.
- Enhance frontend components to support dynamic variable definitions, including a new editor for managing variables.
- Add tests to ensure proper functionality and validation of dynamic variables in various scenarios.
2026-07-12 23:42:56 +08:00

189 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Video Assistant — 后端引擎
参考 [dograh](../dograh),用 **pipecat** 作语音引擎的自建后端。目标是逐步长成
类 dograh 平台,但**同时支持 WebRTC 和 WS 两种音频输出**。
## 双输出架构(核心)
pipecat 把"管线"和"输出方式"解耦:同一条 `STT→LLM→TTS` 管线可挂不同 transport。
```
┌─────────────────────────────────┐
浏览器 ──WebRTC──► /ws/voice ──┤ │
│ run_pipeline(transport, cfg): │
自定义/话务 ─WS──► /ws/stream ─┤ input→STT→LLM→TTS→output │
└─────────────────────────────────┘
```
- **WebRTC**(`/ws/voice`):浏览器,低延迟,带 NAT 穿透。`SmallWebRTCTransport`
- **WS**(`/ws/stream`):裸音频流,服务端/话务/自定义客户端,无 ICE/TURN。`FastAPIWebsocketTransport`
加第三种输出(如 Twilio 电话)= 在 `services/pipecat/transports.py` 再加一个 `build_xxx_transport` + serializer,管线一行不用改。
## 目录结构(对齐 dograh 的 `api/`,便于生长)
```
ai-video-backend/
├── app.py # FastAPI 入口,挂路由 + CORS
├── settings.py # 读 .env,仅存数据库/CORS/TURN 等运行设置
├── models.py # AssistantConfig(对齐前端 AssistantForm)
├── routes/ # 一个文件一组端点(对齐 dograh routes/)
│ ├── health.py
│ ├── voice_webrtc.py # WebRTC 信令
│ └── voice_ws.py # WS 裸音频流
├── services/
│ └── pipecat/ # 引擎(对齐 dograh services/pipecat/)
│ ├── service_factory.py # 建 STT/LLM/TTS(按 interface_type 分发)
│ ├── transports.py # transport 工厂(加输出方式在此)
│ └── pipeline.py # 管线拼装与运行(transport 无关)
├── Dockerfile
├── requirements.txt
└── .env.example
# 平台长大后会再加(对齐 dograh):
# db/ SQLAlchemy 模型 + 会话(助手/对话/向量)
# schemas/ pydantic 请求响应
# tasks/ 后台任务(转写、报表)—— 配 redis
# services/storage.py 录音存储 —— 配 minio
```
## 国产栈(全走 OpenAI 兼容,换栈只改 .env)
| 类型 | 默认 | 接入 |
|------|------|------|
| LLM | DeepSeek | 云端直连,只需 key |
| STT | SenseVoice / FunASR | 本地 OpenAI 兼容转写服务 |
| TTS | CosyVoice | 本地 OpenAI 兼容 TTS 服务 |
### 讯飞 ASR / TTS / SuperTTS
讯飞鉴权直接存入对应 `ModelResource.secrets`,接口参数存入 `ModelResource.values`
- 普通语音识别:`interface_type=xfyun-asr`
- 普通语音合成:`interface_type=xfyun-tts`
- 超拟人语音合成:`interface_type=xfyun-super-tts`
- `values.apiUrl` 保存讯飞 WebSocket URL音色、语速等可选参数也放在 `values`
- `secrets` 分别保存 `appId``apiKey``apiSecret`
## 接口定义驱动的模型注册表
LLM、ASR、TTS、Embedding、Realtime 使用同一套两层结构:
```text
assistant_model_bindings -> model_resources -> interface_definitions
```
- `interface_definitions`: 定义具体接入协议、能力和动态表单字段。
- `model_resources`: 每条资源自带 `values/secrets`,不复用供应商账号。
- `assistant_model_bindings`: 助手按能力选择模型资源。
`interface_type` 是具体协议,例如 `xfyun-asr``xfyun-tts`
`xfyun-super-tts`,后端严格按它选择服务实现,不根据模型 ID 或 URL 猜测。
API
- `/api/interface-definitions`: 前端读取字段定义并动态生成 Dialog。
- `/api/model-resources`: 统一模型资源 CRUD敏感字段逐项打码。
## 本地运行(用 uv,Python 3.12)
```bash
cd ai-video/backend
uv venv # 按 .python-version 用 3.12
# 阶段 A:只验证存储/CRUD(不装 pipecat,秒级)
uv pip install fastapi "uvicorn[standard]" sqlalchemy asyncpg greenlet python-dotenv pydantic loguru
# 阶段 B:做语音时再装全量(含 pipecat,需 3.10+)
# uv pip install -r requirements.txt
cp .env.example .env # 只放数据库/CORS/TURN;模型 key 在模型资源里维护
# 起 Postgres:在 ai-video/ 下 docker compose up -d postgres
cd ..
make db-migrate # 首次或表结构变更后执行 Alembic 迁移
cd backend
uv run --with-requirements requirements.txt uvicorn app:app --reload --port 8000
```
> pipecat 相关代码用**惰性导入**,所以阶段 A 不装 pipecat 也能启动并跑 `/api/*` 与 `/health`;
> 只有真正连 `/ws/voice`、`/ws/stream` 时才需要全量依赖。
>
> 交互式 API 文档:启动后访问 http://localhost:8000/docs(手动戳 CRUD、定 schema 用)。
## 数据库迁移
表结构由 Alembic 管理SQLAlchemy 模型在 `db/models.py`,迁移文件在
`migrations/versions/`
```bash
cd ai-video
make db-migrate # 升级到最新版
make db-revision msg="add xxx" # 根据模型差异生成迁移
make db-current # 查看当前库版本
```
`interface_definitions` 的默认数据由 `services/interface_catalog.py` 维护,并通过
启动时同步或 `make db-sync-interface-definitions` 写入数据库;模型资源、知识库和助手示例数据继续走 `db/seed_*.sql`
## Docker(ai-video/docker-compose.yaml)—— 调试主路径
api 服务挂了源码 + `--reload`,前端用 npm dev + HMR,改代码都即时生效。
```bash
cd ai-video
docker compose up # 前台起 pg + api(:8000)+ ui(:3030),日志直出
docker compose up -d # 后台起;看日志 docker compose logs -f api
docker compose down # 停止全部
# 知识库依赖 RustFS默认 compose 会一起启动。Redis 仍是可选服务。
docker compose up -d postgres rustfs api ui
docker compose --profile data up -d redis
# 可选:公网部署(WebRTC 需 TURN)
docker compose --profile remote up -d
```
> 首次 `up` 会构建 api 镜像(装全量 `requirements.txt`,含 pipecat,较慢)。
> 之后改 Python 代码靠 `--reload` 热更新,不用重建;只有改 `requirements.txt` 才 `docker compose build api`。
## 极简知识库 MVP
知识库入口为前端「组件 / 知识库」。使用前先在「组件 / 模型」配置并启用
一个 Embedding 资源,然后:
1. 创建知识库并选择 Embedding 模型。
2. 上传 PDF、DOCX、TXT、Markdown、CSV、JSON 或 HTML或者直接添加文字。
3. 文档状态会从 `pending` 变为 `processing`,最终进入 `ready``failed`
4. 失败记录会保留,可在页面重试;完成后可预览分块并使用「检索测试」验证召回。
5. 在提示词助手的 pipeline 模式下选择知识库。每轮 LLM 推理前会自动检索并注入相关片段。
当前后台处理使用 FastAPI 进程内任务,适合 MVP。服务重启时未完成任务会转为失败
可在页面重试;需要多实例或高吞吐时再迁移到 Redis/ARQ worker。
## Prompt 动态变量
提示词助手的 Pipeline 与 Realtime 模式都支持在开场白和系统提示词中使用
`{{ variable_name }}`。Pipeline 模式还支持在 HTTP 工具的 URL、Header 和 Body
中引用变量。助手页维护变量类型、默认值和必填规则;调试面板在每次通话开始前
传入会话值。Realtime 会把渲染后的提示词作为模型 instructions。
内置系统变量包括 `system__conversation_id``system__time`
`system__agent_turns``system__conversation_history`。客户端不能提交
`system__*``secret__*`。HTTP 工具的密钥变量必须在工具的服务端密钥配置中
`secret__` 开头声明,而且只能用于 Header。
HTTP 工具可通过“响应变量赋值”把 JSON 路径写回普通会话变量,例如:
```json
{"order_status": "response.order.status"}
```
后续轮次会使用新值重新渲染系统提示词。上线前执行 `make db-migrate`,应用
`20260712_0007` 迁移。
## 待联调 / TODO
- [ ] 联调 Pipecat 1.3.0 语音链路与各 OpenAI 兼容服务
- [ ] 起本地 SenseVoice / CosyVoice 的 OpenAI 兼容服务
- [x] `realtime` 模式(StepFun StepAudio Realtime)
- [x] 前端 `DebugVoicePanel``/ws/voice`(参考 dograh `useWebSocketRTC.tsx`)
- [ ] 加 DB 后:助手配置入库(目前随请求内联)