@optima-chat/optima-agent 0.9.10 → 0.9.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.claude/skills/.kb-skills-managed.json +9 -9
  2. package/.claude/skills/ads/SKILL.md +244 -244
  3. package/.claude/skills/ads/template/campaign/CREATIVES.md +18 -18
  4. package/.claude/skills/ads/template/campaign/NOTES.md +10 -10
  5. package/.claude/skills/ads/template/campaign/STRATEGY.md +29 -29
  6. package/.claude/skills/ads/template/user/ADS.md +29 -29
  7. package/.claude/skills/ads/template/user/LEARNINGS.md +15 -15
  8. package/.claude/skills/ads/template/user/PROGRESS.md +20 -20
  9. package/.claude/skills/ads/template/user/README.md +25 -25
  10. package/.claude/skills/ads/template/user/assets/.gitignore +2 -2
  11. package/.claude/skills/bi/SKILL.md +131 -131
  12. package/.claude/skills/browser/SKILL.md +201 -201
  13. package/.claude/skills/channels/SKILL.md +188 -188
  14. package/.claude/skills/collection/SKILL.md +88 -88
  15. package/.claude/skills/douyin/SKILL.md +408 -408
  16. package/.claude/skills/ffmpeg/SKILL.md +164 -164
  17. package/.claude/skills/gen/SKILL.md +279 -279
  18. package/.claude/skills/growth/SKILL.md +90 -90
  19. package/.claude/skills/growth/template/ACCOUNTS.md +14 -14
  20. package/.claude/skills/growth/template/CALENDAR.md +7 -7
  21. package/.claude/skills/growth/template/COMMENTS.md +7 -7
  22. package/.claude/skills/growth/template/GROWTH.md +37 -37
  23. package/.claude/skills/growth/template/PROGRESS.md +4 -4
  24. package/.claude/skills/growth/template/README.md +20 -20
  25. package/.claude/skills/growth/template/TOPICS.md +7 -7
  26. package/.claude/skills/homepage/SKILL.md +177 -177
  27. package/.claude/skills/i18n/SKILL.md +517 -517
  28. package/.claude/skills/ingesting-sources/SKILL.md +94 -94
  29. package/.claude/skills/initializing-kb/SKILL.md +117 -117
  30. package/.claude/skills/instagram/SKILL.md +321 -321
  31. package/.claude/skills/inventory/SKILL.md +328 -328
  32. package/.claude/skills/kol-outreach/SKILL.md +232 -232
  33. package/.claude/skills/kol-outreach/template/campaign/CONFIG.md +60 -60
  34. package/.claude/skills/kol-outreach/template/campaign/KOLS.md +6 -6
  35. package/.claude/skills/kol-outreach/template/campaign/PROGRESS.md +3 -3
  36. package/.claude/skills/kol-outreach/template/campaign/TEMPLATES.md +88 -88
  37. package/.claude/skills/kol-outreach/template/merchant/BRAND.md +36 -36
  38. package/.claude/skills/kol-outreach/template/merchant/CAMPAIGNS.md +6 -6
  39. package/.claude/skills/kol-outreach/template/merchant/MERCHANT_LIMITS.md +16 -16
  40. package/.claude/skills/kol-outreach/template/merchant/PROGRESS.md +4 -4
  41. package/.claude/skills/kol-outreach/template/merchant/README.md +20 -20
  42. package/.claude/skills/linting-the-wiki/SKILL.md +68 -68
  43. package/.claude/skills/logistics/SKILL.md +180 -180
  44. package/.claude/skills/markdown-pdf/SKILL.md +72 -72
  45. package/.claude/skills/merchant/SKILL.md +110 -110
  46. package/.claude/skills/multigrid-poster/SKILL.md +192 -192
  47. package/.claude/skills/multigrid-poster/layouts/2x2.json +34 -34
  48. package/.claude/skills/multigrid-poster/layouts/3x3.json +43 -43
  49. package/.claude/skills/multigrid-poster/scripts/compose.py +116 -116
  50. package/.claude/skills/order/SKILL.md +452 -452
  51. package/.claude/skills/product/SKILL.md +379 -379
  52. package/.claude/skills/product-page/SKILL.md +106 -106
  53. package/.claude/skills/querying-the-wiki/SKILL.md +59 -59
  54. package/.claude/skills/reddit/SKILL.md +277 -277
  55. package/.claude/skills/review/SKILL.md +321 -321
  56. package/.claude/skills/scout/SKILL.md +575 -575
  57. package/.claude/skills/sentinel/SKILL.md +281 -281
  58. package/.claude/skills/shein/SKILL.md +246 -246
  59. package/.claude/skills/shipping/SKILL.md +200 -200
  60. package/.claude/skills/shop-content/SKILL.md +101 -101
  61. package/.claude/skills/shopify/SKILL.md +282 -282
  62. package/.claude/skills/skillify/SKILL.md +114 -114
  63. package/.claude/skills/taobao/SKILL.md +238 -238
  64. package/.claude/skills/tiktok/SKILL.md +381 -381
  65. package/.claude/skills/twitter/SKILL.md +302 -302
  66. package/.claude/skills/updating-related-pages/SKILL.md +65 -65
  67. package/.claude/skills/video-edit/SKILL.md +138 -138
  68. package/.claude/skills/video-gen/SKILL.md +630 -548
  69. package/.claude/skills/video-gen/templates/INDEX.md +78 -78
  70. package/.claude/skills/video-gen/templates/before-after-beauty.md +183 -183
  71. package/.claude/skills/video-gen/templates/drama-fmcg.md +183 -183
  72. package/.claude/skills/video-gen/templates/kol-reaction-food.md +193 -193
  73. package/.claude/skills/video-gen/templates/multi-point-apparel.md +185 -185
  74. package/.claude/skills/video-gen/templates/pain-solution-home.md +184 -184
  75. package/.claude/skills/video-gen/templates/pdp-360-showcase.md +189 -189
  76. package/.claude/skills/video-gen/templates/pdp-feature-highlight.md +182 -182
  77. package/.claude/skills/video-gen/templates/scene-digital.md +183 -183
  78. package/.claude/skills/wechat/SKILL.md +174 -174
  79. package/.claude/skills/xhs/SKILL.md +170 -170
  80. package/README.md +276 -276
  81. package/dist/bin/optima.js +26 -26
  82. package/dist/bin/serve.js +23 -23
  83. package/dist/bin/video-edit.d.ts +3 -0
  84. package/dist/bin/video-edit.d.ts.map +1 -0
  85. package/dist/bin/video-edit.js +153 -0
  86. package/dist/bin/video-edit.js.map +1 -0
  87. package/dist/src/agent.d.ts +1 -1
  88. package/dist/src/agent.js +4 -4
  89. package/dist/src/system-prompt.d.ts.map +1 -1
  90. package/dist/src/system-prompt.js +175 -173
  91. package/dist/src/system-prompt.js.map +1 -1
  92. package/dist/src/tools/memory.js +10 -10
  93. package/dist/src/ui/headless.js +7 -7
  94. package/package.json +79 -79
