Compare commits
2 Commits
7d3a93fc1f
...
5faff8a127
| Author | SHA1 | Date |
|---|---|---|
|
|
5faff8a127 | |
|
|
da71daa789 |
|
|
@ -26,6 +26,7 @@ image:
|
|||
request_timeout_s: 60 # 出图慢于此判超时
|
||||
|
||||
video:
|
||||
# fast 放第一个 → 默认 variant(成本敏感场景优先);开通了 Pro 的用户从顶栏下拉切。
|
||||
seedance_2_fast:
|
||||
model_id: doubao-seedance-2-0-fast-260128
|
||||
display_name: 豆包 Seedance 2.0 Fast
|
||||
|
|
@ -52,8 +53,41 @@ video:
|
|||
default_ratio: "16:9" # 16:9 / 9:16 / 1:1 / 4:3 / 3:4 / 21:9 / adaptive
|
||||
default_duration: 5 # 4-15s
|
||||
default_watermark: false
|
||||
# generate_audio: Seedance 2.0 旗舰特性 —— 原生 AI 生成背景音效 / 角色对白(无需后期配音)。
|
||||
# 开启会增加 token 消耗(模型还要算音轨),cost 比纯视频高;默认关闭让 cost 可预测,
|
||||
# 用户要带音的视频(广告 / 角色对白)时显式传 true。
|
||||
default_generate_audio: false
|
||||
|
||||
# 轮询参数
|
||||
request_timeout_s: 60 # submit POST 超时(异步,只是提交)
|
||||
poll_interval_s: 5 # 单次 GET 间隔(秒);典型 30-90s 出片
|
||||
poll_timeout_s: 600 # 总等待上限(10min)→ 超时返 [Error]
|
||||
|
||||
seedance_2_pro:
|
||||
model_id: doubao-seedance-2-0-260128
|
||||
display_name: 豆包 Seedance 2.0 Pro
|
||||
# 同 fast 一套异步 task + 轮询接口,只换 model_id + 单价 + 分辨率上限。
|
||||
endpoint_submit: /contents/generations/tasks
|
||||
endpoint_poll: /contents/generations/tasks
|
||||
|
||||
# 计费(per-token,公式同 fast):
|
||||
# 文生视频: ¥46 / Mtok (vs fast ¥37)
|
||||
# 图生视频: ¥28 / Mtok (vs fast ¥22)
|
||||
# 实测档位(Pro, 5s, 文生视频, 24fps):
|
||||
# 720p 16:9 → ¥4.97 (vs fast ¥4.00)
|
||||
# 1080p 16:9 → 更高(Pro 独占,fast 不支持)
|
||||
price_cny_per_mtoken_text2video: 46.0
|
||||
price_cny_per_mtoken_video2video: 28.0
|
||||
fps: 24
|
||||
|
||||
# 支持参数 — Pro 支持 1080p,默认仍 720p 控成本
|
||||
default_resolution: 720p # 480p / 720p / 1080p(Pro 独占)
|
||||
default_ratio: "16:9"
|
||||
default_duration: 5
|
||||
default_watermark: false
|
||||
default_generate_audio: false
|
||||
|
||||
# 轮询参数:Pro 出片慢于 Fast(更精细),拉长超时
|
||||
request_timeout_s: 60
|
||||
poll_interval_s: 5
|
||||
poll_timeout_s: 900 # Pro 上限拉到 15min 保险
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ def main() -> int:
|
|||
if not video_cfg:
|
||||
print("[SKIP] doubao.yaml 无 video 段")
|
||||
return 0
|
||||
# 允许命令行指定 variant:`smoke_seedance.py seedance_2_pro`;不传走 yaml 第一个
|
||||
want_variant = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
if want_variant:
|
||||
if want_variant not in video_cfg:
|
||||
print(f"[FAIL] variant {want_variant!r} 不在 yaml video 段, 已知: {list(video_cfg.keys())}")
|
||||
return 2
|
||||
variant_key, variant_cfg = want_variant, video_cfg[want_variant]
|
||||
else:
|
||||
variant_key, variant_cfg = next(iter(video_cfg.items()))
|
||||
print(f"[setup] variant={variant_key} model={variant_cfg.get('model_id')}")
|
||||
print(f" price_text2video=¥{variant_cfg.get('price_cny_per_mtoken_text2video')}/Mtok")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: videogen
|
||||
description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何生视频任务调 tool 前必须 load 本 skill**。触发词:视频 / 动画 / 动起来 / 做个 video / 做段视频 / 出段视频 / 生成视频 / mov / mp4 / 短片 / 镜头 / 运动镜头 / 演示视频 / 动效。核心:视频比图贵 10 倍(¥1.86-¥4+ / 段),且要等 30-90s,问清楚再画 + 强制确认。
|
||||
description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何生视频任务调 tool 前必须 load 本 skill**。触发词:视频 / 动画 / 动起来 / 做个 video / 做段视频 / 出段视频 / 生成视频 / mov / mp4 / 短片 / 镜头 / 运动镜头 / 演示视频 / 动效。核心:视频比图贵 10 倍(¥1.86-¥4+ / 段),且要等 Fast 30-90s / Pro 2-3min,问清楚再画 + 强制确认。
|
||||
---
|
||||
|
||||
# Videogen
|
||||
|
|
@ -20,7 +20,7 @@ description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何
|
|||
- 用户**沉默 / 长时间不回 / 追问别的事** → 不算确认,**继续等**,不要自作主张
|
||||
- 用户回 "看起来不错" / "差不多" / 模棱两可 → **主动追问一句"这就开烧 ¥X?"**,拿到明确"是"再调
|
||||
|
||||
**为什么比 imagegen 还严**:视频单价 ¥4 起,比图贵 10 倍以上;一次失败相当于 18 张错图;且要等 30-90s,用户改方向的等待代价也很高。**装配 prompt 不等于授权调用** —— 装配是模型脑内运算,授权要落到用户的"嗯,画吧"上。
|
||||
**为什么比 imagegen 还严**:视频单价 ¥4 起,比图贵 10 倍以上;一次失败相当于 18 张错图;且要等 Fast 30-90s / Pro 2-3min,用户改方向的等待代价也很高。**装配 prompt 不等于授权调用** —— 装配是模型脑内运算,授权要落到用户的"嗯,画吧"上。
|
||||
|
||||
## 何时用本 skill
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何
|
|||
|
||||
**模糊时主动问一句**:
|
||||
|
||||
> 你这是想要 **一张静态图**(seedream,¥0.22,3-5 秒出图),还是 **一段短视频**(seedance,¥4 起,等 30-90s)?静态图够的话省钱省时间。
|
||||
> 你这是想要 **一张静态图**(seedream,¥0.22,3-5 秒出图),还是 **一段短视频**(seedance,¥4 起,等 Fast 30-90s / Pro 2-3min)?静态图够的话省钱省时间。
|
||||
|
||||
## 诊断模糊度 — 六维清单(运动是新增的必填维)
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何
|
|||
> - **场景**:工地中景,远处有塔吊
|
||||
> - **镜头**:固定俯视 + 缓慢推近模板中心
|
||||
> - **风格**:写实工程纪录片
|
||||
> - **时长 / 分辨率 / 比例**:5s / 720p / 16:9(ppt 用) — ¥4.00,等 30-90s
|
||||
> - **时长 / 分辨率 / 比例**:5s / 720p / 16:9(ppt 用) — ¥4.00,等 Fast 30-90s / Pro 2-3min
|
||||
>
|
||||
> 这样画可以吗?或者告诉我:想突出什么?(浇筑工艺细节 / 振动棒动作 / 大场面气势 / 慢动作)
|
||||
|
||||
|
|
@ -115,11 +115,12 @@ description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何
|
|||
> ratio: 16:9(ppt 横版)
|
||||
> duration: 5 秒
|
||||
> watermark: false
|
||||
> generate_audio: false(静音视频,后期 ppt 加 BGM)
|
||||
> 预计花费: ¥4.00
|
||||
> 预计等待: 30-90 秒
|
||||
> ````
|
||||
>
|
||||
> 这样开烧?要改什么?(改 prompt 文字 / 改时长 / 换比例 / 降到 480p 省钱)
|
||||
> 这样开烧?要改什么?(改 prompt 文字 / 改时长 / 换比例 / 降到 480p 省钱 / 开 audio 加 AI 配音)
|
||||
|
||||
然后 ⛔ **BLOCKING:等用户明确回复**。
|
||||
|
||||
|
|
@ -169,6 +170,21 @@ description: 用豆包 Seedance 2.0 Fast 生视频(`seedance` tool)。**任何
|
|||
|---|---|
|
||||
| `false` | 默认无水印(申报 / ppt / 客户交付都不该带);仅当用户明确说"加水印"才传 `true` |
|
||||
|
||||
### `generate_audio`(Seedance 2.0 旗舰特性)
|
||||
|
||||
| 默认 | 何时开 |
|
||||
|---|---|
|
||||
| `false` | 默认关 —— 控成本 + 大多数 ppt / 申报场景用静音视频(后期配音 / 当背景视频)。**模型还要算音轨,开启 cost 会高于纯视频估算**(具体增幅未实测,首次开时盯一下返回的 tokens)。 |
|
||||
| `true` | 用户明确要**带声音的视频**:广告 / 短剧 / 角色对白 / 配乐场景。**调用前必须告诉用户**"开启 audio,cost 会高于估算 ¥X"并等确认。 |
|
||||
|
||||
prompt 写法变化:开 `generate_audio=true` 时,prompt 里要描述**声音是什么**(背景音 / 音效 / 对白台词具体说啥 / 音色),否则模型随机配,效果难控:
|
||||
|
||||
```
|
||||
... 背景音「鲜切现摇」,女生音色,轻快鼓点卡点
|
||||
```
|
||||
|
||||
参考火山方舟官方 r2v 例子(`r2v_tea_*`):每个镜头段都明示"背景音 XX / 卡点 XX / 音效 XX"。**不写 = 不可预期**。
|
||||
|
||||
## 调用范式
|
||||
|
||||
**前置条件**:用户已经看过最终 prompt + 所有参数,明确回复"可以" / "OK" / "出片吧" 之类。**没看到这个确认就不要调**。
|
||||
|
|
@ -185,7 +201,7 @@ seedance(
|
|||
)
|
||||
```
|
||||
|
||||
**调用是同步阻塞 30-90s** —— tool 内部 submit 后轮询直到 succeeded,期间 LLM 卡住。这不是 bug,告诉用户"提交了,等 30-90 秒"再耐心等返回。
|
||||
**调用是同步阻塞 Fast 30-90s / Pro 2-3min** —— tool 内部 submit 后轮询直到 succeeded,期间 LLM 卡住。这不是 bug,告诉用户"提交了,等 30-90 秒"再耐心等返回。
|
||||
|
||||
返回串首行是 `[seedance] model=... · resolution=... · ratio=... · duration=Xs · cost=¥... · elapsed=...s` —— 原样保留给用户(SPA 会 parse 挂徽章)。第二行 `saved: <相对路径>` 是产物路径,告诉用户。
|
||||
|
||||
|
|
@ -232,6 +248,7 @@ seedance(
|
|||
- ❌ prompt 里写否定 "no shaking, not blurry" —— Seedance 不支持 negative,反向起效
|
||||
- ❌ 让用户在 seedream / seedance 之间默默替他决定 —— 模糊就一句话问明白
|
||||
- ❌ phase 1 拿用户已生成的图试图 i2v —— **当前不支持**,明确告诉用户
|
||||
- ❌ 用户没说要声音就把 `generate_audio` 设 true —— 多花钱且大概率配出不合用户预期的随机音效;开它前必须问"要 AI 配音吗?cost 会高于估算"
|
||||
- ❌ 用 `run_python` 调 `requests` 裸打豆包 API —— 走 `seedance` tool(已封装异步轮询 + 计费 + 落盘 + meta + cancel)
|
||||
|
||||
## 输出
|
||||
|
|
|
|||
|
|
@ -102,6 +102,13 @@ class SeedanceTool(Tool):
|
|||
"type": "boolean",
|
||||
"description": "是否打豆包水印。默认 false(申报/PPT 场景反需求)。",
|
||||
},
|
||||
"generate_audio": {
|
||||
"type": "boolean",
|
||||
"description": (
|
||||
"是否同步生成 AI 背景音 / 对白(Seedance 2.0 旗舰特性)。默认 false 控成本;"
|
||||
"广告 / 短剧 / 角色对白等场景传 true,模型会一并算音轨,cost 高于纯视频。"
|
||||
),
|
||||
},
|
||||
},
|
||||
"required": ["prompt"],
|
||||
}
|
||||
|
|
@ -135,6 +142,7 @@ class SeedanceTool(Tool):
|
|||
ratio: Optional[str] = None,
|
||||
duration: Optional[int] = None,
|
||||
watermark: Optional[bool] = None,
|
||||
generate_audio: Optional[bool] = None,
|
||||
) -> str:
|
||||
if not (prompt or "").strip():
|
||||
return "[Error] prompt 不能为空"
|
||||
|
|
@ -145,6 +153,9 @@ class SeedanceTool(Tool):
|
|||
chosen_ratio = ratio or cfg.get("default_ratio", "16:9")
|
||||
chosen_duration = int(duration) if duration is not None else int(cfg.get("default_duration", 5))
|
||||
chosen_watermark = bool(cfg.get("default_watermark", False)) if watermark is None else bool(watermark)
|
||||
chosen_generate_audio = (
|
||||
bool(cfg.get("default_generate_audio", False)) if generate_audio is None else bool(generate_audio)
|
||||
)
|
||||
fps = int(cfg.get("fps", 24))
|
||||
|
||||
submit_timeout = float(cfg.get("request_timeout_s", 60))
|
||||
|
|
@ -162,6 +173,7 @@ class SeedanceTool(Tool):
|
|||
"resolution": chosen_resolution,
|
||||
"duration": chosen_duration,
|
||||
"watermark": chosen_watermark,
|
||||
"generate_audio": chosen_generate_audio,
|
||||
}
|
||||
|
||||
t0 = time.monotonic()
|
||||
|
|
@ -232,6 +244,7 @@ class SeedanceTool(Tool):
|
|||
"duration_s": chosen_duration,
|
||||
"fps": fps,
|
||||
"watermark": chosen_watermark,
|
||||
"generate_audio": chosen_generate_audio,
|
||||
"tokens": tokens_actual,
|
||||
"tokens_estimated": tokens_estimated,
|
||||
"price_cny_per_mtoken": price_t2v,
|
||||
|
|
@ -258,7 +271,11 @@ class SeedanceTool(Tool):
|
|||
price_cny_per_mtoken=price_t2v,
|
||||
has_video_input=False, # phase 1 仅 t2v;i2v 接入后这里读 body 判断
|
||||
watermark=chosen_watermark,
|
||||
extra_units={"cgt_id": cgt_id, "elapsed_s": round(elapsed, 1)},
|
||||
extra_units={
|
||||
"cgt_id": cgt_id,
|
||||
"elapsed_s": round(elapsed, 1),
|
||||
"generate_audio": chosen_generate_audio,
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[seedance] record_video_usage failed: {type(e).__name__}: {e}", flush=True)
|
||||
|
|
@ -268,7 +285,8 @@ class SeedanceTool(Tool):
|
|||
# 前端 extractMediaBanner 已 whitelist seedance,正则抓 key=value 挂徽章
|
||||
return (
|
||||
f"[seedance] model={model_id} · resolution={chosen_resolution} · ratio={chosen_ratio} · "
|
||||
f"duration={chosen_duration}s · cost=¥{cost_cny:.2f} · elapsed={elapsed:.1f}s\n"
|
||||
f"duration={chosen_duration}s · audio={chosen_generate_audio} · "
|
||||
f"cost=¥{cost_cny:.2f} · elapsed={elapsed:.1f}s\n"
|
||||
f"saved: {disp}\n"
|
||||
f"prompt={prompt!r}\n"
|
||||
f"watermark={chosen_watermark} cgt_id={cgt_id}"
|
||||
|
|
|
|||
Loading…
Reference in New Issue