From 8cf8ba41c97bc28149701811153298d65c23debe Mon Sep 17 00:00:00 2001 From: Lixi20 Date: Sun, 20 Sep 2026 15:14:18 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20Seedance=20=E5=8F=96=E8=AF=81=E9=A1=B5?= =?UTF-8?q?=E8=A1=A5=E5=AE=9E=E9=99=85=E5=BC=80=E9=80=9A=E7=9A=84=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=A8=A1=E5=9E=8B=20+=20=E4=BF=AE=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E8=BF=87=E6=9C=9F=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增「账号实际开通的模型」一节(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) --- .../providers/volcengine-seedance.md | 62 +++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/docs/development/providers/volcengine-seedance.md b/docs/development/providers/volcengine-seedance.md index 529c9c6..f0edf65 100644 --- a/docs/development/providers/volcengine-seedance.md +++ b/docs/development/providers/volcengine-seedance.md @@ -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 按任务行冻结的快照查不到适配器,任务会永远停在排队——而那看起来 +像队列坏了,不像两个字符串不一致。