@@ -1,548 +1,630 @@
1
- ---
2
- name: video-gen
3
- description: "帮商家用 AI 生成产品视频(社媒投放 / 产品详情页)。触发场景:用户要做视频(做视频/生成视频/产品视频/宣传视频/图生视频)、用户给视频链接+产品图要复刻(复刻/翻拍/仿拍/做同款/爆款复刻)、用户给产品图想发社媒(TikTok视频/IG视频/短视频)、用户给产品图想放详情页(PDP视频/产品展示视频)"
4
- ---
5
-
6
- # Video Generation Skill
7
-
8
- 帮电商商家用 AI 视频生成替代传统实拍。核心价值:**帮用户形成一份满意的 Storyboard,然后按 Storyboard 执行生成。**
9
-
10
- ## Global Rules
11
-
12
- 优先级高于任何 pipeline 步骤。违反会导致泄漏、超支或数据丢失。
13
-
14
- 1. **User-facing 不出现模型名或服务名**
15
- status / 成本 / 进度 / 错误 / 总结 统一用"视频生成中"。模型名仅用于 skill 内部路由,**代码注释里的也不能抄给用户**。
16
-
17
- 2. **花钱前必走 COST-GATE**
18
- 任何 `gen video` / `gen image` 调用之前必走一次成本确认(§执行生成)。**Fast-path、迭代、重试均无例外**。成本按秒估算:`Σ(seg.duration_s) × per_second_rate_usd[mode]`,rate 从所选模板的 `production_cost.per_second_rate_usd` 读取。rate 为 TBD 时成本前缀"~"明示粗估。
19
-
20
- 3. **任何 pipeline 第一步必须 Per-video init**
21
- 分析 / Storyboard / Plan / 生成 / Review 执行前先跑 §Per-video init(建目录 + cd)。否则后续 write 写错位置。迭代场景用 `{旧id}-vN`。
22
-
23
- 4. **Anti-fabrication**
24
- 未在本 skill 显式列出的命令 / flag / 参数,**不允许凭印象拼**。要么走 §相关工具 里的精确命令,要么 ask user。ffmpeg / gen / scout 子命令同样适用。
25
-
26
- 5. **git 只前进,不 reset**
27
- 每步完成立刻 commit。迭代用 `-vN` 目录不覆盖。**禁止** `git reset --hard` / `git checkout .` / `git clean -f`。
28
-
29
- ## 工作目录
30
-
31
- 所有状态都在 `~/video-gen/`,整个目录是一个 git repo。
32
-
33
- ```
34
- ~/video-gen/
35
- ├── preferences.md
36
- ├── history.md
37
- └── videos/{video-id}/
38
- ├── analysis.md
39
- ├── storyboard.md
40
- ├── production-plan.md
41
- ├── quality-report.md
42
- ├── assets/
43
- │ ├── product.jpg
44
- │ ├── reference.mp4
45
- │ └── keyframes/
46
- ├── prompts/
47
- │ └── seg-N.txt
48
- ├── clips/
49
- │ ├── seg-N.pending.json
50
- │ ├── seg-N.meta.json
51
- │ └── seg-N.mp4
52
- └── final.mp4
53
- ```
54
-
55
- ## 每次 session 的启动流程
56
-
57
- 按顺序执行:
58
-
59
- 1. **检查工作目录**:`ls ~/video-gen/preferences.md`
60
- - 不存在 → 走「First-time init」
61
- - 存在 → 继续步骤 2
62
- 2. **扫描未完成任务**:找 `~/video-gen/videos/` 下无 `quality-report.md` 且创建 < 7 天的目录
63
- - 有 → 在回复用户前主动提一次:"你有 N 个视频没完成..."
64
- - 无 → 继续步骤 3
65
- 3. **读 preferences.md** 和 **history.md**
66
- 4. **按用户意图分流**(**任何路径的第一步都是 Per-video init,见下文专段**):
67
- - 有视频 + 有产品图 → Fast-path:直接走「分析 → Storyboard → Production Plan → 生成」全管道
68
- - 有视频,无产品图 → 问"换成哪个产品?"
69
- - **只有产品图(社媒目标)** → **爆款驱动默认流程**:
70
- 1. agent 从产品图 + preferences 推断**品类 + 平台 + 关键词**
71
- 2. 走「参考发现」(见下段):自动跑 scout 取 Top 3 爆款
72
- 3. 展示候选 → 用户选一条 → 进「分析源视频」→ 复刻 storyboard
73
- 4. 用户说**"跳过"/"不要参考"** → 从模板构建 storyboard(opt-out 必须显式)
74
- - **只有产品图(PDP 目标)** → 从 PDP 模板构建 Storyboard(PDP 场景**不走爆款**,因为 PDP 视频不是社交叙事)
75
- - **用户意图模糊**(没说社媒 vs PDP)→ 问**一个**关键问题确认 → 再分流
76
- - "再试 / 更活泼 / 改 X" → 走「迭代」
77
-
78
- **为什么社媒默认走爆款驱动**:单靠模板 + 产品图生成的视频是"平均水平"——爆款的节奏 / Hook / 卡点来自具体成功案例,不来自抽象模板。agent 主动拉爆款 → 分析 → 复刻,是把 video-gen 从"出得来"升级到"出得好"。用户想要纯模板产出 → 一句"跳过"即可,opt-out 成本为 0。
79
-
80
- **Fast-path 触发条件**(必须全部满足才走 fast-path,否则先问):
81
-
82
- | 场景 | 必须有 | 可从 preferences 兜底 |
83
- |---|---|---|
84
- | **复刻(用户自带参考)** | 视频文件/链接 + 产品图 | 调性、平台 |
85
- | **生成(社媒)** | 产品图 + 明确意图动词 + 平台 | 调性;**品类关键词从产品图 + preferences 推**,不够时追问 1 次 |
86
- | **生成(PDP)** | 产品图 + 明确说"详情页"/"PDP" | 调性 |
87
- | **迭代** | 明确的 delta("更活泼"/"暖一点")+ history 无歧义匹配 | — |
88
-
89
- **社媒 Fast-path 的"爆款发现"不算"问用户"**——agent 自动拉 Top 3 + 展示让用户选 1 条是**必要数据输入**(和"选模板"同级),不是"审批"。用户选条或"跳过"都保持在 Fast-path 内。
90
-
91
- **Fast-path 行为**:Storyboard 展示后告知而非审批,但**生成前必须告知预估成本**(见「执行生成」的成本确认)。用户可随时喊停。
92
-
93
- ## First-time init
94
-
95
- 首次使用时执行:
96
-
97
- ```bash
98
- mkdir -p ~/video-gen/videos
99
- cd ~/video-gen
100
- git init -b main
101
- ```
102
-
103
- 创建 `~/video-gen/preferences.md`:
104
-
105
- ```markdown
106
- # Preferences
107
-
108
- ## Brand
109
- name:
110
- palette:
111
- tone:
112
- forbidden:
113
-
114
- ## Defaults
115
- platform:
116
- aspect_ratio:
117
- duration_seconds:
118
-
119
- ## Learned
120
- ```
121
-
122
- 创建 `~/video-gen/history.md`:
123
-
124
- ```markdown
125
- # History
126
-
127
- | date | video-id | product | purpose | template | storyboard-summary | parent | status | liked |
128
- |---|---|---|---|---|---|---|---|---|
129
- ```
130
-
131
- 创建 `.gitignore`:
132
-
133
- ```
134
- videos/**/assets/reference.mp4
135
- videos/**/assets/*.mov
136
- videos/**/clips/*.mp4
137
- videos/**/clips/*.mov
138
- videos/**/final.mp4
139
- videos/**/final.mov
140
- ```
141
-
142
- ```bash
143
- git add -A && git commit -m "init: video-gen workspace"
144
- ```
145
-
146
- **Minimal init**:不要在首次使用时做问卷。只建骨架文件,preferences 留空。
147
-
148
- 如果用户的首条消息已经包含了足够的信息(产品图 + 意图),**直接进管道**,在过程中自然补充 preferences:
149
- - 用户说了"TikTok" → 默默填 Defaults.platform = TikTok
150
- - 用户说了"warm 风格" → 默默填 Brand.tone = warm
151
- - 都没说 → 从模板默认值兜底,不打断流程去问
152
-
153
- 只有当管道完全无法推进时(例如连产品图都没有),才问**一个**关键问题。
154
-
155
- 每次有新信息写入 preferences → `git commit -m "prefs: update <field>"`
156
-
157
- ## 参考发现(社媒默认触发 · 用户可跳过)
158
-
159
- **触发**:按上方「分流」的第 3 条(社媒目标 · 无用户自带参考视频)自动进入。
160
-
161
- **不触发**:用户自带参考视频(走"分析源视频")/ PDP 目标 / 用户明确说"跳过"。
162
-
163
- ### 步骤
164
-
165
- 1. **推断品类 + 关键词**(不打断用户)
166
- - 从产品图(文件名、用户文字、先前 preferences)推断,例:"懒人拖把" → 品类=家居清洁 / 关键词="拖把"
167
- - preferences 有 `default_platform` 用 preferences;无则按"TikTok(海外)/ 抖音(国内)"默认,等用户纠正
168
- - 关键词低置信(产品图模糊或全新品类)→ 追问 1 次 `"产品属于哪个品类?(如美妆/家居/数码)"`,否则不打断
169
- 2. **调 scout**
170
- - 平台=TikTok → `scout tiktok search-videos "<关键词>" --region <US|...>`
171
- - 平台=抖音 → `scout douyin search-videos "<关键词>"` 或 `scout douyin hot-search`(按品类筛)
172
- - 其他平台:按 scout 可用命令对应(见 `storyboard-learning/analyses/2026-04-21-viral-top5-reverse-breakdown.md` 的 SOP 段)
173
- 3. **过滤 + 排序**:品牌契合(不违反 preferences.forbidden)+ 产品形态匹配 + 按 likes 降序取 Top 3
174
- 4. **展示 3 个候选**:平台 / 时间 / 指标(点赞 · 分享 · 评论)/ 风格摘要(hook 类型 · 时长 · BGM 类型)
175
- 5. **用户选一条** → 写入 `assets/reference.mp4` 或保留 URL → 继续「分析源视频」
176
- 6. **用户说"跳过"/"都不要"/"不要参考"** → 记录到 preferences.Learned("此类任务偏好无参考")→ 从模板构建 Storyboard
177
-
178
- ### 硬规则
179
-
180
- - **绝不自动选参考**——Top 3 必须让用户选 1 条(或明说跳过)
181
- - **"跳过"必须是一键**,不问理由(用户说过就记 preferences,未来同类不再默认拉爆款)
182
- - **scout 调用成本算进 COST-GATE**——参考发现本身消耗 Optima credits(scout API 不免费)
183
-
184
- ## Per-video init
185
-
186
- **触发条件**:走任何管道(分析 / Storyboard / Production Plan / 生成)前**必须**先执行此段。否则后续 write 操作会失败或写到错位置。
187
-
188
- **每次新 video session 第一步**:
189
-
190
- ```bash
191
- # <slug> = 由 agent 从产品名 / 用户意图提取的 kebab-case 短语(前 20 字符内)
192
- # 例:"懒人拖把" → "lazy-mop";"免洗洗手液" → "no-rinse-sanitizer"
193
- VIDEO_ID="$(date +%Y%m%d-%H%M)-<slug>"
194
- mkdir -p ~/video-gen/videos/$VIDEO_ID/{assets/keyframes,prompts,clips}
195
- cd ~/video-gen/videos/$VIDEO_ID
196
- echo "Using VIDEO_ID=$VIDEO_ID"
197
- ```
198
-
199
- **迭代场景**(用户说"再试" / "改 X"):保留旧版本、写入新目录。用自动递增版本号防覆盖:
200
-
201
- ```bash
202
- BASE_ID="<旧 video-id>" # 例如 20260422-1430-product-demo
203
- n=2
204
- while [ -d ~/video-gen/videos/${BASE_ID}-v${n} ]; do n=$((n+1)); done
205
- VIDEO_ID="${BASE_ID}-v${n}"
206
- mkdir -p ~/video-gen/videos/$VIDEO_ID/{assets/keyframes,prompts,clips}
207
- cd ~/video-gen/videos/$VIDEO_ID
208
- echo "Using VIDEO_ID=$VIDEO_ID"
209
- ```
210
-
211
- **场景路由**:
212
-
213
- | 用户输入 | 触发 Per-video init 的路径 |
214
- |---|---|
215
- | 产品图 + 意图(无参考视频) | 进 Storyboard 前先跑 Per-video init |
216
- | 产品图 + 参考视频 | 进「分析源视频」前先跑 Per-video init |
217
- | 迭代(沿用旧 video) | 建 `{旧id}-vN` 目录(N 自动递增)+ cd |
218
-
219
- ## 分析源视频
220
-
221
- **前置**:已完成 Per-video init。
222
-
223
- 有源视频时执行。产出 `videos/{id}/analysis.md`。
224
-
225
- 1. 保存素材到 `assets/`
226
-
227
- 2. ffmpeg 场景检测:
228
-
229
- ```bash
230
- ffprobe -v quiet -print_format json -show_format -show_streams assets/reference.mp4
231
- ffmpeg -i assets/reference.mp4 -vf "select='gt(scene,0.3)',showinfo" -vsync 0 -f null - 2>&1 | grep showinfo
232
- ```
233
-
234
- 3. 每段抽 3 帧(首/中/尾):
235
-
236
- ```bash
237
- ffmpeg -i assets/reference.mp4 -vf "select='eq(n\,<FRAME_NUM>)'" -vsync 0 assets/keyframes/seg-<N>-<pos>.jpg
238
- ```
239
-
240
- 4. 读取关键帧图片,分析每段的 subject / composition / camera / lighting / palette / description
241
-
242
- 5. 验证 ffmpeg 切段合理性(修正软切/漏切)
243
-
244
- 6. 以表格写入 `analysis.md`:
245
-
246
- ```markdown
247
- # Analysis
248
-
249
- ## 元数据
250
- | 项目 | 值 |
251
- |---|---|
252
- | 总时长 | 7.0s |
253
- | 比例 | 9:16 |
254
- | FPS | 30 |
255
- | 片段数 | 4 |
256
-
257
- ## 镜头分析
258
-
259
- | 段 | 时长 | 主体 | 角色 | 构图 | 运镜 | 光线 | 色调 | 描述 |
260
- |---|---|---|---|---|---|---|---|---|
261
- | 1 | 0-1.5s | ... | ... | ... | ... | ... | ... | ... |
262
- | ... |
263
-
264
- ## 整体风格
265
- | 项目 | 值 |
266
- |---|---|
267
- | Pacing | slow |
268
- | Mood | aspirational, minimalist |
269
- | Hook | subtle visual intrigue |
270
- | CTA | logo reveal |
271
- ```
272
-
273
- 8. `git commit -m "video: analyze $VIDEO_ID — N segments, Xs"`
274
-
275
- ## 形成 Storyboard
276
-
277
- **前置**:已完成 Per-video init。
278
-
279
- 核心产出。**用户语言写,用户能读能改。**
280
-
281
- 1. 读输入:preferences + analysis(如有)+ history 匹配 liked 记录 + 匹配模板(**先读 `$CLAUDE_SKILL_DIR/templates/INDEX.md` 路由决定选哪个,再读选中的那一份**,不要把所有模板都读一遍)
282
-
283
- 2. 有模板则以模板为骨架填入产品/品牌信息;否则从零构建
284
-
285
- 3. 复刻场景做**物理合理性预检**:原主体和用户产品形态是否兼容
286
- - 不合理 → 告知原因,降级策略或建议换参考
287
-
288
- 4. 写 `videos/{id}/storyboard.md`:
289
-
290
- ```markdown
291
- # Storyboard
292
-
293
- ## 基本信息
294
- | 项目 | 值 |
295
- |---|---|
296
- | 产品 | <名称> |
297
- | 平台 | <TikTok / IG / PDP> |
298
- | 时长目标 | <Ns> |
299
- | 调性 | <调性> |
300
- | 参考来源 | <来源或"从模板构建"> |
301
-
302
- ## 镜头表
303
- | 段 | 时长 | 内容 | 运镜 | 替换说明 |
304
- |---|---|---|---|---|
305
- | 1 | 0-1.5s | <内容> | <运镜> | <替换或"原创"> |
306
- | ... |
307
-
308
- > **段时长约束**:Storyboard 按叙事节奏自由分段(推荐 2-15s),不受 Sora2 时长限制。Production Plan 阶段会将多个短段合并为 10/15s 的 gen video 调用,再用 ffmpeg trim 切回各段时长。单段 >15s 必须拆段。段时长精度到 0.5s(3.73s 四舍五入到 3.5s)。
309
-
310
- ## Hook
311
- <第 1 秒如何抓注意力>
312
-
313
- ## CTA
314
- <末尾留什么>
315
-
316
- ## 物理合理性预检
317
- <复刻时:替换是否合理。无参考时写 N/A>
318
- ```
319
-
320
- 5. 展示给用户:
321
- - Fast-path:告知(不等审批),用户可喊停
322
- - 非 Fast-path:问"OK 吗?想改哪段告诉我。"
323
-
324
- 6. 确认后 `git commit -m "video: storyboard $VIDEO_ID — <summary>"`
325
-
326
- ## 产出 Production Plan
327
-
328
- **前置**:已完成 Per-video init + Storyboard。
329
-
330
- Storyboard 确认后自动推导。用户通常不改。
331
-
332
- ### 0. 选策略
333
-
334
- 所有视频生成统一使用 Sora2(GrsAI),支持文生视频和图生视频。**Sora2 生成静音视频,音频需后期处理**(ffmpeg 叠 BGM / `gen tts` 配旁白)。
335
-
336
- | 特征 | 策略 |
337
- |---|---|
338
- | 1 镜头,无参考 | single-shot |
339
- | 多镜头,无参考 | multi-shot-concat |
340
- | 有参考,大致复刻 | clone-loose |
341
- | 有参考,高度还原 | clone-strict |
342
- | PDP 多卖点 | pdp-feature-concat |
343
- | 人物讲话 | talking-head |
344
-
345
- > **DashScope 回退**:如需 DashScope 特有功能(自动配音、负向提示词),可用 `--provider dashscope`,但仅支持图生视频,时长 5|10s。
346
-
347
- ### 1. `videos/{id}/production-plan.md`
348
-
349
- Sora2 仅支持 10 或 15 秒整段生成。Storyboard 的细粒度段需要在 Production Plan 中**合并为 gen video 调用单元**:
350
-
351
- - 相邻短段(叙事连贯、同一场景)合并成一个 10s15s gen video 调用
352
- - 每个调用的 prompt 合并覆盖所有子段的内容描述
353
- - 生成后用 ffmpeg trim 切回各子段时长
354
- - 单独一个 10s+ 的 storyboard 段直接映射为一个 gen video 调用
355
-
356
- ```markdown
357
- # Production Plan
358
-
359
- ## 策略
360
- <策略名>
361
- 原因: <选择理由>
362
-
363
- ## 生成调用
364
- | Call | 合并段 | gen_duration | seed | aspect_ratio | Prompt 摘要 |
365
- |---|---|---|---|---|---|
366
- | 1 | seg 1-3 (共 8s) | 10 | <seed 或 `-`> | <16:9 \| 9:16 \| 1:1> | <合并 prompt> |
367
- | 2 | seg 4 (12s) | 15 | $PRODUCT_SEED | <同上> | <prompt> |
368
- | ... |
369
-
370
- ## Trim 映射
371
- | seg | 来源 Call | trim 区间 | 输出 |
372
- |---|---|---|---|
373
- | 1 | Call 1 | 0:00-2.5s | clips/seg-1.mp4 |
374
- | 2 | Call 1 | 2.5-5.5s | clips/seg-2.mp4 |
375
- | 3 | Call 1 | 5.5-8.0s | clips/seg-3.mp4 |
376
- | 4 | Call 2 | 0:00-12.0s | clips/seg-4.mp4 |
377
-
378
- **seed 规则**:同一产品的镜头(如 template PRODUCT_LOCK 指定的 #4/#5/#6/#9)**共用一个 seed**(任选一个固定整数记录下来)。PAIN / 场景段(如 #1/#2/#3)无产品时可填 `-`。
379
-
380
- ## 验收标准
381
- - 比例: <从 Storyboard>
382
- - 时长: <从 Storyboard ±20%>
383
- - Hook: <从 Storyboard>
384
- - CTA: <从 Storyboard>
385
- ```
386
-
387
- ### 2. 为每个需 prompt 的步骤生成 `prompts/call-N.txt`
388
-
389
- ### 3. `git commit -m "video: plan $VIDEO_ID — <strategy>"`
390
-
391
- ## 执行生成
392
-
393
- **前置**:已完成 Per-video init + Storyboard + Production Plan。
394
-
395
- <COST-GATE>
396
- **生成前成本确认(必做,包括 Fast-path)**:在执行任何 `gen video` / `gen image` 调用之前,必须向用户展示一次成本摘要:
397
-
398
- > 即将生成 N 段视频(策略: <策略名>),预计:
399
- > - 调用次数: N 次 gen video + M 次 gen image(首帧编辑)
400
- > - 总时长: seg.duration_s>s
401
- > - 预估耗时: ~X 分钟
402
- > - 预估成本: ~$Y(扣 Optima credits)
403
- >
404
- > 继续?
405
-
406
- 用户说"继续"/"好"/"OK" → 开始执行。
407
- 用户说"太贵"/"换个便宜的" → 回到 Production Plan,换策略(如 strict → loose)。
408
- 用户不回应超过合理时间不执行,等用户。
409
-
410
- **即使是 Fast-path 也必须走这一步。** 这是花钱步骤的唯一确认点。**迭代、重试同样无例外。**
411
- </COST-GATE>
412
-
413
- 按 production-plan.md 步骤表逐步执行。
414
-
415
- **每步执行前**写 `clips/seg-N.pending.json`:
416
-
417
- ```json
418
- {
419
- "task_id": "",
420
- "submitted_at": "<ISO>",
421
- "step": 1,
422
- "tool": "<gen video | gen image | ffmpeg>"
423
- }
424
- ```
425
-
426
- **工具调用**:
427
-
428
- ```bash
429
- # 图生视频(--duration 只能是 10 或 15)
430
- gen video <input_image> \
431
- --prompt "$(cat prompts/call-N.txt)" \
432
- --duration <10|15> \
433
- --aspect-ratio <16:9|9:16|1:1> \
434
- --seed $PRODUCT_SEED \
435
- -o clips/call-<N>.mp4
436
-
437
- # 纯文生视频(无输入图像)
438
- gen video \
439
- --prompt "$(cat prompts/call-N.txt)" \
440
- --duration <10|15> \
441
- --aspect-ratio <16:9|9:16|1:1> \
442
- -o clips/call-<N>.mp4
443
-
444
- # ffmpeg trim — 按 Trim 映射表切回 storyboard 各段
445
- ffmpeg -i clips/call-1.mp4 -ss 0 -t 2.5 -c copy clips/seg-1.mp4
446
- ffmpeg -i clips/call-1.mp4 -ss 2.5 -t 3.0 -c copy clips/seg-2.mp4
447
-
448
- # 变量约定(production-plan.md 每个 call 提供):
449
- # $PRODUCT_SEED = 锁定产品一致性的 seed(同一产品的所有镜头共用一个值)
450
-
451
- # 注意 --seed 必须 wire:否则每段 gen 产品外观随机变,templates 的 PRODUCT_LOCK
452
- # 规范(same seed across shots)会失效,电商视频产品一致性崩塌。
453
-
454
- # 首帧编辑(产品替换)— 双图模式
455
- gen image "<编辑指令>" -i <原始首帧> -i <产品图> -o assets/keyframes/seg-<N>-edited.jpg
456
-
457
- # 拼接所有 seg 为最终视频
458
- printf "file '%s'\n" clips/seg-*.mp4 > concat_list.txt
459
- ffmpeg -f concat -safe 0 -i concat_list.txt -c copy final.mp4
460
-
461
- # 任务查询 / 取消 / 重试
462
- gen task get <task_id>
463
- gen task cancel <task_id>
464
- gen task retry <task_id>
465
- ```
466
-
467
- **Duration**:`--duration` 只接受 10 或 15。Production Plan 的 Trim 映射表负责将生成的完整视频切回 Storyboard 各段时长。
468
-
469
- **每步完成后**:
470
- - `seg-N.pending.json`
471
- - `seg-N.meta.json`(duration_s / aspect_ratio / status)
472
- - `git commit -m "video: receive $VIDEO_ID seg-N"`
473
-
474
- **全部完成**:`git commit -m "video: done $VIDEO_ID"`
475
-
476
- **失败**:自动重试 1 次 → 仍失败标记 `needs_user_review`
477
-
478
- **无依赖步骤可并行。生成过程中不问用户。**
479
-
480
- ## Review
481
-
482
- 生成完成后对照 storyboard.md 检查:
483
-
484
- 1. **硬约束**(不过 → 告知用户):
485
- - 比例匹配
486
- - 时长 ±20%
487
- - 文件可播放(`ffprobe final.mp4`)
488
-
489
- 2. **软推荐**(不过 写入迭代建议):
490
- - 产品可见性(抽 5 帧)
491
- - 主体一致性(5 帧比对)
492
- - 首帧质量
493
-
494
- 3. `quality-report.md``git commit -m "video: review $VIDEO_ID"`
495
-
496
- 4. 展示结果 + 质量摘要 + **2-3 个迭代建议**
497
-
498
- 5. 更新 `~/video-gen/history.md` 追加一行
499
-
500
- 6. 用户说"好/完美" → 在 preferences.md Learned 追加一条 → `git commit -m "prefs: learn from $VIDEO_ID — <pattern>"`
501
-
502
- ## 迭代
503
-
504
- 用户说"再试 / 更 X / 改 Y":
505
-
506
- 1. history.md 找匹配项
507
- 2. 读该 video 的 storyboard.md
508
- 3. 判断:
509
- - "故事不对" → 改 storyboard → production-plan 重推 → 重新生成
510
- - "效果不对" → storyboard 不动 → 改 production-plan → 重新生成
511
- 4. 新 video-id = `{旧id}-v2`,history 的 parent 指向旧 id
512
-
513
- ## 核心规则(流程偏好)
514
-
515
- > 硬规则见 §Global Rules。以下为流程偏好。
516
-
517
- - **信息够就直接做(Fast-path)**——最重要的一条
518
- - **Storyboard 是核心产物**,所有路径汇聚于它
519
- - **Production Plan 由 skill 自动推导**
520
- - **每步完成立刻 git commit**
521
- - **生成过程零打扰**
522
- - **参考视频永远让用户选**
523
- - **生成完给迭代建议**
524
- - **新会话有未完成任务先告知一次**
525
-
526
- ## 错误处理
527
-
528
- | 故障 | 处理 |
529
- |---|---|
530
- | gen 返回 failed | 重试 1 次 → 仍失败告知用户 |
531
- | gen video 返回 "duration out of range" | **不**自动重试/裁剪,告知用户并建议调整该段 storyboard 时长(Sora2 支持 10\|15 秒)后重新 Production Plan |
532
- | ffmpeg 失败 | 检查输入完整性,告知用户 |
533
- | 源视频无法下载 | 建议手动下载后重试 |
534
- | scout 无结果 | 告知,转模板构建 |
535
- | 产品替换不合理 | 告知原因,降级策略或换参考 |
536
- | 会话关闭 | 状态在文件系统 + git,下次接续 |
537
- | gen task 超时 | 按 pending.json 重提 |
538
- | git commit 失败 | 说明原因,不 reset |
539
-
540
- ## 相关工具
541
-
542
- - `gen video` — 图/文 → 视频
543
- - `gen image` — 文 → 图
544
- - `gen image` — 文生图,也是图像编辑(`-i` 传入输入图,可多次使用最多 8 张;产品替换首帧用 `-i 源帧 -i 产品图`)
545
- - `gen task get/cancel/retry` — 异步任务控制
546
- - `gen tts` 文本 → 语音
547
- - `ffmpeg` / `ffprobe` — 视频分析、抽帧、拼接
548
- - `scout` 爆款视频发现
1
+ ---
2
+ name: video-gen
3
+ description: "帮商家用 AI 生成产品视频(社媒投放 / 产品详情页 / 数字人口播)。触发场景:用户要做视频(做视频/生成视频/产品视频/宣传视频/图生视频)、用户给视频链接+产品图要复刻(复刻/翻拍/仿拍/做同款/爆款复刻)、用户给产品图想发社媒(TikTok视频/IG视频/短视频)、用户给产品图想放详情页(PDP视频/产品展示视频)、用户要数字人/口播/真人讲解/talking head视频。"
4
+ ---
5
+
6
+ # Video Generation Skill
7
+
8
+ 帮电商商家用 AI 视频生成替代传统实拍。核心价值:**帮用户形成一份满意的 Storyboard,然后按 Storyboard 执行生成。**
9
+
10
+ ## Global Rules
11
+
12
+ 优先级高于任何 pipeline 步骤。违反会导致泄漏、超支或数据丢失。
13
+
14
+ 1. **User-facing 不出现模型名或服务名**
15
+ status / 成本 / 进度 / 错误 / 总结 统一用"视频生成中"。模型名仅用于 skill 内部路由,**代码注释里的也不能抄给用户**。
16
+
17
+ 2. **花钱前必走 COST-GATE**
18
+ 任何 `gen video` / `gen image` 调用之前必走一次成本确认(§执行生成)。**Fast-path、迭代、重试均无例外**。成本按秒估算:`Σ(seg.duration_s) × per_second_rate_usd[mode]`,rate 从所选模板的 `production_cost.per_second_rate_usd` 读取。rate 为 TBD 时成本前缀"~"明示粗估。
19
+
20
+ 3. **任何 pipeline 第一步必须 Per-video init**
21
+ 分析 / Storyboard / Plan / 生成 / Review 执行前先跑 §Per-video init(建目录 + cd)。否则后续 write 写错位置。迭代场景用 `{旧id}-vN`。
22
+
23
+ 4. **Anti-fabrication**
24
+ 未在本 skill 显式列出的命令 / flag / 参数,**不允许凭印象拼**。要么走 §相关工具 里的精确命令,要么 ask user。ffmpeg / gen / scout 子命令同样适用。
25
+
26
+ 5. **git 只前进,不 reset**
27
+ 每步完成立刻 commit。迭代用 `-vN` 目录不覆盖。**禁止** `git reset --hard` / `git checkout .` / `git clean -f`。
28
+
29
+ ## 工作目录
30
+
31
+ 所有状态都在 `~/video-gen/`,整个目录是一个 git repo。
32
+
33
+ ```
34
+ ~/video-gen/
35
+ ├── preferences.md
36
+ ├── history.md
37
+ └── videos/{video-id}/
38
+ ├── analysis.md
39
+ ├── storyboard.md
40
+ ├── production-plan.md
41
+ ├── quality-report.md
42
+ ├── assets/
43
+ │ ├── product.jpg
44
+ │ ├── reference.mp4
45
+ │ └── keyframes/
46
+ ├── prompts/
47
+ │ └── seg-N.txt
48
+ ├── clips/
49
+ │ ├── seg-N.pending.json
50
+ │ ├── seg-N.meta.json
51
+ │ └── seg-N.mp4
52
+ └── final.mp4
53
+ ```
54
+
55
+ ## 每次 session 的启动流程
56
+
57
+ 按顺序执行:
58
+
59
+ 1. **检查工作目录**:`ls ~/video-gen/preferences.md`
60
+ - 不存在 → 走「First-time init」
61
+ - 存在 → 继续步骤 2
62
+ 2. **扫描未完成任务**:找 `~/video-gen/videos/` 下无 `quality-report.md` 且创建 < 7 天的目录
63
+ - 有 → 在回复用户前主动提一次:"你有 N 个视频没完成..."
64
+ - 无 → 继续步骤 3
65
+ 3. **读 preferences.md** 和 **history.md**
66
+ 4. **按用户意图分流**(**任何路径的第一步都是 Per-video init,见下文专段**):
67
+ - 有视频 + 有产品图 → Fast-path:直接走「分析 → Storyboard → Production Plan → 生成」全管道
68
+ - 有视频,无产品图 → 问"换成哪个产品?"
69
+ - **只有产品图(社媒目标)** → **爆款驱动默认流程**:
70
+ 1. agent 从产品图 + preferences 推断**品类 + 平台 + 关键词**
71
+ 2. 走「参考发现」(见下段):自动跑 scout 取 Top 3 爆款
72
+ 3. 展示候选 → 用户选一条 → 进「分析源视频」→ 复刻 storyboard
73
+ 4. 用户说**"跳过"/"不要参考"** → 从模板构建 storyboard(opt-out 必须显式)
74
+ - **只有产品图(PDP 目标)** → 从 PDP 模板构建 Storyboard(PDP 场景**不走爆款**,因为 PDP 视频不是社交叙事)
75
+ - **用户意图模糊**(没说社媒 vs PDP)→ 问**一个**关键问题确认 → 再分流
76
+ - "再试 / 更活泼 / 改 X" → 走「迭代」
77
+
78
+ **为什么社媒默认走爆款驱动**:单靠模板 + 产品图生成的视频是"平均水平"——爆款的节奏 / Hook / 卡点来自具体成功案例,不来自抽象模板。agent 主动拉爆款 → 分析 → 复刻,是把 video-gen 从"出得来"升级到"出得好"。用户想要纯模板产出 → 一句"跳过"即可,opt-out 成本为 0。
79
+
80
+ **Fast-path 触发条件**(必须全部满足才走 fast-path,否则先问):
81
+
82
+ | 场景 | 必须有 | 可从 preferences 兜底 |
83
+ |---|---|---|
84
+ | **复刻(用户自带参考)** | 视频文件/链接 + 产品图 | 调性、平台 |
85
+ | **生成(社媒)** | 产品图 + 明确意图动词 + 平台 | 调性;**品类关键词从产品图 + preferences 推**,不够时追问 1 次 |
86
+ | **生成(PDP)** | 产品图 + 明确说"详情页"/"PDP" | 调性 |
87
+ | **迭代** | 明确的 delta("更活泼"/"暖一点")+ history 无歧义匹配 | — |
88
+
89
+ **社媒 Fast-path 的"爆款发现"不算"问用户"**——agent 自动拉 Top 3 + 展示让用户选 1 条是**必要数据输入**(和"选模板"同级),不是"审批"。用户选条或"跳过"都保持在 Fast-path 内。
90
+
91
+ **Fast-path 行为**:Storyboard 展示后告知而非审批,但**生成前必须告知预估成本**(见「执行生成」的成本确认)。用户可随时喊停。
92
+
93
+ ## First-time init
94
+
95
+ 首次使用时执行:
96
+
97
+ ```bash
98
+ mkdir -p ~/video-gen/videos
99
+ cd ~/video-gen
100
+ git init -b main
101
+ ```
102
+
103
+ 创建 `~/video-gen/preferences.md`:
104
+
105
+ ```markdown
106
+ # Preferences
107
+
108
+ ## Brand
109
+ name:
110
+ palette:
111
+ tone:
112
+ forbidden:
113
+
114
+ ## Defaults
115
+ platform:
116
+ aspect_ratio:
117
+ duration_seconds:
118
+
119
+ ## Learned
120
+ ```
121
+
122
+ 创建 `~/video-gen/history.md`:
123
+
124
+ ```markdown
125
+ # History
126
+
127
+ | date | video-id | product | purpose | template | storyboard-summary | parent | status | liked |
128
+ |---|---|---|---|---|---|---|---|---|
129
+ ```
130
+
131
+ 创建 `.gitignore`:
132
+
133
+ ```
134
+ videos/**/assets/reference.mp4
135
+ videos/**/assets/*.mov
136
+ videos/**/clips/*.mp4
137
+ videos/**/clips/*.mov
138
+ videos/**/final.mp4
139
+ videos/**/final.mov
140
+ ```
141
+
142
+ ```bash
143
+ git add -A && git commit -m "init: video-gen workspace"
144
+ ```
145
+
146
+ **Minimal init**:不要在首次使用时做问卷。只建骨架文件,preferences 留空。
147
+
148
+ 如果用户的首条消息已经包含了足够的信息(产品图 + 意图),**直接进管道**,在过程中自然补充 preferences:
149
+ - 用户说了"TikTok" → 默默填 Defaults.platform = TikTok
150
+ - 用户说了"warm 风格" → 默默填 Brand.tone = warm
151
+ - 都没说 → 从模板默认值兜底,不打断流程去问
152
+
153
+ 只有当管道完全无法推进时(例如连产品图都没有),才问**一个**关键问题。
154
+
155
+ 每次有新信息写入 preferences → `git commit -m "prefs: update <field>"`
156
+
157
+ ## 参考发现(社媒默认触发 · 用户可跳过)
158
+
159
+ **触发**:按上方「分流」的第 3 条(社媒目标 · 无用户自带参考视频)自动进入。
160
+
161
+ **不触发**:用户自带参考视频(走"分析源视频")/ PDP 目标 / 用户明确说"跳过"。
162
+
163
+ ### 步骤
164
+
165
+ 1. **推断品类 + 关键词**(不打断用户)
166
+ - 从产品图(文件名、用户文字、先前 preferences)推断,例:"懒人拖把" → 品类=家居清洁 / 关键词="拖把"
167
+ - preferences 有 `default_platform` 用 preferences;无则按"TikTok(海外)/ 抖音(国内)"默认,等用户纠正
168
+ - 关键词低置信(产品图模糊或全新品类)→ 追问 1 次 `"产品属于哪个品类?(如美妆/家居/数码)"`,否则不打断
169
+ 2. **调 scout**
170
+ - 平台=TikTok → `scout tiktok search-videos "<关键词>" --region <US|...>`
171
+ - 平台=抖音 → `scout douyin search-videos "<关键词>"` 或 `scout douyin hot-search`(按品类筛)
172
+ - 其他平台:按 scout 可用命令对应(见 `storyboard-learning/analyses/2026-04-21-viral-top5-reverse-breakdown.md` 的 SOP 段)
173
+ 3. **过滤 + 排序**:品牌契合(不违反 preferences.forbidden)+ 产品形态匹配 + 按 likes 降序取 Top 3
174
+ 4. **展示 3 个候选**:平台 / 时间 / 指标(点赞 · 分享 · 评论)/ 风格摘要(hook 类型 · 时长 · BGM 类型)
175
+ 5. **用户选一条** → 写入 `assets/reference.mp4` 或保留 URL → 继续「分析源视频」
176
+ 6. **用户说"跳过"/"都不要"/"不要参考"** → 记录到 preferences.Learned("此类任务偏好无参考")→ 从模板构建 Storyboard
177
+
178
+ ### 硬规则
179
+
180
+ - **绝不自动选参考**——Top 3 必须让用户选 1 条(或明说跳过)
181
+ - **"跳过"必须是一键**,不问理由(用户说过就记 preferences,未来同类不再默认拉爆款)
182
+ - **scout 调用成本算进 COST-GATE**——参考发现本身消耗 Optima credits(scout API 不免费)
183
+
184
+ ## Per-video init
185
+
186
+ **触发条件**:走任何管道(分析 / Storyboard / Production Plan / 生成)前**必须**先执行此段。否则后续 write 操作会失败或写到错位置。
187
+
188
+ **每次新 video session 第一步**:
189
+
190
+ ```bash
191
+ # <slug> = 由 agent 从产品名 / 用户意图提取的 kebab-case 短语(前 20 字符内)
192
+ # 例:"懒人拖把" → "lazy-mop";"免洗洗手液" → "no-rinse-sanitizer"
193
+ VIDEO_ID="$(date +%Y%m%d-%H%M)-<slug>"
194
+ mkdir -p ~/video-gen/videos/$VIDEO_ID/{assets/keyframes,prompts,clips}
195
+ cd ~/video-gen/videos/$VIDEO_ID
196
+ echo "Using VIDEO_ID=$VIDEO_ID"
197
+ ```
198
+
199
+ **迭代场景**(用户说"再试" / "改 X"):保留旧版本、写入新目录。用自动递增版本号防覆盖:
200
+
201
+ ```bash
202
+ BASE_ID="<旧 video-id>" # 例如 20260422-1430-product-demo
203
+ n=2
204
+ while [ -d ~/video-gen/videos/${BASE_ID}-v${n} ]; do n=$((n+1)); done
205
+ VIDEO_ID="${BASE_ID}-v${n}"
206
+ mkdir -p ~/video-gen/videos/$VIDEO_ID/{assets/keyframes,prompts,clips}
207
+ cd ~/video-gen/videos/$VIDEO_ID
208
+ echo "Using VIDEO_ID=$VIDEO_ID"
209
+ ```
210
+
211
+ **场景路由**:
212
+
213
+ | 用户输入 | 触发 Per-video init 的路径 |
214
+ |---|---|
215
+ | 产品图 + 意图(无参考视频) | 进 Storyboard 前先跑 Per-video init |
216
+ | 产品图 + 参考视频 | 进「分析源视频」前先跑 Per-video init |
217
+ | 迭代(沿用旧 video) | 建 `{旧id}-vN` 目录(N 自动递增)+ cd |
218
+
219
+ ## 分析源视频
220
+
221
+ **前置**:已完成 Per-video init。
222
+
223
+ 有源视频时执行。产出 `videos/{id}/analysis.md`。
224
+
225
+ 1. 保存素材到 `assets/`
226
+
227
+ 2. ffmpeg 场景检测:
228
+
229
+ ```bash
230
+ ffprobe -v quiet -print_format json -show_format -show_streams assets/reference.mp4
231
+ ffmpeg -i assets/reference.mp4 -vf "select='gt(scene,0.3)',showinfo" -vsync 0 -f null - 2>&1 | grep showinfo
232
+ ```
233
+
234
+ 3. 每段抽 3 帧(首/中/尾):
235
+
236
+ ```bash
237
+ ffmpeg -i assets/reference.mp4 -vf "select='eq(n\,<FRAME_NUM>)'" -vsync 0 assets/keyframes/seg-<N>-<pos>.jpg
238
+ ```
239
+
240
+ 4. 读取关键帧图片,分析每段的 subject / composition / camera / lighting / palette / description
241
+
242
+ 5. 验证 ffmpeg 切段合理性(修正软切/漏切)
243
+
244
+ 6. 以表格写入 `analysis.md`:
245
+
246
+ ```markdown
247
+ # Analysis
248
+
249
+ ## 元数据
250
+ | 项目 | 值 |
251
+ |---|---|
252
+ | 总时长 | 7.0s |
253
+ | 比例 | 9:16 |
254
+ | FPS | 30 |
255
+ | 片段数 | 4 |
256
+
257
+ ## 镜头分析
258
+
259
+ | 段 | 时长 | 主体 | 角色 | 构图 | 运镜 | 光线 | 色调 | 描述 |
260
+ |---|---|---|---|---|---|---|---|---|
261
+ | 1 | 0-1.5s | ... | ... | ... | ... | ... | ... | ... |
262
+ | ... |
263
+
264
+ ## 整体风格
265
+ | 项目 | 值 |
266
+ |---|---|
267
+ | Pacing | slow |
268
+ | Mood | aspirational, minimalist |
269
+ | Hook | subtle visual intrigue |
270
+ | CTA | logo reveal |
271
+ ```
272
+
273
+ 8. `git commit -m "video: analyze $VIDEO_ID — N segments, Xs"`
274
+
275
+ ## 形成 Storyboard
276
+
277
+ **前置**:已完成 Per-video init。
278
+
279
+ 核心产出。**用户语言写,用户能读能改。**
280
+
281
+ 1. 读输入:preferences + analysis(如有)+ history 匹配 liked 记录 + 匹配模板(**先读 `$CLAUDE_SKILL_DIR/templates/INDEX.md` 路由决定选哪个,再读选中的那一份**,不要把所有模板都读一遍)
282
+
283
+ 2. 有模板则以模板为骨架填入产品/品牌信息;否则从零构建
284
+
285
+ 3. 复刻场景做**物理合理性预检**:原主体和用户产品形态是否兼容
286
+ - 不合理 → 告知原因,降级策略或建议换参考
287
+
288
+ 4. 写 `videos/{id}/storyboard.md`:
289
+
290
+ ```markdown
291
+ # Storyboard
292
+
293
+ ## 基本信息
294
+ | 项目 | 值 |
295
+ |---|---|
296
+ | 产品 | <名称> |
297
+ | 平台 | <TikTok / IG / PDP> |
298
+ | 时长目标 | <Ns> |
299
+ | 调性 | <调性> |
300
+ | 参考来源 | <来源或"从模板构建"> |
301
+
302
+ ## 镜头表
303
+ | 段 | 时长 | 内容 | 运镜 | 替换说明 |
304
+ |---|---|---|---|---|
305
+ | 1 | 0-1.5s | <内容> | <运镜> | <替换或"原创"> |
306
+ | ... |
307
+
308
+ > **段时长约束**:Storyboard 按叙事节奏自由分段(推荐 2-15s),不受 Sora2 时长限制。Production Plan 阶段会将多个短段合并为 10/15s 的 gen video 调用,再用 ffmpeg trim 切回各段时长。单段 >15s 必须拆段。段时长精度到 0.5s(3.73s 四舍五入到 3.5s)。
309
+
310
+ ## Hook
311
+ <第 1 秒如何抓注意力>
312
+
313
+ ## CTA
314
+ <末尾留什么>
315
+
316
+ ## 物理合理性预检
317
+ <复刻时:替换是否合理。无参考时写 N/A>
318
+ ```
319
+
320
+ 5. 展示给用户:
321
+ - Fast-path:告知(不等审批),用户可喊停
322
+ - 非 Fast-path:问"OK 吗?想改哪段告诉我。"
323
+
324
+ 6. 确认后 `git commit -m "video: storyboard $VIDEO_ID — <summary>"`
325
+
326
+ ## 产出 Production Plan
327
+
328
+ **前置**:已完成 Per-video init + Storyboard。
329
+
330
+ Storyboard 确认后自动推导。用户通常不改。
331
+
332
+ ### 0. 选策略
333
+
334
+ 所有视频生成统一使用 Sora2(GrsAI),支持文生视频和图生视频。**Sora2 生成静音视频,音频需后期处理**(ffmpeg 叠 BGM / `gen tts` 配旁白)。
335
+
336
+ | 特征 | 策略 |
337
+ |---|---|
338
+ | 1 镜头,无参考 | single-shot |
339
+ | 多镜头,无参考 | multi-shot-concat |
340
+ | 有参考,大致复刻 | clone-loose |
341
+ | 有参考,高度还原 | clone-strict |
342
+ | PDP 多卖点 | pdp-feature-concat |
343
+ | 人物讲话 | talking-head |
344
+
345
+ > **DashScope 回退**:如需 DashScope 特有功能(自动配音、负向提示词),可用 `--provider dashscope`,但仅支持图生视频,时长 5|10s。
346
+ >
347
+ > **数字人口播(talking-head)**:策略为 `talking-head` 时,使用 `gen video --provider heygen` 生成。不走 Sora2。详见下方「数字人口播」段。
348
+
349
+ ### 1. `videos/{id}/production-plan.md`
350
+
351
+ Sora2 仅支持 1015 秒整段生成。Storyboard 的细粒度段需要在 Production Plan 中**合并为 gen video 调用单元**:
352
+
353
+ - 相邻短段(叙事连贯、同一场景)合并成一个 10s 15s 的 gen video 调用
354
+ - 每个调用的 prompt 合并覆盖所有子段的内容描述
355
+ - 生成后用 ffmpeg trim 切回各子段时长
356
+ - 单独一个 10s+ 的 storyboard 段直接映射为一个 gen video 调用
357
+
358
+ ```markdown
359
+ # Production Plan
360
+
361
+ ## 策略
362
+ <策略名>
363
+ 原因: <选择理由>
364
+
365
+ ## 生成调用
366
+ | Call | 合并段 | gen_duration | seed | aspect_ratio | Prompt 摘要 |
367
+ |---|---|---|---|---|---|
368
+ | 1 | seg 1-3 (共 8s) | 10 | <seed 或 `-`> | <16:9 \| 9:16 \| 1:1> | <合并 prompt> |
369
+ | 2 | seg 4 (12s) | 15 | $PRODUCT_SEED | <同上> | <prompt> |
370
+ | ... |
371
+
372
+ ## Trim 映射
373
+ | seg | 来源 Call | trim 区间 | 输出 |
374
+ |---|---|---|---|
375
+ | 1 | Call 1 | 0:00-2.5s | clips/seg-1.mp4 |
376
+ | 2 | Call 1 | 2.5-5.5s | clips/seg-2.mp4 |
377
+ | 3 | Call 1 | 5.5-8.0s | clips/seg-3.mp4 |
378
+ | 4 | Call 2 | 0:00-12.0s | clips/seg-4.mp4 |
379
+
380
+ **seed 规则**:同一产品的镜头(如 template PRODUCT_LOCK 指定的 #4/#5/#6/#9)**共用一个 seed**(任选一个固定整数记录下来)。PAIN / 场景段(如 #1/#2/#3)无产品时可填 `-`。
381
+
382
+ ## 验收标准
383
+ - 比例: <从 Storyboard>
384
+ - 时长: <从 Storyboard ±20%>
385
+ - Hook: <从 Storyboard>
386
+ - CTA: <从 Storyboard>
387
+ ```
388
+
389
+ ### 2. 为每个需 prompt 的步骤生成 `prompts/call-N.txt`
390
+
391
+ ### 3. `git commit -m "video: plan $VIDEO_ID — <strategy>"`
392
+
393
+ ## 执行生成
394
+
395
+ **前置**:已完成 Per-video init + Storyboard + Production Plan。
396
+
397
+ <COST-GATE>
398
+ **生成前成本确认(必做,包括 Fast-path)**:在执行任何 `gen video` / `gen image` 调用之前,必须向用户展示一次成本摘要:
399
+
400
+ > 即将生成 N 段视频(策略: <策略名>),预计:
401
+ > - 调用次数: N 次 gen video + M 次 gen image(首帧编辑)
402
+ > - 总时长: seg.duration_s>s
403
+ > - 预估耗时: ~X 分钟
404
+ > - 预估成本: ~$Y(扣 Optima credits)
405
+ >
406
+ > 继续?
407
+
408
+ 用户说"继续"/"好"/"OK"开始执行。
409
+ 用户说"太贵"/"换个便宜的" → 回到 Production Plan,换策略(如 strict → loose)。
410
+ 用户不回应超过合理时间 不执行,等用户。
411
+
412
+ **即使是 Fast-path 也必须走这一步。** 这是花钱步骤的唯一确认点。**迭代、重试同样无例外。**
413
+ </COST-GATE>
414
+
415
+ production-plan.md 步骤表逐步执行。
416
+
417
+ **每步执行前**写 `clips/seg-N.pending.json`:
418
+
419
+ ```json
420
+ {
421
+ "task_id": "",
422
+ "submitted_at": "<ISO>",
423
+ "step": 1,
424
+ "tool": "<gen video | gen image | ffmpeg>"
425
+ }
426
+ ```
427
+
428
+ **工具调用**:
429
+
430
+ ```bash
431
+ # 图生视频(--duration 只能是 10 或 15)
432
+ gen video <input_image> \
433
+ --prompt "$(cat prompts/call-N.txt)" \
434
+ --duration <10|15> \
435
+ --aspect-ratio <16:9|9:16|1:1> \
436
+ --seed $PRODUCT_SEED \
437
+ -o clips/call-<N>.mp4
438
+
439
+ # 纯文生视频(无输入图像)
440
+ gen video \
441
+ --prompt "$(cat prompts/call-N.txt)" \
442
+ --duration <10|15> \
443
+ --aspect-ratio <16:9|9:16|1:1> \
444
+ -o clips/call-<N>.mp4
445
+
446
+ # ffmpeg trim Trim 映射表切回 storyboard 各段
447
+ ffmpeg -i clips/call-1.mp4 -ss 0 -t 2.5 -c copy clips/seg-1.mp4
448
+ ffmpeg -i clips/call-1.mp4 -ss 2.5 -t 3.0 -c copy clips/seg-2.mp4
449
+
450
+ # 变量约定(production-plan.md 每个 call 提供):
451
+ # $PRODUCT_SEED = 锁定产品一致性的 seed(同一产品的所有镜头共用一个值)
452
+
453
+ # 注意 --seed 必须 wire:否则每段 gen 产品外观随机变,templates 的 PRODUCT_LOCK
454
+ # 规范(same seed across shots)会失效,电商视频产品一致性崩塌。
455
+
456
+ # 首帧编辑(产品替换)— 双图模式
457
+ gen image "<编辑指令>" -i <原始首帧> -i <产品图> -o assets/keyframes/seg-<N>-edited.jpg
458
+
459
+ # 拼接所有 seg 为最终视频
460
+ printf "file '%s'\n" clips/seg-*.mp4 > concat_list.txt
461
+ ffmpeg -f concat -safe 0 -i concat_list.txt -c copy final.mp4
462
+
463
+ # 数字人口播视频(talking-head 策略)
464
+ gen video --provider heygen \
465
+ --avatar <avatar_id> \
466
+ --voice <voice_id> \
467
+ --text "口播文本" \
468
+ -o clips/seg-N.mp4
469
+
470
+ # 数字人口播 + 可选参数
471
+ gen video --provider heygen \
472
+ --avatar <avatar_id> \
473
+ --voice <voice_id> \
474
+ --text "口播文本" \
475
+ --voice-emotion Friendly \
476
+ --bg-color "#1a1a2e" \
477
+ -o clips/seg-N.mp4
478
+
479
+ # 任务查询 / 取消 / 重试
480
+ gen task get <task_id>
481
+ gen task cancel <task_id>
482
+ gen task retry <task_id>
483
+ ```
484
+
485
+ **Duration**:`--duration` 只接受 10 或 15。Production Plan 的 Trim 映射表负责将生成的完整视频切回 Storyboard 各段时长。
486
+
487
+ **每步完成后**:
488
+ - 删 `seg-N.pending.json`
489
+ - 写 `seg-N.meta.json`(duration_s / aspect_ratio / status)
490
+ - `git commit -m "video: receive $VIDEO_ID seg-N"`
491
+
492
+ **全部完成**:`git commit -m "video: done $VIDEO_ID"`
493
+
494
+ **失败**:自动重试 1 仍失败标记 `needs_user_review`
495
+
496
+ **无依赖步骤可并行。生成过程中不问用户。**
497
+
498
+ ## Review
499
+
500
+ 生成完成后对照 storyboard.md 检查:
501
+
502
+ 1. **硬约束**(不过 → 告知用户):
503
+ - 比例匹配
504
+ - 时长 ±20%
505
+ - 文件可播放(`ffprobe final.mp4`)
506
+
507
+ 2. **软推荐**(不过 写入迭代建议):
508
+ - 产品可见性(抽 5 帧)
509
+ - 主体一致性(5 帧比对)
510
+ - 首帧质量
511
+
512
+ 3. 写 `quality-report.md` → `git commit -m "video: review $VIDEO_ID"`
513
+
514
+ 4. 展示结果 + 质量摘要 + **2-3 个迭代建议**
515
+
516
+ 5. 更新 `~/video-gen/history.md` 追加一行
517
+
518
+ 6. 用户说"好/完美" → 在 preferences.md Learned 追加一条 → `git commit -m "prefs: learn from $VIDEO_ID — <pattern>"`
519
+
520
+ ## 迭代
521
+
522
+ 用户说"再试 / 更 X / 改 Y":
523
+
524
+ 1. history.md 找匹配项
525
+ 2. 读该 video 的 storyboard.md
526
+ 3. 判断:
527
+ - "故事不对" → 改 storyboard → production-plan 重推 → 重新生成
528
+ - "效果不对" storyboard 不动 → 改 production-plan → 重新生成
529
+ 4. 新 video-id = `{旧id}-v2`,history 的 parent 指向旧 id
530
+
531
+ ## 核心规则(流程偏好)
532
+
533
+ > 硬规则见 §Global Rules。以下为流程偏好。
534
+
535
+ - **信息够就直接做(Fast-path)**——最重要的一条
536
+ - **Storyboard 是核心产物**,所有路径汇聚于它
537
+ - **Production Plan skill 自动推导**
538
+ - **每步完成立刻 git commit**
539
+ - **生成过程零打扰**
540
+ - **参考视频永远让用户选**
541
+ - **生成完给迭代建议**
542
+ - **新会话有未完成任务先告知一次**
543
+
544
+ ## 错误处理
545
+
546
+ | 故障 | 处理 |
547
+ |---|---|
548
+ | gen 返回 failed | 重试 1 次 → 仍失败告知用户 |
549
+ | gen video 返回 "duration out of range" | **不**自动重试/裁剪,告知用户并建议调整该段 storyboard 时长(Sora2 支持 10\|15 秒)后重新 Production Plan |
550
+ | ffmpeg 失败 | 检查输入完整性,告知用户 |
551
+ | 源视频无法下载 | 建议手动下载后重试 |
552
+ | scout 无结果 | 告知,转模板构建 |
553
+ | 产品替换不合理 | 告知原因,降级策略或换参考 |
554
+ | 会话关闭 | 状态在文件系统 + git,下次接续 |
555
+ | gen task 超时 | 按 pending.json 重提 |
556
+ | git commit 失败 | 说明原因,不 reset |
557
+
558
+ ## 数字人口播(talking-head 策略)
559
+
560
+ 用于需要人物讲话的场景(产品介绍、品牌宣传、客服应答等)。使用 `--provider heygen` 调用。
561
+
562
+ ### 触发条件
563
+
564
+ 用户意图包含:数字人 / 真人讲解 / 口播 / talking head / 主播 / 代言人 / 讲话视频
565
+
566
+ ### 可用 Avatar
567
+
568
+ | avatar_id | 名称 |
569
+ |---|---|
570
+ | `Abigail_expressive_2024112501` | Abigail(上半身,表情丰富) |
571
+ | `Abigail_standing_office_front` | Abigail 办公室正面 |
572
+ | `Aditya_public_4` | Aditya 棕色西装 |
573
+ | `Adrian_public_3_20240312` | Adrian 蓝色衬衫 |
574
+
575
+ ### 可用 Voice
576
+
577
+ | voice_id | 名称 |
578
+ |---|---|
579
+ | `f38a635bee7a4d1f9b0a654a31d050d2` | Chill Brian(男) |
580
+ | `cef3bc4e0a84424cafcde6f2cf466c97` | Ivy(女) |
581
+ | `b966c31caf124c2a99f19ff1479c964f` | Jessica Anne Bogart(女) |
582
+ | `42d00d4aac5441279d8536cd6b52c53c` | Hope(女) |
583
+
584
+ ### 可选参数
585
+
586
+ | 参数 | 说明 | 默认值 |
587
+ |---|---|---|
588
+ | `--avatar-style <style>` | normal \| circle \| closeUp | normal |
589
+ | `--voice-speed <n>` | 语速 0.5-1.5 | 1.0 |
590
+ | `--voice-emotion <emotion>` | Excited \| Friendly \| Serious \| Soothing \| Broadcaster | — |
591
+ | `--bg-color <hex>` | 背景色 | — |
592
+ | `--bg-image <url>` | 背景图 URL | — |
593
+ | `--caption` | 启用字幕 | — |
594
+ | `--title <title>` | 视频标题 | — |
595
+
596
+ ### 用法示例
597
+
598
+ ```bash
599
+ # 基本用法
600
+ gen video --provider heygen \
601
+ --avatar Abigail_expressive_2024112501 \
602
+ --voice f38a635bee7a4d1f9b0a654a31d050d2 \
603
+ --text "欢迎来到我们的店铺,今天给大家介绍一款新品" \
604
+ -o clips/talking-head.mp4
605
+
606
+ # 带情感和背景
607
+ gen video --provider heygen \
608
+ --avatar Aditya_public_4 \
609
+ --voice f38a635bee7a4d1f9b0a654a31d050d2 \
610
+ --text "This product will change your daily routine" \
611
+ --voice-emotion Friendly \
612
+ --bg-color "#ffffff" \
613
+ -o clips/talking-head.mp4
614
+ ```
615
+
616
+ ### 注意事项
617
+
618
+ - text 最长 5000 字符
619
+ - 数字人视频生成约 2-5 分钟
620
+ - 可与 Sora2 产品镜头混合剪辑(数字人做 intro/outro,产品展示用 Sora2)
621
+
622
+ ## 相关工具
623
+
624
+ - `gen video` — 图/文 → 视频
625
+ - `gen image` — 文 → 图
626
+ - `gen image` — 文生图,也是图像编辑(`-i` 传入输入图,可多次使用最多 8 张;产品替换首帧用 `-i 源帧 -i 产品图`)
627
+ - `gen task get/cancel/retry` — 异步任务控制
628
+ - `gen tts` — 文本 → 语音
629
+ - `ffmpeg` / `ffprobe` — 视频分析、抽帧、拼接
630
+ - `scout` — 爆款视频发现