feat: #1209 AI智能选片段接入MediaKit视频理解 #1224

Merged
xiaoxia merged 1 commits from feat/mediakit-video-understand-issue1209 into develop 2026-08-03 10:53:56 +08:00
Owner

改动内容

问题

当前 _call_ai_recommend_service 只给豆包大模型传了素材 ID 列表,LLM 对每个视频的内容一无所知,无法做出有意义的编排决策。fallback 逻辑也只是机械地顺序分配素材。

方案

接入 MediaKit 视频理解智能策略 API(POST /api/v1/tools/video-understand-router),在调用豆包 LLM 编排前,先对每个素材视频做内容分析,将分析结果注入 prompt,让 LLM 能基于视频实际内容做智能编排。

改动详情

1. MediaKitClient 新增 analyze_videos() 方法

  • 调用 /tools/video-understand-router 提交异步任务
  • 轮询 /tasks/{task_id} 直到完成
  • 返回 result.contents 列表(每个视频一段自然语言描述)
  • Economy 档位,成本最优

2. API 路由层 _build_asset_analyses() 函数

  • 从 DB 查找素材,获取视频下载 URL
  • 调用 MediaKit 批量分析视频内容
  • 构建 {asset_id: 分析文本} 映射
  • 任何异常返回空 dict,不阻塞主流程

3. _call_ai_recommend_service 增强

  • 新增 asset_analyses 可选参数
  • 有分析结果时,prompt 注入视频内容描述 + 编排指导(叙事连贯、场景匹配等)
  • 分析文本截断至 300 字,避免 token 爆炸
  • 无分析结果时保持原有 prompt 格式

4. run_ai_recommend 透传 asset_analyses

降级策略

  • MediaKit 未配置 → 跳过分析,保持原有行为
  • MediaKit 调用失败 → 跳过分析,保持原有行为
  • 部分素材分析成功 → 只注入成功的,其余保持基本 prompt

测试

  • 15 个新单元测试全部通过
  • 覆盖:MediaKitClient 正常/异常/超时、prompt 注入验证、透传验证、降级逻辑、截断验证
  • 260 个相关测试全绿,无回归
## 改动内容 ### 问题 当前 `_call_ai_recommend_service` 只给豆包大模型传了素材 ID 列表,LLM 对每个视频的内容一无所知,无法做出有意义的编排决策。fallback 逻辑也只是机械地顺序分配素材。 ### 方案 接入 MediaKit 视频理解智能策略 API(`POST /api/v1/tools/video-understand-router`),在调用豆包 LLM 编排前,先对每个素材视频做内容分析,将分析结果注入 prompt,让 LLM 能基于视频实际内容做智能编排。 ### 改动详情 **1. MediaKitClient 新增 `analyze_videos()` 方法** - 调用 `/tools/video-understand-router` 提交异步任务 - 轮询 `/tasks/{task_id}` 直到完成 - 返回 `result.contents` 列表(每个视频一段自然语言描述) - Economy 档位,成本最优 **2. API 路由层 `_build_asset_analyses()` 函数** - 从 DB 查找素材,获取视频下载 URL - 调用 MediaKit 批量分析视频内容 - 构建 `{asset_id: 分析文本}` 映射 - 任何异常返回空 dict,不阻塞主流程 **3. `_call_ai_recommend_service` 增强** - 新增 `asset_analyses` 可选参数 - 有分析结果时,prompt 注入视频内容描述 + 编排指导(叙事连贯、场景匹配等) - 分析文本截断至 300 字,避免 token 爆炸 - 无分析结果时保持原有 prompt 格式 **4. `run_ai_recommend` 透传 `asset_analyses`** ### 降级策略 - MediaKit 未配置 → 跳过分析,保持原有行为 - MediaKit 调用失败 → 跳过分析,保持原有行为 - 部分素材分析成功 → 只注入成功的,其余保持基本 prompt ### 测试 - 15 个新单元测试全部通过 - 覆盖:MediaKitClient 正常/异常/超时、prompt 注入验证、透传验证、降级逻辑、截断验证 - 260 个相关测试全绿,无回归
xiaoxia added 1 commit 2026-08-03 09:44:26 +08:00
feat: #1209 AI智能选片段接入MediaKit视频理解
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 40s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 45s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 49s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m35s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m51s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 2m51s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m39s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m30s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 4m47s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 4m47s
AI Code Review / AI Code Review (pull_request) Failing after 6m38s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 8m29s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 12s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 51s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m1s
82bc193693
- MediaKitClient 新增 analyze_videos() 方法,调用视频理解智能策略 API
- _call_ai_recommend_service 支持 asset_analyses 参数,将视频内容分析注入 prompt
- API 路由层自动获取素材 URL 并调用 MediaKit 分析视频内容
- LLM 可根据视频实际内容做智能编排(叙事连贯、场景匹配等)
- 降级策略:MediaKit 不可用时保持原有 fallback 行为
- 15 个新单元测试全部通过

🚀 预览环境已部署

