fix(viral-video): P1 VLM模型ID/僵尸任务心跳/文案兜底; P2 ratio/OSS一致性 #2146

Merged
xiaoxia merged 2 commits from fix/2141-p1-vlm-timeout-heartbeat-copy into develop 2026-10-02 14:36:22 +08:00
Owner

修复 v8 E2E 冒烟发现的 3 P1 + 2 P2

P1-1 VLM lite 总是降级到 pro(44-53s)

根因:视觉模型 ID doubao-1-5-vision-lite-250915 / doubao-1-5-vision-pro-250915 不存在于火山方舟官方模型列表,正确 ID 为 doubao-1-5-vision-lite-250315(lite)/ doubao-1-5-vision-pro-250328(pro)。模型名错误 → lite 调用始终失败 → 重试超时后降级 pro。

  • 修正 packages/config/base.py、packages/shared/ai_client.py、apps/worker/.../viral_video.py、.env.example 中全部模型 ID

P1-2 僵尸任务无超时回收(永久 running、retry 409)

  • 新增 heartbeat_at 字段(DateTime, index):worker 后台心跳线程每 25s 更新
  • 新增 _recover_stale_jobs():每次任务启动时扫描,running > 10min 且心跳 > 2min 未更新 → 自动标记 failed
  • retry 接口放宽:允许对超时僵尸任务重试(清空状态后重新入队)
  • 新建 alembic migration 092_viral_video_heartbeat(幂等加列 + 初始化已有 running 任务)
  • pipeline/analyze/generate_copy/render 四个 celery 任务统一接入心跳生命周期

P1-3 文案生成走兜底模板 + 错别字

  • 兜底脚本「很近」→「最近」
  • 编导脚本三级重试:fast(0.8/2500tok) → fast(0.6/3200tok) → pro(0.7/3500tok),任意一级产出合格脚本(口播≥20字、镜头≥1、不含兜底特征串)即返回
  • prompt 关键要求新增「输出前自检:口播禁止错别字和语病」
  • 关键路径打 info 日志(模型/标签/口播长度/镜头数/是否兜底),便于后续排查

P2-1 视频比例 9:16 出 960×960(1:1)

根因:旧 Bug #2110 修复时在 image_url 存在时强制不传 ratio,模型默认 adaptive → 首帧方图商品图被识别为 1:1 输出。

  • 查证火山方舟官方文档:图生视频支持 ratio 参数(16:9/9:16/1:1 等),会自动居中裁剪首帧
  • packages/shared/ai_client.py + ai_service.py:删除 image_url 判空,始终透传 ratio

P2-2 completed 后 NoSuchKey 5 秒

  • 新增 _wait_oss_ready(url, timeout=10s):mark_completed 前循环 HEAD 公网 URL 确认 200 + content-length>0

测试

  • viral-video 相关 97 个单测全部通过
  • 同步更新 test_viral_video_p0 中被旧行为断言的用例(ratio 透传)
  • 2 个 musetalk 单测失败为已存在的无关问题(stash 验证复现)
