docs: Seedance 取证页补实际开通的两个模型 + 修重构后的过期路径
CI / docs-build (push) Successful in 1m18s

- 新增「账号实际开通的模型」一节(2026-09-20 确认):两个 model ID 的关键限制
  对照表,以及为何限制差异不进目录表而放在 patbond-ai 的 capabilities.py
  (正典 generation_models 无能力列,不发明超出已评审模型的列)。
  记下两处刻意设计:按模型族前缀匹配使小版本升级不必改表;未知模型一律放行,
  使「开通即可用」不退化为「开通还得改代码发版」。
- 说明风格表与图片模型刻意未播种的原因。
- 实现状态表按重构后的分层重写,并记下一处**跨语言约定**:目录表的
  provider_code 必须与适配器的 PROVIDER_CODE 逐字一致,两侧均有测试钉住。
- **修过期路径**:文档头与 §4 还指向重构前已删除的 app/providers/seedance.py
  与 tests/test_errors.py。这正是本项目反复被咬的文档漂移,趁热修掉。

验证:mkdocs build --strict exit 0;secret-scan exit 0。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-20 15:14:18 +08:00
parent 3f3a5cc50b
commit 8cf8ba41c9
@@ -2,7 +2,8 @@
> 取证日期:2026-09-20 来源:用户提供的三份官方文档(`doc_temp/火山视频请求.md`、
> `doc_temp/火山错误码.md`、`doc_temp/火山查询.md`)
> 实现位置:`patbond-ai` 的 `app/providers/seedance.py` 与 `app/providers/errors.py`
> 实现位置:`patbond-ai` 的 `app/providers/volcengine/`(`client.py` 传输 / `errors.py` 错误映射 /
> `models.py` 厂商 DTO / `video.py` 视频业务 / `capabilities.py` 模型限制)
本页记录**从官方文档实际读到的事实**,供实现与排查引用。凡本页与代码不一致,
以代码为准并回改本页;凡本页与厂商文档不一致,以厂商文档为准并回改两处。
@@ -131,7 +132,8 @@
## 4. 错误码映射
实现在 `app/providers/errors.py`,测试在 `tests/test_errors.py`(32 项)。
实现在 `app/providers/volcengine/errors.py`,测试在
`tests/providers/volcengine/test_errors.py`(32 项)。
### 🔴 `QuotaExceeded` 一码两义
@@ -167,7 +169,7 @@
**403 的欠费/未开通归入配额族**:HTTP 状态码不同(403 而非 429),但用户要做的
事一样——去充值。按状态码分族会把它们错分。
## 5. 模型与能力矩阵(供 V7 目录种子取用)
## 5. 模型与能力矩阵
| 模型 | 文生视频 | 图生视频-首帧 | 首尾帧 | 全模态参考 | 有声 |
| --- | --- | --- | --- | --- | --- |
@@ -185,17 +187,55 @@
`doubao-seedance-2-0-260128`、`doubao-seedance-1-0-pro-250528`、
`doubao-seedance-1-0-lite-i2v-250428`。
> **V7 种子待定项**:实际可用的 model ID 取决于账号开通与推理接入点配置,
> 文档示例值不能直接当种子。需确认账号实际开通的模型后再写 V7,否则种子里
> 的 `provider_model_name` 会指向一个不存在或无权访问的模型
> (对应错误码 `InvalidEndpointOrModel.NotFound` / `ModelNotOpen`)。
### 账号实际开通的模型(2026-09-20 确认)
| model ID | 目录 code | 关键限制 |
| --- | --- | --- |
| `doubao-seedance-2-5-260628` | `seedance-2-5` | 时长 `[4,30]`;分辨率 480p/720p/1080p(**无 4k**);**图生视频时 `ratio` 只支持 `adaptive`**;支持 `output_format` mp4/mov;1080p 为 10bit + H.265/HEVC |
| `doubao-seedance-2-0-260128` | `seedance-2-0` | 时长 `[4,15]`;分辨率 480p/720p/1080p/**4k**;`ratio` 可指定;不支持 `output_format`;4k 为 10bit + H.265/HEVC |
已由 **V7 目录种子**播种(`provider_code = 'volcengine-seedance'`)。注意与目标
模型 `patbond_postgresql.sql:1495` 的种子**有意不同**——正典那份是服务商未定时
写下的 `provider_code='fixture'` 占位。
**两个模型的限制差异不进目录表**(正典的 `generation_models` 没有能力列,本迭代
不发明超出已评审模型的列),而是由 `patbond-ai` 的
`app/providers/volcengine/capabilities.py` 承载并在提交前**本地预校验**。这样
超范围的请求不必花一次往返去换一个厂商 400——而那一次往返还会计入 RPM 并表现为
一个失败的任务。按**模型族前缀**匹配而非完整 ID,故一次小版本升级(如
`2-5-261231`)不需要改表;**未知模型一律放行**,使「账号开通即可用」不退化为
「开通还得改代码发版」。
同一组参数在两个模型上一个合法一个不合法(如 20 秒时长、4k 分辨率),这正是
需要这张表的理由,测试里两个方向都钉住了。
**风格表(`generation_styles`)刻意未播种**:风格是产品内容决策(提供哪些艺术
风格、叫什么、配图是什么),无法从服务商文档推导;正典那 4 条风格均为 `image`
类且其 `preview_asset_id` 指向 demo 资产,而 V1..V7 链路不含该 demo 种子,照抄
会违反外键。`generation_jobs.style_id` 可空,故空风格表不阻塞任何功能。
**图片模型同样未播种**:gpt-image-2 的适配层尚未落地,播种一个没有适配器的模型
会让客户端渲染出一个点了没反应的入口(目录端点按 `media_kind` 聚合可用模型,
故当前只返回 `video`)。
## 6. 实现状态
`patbond-ai` 已按高内聚低耦合分层(`config → assembly → providers → domain`),
分层约束由 `tests/test_layering.py` 用 AST 自动守着。以后接火山的图片/语音接口
应新建兄弟模块复用同一个 `ArkClient`,而不是再抄一遍鉴权与错误解包。
| 项 | 状态 |
| --- | --- |
| 错误分类(`errors.py`) | ✅ 32 测试 |
| 提交与查询客户端(`seedance.py`) | ✅ 26 测试,全部离线(MockTransport) |
| 错误分类(`providers/volcengine/errors.py`) | ✅ 32 测试 |
| HTTP 传输与鉴权(`providers/volcengine/client.py`) | ✅ 15 测试,全部离线(MockTransport) |
| 视频业务(`providers/volcengine/video.py`) | ✅ 提交与查询 + 状态映射 |
| 模型限制预校验(`providers/volcengine/capabilities.py`) | ✅ 23 测试 |
| V7 目录种子(两个已开通模型) | ✅ 6 测试(含 `provider_code` 跨语言一致性) |
| 产物转存 | ⏸ 阻塞于存储决策(ADR-023 §7)。注意 §2-④ 的 24 小时硬约束 |
| V7 目录种子 | ⏸ 待确认账号实际开通的 model ID |
| Java 侧 provider 适配 | ⏸ 待本服务的 HTTP 端点与 `openapi-internal.yaml` 落地 |
| HTTP 端点与 `openapi-internal.yaml` | ⏸ 未开始 |
| Java 侧 provider 适配 | ⏸ 待上一项落地 |
**一处跨语言约定,两侧都有测试钉住**:目录表的 `provider_code` 必须与
`patbond-ai` 适配器的 `PROVIDER_CODE` **逐字一致**(`volcengine-seedance`)。
对不上时 Worker 按任务行冻结的快照查不到适配器,任务会永远停在排队——而那看起来
像队列坏了,不像两个字符串不一致。