项目 详情
PR号 #1224
预览链接 https://pr-1224.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1224 | | 预览链接 | [https://pr-1224.preview.xiaoxiajianji.com](https://pr-1224.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:2 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

  1. [apps/api/app/api/routes/templates_editor/ai_features.py: 61] 素材ID映射逻辑错误

    • 问题类型:逻辑bug
    • 问题描述:在循环构建 url_to_asset_id 字典时,使用 url 作为 key。如果多个 asset 对应同一个 storage_key(即同一个视频文件被多次引用或不同素材指向同一文件),url_to_asset_id[url] = aid 会覆盖之前的映射。导致后续结果回写时,多个分析结果都指向列表中最后一个 asset_id,而前面的 asset_id 丢失分析结果。
    • 修改建议:建议使用列表 processed_asset_idsvideo_urls 保持索引同步,或者使用 (url, index) 作为字典 key。更简单的方式是直接维护两个列表:valid_asset_idsvideo_urls,在回写时通过索引直接对应。
  2. [apps/api/app/api/routes/templates_editor/ai_features.py: 76] 同步路由中存在长时间阻塞调用

    • 问题类型:性能问题
    • 问题描述:client.analyze_videos 方法内部使用了轮询机制(默认 poll_interval=3.0s, max_poll_attempts=60),最长可能阻塞 180 秒(3分钟)。在 FastAPI 的同步路由中直接调用此方法会占用工作线程,在高并发场景下极易耗尽线程池,导致服务不可用(DoS)。
    • 修改建议:应将此耗时操作改为异步执行(如使用 FastAPI BackgroundTasks 或 Celery),或者大幅缩短轮询超时时间并告知用户前端异步查询结果。如果必须同步等待,请务必覆盖默认参数,将超时时间控制在合理范围(如 10-20 秒)。

💡 改进建议(不阻塞合并)

  1. [packages/shared/mediakit_client.py: 125] 轮询间隔建议
    • 具体内容:poll_interval 默认值为 3.0 秒,对于视频理解任务可能偏长,会导致响应延迟。建议根据实际 API 性能调整默认值,或在调用方显式传入更短的间隔。

良好实践

  • 代码中增加了对 asset_analyses 的详细单测覆盖,包括成功、失败、超时及降级场景,测试覆盖率较好。
  • ai_service.py 中对过长的分析文本进行了截断(300字符),有效防止了 Token 消耗过大导致的成本或性能问题。
  • 异常处理较为完善,MediaKit 不可用或失败时会自动降级,不影响主流程。

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


🤖 由 AI 代码审查机器人自动生成 | 2026-08-03 01:51:04 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:2 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/api/app/api/routes/templates_editor/ai_features.py: 61] 素材ID映射逻辑错误** - 问题类型:逻辑bug - 问题描述:在循环构建 `url_to_asset_id` 字典时,使用 `url` 作为 key。如果多个 asset 对应同一个 `storage_key`(即同一个视频文件被多次引用或不同素材指向同一文件),`url_to_asset_id[url] = aid` 会覆盖之前的映射。导致后续结果回写时,多个分析结果都指向列表中最后一个 asset_id,而前面的 asset_id 丢失分析结果。 - 修改建议:建议使用列表 `processed_asset_ids` 与 `video_urls` 保持索引同步,或者使用 `(url, index)` 作为字典 key。更简单的方式是直接维护两个列表:`valid_asset_ids` 和 `video_urls`,在回写时通过索引直接对应。 2. **[apps/api/app/api/routes/templates_editor/ai_features.py: 76] 同步路由中存在长时间阻塞调用** - 问题类型:性能问题 - 问题描述:`client.analyze_videos` 方法内部使用了轮询机制(默认 `poll_interval=3.0s`, `max_poll_attempts=60`),最长可能阻塞 180 秒(3分钟)。在 FastAPI 的同步路由中直接调用此方法会占用工作线程,在高并发场景下极易耗尽线程池,导致服务不可用(DoS)。 - 修改建议:应将此耗时操作改为异步执行(如使用 FastAPI `BackgroundTasks` 或 Celery),或者大幅缩短轮询超时时间并告知用户前端异步查询结果。如果必须同步等待,请务必覆盖默认参数,将超时时间控制在合理范围(如 10-20 秒)。 ### 💡 改进建议(不阻塞合并) 1. **[packages/shared/mediakit_client.py: 125] 轮询间隔建议** - 具体内容:`poll_interval` 默认值为 3.0 秒,对于视频理解任务可能偏长,会导致响应延迟。建议根据实际 API 性能调整默认值,或在调用方显式传入更短的间隔。 ### ✅ 良好实践 - 代码中增加了对 `asset_analyses` 的详细单测覆盖,包括成功、失败、超时及降级场景,测试覆盖率较好。 - 在 `ai_service.py` 中对过长的分析文本进行了截断(300字符),有效防止了 Token 消耗过大导致的成本或性能问题。 - 异常处理较为完善,MediaKit 不可用或失败时会自动降级,不影响主流程。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-03 01:51:04 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia merged commit 598e2b6fb7 into develop 2026-08-03 10:53:56 +08:00
xiaoxia deleted branch feat/mediakit-video-understand-issue1209 2026-08-03 10:53:56 +08:00

🗑️ 预览环境已清理

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

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

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