## 修复 v8 E2E 冒烟发现的 3 P1 + 2 P2 ### P1-1 VLM lite 总是降级到 pro(44-53s) **根因**:视觉模型 ID `doubao-1-5-vision-lite-250915` / `doubao-1-5-vision-pro-250915` 不存在于火山方舟官方模型列表,正确 ID 为 `doubao-1-5-vision-lite-250315`(lite)/ `doubao-1-5-vision-pro-250328`(pro)。模型名错误 → lite 调用始终失败 → 重试超时后降级 pro。 - 修正 packages/config/base.py、packages/shared/ai_client.py、apps/worker/.../viral_video.py、.env.example 中全部模型 ID ### P1-2 僵尸任务无超时回收(永久 running、retry 409) - 新增 `heartbeat_at` 字段(DateTime, index):worker 后台心跳线程每 25s 更新 - 新增 `_recover_stale_jobs()`:每次任务启动时扫描,running > 10min 且心跳 > 2min 未更新 → 自动标记 failed - retry 接口放宽:允许对超时僵尸任务重试(清空状态后重新入队) - 新建 alembic migration 092_viral_video_heartbeat(幂等加列 + 初始化已有 running 任务) - pipeline/analyze/generate_copy/render 四个 celery 任务统一接入心跳生命周期 ### P1-3 文案生成走兜底模板 + 错别字 - 兜底脚本「很近」→「最近」 - 编导脚本三级重试:fast(0.8/2500tok) → fast(0.6/3200tok) → pro(0.7/3500tok),任意一级产出合格脚本(口播≥20字、镜头≥1、不含兜底特征串)即返回 - prompt 关键要求新增「输出前自检:口播禁止错别字和语病」 - 关键路径打 info 日志(模型/标签/口播长度/镜头数/是否兜底),便于后续排查 ### P2-1 视频比例 9:16 出 960×960(1:1) **根因**:旧 Bug #2110 修复时在 `image_url` 存在时强制不传 `ratio`,模型默认 adaptive → 首帧方图商品图被识别为 1:1 输出。 - 查证火山方舟官方文档:图生视频支持 ratio 参数(16:9/9:16/1:1 等),会自动居中裁剪首帧 - packages/shared/ai_client.py + ai_service.py:删除 image_url 判空,始终透传 ratio ### P2-2 completed 后 NoSuchKey 5 秒 - 新增 `_wait_oss_ready(url, timeout=10s)`:mark_completed 前循环 HEAD 公网 URL 确认 200 + content-length>0 ### 测试 - viral-video 相关 97 个单测全部通过 - 同步更新 test_viral_video_p0 中被旧行为断言的用例(ratio 透传) - 2 个 musetalk 单测失败为已存在的无关问题(stash 验证复现)
xiaoxia added 1 commit 2026-10-02 14:06:20 +08:00
fix(viral-video): P1 VLM模型ID/僵尸任务心跳/文案兜底/P2 ratio映射/OSS一致性
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
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 API Image (pull_request) Successful in 19s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 35s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker 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
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m24s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m9s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m44s
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Has been cancelled
ad686dcd8b
P1-1: VLM lite/pro模型ID修正(250915→250315/250328),根因是旧ID不存在导致lite必然超时降级pro
- packages/config/base.py: doubao_vision_model/pro/lite 改为火山方舟官方正确ID
- packages/shared/ai_client.py docstring同步更新
- apps/worker/worker_app/tasks/viral_video.py 硬编码字符串同步
- .env.example 同步新ID

P1-2: worker心跳+僵尸任务超时回收
- packages/domain/viral_video.py: 新增heartbeat_at字段+touch_heartbeat()方法
- packages/adapters/sqlalchemy_impl/models.py: ViralVideoJobModel加heartbeat_at列(index=True)
- packages/adapters/sqlalchemy_impl/viral_video_repository.py: to_entity/save/update映射heartbeat_at
- alembic/versions/092_viral_video_heartbeat.py: 幂等迁移,加列+index+给已有running任务初始化
- apps/worker/worker_app/tasks/viral_video.py:
  - 新增_start_heartbeat_thread后台线程,每25s独立session更新heartbeat_at
  - 新增_recover_stale_jobs(): running>10min且心跳>2min未更新→自动标记failed
  - pipeline/analyze/generate_copy/render四个celery任务接入心跳启停+启动时回收僵尸
- apps/api/app/api/routes/viral_video.py: retry接口放宽,允许对超时僵尸任务重试

P1-3: 文案生成质量与兜底修复
- 兜底脚本'很近'→'最近'(之前commit已改)
- _step_script_generation 三级重试: fast(0.8/2500tok)→fast(0.6/3200tok)→pro(0.7/3500tok)
- 新增fallback判定:口播<20字/含兜底特征串/镜头数<1才视为降级,避免正常短脚本误判
- prompt关键要求新增'输出前自检:口播禁止错别字和语病'
- 关键路径打info日志(模型/label/口播长度/镜头数/是否兜底),便于后续排查

P2-1: Seedance图生视频ratio不生效导致9:16出1:1
- 根因: 旧逻辑Bug #2110在image_url存在时不传ratio,模型默认adaptive→首帧方图商品图输出1:1
- 官方文档确认图生视频支持ratio参数,模型会自动居中裁剪首帧
- packages/shared/ai_client.py+ai_service.py: 删除image_url判空,始终传ratio
- 同步更新docstring注释

P2-2: OSS成片eventual consistency导致completed后NoSuchKey
- apps/worker/worker_app/tasks/viral_video.py: 新增_wait_oss_ready(url,timeout=10s)
- mark_completed前循环HEAD公网URL,等200+content-length>0或10s超时

测试: viral-video相关97个单测全部通过,仅更新test_passes_reference_params_to_client以反映新ratio透传行为
auto-approve-bot added 1 commit 2026-10-02 14:12:10 +08:00
style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker 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 / PR Build API Image (pull_request) Successful in 38s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 50s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m5s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m45s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 6m48s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m58s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 3m52s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 3m57s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m41s
AI Code Review / AI Code Review (pull_request) Successful in 15m53s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 10m20s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 10m40s
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 / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 33s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 5m59s
0c0fe4619d

🚀 预览环境已部署

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

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

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

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

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

🗑️ 预览环境已清理

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

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

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