Files
happy-life-star/docs/superpowers/specs/2026-05-22-ai-scene-routing-design.md
T

500 lines
15 KiB
Markdown
Raw 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 场景路由配置中心设计
日期:2026-05-22
## 背景
当前后台 `web-admin` 已有 AI 配置管理功能,后端使用 `t_ai_config` 保存 Coze 相关配置。该表同时承载服务商凭证、接口 URL、Bot/Workflow ID、业务场景、请求参数、测试保存等多种职责。随着短片小说生成、剧本生成迁移到自建 Dify 平台,且后续可能继续接入更多 AI 服务商,现有单表模型难以支持灵活切换和统一测试。
目标是将后台升级为 AI 场景路由配置中心:管理员可以配置服务商、接口/工作流、业务场景绑定,并让所有需要使用 AI 的业务都通过场景编码调用。后台切换场景绑定后,不需要发版,下一次调用立即生效。
## 现状
现有实现包含:
- `web-admin/src/views/aiconfig/AiConfigList.vue`:AI 配置列表、编辑、测试、测试后保存。
- `backend-single/src/main/java/com/emotion/entity/AiConfig.java`:对应 `t_ai_config`
- `AiConfigController``AiConfigService``AiConfigServiceImpl`:配置 CRUD、启用禁用、默认配置、测试后更新。
- `AiChatServiceImpl`:包含大量 Coze 专用调用、请求组装、SSE 解析、工作流调用和日志记录逻辑。
- `docs/dify平台接口.md`:Dify 平台接口文档,当前重点使用 `/chat-messages`
现有 AI 业务入口包括:
- 对话 / WebSocket 对话。
- 剧本生成。
- 短片小说生成。
- 日记总结 / AI 评论。
- 情绪总结 / 情绪分析。
- 人生事件疗愈回复。
- 后续新增 AI 场景。
## 设计目标
1. 后台可配置所有 AI 服务商,例如 Dify、Coze、未来 OpenAI 或自定义 HTTP 服务。
2. 后台可配置具体接口或工作流,例如 Dify `/chat-messages`、Coze workflow。
3. 后台可列出所有业务场景,并为每个场景选择当前生效的接口配置。
4. 场景绑定修改后立即对后续调用生效。
5. 支持按服务商和按场景测试,测试结果可用于排错和保存配置。
6. 保留现有 Coze 能力,并支持短片小说生成、剧本生成优先绑定 Dify。
7. 后续新增 AI 场景时,业务代码只新增稳定 `sceneCode`,不直接依赖服务商。
## 非目标
- 本期不做复杂流量权重、AB 实验和多配置灰度。
- 本期不删除旧 `t_ai_config`,它作为迁移来源和兼容兜底保留。
- 本期不要求所有历史 Coze 调用代码一次性完全清理,但新调用入口必须具备统一路由能力。
## 总体架构
采用三层配置模型:
1. `ai_provider`:服务商配置。
2. `ai_endpoint_config`:接口/工作流配置。
3. `ai_scene_binding`:业务场景绑定。
运行时新增 `AiRuntimeService`,业务服务只传 `sceneCode` 和输入参数:
```java
aiRuntimeService.invoke("chat", params, userId);
aiRuntimeService.invoke("script_generate", params, userId);
aiRuntimeService.invoke("short_story_generate", params, userId);
aiRuntimeService.invoke("diary_summary", params, userId);
```
调用链:
```text
业务服务
-> AiRuntimeService.invoke(sceneCode, inputs, userId)
-> 查询 ai_scene_binding 当前启用绑定
-> 加载 ai_endpoint_config
-> 加载 ai_provider
-> 根据 provider_type 选择 DifyProviderAdapter / CozeProviderAdapter
-> 按请求模板组包并调用外部服务
-> 按响应解析规则提取结果
-> 写 ai_call_log
```
## 数据模型
### ai_provider
服务商账号和基础能力配置。
| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `provider_code` | 唯一编码,如 `dify_default``coze_prod` |
| `provider_name` | 显示名称 |
| `provider_type` | `dify``coze``openai``custom` |
| `base_url` | 服务商基础地址,如 `http://49.232.138.53/v1` |
| `auth_type` | `bearer``api_key``oauth``none` |
| `api_key` | 服务商级 API Key |
| `client_id` | OAuth Client ID |
| `client_secret` | OAuth Client Secret |
| `grant_type` | OAuth 授权类型 |
| `default_headers` | JSON,默认请求头 |
| `health_check_url` | 健康检查地址 |
| `timeout_ms` | 默认超时时间 |
| `retry_count` | 默认重试次数 |
| `retry_delay_ms` | 默认重试延迟 |
| `environment` | `development``testing``production` |
| `is_enabled` | 是否启用 |
| `description` | 描述 |
### ai_endpoint_config
具体接口、工作流或模型调用配置。
| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `provider_id` | 关联 `ai_provider.id` |
| `endpoint_code` | 唯一编码,如 `dify.short_story.chat_messages` |
| `endpoint_name` | 显示名称 |
| `endpoint_type` | `chat``workflow``completion``audio``custom` |
| `http_method` | `GET``POST` 等 |
| `path` | 接口路径,如 `/chat-messages` |
| `full_url_override` | 特殊接口完整 URL 覆盖 |
| `app_id` | Dify App 或未来扩展 |
| `bot_id` | Coze Bot ID |
| `workflow_id` | Dify 或 Coze Workflow ID |
| `model_name` | 模型名称 |
| `request_template` | JSON,请求模板 |
| `response_parser` | JSON,响应解析规则 |
| `support_stream` | 是否支持流式 |
| `support_file_upload` | 是否支持文件上传 |
| `timeout_ms` | 接口级超时时间 |
| `retry_count` | 接口级重试次数 |
| `retry_delay_ms` | 接口级重试延迟 |
| `is_enabled` | 是否启用 |
| `description` | 描述 |
### ai_scene_binding
业务场景到接口配置的绑定。
| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `scene_code` | 稳定业务场景编码,如 `chat``script_generate` |
| `scene_name` | 场景名称 |
| `scene_category` | `chat``content``analysis``healing` |
| `endpoint_config_id` | 当前生效接口配置 |
| `fallback_endpoint_id` | 兜底接口配置,可为空 |
| `environment` | 环境 |
| `is_enabled` | 是否启用 |
| `priority` | 预留优先级 |
| `input_schema` | JSON,说明入参结构 |
| `test_payload` | JSON,后台场景测试默认入参 |
| `description` | 描述 |
### ai_call_log
统一调用日志,替代后续新增场景对 `t_coze_api_call` 的依赖。
| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `trace_id` | 链路追踪 ID |
| `scene_code` | 场景编码 |
| `provider_id` | 服务商 ID |
| `provider_type` | 服务商类型 |
| `endpoint_config_id` | 接口配置 ID |
| `fallback_used` | 是否使用兜底 |
| `request_url` | 请求 URL |
| `request_headers` | 脱敏后的请求头 |
| `request_body` | 请求体 |
| `response_status` | HTTP 状态码 |
| `response_body` | 原始响应 |
| `parsed_result` | 解析后的结果 |
| `duration_ms` | 耗时 |
| `status` | `success``failed` |
| `error_code` | 错误码 |
| `error_message` | 错误信息 |
## 初始场景编码
| sceneCode | 场景 |
| --- | --- |
| `chat` | 对话 |
| `script_generate` | 剧本生成 |
| `short_story_generate` | 短片小说生成 |
| `diary_summary` | 日记总结 / AI 评论 |
| `emotion_summary` | 情绪总结 |
| `emotion_analysis` | 情绪分析 |
| `life_healing` | 人生事件疗愈回复 |
后续新增场景只需要新增 `ai_scene_binding` 和业务调用点,不需要新增服务商专用字段。
## Dify 适配
依据 `docs/dify平台接口.md`,本期优先支持:
```text
POST /chat-messages
```
Dify 请求体模板应支持:
```json
{
"inputs": {},
"query": "{{input}}",
"response_mode": "blocking",
"conversation_id": "{{conversationId}}",
"user": "{{userId}}",
"workflow_id": "{{workflowId}}"
}
```
响应解析规则:
```json
{
"mode": "json_path",
"answerPath": "$.answer"
}
```
流式响应后续可支持 SSE 事件解析,优先提取 `message``message_end` 中的内容。
## Coze 适配
现有 Coze 工作流能力迁移到 `CozeProviderAdapter`
- 组装 `bot_id``workflow_id``user_id``stream``additional_messages``parameters`
- 保留现有 SSE 解析能力。
- 保留现有重试和异常处理策略。
- 新日志写入 `ai_call_log`,旧 `t_coze_api_call` 可在过渡期继续写入。
## 后端接口
新增管理 API 前缀:
```text
/ai/providers
/ai/endpoints
/ai/scenes
/ai/runtime/test
/ai/call-logs
```
### 服务商接口
```text
GET /ai/providers/page
GET /ai/providers/detail?id=
POST /ai/providers/create
PUT /ai/providers/update
DELETE /ai/providers/delete?id=
PUT /ai/providers/enable?id=
PUT /ai/providers/disable?id=
POST /ai/providers/test
```
### 接口/工作流接口
```text
GET /ai/endpoints/page
GET /ai/endpoints/detail?id=
POST /ai/endpoints/create
PUT /ai/endpoints/update
DELETE /ai/endpoints/delete?id=
POST /ai/endpoints/test
```
### 场景绑定接口
```text
GET /ai/scenes/page
GET /ai/scenes/detail?id=
POST /ai/scenes/create
PUT /ai/scenes/update
PUT /ai/scenes/bind
POST /ai/scenes/test
```
### 运行时测试接口
`POST /ai/runtime/test` 支持:
- 按 endpoint 测试:验证某个接口配置能否调通。
- 按 scene 测试:验证某个业务场景当前绑定是否能返回结果。
## 后台页面
保留现有菜单 `AI配置管理`,内部升级为四个 Tab 或子路由:
1. 服务商配置。
2. 接口/工作流配置。
3. 场景绑定。
4. 调用日志。
### 服务商配置页
列表展示:
- 服务商名称。
- 类型。
- Base URL。
- 环境。
- 状态。
- 健康状态。
- 更新时间。
操作:
- 新增。
- 编辑。
- 测试连接。
- 启用/禁用。
- 查看关联接口。
### 接口/工作流配置页
列表展示:
- 接口名称。
- 编码。
- 服务商。
- 类型。
- 路径 / Workflow。
- 是否流式。
- 状态。
- 最近测试结果。
表单包含:
- 服务商。
- HTTP 方法。
- 接口路径或完整 URL 覆盖。
- `botId``workflowId``appId`
- 请求模板 JSON。
- 响应解析规则 JSON。
- 超时和重试。
- 流式、文件上传等能力开关。
### 场景绑定页
列表展示:
- 场景名称。
- `sceneCode`
- 当前绑定接口。
- 服务商。
- 兜底接口。
- 环境。
- 状态。
操作:
- 切换接口配置。
- 配置兜底接口。
- 场景测试。
- 启用/禁用。
- 查看调用日志。
### 调用日志页
列表展示:
- 时间。
- 场景。
- 服务商。
- 接口配置。
- 状态。
- 耗时。
- 错误信息。
详情展示:
- 请求 URL。
- 请求头,敏感字段脱敏。
- 请求体。
- 原始响应。
- 解析结果。
- fallback 信息。
## 运行时行为
### 立即生效
每次 `AiRuntimeService.invoke` 都从数据库读取当前启用的场景绑定、接口配置和服务商配置。因此以下修改在保存后立即影响下一次调用:
- 服务商 Token。
- 服务商 Base URL。
- 接口路径。
- Workflow ID。
- 请求模板。
- 响应解析规则。
- 场景绑定的 endpoint。
- 启用/禁用状态。
- 兜底配置。
本期不做长期缓存。后续如增加缓存,必须基于 `update_time` 或版本号自动失效。
### 兜底策略
```text
主配置成功 -> 返回主配置结果
主配置失败且存在 fallback_endpoint_id -> 调用兜底配置
主配置失败且不存在 fallback_endpoint_id -> 返回业务可识别错误
```
调用日志必须记录主配置失败原因和是否发生 fallback。
### 禁用策略
- 服务商禁用:其下接口不可被调用。
- 接口配置禁用:不可作为主配置或兜底配置调用。
- 场景禁用:业务调用直接返回明确错误。
- 后台绑定时应提示禁用配置不可绑定,或允许保存但不可启用。
## 迁移策略
第一期保留 `t_ai_config`
迁移脚本将现有 Coze 配置拆分为:
```text
t_ai_config.provider/apiBaseUrl/apiToken -> ai_provider
t_ai_config.botId/workflowId/customParams -> ai_endpoint_config
t_ai_config.usageScenario/configKey -> ai_scene_binding 初始绑定
```
Dify 初始化:
-`docs/dify平台接口.md` 的基础地址创建 `dify_default` provider。
- 为短片小说生成创建 Dify endpoint。
- 为剧本生成创建 Dify endpoint。
- 分别创建 `short_story_generate``script_generate` 的 scene 绑定。
旧配置键到新场景建议映射:
| 旧配置键 | 新场景 |
| --- | --- |
| `coze.chat.default` | `chat` |
| `coze.course.life.generate` | `script_generate` |
| `coze.user.dairy.summary` | `diary_summary``life_healing` |
| `coze.emotion_analysis.default` | `emotion_analysis` |
| `coze.summary.default` | `emotion_summary` |
迁移后,业务代码逐步从 `callWorkflowByConfigKey(configKey, ...)` 迁移到 `invoke(sceneCode, ...)`
## 实施顺序
1. 新增数据库表、实体、Mapper、DTO、Service、Controller。
2. 新增 `AiRuntimeService` 和 provider adapter 接口。
3. 实现 `DifyProviderAdapter``CozeProviderAdapter`
4. 实现 endpoint 测试和 scene 测试。
5. 升级 web-admin AI 配置管理为四个页面。
6. 编写迁移脚本和初始数据。
7. 将短片小说生成、剧本生成迁到 `sceneCode` 调用。
8. 将对话、日记总结、情绪分析、疗愈等旧 Coze 场景逐步迁到 `sceneCode`
9. 保留旧 `AiConfig` 页面或提供只读迁移视图,确认稳定后再下线。
## 测试计划
后端测试:
- `AiRuntimeServiceTest`:验证场景路由、禁用状态、fallback。
- `DifyProviderAdapterTest`:验证 Dify 请求体生成和 `answer` 解析。
- `CozeProviderAdapterTest`:验证 Coze 请求体生成和 SSE 解析。
- 迁移脚本测试:验证旧 `t_ai_config` 能拆成 provider、endpoint、scene。
前端测试:
- 服务商配置可创建、编辑、启用、禁用和测试连接。
- 接口配置可按服务商生成默认请求模板。
- 场景绑定切换后,场景测试走新的接口配置。
- 禁用配置后不能被正常调用。
集成验收:
- 短片小说生成绑定 Dify 后能返回可解析结果。
- 剧本生成绑定 Dify 后能返回可解析结果。
- 对话绑定 Coze 后保持现有可用。
- 将剧本生成从 Dify 切回 Coze 后,不发版,下一次调用立即生效。
- 主配置失败且配置了兜底时,调用日志记录 fallback。
## 风险与缓解
| 风险 | 缓解 |
| --- | --- |
| Dify 与 Coze 响应结构不同 | 使用 provider adapter 和 response_parser 隔离差异 |
| 请求模板过于自由导致配置错误 | 后台提供 Dify、Coze 默认模板,并在测试时校验 JSON |
| 立即生效可能导致误操作影响线上 | 增加测试按钮、启用状态、环境隔离和调用日志 |
| 旧业务调用链较长 | 分阶段迁移,旧 `t_ai_config` 保留兼容 |
| Token 暴露风险 | 管理后台可编辑但日志和普通详情默认脱敏 |
## 验收标准
1. 管理员可以在后台创建 Dify 和 Coze 服务商。
2. 管理员可以创建 Dify `/chat-messages` endpoint 和 Coze workflow endpoint。
3. 管理员可以在场景绑定页将 `script_generate``short_story_generate``chat` 绑定到任意启用 endpoint。
4. 后台场景测试可以展示原始响应和解析结果。
5. 业务调用只依赖 `sceneCode`,不再需要知道当前场景使用 Dify 还是 Coze。
6. 修改场景绑定后,下一次业务调用立即走新配置。
7. 调用日志能区分服务商、接口配置、场景、成功/失败和 fallback。