From 8a4486801f0b6cfadcde3842a7027590d506eb98 Mon Sep 17 00:00:00 2001 From: Peanut Date: Fri, 22 May 2026 22:28:29 +0800 Subject: [PATCH] docs: add AI scene routing design spec --- .../2026-05-22-ai-scene-routing-design.md | 499 ++++++++++++++++++ 1 file changed, 499 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-22-ai-scene-routing-design.md diff --git a/docs/superpowers/specs/2026-05-22-ai-scene-routing-design.md b/docs/superpowers/specs/2026-05-22-ai-scene-routing-design.md new file mode 100644 index 0000000..fdfdcef --- /dev/null +++ b/docs/superpowers/specs/2026-05-22-ai-scene-routing-design.md @@ -0,0 +1,499 @@ +# 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。