返回 Social Auto Upload
2026-03-25-browser-cli-unification-design.md
根目录 / docs / superpowers / specs / 2026-03-25-browser-cli-unification-design.md
1 # 浏览器平台 CLI 统一与小红书 Skill 设计
2
3 日期:2026-03-25
4
5 ## 概要
6
7 这份设计处理三个浏览器自动化平台的主线接口统一:
8
9 - 抖音
10 - 快手
11 - 小红书
12
13 目标不是重写 uploader,也不是再抽一层复杂框架,而是把当前已经存在但不一致的 CLI、skill、文档、示例收口成一套统一契约。
14
15 这次设计同时解决两个现实问题:
16
17 1. 小红书虽然已经有可用的浏览器 uploader,但还没有接入 `sau` CLI,也没有对应 skill。
18 2. 抖音、快手当前的 CLI 契约还带着历史字段,比如视频没有单独 `--desc`,而图文正文命名和视频描述语义混杂,不利于三家浏览器平台形成稳定统一的主线接口。
19
20 这次统一后的对外入口固定为:
21
22 - `sau douyin ...`
23 - `sau kuaishou ...`
24 - `sau xiaohongshu ...`
25
26 并让三家浏览器平台的视频、图文上传都遵循统一的主线参数模型:
27
28 - 视频:`title + desc + tags`
29 - 图文:`title + note + tags`
30
31 ## 目标
32
33 - 给小红书补齐主线 CLI:
34 - `login`
35 - `check`
36 - `upload-video`
37 - `upload-note`
38 - 统一抖音、快手、小红书三家浏览器平台的 CLI 上传参数模型
39 - 补齐小红书 skill、示例脚本、README、CLI 文档、安装/更新文档
40 - 修正抖音、快手现有 CLI 契约里缺失的 `desc` 能力
41 - 保持现有 uploader 主体逻辑不大改,不做过度封装
42
43 ## 非目标
44
45 - 这次不重构 uploader 架构
46 - 这次不改 Web 旧路径
47 - 这次不改 Bilibili 的上传契约
48 - 这次不做浏览器集成测试
49 - 这次不保留公开的 `--note` 主契约
50
51 ## 当前项目基础
52
53 ### 已有能力
54
55 - 抖音、快手已经接入 `sau_cli.py`
56 - Bilibili 已经接入 CLI 和 skill
57 - 小红书已经具备:
58 - 登录
59 - cookie 校验
60 - 视频上传
61 - 图文上传
62 - 定时发布
63 - 小红书 uploader 内部已经支持:
64 - 视频:`title + desc + tags`
65 - 图文:`title + desc + tags`
66 - 图文里的 `desc` 可选
67
68 ### 当前不一致点
69
70 - 抖音视频 CLI:`--title`、`--tags`,没有 `--desc`
71 - 快手视频 CLI:`--title`、`--tags`,没有 `--desc`
72 - 抖音图文 CLI:`--note`、`--tags`
73 - 快手图文 CLI:`--note`、`--tags`
74 - 小红书还没有 CLI/skill 接口
75
76 也就是说,当前三家浏览器平台的主线能力并不统一,尤其是:
77
78 - 视频描述没有统一暴露为 `desc`
79 - 图文正文是否应该沿用 `note` 语义没有统一
80
81 ## 统一后的 CLI 设计
82
83 ### 支持的平台
84
85 - `douyin`
86 - `kuaishou`
87 - `xiaohongshu`
88
89 ### 支持的动作
90
91 每个平台统一支持:
92
93 - `login`
94 - `check`
95 - `upload-video`
96 - `upload-note`
97
98 ### 统一后的上传参数模型
99
100 #### 视频上传
101
102 ```bash
103 sau <platform> upload-video \
104 --account <account_name> \
105 --file <video-path> \
106 --title "<title>" \
107 [--desc "<description>"] \
108 [--tags tag1,tag2] \
109 [--schedule "YYYY-MM-DD HH:MM"] \
110 [平台特有参数...]
111 ```
112
113 统一规则:
114
115 - `--title` 必填
116 - `--desc` 选填
117 - `--tags` 选填
118 - `--schedule` 选填
119
120 平台特有参数:
121
122 - 抖音:
123 - `--thumbnail`
124 - `--product-link`
125 - `--product-title`
126 - 快手:
127 - `--thumbnail`
128 - 小红书:
129 - `--thumbnail`
130
131 #### 图文上传
132
133 ```bash
134 sau <platform> upload-note \
135 --account <account_name> \
136 --images <image-1> [image-2 ...] \
137 --title "<title>" \
138 [--note "<content>"] \
139 [--tags tag1,tag2] \
140 [--schedule "YYYY-MM-DD HH:MM"]
141 ```
142
143 统一规则:
144
145 - `--images` 必填
146 - `--title` 必填
147 - `--note` 选填
148 - `--tags` 选填
149 - `--schedule` 选填
150
151 明确决定:
152
153 - 图文主线正文统一叫 `note`
154 - 视频主线描述统一叫 `desc`
155 - 文档、skill、示例统一使用:
156 - 视频:`--title + --desc + --tags`
157 - 图文:`--title + --note + --tags`
158
159 ## 数据模型设计
160
161 为了让 CLI 层和 uploader 层映射清晰,每个平台都保持各自的 request dataclass,但字段命名统一。
162
163 ### 视频请求对象
164
165 统一字段:
166
167 - `account_name`
168 - `video_file`
169 - `title`
170 - `description`
171 - `tags`
172 - `publish_date`
173 - `publish_strategy`
174 - `debug`
175 - `headless`
176
177 平台特有字段保留:
178
179 - 抖音:
180 - `thumbnail_file`
181 - `product_link`
182 - `product_title`
183 - 快手:
184 - `thumbnail_file`
185 - 小红书:
186 - `thumbnail_file`
187
188 ### 图文请求对象
189
190 统一字段:
191
192 - `account_name`
193 - `image_files`
194 - `title`
195 - `note`
196 - `tags`
197 - `publish_date`
198 - `publish_strategy`
199 - `debug`
200 - `headless`
201
202 这里明确保留 `note`,因为它更符合图文正文语义,不应强行复用视频里的 `description / desc` 命名。
203
204 ## 与现有 uploader 的映射
205
206 ### 抖音
207
208 - 视频上传继续复用 `DouYinVideo`
209 - 给抖音视频补齐 `desc` 输入映射
210 - 图文上传改为显式接收 `title + note + tags`
211 - `note` 在 CLI 层映射到抖音图文正文输入区
212
213 ### 快手
214
215 - 视频上传继续复用 `KSVideo`
216 - 给快手视频补齐 `desc` 输入映射
217 - 图文上传改为显式接收 `title + note + tags`
218
219 ### 小红书
220
221 - 登录、校验直接接 `xiaohongshu_setup` / `cookie_auth`
222 - 视频上传复用 `XiaoHongShuVideo`
223 - 图文上传复用 `XiaoHongShuNote`
224 - 因为小红书 uploader 已经支持 `title + desc + tags`,CLI 层把 `note` 稳定映射到图文正文即可
225
226 ## 兼容与迁移策略
227
228 这次采用“直接统一,不保留旧的模糊公开契约”的策略。
229
230 具体表现:
231
232 - `README.md`
233 - `docs/CLI.md`
234 - `docs/install.md`
235 - `docs/update.md`
236 - `skills/douyin-upload/...`
237 - `skills/kuaishou-upload/...`
238 - 新增 `skills/xiaohongshu-upload/...`
239 - `scripts/examples/...`
240
241 都会在同一轮里切换到新契约,避免出现:
242
243 - 一部分文档把图文正文写成 `--note`
244 - 一部分文档把图文正文写成 `--desc`
245
246 这样做的代价是旧示例命令会失效,但换来的是主线契约彻底统一:
247
248 - 视频永远是 `desc`
249 - 图文永远是 `note`
250
251 ## Skill 设计
252
253 新增:
254
255 - `skills/xiaohongshu-upload/SKILL.md`
256 - `skills/xiaohongshu-upload/references/cli-contract.md`
257 - `skills/xiaohongshu-upload/references/runtime-requirements.md`
258 - `skills/xiaohongshu-upload/references/troubleshooting.md`
259 - `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_commands.ps1`
260 - `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_commands.sh`
261 - `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_cli_template.py`
262
263 并同步更新:
264
265 - `skills/douyin-upload/SKILL.md`
266 - `skills/douyin-upload/references/cli-contract.md`
267 - `skills/kuaishou-upload/SKILL.md`
268 - `skills/kuaishou-upload/references/cli-contract.md`
269
270 skill 原则继续保持:
271
272 - 优先走 `sau`
273 - agent 不要先读 uploader 源码
274 - CLI 失败时再看 troubleshooting
275 - 登录二维码图片优先直接展示给用户扫码
276
277 ## 文档设计
278
279 至少更新:
280
281 - `README.md`
282 - `docs/CLI.md`
283 - `docs/install.md`
284 - `docs/update.md`
285
286 统一后的表达口径:
287
288 - 三家浏览器平台都已经接入 CLI
289 - 三家浏览器平台都已经接入 skill
290 - 视频上传统一字段:
291 - `title`
292 - `desc`
293 - `tags`
294 - 图文上传统一字段:
295 - `title`
296 - `note`
297 - `tags`
298 - `account_name` 是用户自定义账号名,不是固定只能叫 `creator`
299 - 一个 `account_name` 对应一个账号文件,可多账号隔离并发
300
301 ## Example 设计
302
303 examples 保留两类路径:
304
305 1. CLI 主线示例
306 2. 历史直连 uploader 示例
307
308 小红书需要补到和其他平台同等级的主线表达里:
309
310 - `examples/get_xiaohongshu_cookie.py`
311 - `examples/upload_video_to_xiaohongshu.py`
312 - 如有必要,补一份更贴近 CLI 契约的调用示例
313
314 README 和 docs 中要明确说明:
315
316 - 推荐优先使用 `sau xiaohongshu ...`
317 - 历史直连 uploader 示例只是调试入口
318
319 ## 错误处理
320
321 ### 参数级错误
322
323 由 CLI parser 负责:
324
325 - 文件不存在
326 - 时间格式非法
327 - 缺少 `--title`
328 - 缺少 `--images`
329
330 ### 业务级错误
331
332 由 uploader 和现有校验负责:
333
334 - cookie 不存在
335 - cookie 已失效
336 - 上传失败
337 - 页面结构异常
338
339 ### 二维码口径
340
341 三家浏览器平台统一保留这条说明:
342
343 - 如果登录流程生成了本地二维码图片,agent 应优先直接展示/发送图片给用户扫码,而不是只返回路径
344
345 ## 测试策略
346
347 这次只做最小但有价值的 CLI 级验证,不做浏览器集成测试。
348
349 至少补这些测试:
350
351 - parser 能识别 `xiaohongshu`
352 - 三个平台新契约能正确解析:
353 - `upload-video --title --desc --tags`
354 - `upload-note --images --title --note --tags`
355 - dispatch 能正确把参数转成对应 request
356 - 小红书 `login/check/upload-video/upload-note` 分支能被正确路由
357
358 保留现有:
359
360 - `tests/test_xiaohongshu_uploader.py`
361
362 ## 文件影响范围
363
364 ### 必改
365
366 - `sau_cli.py`
367 - `README.md`
368 - `docs/CLI.md`
369 - `docs/install.md`
370 - `docs/update.md`
371
372 ### 新增
373
374 - `skills/xiaohongshu-upload/` 全套文件
375 - 对应 CLI 单测文件
376
377 ### 同步修改
378
379 - `skills/douyin-upload/...`
380 - `skills/kuaishou-upload/...`
381 - `examples/get_xiaohongshu_cookie.py`
382 - `examples/upload_video_to_xiaohongshu.py`
383
384 ## 推荐实现顺序
385
386 1. 先改 `sau_cli.py` 和 request 模型
387 2. 接上小红书 CLI 路由
388 3. 给抖音、快手补 `desc` / 图文新字段映射
389 4. 补 CLI 单测
390 5. 新增小红书 skill
391 6. 更新抖音、快手 skill 契约
392 7. 更新 README / CLI / install / update 文档
393 8. 更新 examples
394
395 ## 最终结论
396
397 - 三家浏览器平台统一成同一套 CLI 动作:
398 - `login`
399 - `check`
400 - `upload-video`
401 - `upload-note`
402 - 三家浏览器平台统一成同一套主线元数据模型:
403 - 视频:`title + desc + tags`
404 - 图文:`title + note + tags`
405 - 小红书补齐 CLI 与 skill
406 - 抖音、快手补齐 `desc` 能力,并统一图文正文字段为 `note`
407 - 实现保持轻量,不做过度封装
408
408 lines MARKDOWN