refactor: separate provider capability policy

This commit is contained in:
2026-04-18 13:37:59 +08:00
parent 0444b81df6
commit 7b8e7c9944
11 changed files with 393 additions and 88 deletions

View File

@@ -0,0 +1,63 @@
# Provider Routing 技术说明
本说明用于支撑求职版 DreamWeaver 的 Provider 分层表达。当前目标不是做复杂平台化,而是把 AI 能力供应链讲清楚、跑稳定、便于后续演进。
## 核心概念
| 概念 | 含义 | 当前代码位置 |
| --- | --- | --- |
| Capability | 产品需要的 AI 能力类型,例如文本、图片、语音、绘本结构 | `backend/app/services/provider_policy.py` |
| Provider | 某个能力下的可调用供应商配置,例如 Gemini、OpenAI、CQTAI、MiniMax | `providers` 表与 `provider_cache.py` |
| Adapter | 供应商调用实现,负责把统一入参翻译成具体 API 调用 | `backend/app/services/adapters/` |
| Routing Policy | 调用前如何排序与选择 Provider例如优先级、成本、延迟、轮询 | `provider_policy.py` + `provider_router.py` |
| Failover | 当前 Provider 调用失败后自动尝试下一 Provider | `provider_router.py` |
## 当前 Capability
| Capability | 用途 | 默认 Provider | Demo Provider |
| --- | --- | --- | --- |
| `text` | 生成/润色儿童故事文本 | `gemini`, `openai` | `demo` |
| `image` | 生成封面和绘本插图 | `cqtai` | `demo` |
| `tts` | 故事语音合成 | `minimax`, `elevenlabs`, `edge_tts` | 无 |
| `storybook` | 生成多页绘本结构和插图提示词 | `storybook_primary` | `demo` |
`ENABLE_DEMO_PROVIDERS=true` 时,只会给具备 demo adapter 的能力前置 `demo` provider。TTS 暂无 demo adapter因此不会插入不存在的 `tts:demo`
## 代码边界
`provider_policy.py` 负责定义“产品级策略”:
- Capability 清单
- 默认 Provider 顺序
- `.env` 中对应的 provider 列表字段
- 默认 routing strategy
- API key ref 到 settings 字段的映射
- 哪些能力支持本地 demo provider
`provider_router.py` 负责执行“运行时路由”:
- 从 DB cache 或 `.env` 读取 Provider 配置
- 构建 `AdapterConfig`
- 按 Routing Policy 排序
- 熔断过滤
- 调用 adapter
- 记录 metrics、health、cost
- failover 并聚合错误
`adapters/` 负责具体供应商 API
- 不决定业务工作流
- 不读取用户故事上下文
- 不负责 Provider 排序或熔断
## 演进原则
- 新增 AI 能力时,先在 `provider_policy.py` 增加 Capability再注册 adapter。
- 新增供应商时,先实现 adapter再把默认顺序或 DB 配置接入对应 Capability。
- 路由策略只影响调用顺序,不应该改变故事/绘本/音频的产品工作流。
- 本轮求职版不做多租户供应商市场,也不做复杂负载均衡;优先保证能力分层清楚、失败可恢复、演示稳定。
- 后台 `config_ref` 可以使用 adapter 别名,也可以直接使用 settings 字段名,例如 `text_api_key``antigravity_api_key`
## 面试表达口径
DreamWeaver 的 Provider 体系不是把供应商暴露给用户,而是把多模型能力整理成稳定的产品能力。用户看到的是“生成故事、生成封面、播放语音”,系统内部才把它映射到 `text``image``tts``storybook` 这些 Capability再通过 Routing Policy 选择具体 Provider 和 Adapter。