Files
yingqing/docs/todo/模型调用与动态Fallback-完成说明.md
T

6.0 KiB
Raw Blame History

模型调用与动态 Fallback 完成说明

状态:已完成

最后核对:2026-07-21

用途:说明当前模型调用、重试、动态切换、计费和日志流程。

1. 当前调用流程

用户选择模型 / 系统默认模型
→ 创建一个 AITask
→ 预留一次积分
→ 调用主模型
→ 失败后按配置重试主模型
→ 仍失败且允许 Fallback
→ 实时查询已启用的兼容模型
→ 按动态顺序逐个尝试
→ 成功:保存结果并结算一次
→ 全部失败:释放一次预留

主模型始终是用户本次选择的模型;Fallback 不修改用户选择、默认模型或下次调用。

2. Retry 与 Fallback

  • Retry:再次调用当前模型。
  • Fallback:切换到其他兼容模型。
  • 调用审计:记录每次真实调用,不参与模型评分或自动学习。

当前默认值:

能力 主模型重试 单次超时 总时限
文本 2 次,等待 1 / 3 秒 120 秒;流式 300 秒 480 秒
图片 1 次,等待 3 秒 300 秒 900 秒
配音 1 次,等待 2 秒 60 秒 180 秒
视频提交 1 次,等待 3 秒 120 秒 300 秒
视频成片 不重新提交 单次轮询 60 秒 1800 秒

单个逻辑任务最多尝试 3 个模型、发出 5 次真实请求。

3. 配置位置

全局策略在:

core/backend/.env
core/backend/airshelf/settings/base.py → MODEL_ROUTING_POLICY

控制重试、超时、总时限、最多模型数、最多调用数和后处理退避。修改后必须同时重启 API 与 Celery Worker。

每个模型的开关保存在数据库 ModelConfig.metadata.routing

{
  "fallback_on_failure": false,
  "fallback_candidate": true
}
  • fallback_on_failure:当前模型失败后是否允许切到其他模型。
  • fallback_candidate:当前模型是否允许被其他失败模型选中。
  • 开关按模型独立配置,不在代码中写死供应商或模型名单。

4. 火山 / 豆包直连现状

文本、配音、视频都已接入统一 Fallback 代码,但当前直连模型统一配置为:

fallback_on_failure = false
fallback_candidate = true

当前行为:

  • 允许原模型重试。
  • 不允许从直连模型主动切出。
  • 已启用且能力匹配时,可以作为其他模型的候选。
  • 以后只改模型 metadata 即可开启,无需重新开发路由代码。

5. 动态候选规则

候选每次失败后实时读取数据库,必须同时满足:

  • 供应商已启用。
  • 模型已启用。
  • fallback_candidate=true
  • 能力一致:textimageaudiovideo
  • 操作要求一致:流式、结构化、图片编辑、参考素材数量、比例、分辨率、时长、音色映射等。
  • 本任务尚未尝试过。

排序规则:

火山 / 豆包直连
→ YunQi
→ 其他 OpenAI API 兼容供应商
→ 同层级按 ModelConfig.updated_at 从新到旧

除现有火山 / 豆包专用适配器外,新增供应商只支持 OpenAI API 兼容协议。

6. 任务与计费

一次用户操作始终只有:

  • 一个 AITask
  • 一次积分预留。
  • 一次最终扣费或释放。

每次真实模型调用只新增一条 AIModelAttempt,不会单独预留或扣费。

  • Fallback 成功:按原逻辑任务结算一次。
  • 全部失败:释放原预留,用户扣费为 0。
  • 多次尝试产生的上游费用累计为平台成本,不转换成多笔用户扣费。

7. 调用日志

AIModelAttempt 记录:

  • 调用顺序。
  • 供应商与真实模型快照。
  • 首次调用、重试或 Fallback。
  • 成功 / 失败、耗时和错误分类。
  • Provider 任务 ID、用量和平台成本。
  • 脱敏请求 / 响应摘要。

管理员在 /admin/tasks 的任务详情查看完整调用链。普通用户端保持静默,不显示内部供应商、真实候选、失败原因或尝试次数。

公开别名保持不变:

  • Gemini 3.1 Pro → AirShelf Script
  • gpt-image-2AirShelf Image
  • 火山 / 豆包直连继续显示原公开名称。

8. 视频特殊规则

  • 只有尚未取得远端任务 ID,且明确提交失败时,才允许重试或 Fallback。
  • 提交读取超时或响应缺少任务 ID 视为“远端状态未知”,禁止重复提交。
  • 获得远端任务 ID 后固定使用真正提交成功的模型轮询和结算。
  • 普通轮询超时只继续轮询,不切模型、不重新提交。
  • 达到成片总时限后才进入最终失败。
  • 下载、上传、TOS 或资产保存失败只重试后处理,不重新调用模型。

9. 已接入入口

  • 脚本生成、脚本优化、单镜优化。
  • 显式实体提取、脚本实体同步兼容入口。
  • 独立图片生成 / 编辑、模特上身图、平台套图。
  • 商品 / 人物 / 场景基础资产、项目与模特三视图。
  • 故事板分镜生成。
  • 配音生成。
  • 视频片段生成。
  • 自由创作 / 免费视频生成。

10. 发布要求

  • 数据库迁移:0028_seed_model_routing_metadata0029_aimodelattempt
  • API 与 Celery Worker 必须使用同一版后端镜像。
  • API 与 Worker 必须读取同一份路由配置。
  • 发布后至少冒烟验证文本、图片、配音、视频和 /admin/tasks 调用链。
  • 回滚代码时不要直接反向执行 0028,避免删除已维护的模型路由 metadata。

11. 关键代码

core/backend/apps/ai/routing_policy.py    全局策略读取与校验
core/backend/apps/ai/model_routing.py     能力匹配与动态候选排序
core/backend/apps/ai/routing_executor.py  重试、Fallback 与调用审计
core/backend/apps/ai/models.py            AITask / AIModelAttempt
core/backend/apps/ai/services.py          各业务入口编排
core/backend/apps/ai/free_video.py        自由视频提交与轮询
core/backend/apps/ai/script_agent.py       脚本流式调用

12. 非本次范围

  • 未修改 /admin/providers 页面。
  • 未实现用户反馈学习、模型评分或自动调权。
  • 未写死备用模型链。
  • 未支持新增非 OpenAI API 私有协议供应商。