feat(#674): 豆包大模型 Phase 3 - AI推荐片段编排 + 客户端抽共享层 #754

Merged
xiaoxia merged 1 commits from feat/doubao-ai-integration-phase3 into develop 2026-07-23 17:33:19 +08:00
Owner

变更说明

#674 接入豆包大模型 Phase 3 完成。

基于 Phase 2(PR #753),完成AI推荐片段编排接入 + 客户端架构统一。

核心变更

1. 客户端抽共享层

  • 新增 packages/shared/ai_client.py — DoubaoClient 统一封装
  • 配置移到 packages/shared/config.py(SharedSettings)
  • API 和 Worker 两边共用同一套客户端和配置
  • 移除 apps/api 层的重复 DOUBAO_ 配置和客户端实现

2. Worker AI推荐接入豆包

  • _call_ai_recommend_service 改为真实豆包调用
  • 三段式编排:intro(开场)+ showcase(展示)+ outro(结尾)
  • 智能分配转场效果(fade/cut/dissolve)
  • 返回结构与原有stub完全一致,调用方零改动

3. 降级保障(三层)

  1. 无 API Key → 直接走本地规则
  2. API调用失败 → 自动重试后降级
  3. 返回解析失败(格式不对/字段缺失)→ 降级到本地

4. 响应解析鲁棒性

  • 支持标准JSON / markdown代码块
  • 字段全部有默认值兜底
  • 非法 asset_id 自动过滤清空
  • clips自动按order排序并重新编号
  • duration/confidence 限制在合理范围

测试

  • 新增22个worker AI单测
  • 调整41个API单测的mock路径(改为mock共享客户端)
  • 累计 63个AI单测全部通过

PR依赖链

  • #752 Phase 1 → #753 Phase 2 → #754 Phase 3 → develop
## 变更说明 #674 接入豆包大模型 Phase 3 完成。 基于 Phase 2(PR #753),完成AI推荐片段编排接入 + 客户端架构统一。 ## 核心变更 ### 1. 客户端抽共享层 - 新增 `packages/shared/ai_client.py` — DoubaoClient 统一封装 - 配置移到 `packages/shared/config.py`(SharedSettings) - API 和 Worker 两边共用同一套客户端和配置 - 移除 apps/api 层的重复 DOUBAO_ 配置和客户端实现 ### 2. Worker AI推荐接入豆包 - `_call_ai_recommend_service` 改为真实豆包调用 - 三段式编排:intro(开场)+ showcase(展示)+ outro(结尾) - 智能分配转场效果(fade/cut/dissolve) - 返回结构与原有stub完全一致,调用方零改动 ### 3. 降级保障(三层) 1. 无 API Key → 直接走本地规则 2. API调用失败 → 自动重试后降级 3. 返回解析失败(格式不对/字段缺失)→ 降级到本地 ### 4. 响应解析鲁棒性 - 支持标准JSON / markdown代码块 - 字段全部有默认值兜底 - 非法 asset_id 自动过滤清空 - clips自动按order排序并重新编号 - duration/confidence 限制在合理范围 ## 测试 - 新增22个worker AI单测 - 调整41个API单测的mock路径(改为mock共享客户端) - 累计 **63个AI单测全部通过** ## PR依赖链 - #752 Phase 1 → #753 Phase 2 → #754 Phase 3 → develop
Collaborator

代码审查结果 - PR #754

⚠️ 问题(2个需要修改)

  1. packages/shared/ai_client.py 第99行:HTTP客户端未复用,存在性能隐患

    • 问题描述:在 chat_completion 方法中直接使用 httpx.post(...) 顶级函数。这会导致每次请求都创建一个新的 Client 实例,意味着每次请求都会经历 DNS 解析、TCP 握手和 TLS 握手,无法利用连接池(Keep-Alive),在高并发场景下会显著增加延迟和资源消耗。
    • 修改建议:在 DoubaoClient.__init__ 中初始化 self._http_client = httpx.Client(timeout=self.timeout),并在 chat_completion 中使用 self._http_client.post。同时实现 close 方法或在类中妥善管理客户端生命周期。
  2. apps/worker/worker_app/tasks/ai_tasks.py 第145行:素材ID校验逻辑可能导致渲染失败

    • 问题描述:在 _parse_recommend_response 中,当 AI 返回的 asset_id 不在允许的列表中时,代码将其置为空字符串 "",但保留了原有的 clip_type(如 "showcase")。如果下游渲染逻辑要求 "showcase" 类型的片段必须包含有效的 asset_id,这将导致渲染错误或崩溃。
    • 修改建议:当 asset_id 被置空时,应将 clip_type 修改为 "text"(如果支持)或者记录警告日志并丢弃该片段,而不是保留一个依赖素材但缺少素材的片段结构。

💡 建议(2个可选)

  1. apps/api/app/services/ai_service.py:同步HTTP调用阻塞事件循环

    • 具体内容:apps/api 通常运行在异步框架(如 FastAPI)中,而 httpx 的同步调用会阻塞事件循环。虽然这是从旧代码继承的,但在重构共享库时,建议考虑提供 async_chat_completion 方法或使用 run_in_executor 来包装同步调用,以避免阻塞整个服务。
  2. packages/shared/ai_client.py 第113行:异常捕获范围过大

    • 具体内容:except Exception as e 捕获了所有异常,包括 KeyboardInterruptSystemExit(虽然通常在主线程不触发)。建议细化捕获类型,如 except (httpx.HTTPError, json.JSONDecodeError, KeyError) as e,避免掩盖未预期的严重错误。

格式检查通过 | 逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-07-23 06:15:50 | 模型:

## 代码审查结果 - PR #754 ### ⚠️ 问题(2个需要修改) 1. **packages/shared/ai_client.py 第99行**:HTTP客户端未复用,存在性能隐患 - 问题描述:在 `chat_completion` 方法中直接使用 `httpx.post(...)` 顶级函数。这会导致每次请求都创建一个新的 `Client` 实例,意味着每次请求都会经历 DNS 解析、TCP 握手和 TLS 握手,无法利用连接池(Keep-Alive),在高并发场景下会显著增加延迟和资源消耗。 - 修改建议:在 `DoubaoClient.__init__` 中初始化 `self._http_client = httpx.Client(timeout=self.timeout)`,并在 `chat_completion` 中使用 `self._http_client.post`。同时实现 `close` 方法或在类中妥善管理客户端生命周期。 2. **apps/worker/worker_app/tasks/ai_tasks.py 第145行**:素材ID校验逻辑可能导致渲染失败 - 问题描述:在 `_parse_recommend_response` 中,当 AI 返回的 `asset_id` 不在允许的列表中时,代码将其置为空字符串 `""`,但保留了原有的 `clip_type`(如 "showcase")。如果下游渲染逻辑要求 "showcase" 类型的片段必须包含有效的 `asset_id`,这将导致渲染错误或崩溃。 - 修改建议:当 `asset_id` 被置空时,应将 `clip_type` 修改为 "text"(如果支持)或者记录警告日志并丢弃该片段,而不是保留一个依赖素材但缺少素材的片段结构。 ### 💡 建议(2个可选) 1. **apps/api/app/services/ai_service.py**:同步HTTP调用阻塞事件循环 - 具体内容:`apps/api` 通常运行在异步框架(如 FastAPI)中,而 `httpx` 的同步调用会阻塞事件循环。虽然这是从旧代码继承的,但在重构共享库时,建议考虑提供 `async_chat_completion` 方法或使用 `run_in_executor` 来包装同步调用,以避免阻塞整个服务。 2. **packages/shared/ai_client.py 第113行**:异常捕获范围过大 - 具体内容:`except Exception as e` 捕获了所有异常,包括 `KeyboardInterrupt` 或 `SystemExit`(虽然通常在主线程不触发)。建议细化捕获类型,如 `except (httpx.HTTPError, json.JSONDecodeError, KeyError) as e`,避免掩盖未预期的严重错误。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-23 06:15:50 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia changed target branch from feat/doubao-ai-integration-phase2 to main 2026-07-23 17:33:09 +08:00
xiaoxia changed target branch from main to develop 2026-07-23 17:33:13 +08:00
xiaoxia added 1 commit 2026-07-23 17:33:13 +08:00
feat(#674): 豆包大模型 Phase 3 - AI推荐片段编排 + 客户端抽共享层
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m39s
AI Code Review / AI Code Review (pull_request) Successful in 4m36s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 35s
545293fe5c
- 豆包客户端抽 packages/shared/ai_client.py,API和Worker共用
- 配置移到 SharedSettings,两边统一读取
- Worker AI推荐接入豆包大模型,替换原stub
- 智能编排:intro/showcase/outro 三段式结构 + 转场分配
- 降级机制:无Key/调用失败/解析失败均回退本地规则
- 响应解析:格式校验+字段兜底+非法asset过滤+order排序重编号
- 新增22个worker AI单测 + 调整41个API单测mock
- 累计63个AI单测全部通过
xiaoxia merged commit 5c5aabd311 into develop 2026-07-23 17:33:19 +08:00
xiaoxia deleted branch feat/doubao-ai-integration-phase3 2026-07-23 17:33:19 +08:00

🗑️ 预览环境已清理

PR #754 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #754 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.