
Workrally
- 28 installs
- 74 repo stars
- Updated June 24, 2026
- tencent/workrally
Helps with ai & agent building tasks during AI-assisted development.
About
workrally is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- workrally
- AI & Agent Building
- AI-coding skill
Workrally by the numbers
- 28 all-time installs (skills.sh)
- +3 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #9,462 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/tencent/workrally --skill workrallyAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 28 |
|---|---|
| repo stars | ★ 74 |
| Last updated | June 24, 2026 |
| Repository | tencent/workrally ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
WorkRally CLI (workrally)
面向 AI Agent 的 AIGC 漫剧视频创作全流程命令行工具,封装 WorkRally 平台 30+ 核心能力,支持项目/剧集/场次的完整 CRUD、AI 生图/生视频、画布、资产库、媒资管理、文件上传等。
安装 & 配置
npm install -g workrally
# 配置 API Key(三选一)
workrally auth login # 交互式登录(推荐)
workrally auth login --token <YOUR_API_KEY> # 命令行传入
export WORKRALLY_API_KEY=<YOUR_API_KEY> # 环境变量(仅推荐 CI/CD,Agent/子进程可能读不到 shell 配置)
# ↑ auth login 自动将 Token 写入配置文件:
# 若 WORKRALLY_CONFIG_DIR 已设置 → $WORKRALLY_CONFIG_DIR/config.json
# 否则 → ~/.workrally/config.json
workrally auth status # 验证登录状态API Key 申请:龙虾配置
命令速查
# === 项目(project)— list / get / create / update(软删除无子命令,见下) ===
workrally project list [--search "关键词"] # 列出/搜索项目
workrally project get <id> # 项目详情
workrally project create "项目名" # 创建项目
workrally project update <id> --name "新名称" # 更新项目
workrally tools call project_delete --json-args '{"project_id":"<id>"}' # 软删除单个项目(→回收站)
# 批量:workrally tools describe project_delete # 使用 project_ids 数组
# === 剧集(series)— 全新命令组(CRUD 完整) ===
workrally series list --project-id <id> # 剧集列表
workrally series get <series_id> --project-id <id> # 剧集详情
workrally series create --project-id <id> --name "第一集" # 创建剧集
workrally series update <series_id> --project-id <id> --name "新名称" # 更新剧集
workrally series delete <ids...> # 软删除(→回收站)
# === 场次(shot/story)— 短番制作核心单元 ===
# --- CRUD 五件套 ---
workrally shot list --series-id <id> # 场次列表
workrally shot get <story_id> # 场次详情
workrally shot create --series-id <id> --json-list '[{"image_prompt":"..."}]' # 批量创建
workrally shot update <story_id> --image-prompt "..." --animation-prompt "..." # 单条更新
workrally shot update <story_id> --story-num "EP01-SC01" # 单条改名(story_num)
workrally shot update --batch '[{"story_id":"...","image_prompt":"..."}]' # 批量更新
workrally shot delete <story_ids...> # 软删除(→回收站)
# --- 业务语义糖(CRUD 之外)---
workrally shot sort --series-id <id> --order id1,id2,id3 # 重排
workrally shot image-models # ⭐ 场次专用图片模型(≠ canvas)
workrally shot video-models # ⭐ 场次专用视频模型(固定 mode=9)
workrally shot set-model [--story-ids id1,id2] --video-provider 1 --duration 5 --aspect-ratio 16:9 # 配置视频模型(推荐)
workrally shot set-model [--story-ids id1,id2] --image-model <en_name> --aspect-ratio 16:9 # 配置图片模型
workrally shot bind --story-id <id> --type image --assets '[{...}]' # 绑定参考资产
workrally shot recognize --project-id <id> --series-id <id> [--scope all|project] # 识别角色
workrally shot generate-image --story-ids id1,id2 [--count N] # 仅提交;无 --poll/--model;查结果 shot get-result --type image [--watch]
workrally shot generate-video --story-ids id1,id2 [--count N] # 同上;--type video。无 --model/duration/ratio/--poll
# === 上传 / 下载 ===
workrally upload ./file.png -o json # 上传文件 (COS SDK 直传)
workrally download <asset_id> [-d ./output/] # 下载素材 (自动处理访问凭证)
# === AI 生图 ===
workrally generate image-models # 查看可用模型(必须先调用!)
workrally generate image --prompt "描述" --model <model_id> [--aspect-ratio 16:9] [--input-images "url"] --poll
# === AI 生视频 (4 种驱动模式) ===
workrally generate video-models # 查看可用模型(必须先调用!)
workrally generate video --prompt "描述" --model <provider_id> --poll # 纯文生视频(默认 Text 模式)
workrally generate video --prompt "描述" --model <provider_id> --single-image-url "url" --poll # 图生视频(Text 模式 + 参考图)
workrally generate video --mode FirstLastFrame --prompt "描述" --model <provider_id> --first-frame-url "url" --poll # 首尾帧
# 其他模式: FrameSequence(--sequence-frames) SubjectToVideo(--reference-assets)
# --mode 默认 Text;通用选项: --duration <秒> --count 1-4 --enable-sound --poll
# === 媒资库 (asset) — 项目级媒体文件池 ===
workrally asset create --url <cdn_url> --project-id <id> -o json # 入库(返回可访问 URL)
workrally asset search --project-id <id> # 搜索
workrally asset get <asset_id> # 详情
workrally asset update <asset_id> --name "新名称" # 更新素材 (目前仅支持改名)
# === 资产库 (material) — 树形管理:人物/道具/场景/网盘 ===
workrally material list role_person # 人物 | role_prop 道具 | role_scene 场景 | root 网盘文件夹
workrally material add ... # 创建素材/文件夹(从媒资库挂载)
workrally material get <material_id> # 素材详情
workrally role get <role_id> # 角色详情(LoRA/提示词/版本)
# === 画布 ===
workrally canvas list # 列出画布
workrally canvas create "名称" # 创建画布
workrally canvas build-draft <canvas_id> --file nodes.json # 增量合并(默认保留已有节点)
workrally canvas build-draft <canvas_id> --nodes '[...]' # 同上,直接传 JSON
workrally canvas build-draft <canvas_id> -d "id1,id2" # 删除指定节点
workrally canvas build-draft <canvas_id> -n '[...]' -d "old1" # 同时增删改
workrally canvas build-draft <canvas_id> -n '[...]' --mode overwrite # 全量覆盖(清空后重建)
# === 任务查询 ===
workrally generate task <task_id> [--poll] # 查询/轮询生成任务状态
# === 通用透传(调用任意 MCP 工具)===
workrally tools list # 列出所有工具
workrally tools describe <tool_name> # 查看参数 schema
workrally tools call <tool_name> --arg key=value [--json-args '{}']
# === URL / 升级 ===
workrally url build "页面名" [--params '{}'] # 构建 WorkRally 前端链接
workrally url parse <url> # 解析 URL
workrally upgrade [--check] # 升级 / 仅检查输出格式: -o json(默认, Agent 推荐) | -o table(人类阅读) | -o text(管道/脚本) | workrally config set output_format <fmt>
关键工作流:上传文件
概念:媒资库(asset) = 项目级文件池;资产库(material) = 树形目录(人物/道具/场景/网盘文件夹)。资产库的素材只能从媒资库挂载。
# 步骤 1: 上传 → CDN URL
workrally upload ./character.png -o json
# 步骤 2: 入媒资库(必须!返回 asset_id + asset_details)
workrally asset create --url <cdn_url> --project-id <project_id> -o json
# 步骤 3(按需): 挂载到资产库(必传 asset_id + 完整 asset_details)
workrally material add --json-list '[{"material_id":"<asset_id>","material_name":"名称","material_type":2,"parent_id":"<target_id>","material_detail":<asset_details_json>}]' \
--project-ids <project_id>步骤 1→2 强制绑定,上传后必须入媒资库。视频/音频为私有读,需经媒资库才能正常访问。
>
步骤 3 由 Agent 判断:"上传文件" → 两步 | "上传到角色/道具/场景/文件夹" → 三步 | "媒资素材添加到资产库" → 仅步骤 3
关键工作流:场次创作
⚠️ 重要规则
1. 前端链接必须用 `workrally url build` 生成,严禁自行拼接 URL 2. 模型 ID 必须动态获取:image-models / video-models,严禁猜测或硬编码 3. `canvas` ≠ `project`:画布用 canvas,项目用 project,两者 ID 不能互换 4. `build-draft` 实时协同:写入后所有在线用户立即看到变更,默认增量合并(只传变更节点),支持多人并发安全操作 5. `build-draft` 节点校验:8种节点类型各有必填字段,详见 `canvas-guide.md` 6. AI 生成自动占位:generate image/video 传入 --project-id(画布ID)后自动在画布创建占位节点,无需再手动 build-draft 7. 素材命名:--name 传入"画布名_素材特征"(画布场景)或 prompt 关键词(非画布场景) 8. 不确定参数时用 --help 或 tools describe 自行探索 9. URL 白名单:所有 URL 类参数(生图/生视频的 --*-url / --*-assets / --*-images、asset create --url 等)仅接受 WorkRally 官方媒资 URL。合法来源:① workrally upload 返回值 ② asset get/search 返回值(可直接传入) ③ 用户已提供的官方 URL。本地文件或第三方 URL 必须先 workrally upload。如遇"非法或已过期"提示,通过 asset get/search 重新获取即可。
📚 深度指南 (references/)
本 Skill 附带详细参考文档,覆盖复杂工作流:
| 文档 | 内容 |
|---|---|
| `references/shot-guide.md` | 场次操作 — CRUD/排序、提示词、模型、生成与结果;§9 场次创作工作流与专项规则(原 SKILL 正文迁入) |
| `references/canvas-guide.md` | 无限画布操作 — 8种节点类型、画板嵌套、build-draft 增量/覆盖模式、协同编辑 |
| `references/upload-and-assets-guide.md` | 上传与素材管理 — 三步上传流程、媒资库 vs 资产库、树形目录操作 |
| `references/ai-generation-guide.md` | AI 生成 — Kontext 生图、4种视频驱动模式、模型动态获取、任务轮询 |
| `references/common-pitfalls.md` | 常见易错点 — 项目/画布混淆、模型硬编码、上传缺步骤等10类典型错误 |
遇到画布、上传、AI生成相关的复杂操作时,请优先查阅对应的参考文档。
环境变量
WORKRALLY_API_KEY— API Key (Bearer Token)WORKRALLY_ENDPOINT— API 端点 (默认https://workrally.qq.com/zenstudio/api/mcp)WORKRALLY_CONFIG_DIR— 配置文件目录 (默认~/.workrally,非持久化容器建议指向持久卷)WORKRALLY_NO_UPDATE_CHECK=1— 禁用自动版本检查 (CI/CD 推荐)
Tencent is pleased to support the open source community by making workrally available.
Copyright (C) 2026 Tencent. All rights reserved.
workrally is licensed under the MIT-0.
Terms of the MIT-0:
--------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.WorkRally CLI — Agent Skill
🎬 面向 AI Agent 的 AIGC 漫剧视频创作全流程工具集。
本目录是 WorkRally CLI 的 Agent Skill 定义。
目录结构
skill/
├── SKILL.md ← Skill 入口(元数据 + 指令),ClawHub 解析此文件
└── references/ ← 深度参考文档,AI Agent 按需加载
├── canvas-guide.md 无限画布操作指南
├── upload-and-assets-guide.md 上传与素材管理指南
├── ai-generation-guide.md AI 生成指南
└── common-pitfalls.md 常见易错点核心能力
- AI 生图 — Kontext 模型,支持多参考图
- AI 生视频 — 4 种驱动模式(文本/首尾帧/序列帧/参考主体)
- 无限画布 — Yjs 协同编辑,8 种节点类型,实时同步
- 项目 & 媒资管理 — 项目 CRUD、素材上传入库、资产库树形管理
- 通用透传 — 可调用 WorkRally MCP Server 全部工具
第三方商店
快速开始
npm install -g workrally
workrally auth login
workrally auth status详细用法、命令速查、工作流指南请参阅 [SKILL.md](./SKILL.md)。
AI 生成指南(图片 & 视频)
本文档帮助 AI Agent 正确使用 WorkRally 的 AI 图片/视频生成能力。
---
1. 核心规则
⚠️ 模型 ID 必须动态获取,严禁猜测或硬编码!
模型列表是动态下发的,不同环境(开发/预发/正式)的可用模型可能完全不同。
🔒 所有 URL 类参数仅接受 WorkRally 官方媒资 URL,详见 SKILL.md 规则 9。
# 生图前必须先获取模型列表
workrally generate image-models -o json
# 生视频前必须先获取模型配置
workrally generate video-models -o json---
2. 图片生成 (Kontext)
2.1 获取可用模型
workrally generate image-models -o json返回包含:
models[]— 每个模型的model_id、name、support_resolutions、kontext_configaspect_ratios[]— 全局可用宽高比列表(如 "1:1", "16:9", "9:16" 等)resolutions[]— 所有模型支持的分辨率并集count_options[]— 可选的生成数量
关键字段:
model_id→ 传给--model参数kontext_config.max_input_images→ 该模型允许的最大参考图数量(不同模型不同,不要写死)support_resolutions→ 该模型支持的分辨率列表
2.2 纯文生图
workrally generate image \
--prompt "一只橘猫坐在樱花树下" \
--model <model_id> \
--aspect-ratio 16:9 \
--poll2.3 参考图生图
通过 --input-images 传入参考主体图片 URL,在 prompt 中用 "第一张图片"、"第二张图片" 引用:
workrally generate image \
--prompt "第一张图片趴在第二张图片路中间" \
--model <model_id> \
--input-images "https://cat.png,https://shrine.png" \
--poll📌--input-images的最大数量取决于模型配置中的kontext_config.max_input_images,不要写死。
📌 只允许图片类型的素材作为参考图。
2.4 在画布中生图
workrally generate image \
--prompt "描述" \
--model <model_id> \
--project-id <画布ID> \
--poll传入 --project-id(画布 ID)后:
- 系统会自动在画布中创建 running 状态的占位节点(橙色边框 + 进度条)
- 无需再手动调用
build-draft放置生成器节点 - 生成完成后,前端自动更新节点状态
⚠️--project-id此处是画布 ID(通过canvas list获取),不是项目 ID!
2.5 参数说明
| 参数 | 必填 | 默认值 | 说明 |
|---|---|---|---|
--prompt | ✅ | — | 图片描述 |
--model | ✅ | — | 模型 ID(从 image-models 获取) |
--aspect-ratio | — | 16:9 | 宽高比 |
--resolution | — | 0 | 分辨率等级: 0=1K, 1=2K, 2=4K(各模型支持范围不同,以 image-models 返回的 kontext_config.support_resolutions 为准) |
--count | — | 1 | 生成数量 1-4(后端一个任务生成 1 张,count>1 会并发发起 N 个独立任务并返回 task_ids 数组) |
--input-images | — | — | 参考图 URL(逗号分隔) |
--project-id | — | — | 画布 ID(传入后自动创建占位节点) |
--short-series-project-id | — | — | 项目 ID |
--name | — | — | 素材名称 |
--poll | — | false | 自动轮询直到完成 |
--poll-interval | — | 3 | 轮询间隔(秒) |
---
3. 视频生成
3.1 获取可用模型配置
workrally generate video-models -o json返回按驱动模式分组:
text_providers[]— Text(单图/纯文)模式first_last_frame_providers[]— 首尾帧模式frame_sequence_providers[]— 序列帧模式subject_to_video_providers[]— 参考主体模式
每个模型包含:
provider→ 传给--model参数label— 模型显示名称duration_options[]— 可用时长列表(秒)can_upload_image/video/audio— 支持的输入类型max_image_count/video_count/audio_count— 各类型最大数量support_audio— 是否支持音效
3.2 四种驱动模式
Text 模式(默认)— 纯文生视频 / 单图驱动
# 纯文生视频(不传图片)
workrally generate video \
--prompt "夕阳下海浪拍打沙滩" \
--model <provider_id> \
--poll
# 图生视频(传入参考图)
workrally generate video \
--prompt "图片中的角色缓缓转身" \
--model <provider_id> \
--single-image-url "https://example.com/character.png" \
--pollFirstLastFrame 模式 — 首尾帧驱动
workrally generate video \
--mode FirstLastFrame \
--prompt "角色从左走到右" \
--model <provider_id> \
--first-frame-url "https://example.com/start.png" \
--last-frame-url "https://example.com/end.png" \
--poll可以只传首帧或只传尾帧(至少一个)。
FrameSequence 模式 — 序列帧驱动
workrally generate video \
--mode FrameSequence \
--prompt "连贯的动画过渡" \
--model <provider_id> \
--sequence-frames '[{"url":"https://frame1.png","timestamp":0},{"url":"https://frame2.png","timestamp":2}]' \
--pollSubjectToVideo 模式 — 参考主体驱动
workrally generate video \
--mode SubjectToVideo \
--prompt "角色在场景中行走" \
--model <provider_id> \
--reference-assets '[{"type":"image","url":"https://character.png"},{"type":"video","url":"https://bg.mp4"}]' \
--poll3.3 通用选项
| 参数 | 必填 | 默认值 | 说明 |
|---|---|---|---|
--prompt | ✅ | — | 动画描述 |
--model | ✅ | — | Provider ID(从 video-models 获取) |
--mode | — | Text | 驱动模式: Text/FirstLastFrame/FrameSequence/SubjectToVideo |
--duration | — | — | 视频时长(秒),可选值取决于模型 |
--count | — | 1 | 生成数量 1-4(后端一个任务生成 1 个视频,count>1 会并发发起 N 个独立任务并返回 task_ids 数组) |
--enable-sound | — | false | 生成音效(仅部分模型支持) |
--project-id | — | — | 画布 ID(传入后自动创建占位节点) |
--short-series-project-id | — | — | 项目 ID |
--name | — | — | 素材名称 |
--poll | — | false | 自动轮询直到完成 |
--poll-interval | — | 5 | 轮询间隔(秒) |
3.4 在画布中生视频
与生图类似,传入 --project-id(画布 ID)即可自动创建占位:
workrally generate video \
--prompt "海浪翻涌" \
--model <provider_id> \
--project-id <画布ID> \
--poll---
4. 任务轮询
4.1 使用 --poll 自动轮询(推荐)
workrally generate image --prompt "..." --model <id> --poll使用 --poll 后,CLI 自动: 1. 提交生成任务 2. 每隔 N 秒查询状态(默认3秒/图片,5秒/视频) 3. 显示进度条和状态(排队中/运行中/成功/失败) 4. 完成后输出最终结果
4.2 手动查询任务
# 单次查询
workrally generate task <task_id> -o json
# 手动轮询
workrally generate task <task_id> --poll4.3 任务状态
| state | 含义 | 说明 |
|---|---|---|
| 1 | 排队中 (QUEUED) | 等待资源 |
| 2 | 运行中 (RUNNING) | 正在生成 |
| 3 | 暂停 (PAUSED) | 暂停中 |
| 4 | 成功 (SUCCESS) | output_products 包含结果 |
| 5 | 失败 (FAILED) | error_message 包含错误信息 |
| 6 | 已取消 (CANCELLED) | 用户取消 |
4.4 多任务并发
后端「一个任务只生成 1 个素材」,当 --count > 1 时,CLI 会并发发起 N 个独立任务,返回的 task_ids 是长度为 N 的数组,每个 task 产出 1 个素材。使用 --poll 时 CLI 会自动并发轮询所有任务,总耗时约等于单任务耗时。
---
5. 素材命名最佳实践
画布内生成
使用 --name 传入"画布名称_素材特征":
# 先获取画布名称
workrally canvas get <canvas_id> -o json
# 生成时传入有意义的名称
workrally generate image --prompt "蓝色运动鞋" --model <id> --project-id <canvas_id> \
--name "产品设计画布_蓝色运动鞋" --poll非画布生成
从 prompt 中提取核心关键词作为名称:
workrally generate image --prompt "一只可爱的橘猫在夕阳下奔跑" --model <id> \
--name "橘猫_夕阳奔跑" --poll---
6. 生成后素材处理
AI 生成的图片/视频会自动入库到媒资系统(后台自动完成,无需额外调用 asset create)。
如果需要上传到资产库
# 1. 生成完成后,从结果中获取 asset_id
# 2. 获取 asset_details
workrally asset get <asset_id> -o json
# 3. 挂载到资产库
workrally material add --json-list '[{"material_id":"<asset_id>","material_name":"角色名","material_type":2,"parent_id":"<role_condition_id>","material_detail":<asset_details>}]' \
--project-ids <project_id>如果需要在画布上展示
传入 --project-id 即可,系统自动处理。无需手动调用 build-draft。
无限画布操作指南
本文档帮助 AI Agent 正确操作 WorkRally 无限画布(Infinite Canvas)。画布基于 Yjs 协同编辑引擎,CLI 写入的内容会实时同步给所有在线用户,无需刷新页面。
---
1. 核心概念
两种"项目"(容易混淆,务必区分)
| 概念 | 管理命令 | 用途 | 必要性 |
|---|---|---|---|
| 项目 (project) | workrally project list/create/get | 所有素材都必须归属一个项目,范围更大 | 必须 — 素材不关联项目则在 web 端不可见 |
| 画布 (canvas) | workrally canvas list/create/get | 无限画布空间,可在其中排布节点 | 可选 — 仅当用户要在画布中操作时才需要 |
⚠️ 两者的 ID 不能互相替代!
- workrally project list 返回的是项目 ID- workrally canvas list 返回的是画布 ID- 在画布场景下,素材需要同时关联两者
判断用户意图
| 用户说 | 含义 | 使用命令 |
|---|---|---|
| "我的项目"、"项目列表" | 项目 | workrally project list |
| "我的画布"、"画布列表" | 无限画布 | workrally canvas list |
| "在画布上生成图片" | 画布 + AI 生成 | workrally generate image --project-id <画布ID> |
| "上传到项目" | 仅入媒资库 | upload → asset create |
| "在画布上展示素材" | 需要 build-draft | upload → asset create → canvas build-draft |
---
2. 画布节点类型 (8 种)
类型一览
| type | 说明 | 必填 data 字段 | 可放入画板 |
|---|---|---|---|
image | 图片素材 | data.asset.id (已有素材) 或 data.task (生成中占位) | ✅ |
video | 视频素材 | data.asset.id 或 data.task | ✅ |
audio | 音频素材 | data.asset.id (必须,音频无生成器) | ✅ |
imageGenerator | 图片生成器 | 无必填(params 可选) | ❌ |
videoGenerator | 视频生成器 | 无必填(params 可选) | ❌ |
artboard | 画板容器 | 无(建议设置 style.width/height) | ❌ (画板不可嵌套) |
text | 文本 | data.text.content (字符串,最大2000字符) | ❌ |
freehand | 画笔涂鸦 | data.freehand.points + data.freehand.initialSize | ❌ |
节点通用结构
{
"id": "node_unique_id",
"type": "image",
"position": { "x": 100, "y": 200 },
"data": { },
"style": { "width": 512, "height": 512 },
"parentId": "artboard_id",
"measured": { "width": 512, "height": 512 }
}字段说明:
id— 节点唯一标识,可使用任意唯一字符串position— 节点左上角坐标(缺失时堆叠在原点 0,0)style— 节点显示尺寸parentId— 仅画板内子节点需要,指向父画板的 idmeasured— 渲染尺寸,可选,缺失时服务端自动补全
---
3. 各节点类型详细说明
3.1 图片/视频节点 (image / video)
两种来源: 1. 已有素材 — 必须有 data.asset.id 2. 生成中占位 — 必须有 data.task(由 AI 生成命令自动创建,通常不需要手动构造)
{
"id": "img_001",
"type": "image",
"position": { "x": 0, "y": 0 },
"data": {
"asset": { "id": "asset_abc123" }
},
"style": { "width": 512, "height": 512 }
}带生成任务标记的节点(用于"再次编辑"功能):
{
"id": "gen_img_001",
"type": "image",
"position": { "x": 0, "y": 0 },
"data": {
"asset": { "id": "asset_abc123" },
"task": { "taskId": "task_xyz789", "status": "success" }
},
"style": { "width": 512, "height": 512 }
}💡 data.task 字段决定前端是否显示"再次编辑"按钮。AI 生成的图片/视频应包含此字段。3.2 音频节点 (audio)
音频没有生成器,不支持 task 占位,必须有 data.asset.id。
{
"id": "audio_001",
"type": "audio",
"position": { "x": 0, "y": 0 },
"data": {
"asset": { "id": "asset_audio_456" }
},
"style": { "width": 260, "height": 80 }
}建议尺寸 260×80(与前端默认一致)。
3.3 画板节点 (artboard)
画板是容器,子节点通过 parentId 关联到画板。
{
"id": "board_001",
"type": "artboard",
"position": { "x": 0, "y": 0 },
"data": {},
"style": { "width": 600, "height": 800 }
}画板子节点示例 — 在画板内放置一张图片:
{
"id": "img_in_board",
"type": "image",
"position": { "x": 20, "y": 20 },
"data": { "asset": { "id": "asset_abc123" } },
"style": { "width": 256, "height": 256 },
"parentId": "board_001"
}画板规则:
- ✅
image、video、audio可以放入画板 - ❌
imageGenerator、videoGenerator、text、freehand不可放入画板 - ❌ 画板不可嵌套(画板内不能放画板)
- ❌ 不要设置 `extent: "parent"`,否则子节点会被锁定在画板内无法拖出
- 画板缺少尺寸时自动补全为 600×800
3.4 文本节点 (text)
{
"id": "text_001",
"type": "text",
"position": { "x": 0, "y": 0 },
"data": {
"text": {
"content": "这是一段文本",
"fontSize": 24,
"fontWeight": 400,
"textAlign": "left",
"color": "#ffffff"
}
},
"style": { "width": 200 }
}必填: data.text.content(字符串,最大2000字符) 可选(有默认值): fontSize(24), fontWeight(400, 加粗用700), textAlign("left"), color("#ffffff") 建议设置 style.width(默认200)。
3.5 画笔涂鸦节点 (freehand)
{
"id": "freehand_001",
"type": "freehand",
"position": { "x": 0, "y": 0 },
"data": {
"freehand": {
"points": [[10, 20, 0.5], [30, 40, 0.7], [50, 60, 0.5]],
"initialSize": { "width": 200, "height": 200 },
"color": "rgba(242,72,34,1)",
"size": 7
}
}
}必填: data.freehand.points(二维数组,每个点为 [x, y, pressure])、data.freehand.initialSize({width, height}) 可选: color(默认红色 rgba(242,72,34,1))、size(画笔粗细 1-100,默认7) pressure 值范围 0-1,超出自动截断。
3.6 生成器节点 (imageGenerator / videoGenerator)
⚠️ 通常不需要手动创建! workrally generate image/video --project-id <画布ID> 会自动在画布中创建 running 状态的占位节点。仅在极特殊场景(如手动构建已完成的生成器节点)才需要:
{
"id": "gen_001",
"type": "imageGenerator",
"position": { "x": 0, "y": 0 },
"data": {
"task": { "taskId": "task_abc", "status": "success" },
"params": {}
},
"style": { "width": 512, "height": 512 }
}---
4. build-draft 操作模式
4.1 增量合并(默认模式)
workrally canvas build-draft <canvas_id> --nodes '[...]'规则:
- 同 id → 覆盖更新:传入的节点 id 与已有节点相同时,用新数据替换旧数据
- 新 id → 追加:已有画布中不存在的 id 会被添加
- 未提及 → 保留:已有节点不在传入列表中的,原样保留
4.2 删除节点
workrally canvas build-draft <canvas_id> --delete-node-ids "id1,id2"可与 --nodes 同时使用(先删除,再合并新节点):
workrally canvas build-draft <canvas_id> --nodes '[...]' --delete-node-ids "old1,old2"4.3 全量覆盖
workrally canvas build-draft <canvas_id> --nodes '[...]' --mode overwrite清空画布后仅保留传入的节点。传 --nodes '[]' --mode overwrite 可清空整个画布。
⚠️ 全量覆盖会删除所有已有节点,包括其他用户的内容。在多人协作场景下应优先使用增量合并。
4.4 从文件加载节点
workrally canvas build-draft <canvas_id> --file nodes.json适合节点数据量大或结构复杂的场景。
---
5. 常见工作流示例
场景 A:在画布上排列已有素材
# 1. 搜索项目中的素材
workrally asset search --project-id <project_id> -o json
# 2. 从搜索结果中获取 asset_id,构建节点写入画布
workrally canvas build-draft <canvas_id> --nodes '[
{"id":"n1","type":"image","position":{"x":0,"y":0},"data":{"asset":{"id":"<asset_id_1>"}},"style":{"width":512,"height":512}},
{"id":"n2","type":"image","position":{"x":600,"y":0},"data":{"asset":{"id":"<asset_id_2>"}},"style":{"width":512,"height":512}}
]'场景 B:创建画板并放入多张图片
workrally canvas build-draft <canvas_id> --nodes '[
{"id":"board","type":"artboard","position":{"x":0,"y":0},"data":{},"style":{"width":800,"height":600}},
{"id":"img1","type":"image","position":{"x":20,"y":20},"data":{"asset":{"id":"<id1>"}},"style":{"width":350,"height":250},"parentId":"board"},
{"id":"img2","type":"image","position":{"x":420,"y":20},"data":{"asset":{"id":"<id2>"}},"style":{"width":350,"height":250},"parentId":"board"}
]'场景 C:更新画布中某个节点的位置
# 只传需要修改的节点,其他节点自动保留
workrally canvas build-draft <canvas_id> --nodes '[
{"id":"existing_node_id","type":"image","position":{"x":300,"y":400},"data":{"asset":{"id":"<asset_id>"}},"style":{"width":512,"height":512}}
]'场景 D:删除部分节点并添加新节点
workrally canvas build-draft <canvas_id> \
--nodes '[{"id":"new1","type":"text","position":{"x":0,"y":0},"data":{"text":{"content":"新标题","fontSize":48,"fontWeight":700,"color":"#00ff00"}},"style":{"width":400}}]' \
--delete-node-ids "old_node_1,old_node_2"---
6. 服务端自动修正
服务端会对传入的节点进行以下自动修正(不需要 Agent 操心):
| 场景 | 自动行为 |
|---|---|
| 画板缺少 style | 补全 600×800 |
| 文本节点缺少样式属性 | 补全 fontSize=24, fontWeight=400, textAlign=left, color=#ffffff |
| 文本节点缺少 style.width | 补全 200 |
| 文本内容为空 | 填充"在此输入文本" |
| 画笔节点缺少颜色/大小 | 补全 color=rgba(242,72,34,1), size=7 |
| 画笔 size 超出范围 | 截断到 1-100 |
| 画笔 pressure 超出范围 | 截断到 0-1 |
| 子节点设置了 extent | 自动清除(防止锁定) |
但以下关键字段缺失会被拒绝:
| 场景 | 错误 |
|---|---|
| image/video 既没有 asset.id 也没有 task | ❌ 空节点 |
| audio 没有 asset.id | ❌ 音频无生成器 |
| text 没有 data.text.content 或类型非字符串 | ❌ |
| text 内容超过 2000 字符 | ❌ |
| freehand 缺少 points 或 initialSize | ❌ |
| 不允许的节点类型(如 group) | ❌ |
| 画板子节点类型不是 image/video/audio | ❌ |
常见问题与易错点
本文档汇总 AI Agent 使用 WorkRally CLI 时最容易犯的错误和混淆点,帮助避免常见陷阱。
---
❌ 错误 1:混淆"项目"和"画布"
问题
# ❌ 错误:把项目 ID 当画布 ID 用
workrally generate image --prompt "..." --model <id> --project-id <project_list返回的ID>正确做法
# ✅ 先获取画布 ID
workrally canvas list -o json
# 再传画布 ID
workrally generate image --prompt "..." --model <id> --project-id <canvas_list返回的canvas_id>区分规则
| 获取方式 | 返回的是 | 传给谁 |
|---|---|---|
workrally project list | 项目 ID | asset create --project-id、asset search --project-id |
workrally canvas list | 画布 ID | generate image --project-id、generate video --project-id、canvas build-draft |
---
❌ 错误 2:硬编码模型 ID
问题
# ❌ 错误:猜测或硬编码模型 ID
workrally generate image --prompt "..." --model "kontext_v2"正确做法
# ✅ 动态获取
workrally generate image-models -o json
# 从返回结果中读取 model_id
workrally generate image --prompt "..." --model <从返回结果中获取的model_id>模型列表是动态下发的,不同环境的可用模型可能完全不同。
---
❌ 错误 3:自行拼接前端 URL
问题
# ❌ 错误:自己拼接 URL(域名和路由因环境而异)
echo "https://workrally.qq.com/workrally/toolbox/canvas/abc123"正确做法
# ✅ 使用 url build 命令
workrally url build "无限画布" --params '{"id":"abc123"}'---
❌ 错误 4:生成后手动调用 build-draft
问题
# ❌ 不必要:在画布中生成图片后,又手动创建节点
workrally generate image --prompt "..." --model <id> --project-id <canvas_id> --poll
# 然后又调用 build-draft 创建节点 ← 多余操作
workrally canvas build-draft <canvas_id> --nodes '[...]'正确理解
传入 --project-id 后,系统自动在画布创建 running 状态的占位节点。无需手动 build-draft。
build-draft 的正确使用场景
- 在画布上放置已有素材(非 AI 生成的图片/视频/音频)
- 管理画板布局(创建画板、调整子节点位置)
- 添加文本或涂鸦节点
- 删除画布上的节点
- 重新排列已有节点
---
❌ 错误 5:上传素材缺少入库步骤
问题
# ❌ 错误:上传后直接使用 CDN URL
workrally upload ./file.png -o json
# 然后直接把 cdn_url 作为 asset_id 用 ← 这不是 asset_id!正确做法
# ✅ 上传后必须入媒资库
workrally upload ./file.png -o json
workrally asset create --url <cdn_url> --project-id <project_id> -o json
# 现在才有 asset_id上传只是把文件传到 CDN,必须调用 asset create 入库才能被系统使用。---
❌ 错误 6:资产库挂载缺少关键字段
问题
# ❌ 错误:JSON 中缺少 material_id 或 material_detail
workrally material add --json-list '[{"material_name":"素材","material_type":2,"parent_id":"role_person"}]'
# 素材不会在资产库列表中显示!正确做法
# ✅ 必须在 JSON 中传 material_id(=asset_id)和完整的 material_detail(=asset_details)
workrally material add --json-list '[{
"material_id": "<asset_id>",
"material_name": "素材名",
"material_type": 2,
"parent_id": "<parent_id>",
"material_detail": <完整的 asset_details 对象>
}]' --project-ids <project_id>---
❌ 错误 7:画板内放入不允许的节点类型
问题
# ❌ 错误:把文本节点放入画板
workrally canvas build-draft <id> --nodes '[
{"id":"board","type":"artboard","position":{"x":0,"y":0},"data":{},"style":{"width":600,"height":800}},
{"id":"txt","type":"text","position":{"x":20,"y":20},"data":{"text":{"content":"标题"}},"parentId":"board"}
]'
# 服务端会拒绝!正确理解
画板只接受 image、video、audio 类型的子节点。
---
❌ 错误 8:给画板子节点设置 extent
问题
{
"id": "img1",
"type": "image",
"parentId": "board",
"extent": "parent"
}后果
子节点被 ReactFlow 锁定在画板内,用户无法拖出。服务端会自动清除此属性,但不要主动设置。
---
❌ 错误 9:混淆 material_id 和 role_id
问题
# ❌ 错误:用 material_id 查角色详情
workrally role get "abc_0"
# material_id 格式: "abc_0" (带后缀)
# role_id 格式: "abc" (不带后缀)正确做法
# ✅ 先获取 role_id
workrally material get "abc_0" -o json
# 从返回结果中找到 role_id 字段
workrally role get "abc" -o json---
❌ 错误 10:音视频 URL 使用 original_url
问题
# ❌ 错误:音视频使用 original_url(不含访问凭证)
# original_url 是原始 CDN 路径,音视频无法直接访问正确做法
始终使用 url 或 download_url,这些是可直接访问的临时 URL。过期后通过 asset get 重新获取即可,返回的新 URL 可直接作为其他工具的 URL 参数传入。
---
常见判断速查表
| 场景 | 需要什么 |
|---|---|
| "上传一张图片" | upload → asset create (2步) |
| "上传到人物角色" | upload → asset create → material add (3步) |
| "在画布上生成图片" | generate image --project-id <画布ID> --poll (1步) |
| "把已有图片放到画布上" | asset search → canvas build-draft |
| "生成4张图片" | generate image --count 4 --poll |
| "查看生成进度" | generate task <task_id> --poll |
| "创建一个画板放三张图" | canvas build-draft (一次传画板+3个子节点) |
| "删除画布上的某个节点" | canvas build-draft --delete-node-ids "node_id" |
| "清空整个画布" | canvas build-draft --nodes '[]' --mode overwrite |
| "查看角色的 LoRA 版本" | material get → role get |
| "搜索项目中的视频素材" | asset search --project-id <id> |
---
通用工具透传
当高级封装命令无法满足需求时,使用通用透传直接调用任何 MCP 工具:
# 列出所有可用工具
workrally tools list -o json
# 查看某个工具的参数 schema
workrally tools describe <tool_name>
# 直接调用(适合复杂参数场景)
workrally tools call <tool_name> --json-args '{"key":"value"}'---
输出格式建议
| 格式 | 用途 | 命令 |
|---|---|---|
json | Agent 推荐 — 结构化数据便于解析 | -o json |
table | 人类阅读 — 表格格式 | -o table |
text | 管道/脚本 — 纯文本 | -o text |
设置全局默认格式:
workrally config set output_format json场次操作指南
本文档帮助 AI Agent 通过 workrally shot / workrally series 命令完成场次的全生命周期管理。
---
1. 概念图谱
项目 (project)
└─ 剧集 (series)
└─ 场次 (shot/story) ← 本文档主角
├─ ⭐ 图片提示词 (image_prompt) ← 核心字段:决定关键帧画面
├─ ⭐ 视频提示词 (animation_prompt) ← 核心字段:决定动效/运镜
├─ 角色绑定 (role_data_json / video_role_data_json)
├─ 模型配置 (animation_model / animation_duration / image_model)
├─ 分镜 (layer) × N ← 本期 shot 命令族不封装图层操作;如需修改请用 `tools call layer_batch_*`
└─ [deprecated] 描述 (story_description) ← 已废弃,前端不再展示---
2. 标准工作流
2.1 从零搭建一个剧集
series create → shot create(带 image_prompt 和/或 animation_prompt)→ shot recognize → shot set-model → shot generate-image / generate-video --story-ids id1,id2,... → shot get-result --watch(按场次按类型分别拉结果)
# 1) 新建项目
PROJECT_ID=$(workrally project create "我的短番" -o json | jq -r '.project_id')
# 2) 新建剧集
SERIES_ID=$(workrally series create --project-id $PROJECT_ID --name "第一集" -o json | jq -r '.series_id')
# 3) 批量创建场次(按用户意图填提示词)
workrally shot create --series-id $SERIES_ID --json-list \
'[{"image_prompt":"古风庭院全景","animation_prompt":"镜头缓推"},
{"image_prompt":"两位侠客对峙","animation_prompt":"推近脸部特写"},
{"image_prompt":"日落远景","animation_prompt":"镜头慢慢拉远"}]'
# 4) 自动识别角色
workrally shot recognize --project-id $PROJECT_ID --series-id $SERIES_ID
# 5) 配置模型
workrally shot video-models -o json # 先动态获取场次专用视频模型
workrally shot set-model --series-id $SERIES_ID --video-provider <N> --duration 5 --aspect-ratio 16:9
# 6) 拿到全部场次 ID(用 -o json 拼成逗号串)后多场次一起发起生成
STORY_IDS=$(workrally shot list --series-id $SERIES_ID -o json \
| jq -r '[.story_list[].story_id] | join(",")')
workrally shot generate-image --story-ids "$STORY_IDS"
workrally shot generate-video --story-ids "$STORY_IDS"
# 7) 按场次 + 类型分别等结果(图片和视频是两条独立进度)
for sid in $(echo "$STORY_IDS" | tr ',' ' '); do
workrally shot get-result --story-id $sid --type image --watch
workrally shot get-result --story-id $sid --type video --watch
done2.2 把小说/剧本拆成场次
CLI 不内置"小说拆分"能力,由 Agent 自行:
1. 用 LLM 把小说按场景拆段 2. 根据用户意图按需生成提示词:
- 用户要漫画/插画 → 每个场次只写
image_prompt - 用户要短视频/动效 → 每个场次只写
animation_prompt - 用户要漫剧(图+视频)→ 两个都写
3. shot create --json-list '[{image_prompt}, {animation_prompt}, ...]' 一次入库 4. shot recognize 自动识别角色(按填的提示词路数:1 路或 2 路)
2.3 改写已有场次
# 改一个场次
workrally shot update <story_id> --image-prompt "..." --animation-prompt "..."
# 改一个场次的编号(单条改名)
workrally shot update <story_id> --story-num "EP01-SC01"
# 批量改多个场次(含批量改名:每条传 story_num 即可)
workrally shot update --batch \
'[{"story_id":"st_1","image_prompt":"水墨风格的古城"},
{"story_id":"st_2","animation_prompt":"运镜从近到远"},
{"story_id":"st_3","story_num":"EP01-SC03"}]'注意:CLI 写入的是文本字段;extra.image_prompt_json / extra.animation_prompt_json(lexical 富文本)由前端编辑器保存时同步。
---
3. 模型与时长配置
⚠️ 场次模型 ≠ 画布模型:场次用workrally shot image-models / video-models(专用接口),不是workrally generate image-models / video-models(那是画布的)。两者底层 schema 不同,不能混用。
# 必须先动态获取场次专用模型(严禁硬编码)
workrally shot image-models -o json # → 拿到 models[].en_name(图片模型)
workrally shot video-models -o json # → 拿到 models[].provider(视频 provider 数字,固定 mode=9)
# 全部场次统一配置(不传 --story-ids 时需要 --series-id 拉取全集)
workrally shot set-model --series-id <sid> --video-provider 1 --duration 5 --aspect-ratio 16:9 --enable-sound
# 部分场次覆盖
workrally shot set-model --story-ids st_1,st_2 --duration 103.1 字段说明
| 字段 | 来源 | 说明 |
|---|---|---|
--video-provider ⭐ | shot video-models 的 models[].provider 数字 | 推荐写法。CLI 自动拼成 "9,${provider}" 写入场次 animation_model 字段 |
--animation-model | 完整 "mode,provider" 字符串如 "9,1" | 高级用法,与 --video-provider 互斥 |
--duration | 模型的 models[].duration_options | 视频时长(秒) |
--image-model ⭐ | shot image-models 的 models[].en_name | 图片模型,如 kontext_pro |
--aspect-ratio | 模型的 models[].ratio_options | 视频/图片宽高比,CLI 同步拆成 generate_width/generate_height |
--enable-sound | 模型 models[].support_audio === true 才生效 | 音画直出 |
3.2 视频模型为何要 mode + provider 拼接?
场次的视频生成走 TvShortSeries.GenerateStoryAnimation,后端按 animation_model 字段(格式 "<mode>,<provider>")路由到具体的视频驱动算法。前端 useShotDuration 也按这个格式存储。
场次固定使用 `mode=9 (ANIMATION_SUBJECT_TO_VIDEO,参考主体生视频)` — 这是产品决策(场次模式天然依赖角色绑定+提示词驱动)。
CLI 的 --video-provider 是为这个场景做的语义糖:用户只需选 provider 数字,CLI 自动补上 mode=9。如果要走非 9 的模式(如首尾帧 mode=1),需用 --animation-model "1,N" 直传。
3.3 画布模型 vs 场次模型 — 速记表
| 维度 | canvas(画布) | shot(场次) |
|---|---|---|
| 列模型 | workrally generate image-models / video-models | workrally shot image-models / video-models |
| 图片模型 ID 字段 | model_id | en_name |
| 视频模型 ID 字段 | 单个 provider 字符串 | "mode,provider" 拼接,如 "9,1" |
| 调生成时是否传 model | 是(--model) | 否(用场次自身字段,先 set-model 写入) |
| 多场次/批量 | 在画布里独立任务 | --story-ids id1,id2,id3 一次触发多个 |
---
4. 资产识别(recognize)
# scope=project:仅本项目资产库(推荐,默认值)
workrally shot recognize --project-id <pid> --series-id <sid> --scope project
# scope=all:在全资产库中匹配
workrally shot recognize --project-id <pid> --series-id <sid> --scope all
# 仅识别部分场次
workrally shot recognize --project-id <pid> --series-id <sid> --story-ids st_1,st_2工具内部对每个场次执行:
1. 取 image_prompt / animation_prompt(不再读 story_description,已废弃) 2. 两次 MatchContentRole 并发请求(图片提示词 / 视频提示词) 3. 写回 role_data_json(图片提示词识别结果)/ video_role_data_json(视频提示词识别结果)
识别完成后,前端打开场次会自动显示绑定的角色 tag。
>
💡 两路独立:只填了image_prompt→ 仅识别图片侧角色;只填了animation_prompt→ 仅识别视频侧角色;两个都没填才整体跳过。
---
5. AI 生成与结果查询
⭐ 生成前必做:先shot get <story_id>确认场次的模型/时长/比例字段已配置;缺字段直接调generate-*后端会拒绝。
>
⚠️ 场次生成 ≠ 画布生成:shot generate-*调的是TvShortSeries.GenerateStoryAnimation,只表示"提交是否成功",不返回 task_id,不能用 `canvas_get_task` 轮询;进度归属于「场次 + 类型」维度,必须用shot get-result --story-id <id> --type image|video查。
5.1 三步流程(确认 → 配置 → 生成 → 查结果)
# Step 1: 检查场次字段是否齐全
workrally shot get <story_id> --project-id <pid> -o json
# 关注:
# 生图前:image_model(非空)/ image_generate_width / image_generate_height
# 生视频前:animation_model("9,N" 格式)/ animation_duration / generate_width / generate_height
# Step 2: 字段不全则先用 set-model 配置(先 image-models / video-models 拿可选项)
workrally shot image-models -o json # 选 en_name
workrally shot video-models -o json # 选 provider 数字
workrally shot set-model --story-ids <story_id> \
--image-model <en_name> --video-provider <N> --duration 5 --aspect-ratio 16:9
# Step 3: 触发生成(CLI 只接受 --story-ids + --count,不传 model/duration/ratio,也不传 project/series)
workrally shot generate-image --story-ids <story_id> --count 3
workrally shot generate-video --story-ids <story_id>
# Step 4: 按场次 + 类型分别查结果
workrally shot get-result --story-id <story_id> --type image # 单次拉一页
workrally shot get-result --story-id <story_id> --type image --watch # 持续轮询直到全部任务结束
workrally shot get-result --story-id <story_id> --type video --watch5.2 多场次并发生成
# 单场次生 3 张图(每场次 count 张 = 3 个后端任务)
workrally shot generate-image --story-ids st_1 --count 3
# 多场次一起生视频(每场次 1 个任务,handler 内部循环并发提交)
workrally shot generate-video --story-ids st_1,st_2,st_3
# 等结果:图片 / 视频是两条独立进度,需要按 story + type 分别 watch
for sid in st_1 st_2 st_3; do
workrally shot get-result --story-id $sid --type video --watch --interval 5
done💡shot generate-image / generate-video只接受 `--story-ids` + `--count`:下游GenerateStoryAnimation仅按story_id路由,不接受 `--project-id` / `--series-id`,也不接受--model / --duration / --aspect-ratio / --enable-sound等运行时参数(这些必须先用shot set-model写入场次字段)。这与 canvas 的generate image/video --model <id>行为有意区分(场次走持久化配置)。
5.3 shot get-result 字段速览
shot get-result --story-id <id> --type <image|video> 返回的关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
state | `'all_done' \ | 'running' \ |
doing_count | number | 进行中任务数(=0 时 state 不再是 running) |
done_count | number | 已成功的产物数(即 results.length) |
failed_count | number | 失败任务数(即 failed_tasks.length) |
results[] | {asset_id, asset_url, asset_title, material_poster, created_at} | 已完成产物 |
doing_tasks[] | {task_id, percentage, process_desc, status} | 进行中明细 |
failed_tasks[] | {task_id, failed_reason, status} | 失败明细 |
💡--watch时 CLI 会按--interval秒(默认 5)轮询本工具,直到state === 'all_done';如果连续 6 次返回no_data(后端入队还没完成)才会兜底退出。
---
6. 资产绑定(bind)
# 把图片资产绑定为参考主体
workrally shot bind --story-id st_1 --type image \
--assets '[{"asset_id":"a1","url":"https://..."},{"asset_id":"a2","url":"https://..."}]'
# 替换而非追加
workrally shot bind --story-id st_1 --type image --mode replace --assets '[...]'
# 视频资产
workrally shot bind --story-id st_1 --type video --assets '[{...}]'image/audio写入role_data_json;video写入video_role_data_json。
---
7. 删除与恢复
# 软删除(默认行为,→回收站)
workrally tools call project_delete --json-args '{"project_id":"<pid>"}'
workrally series delete <sid>
workrally shot delete <story_id_1> <story_id_2>
# 查回收站 / 恢复 / 彻底删
workrally tools call recycle_bin_list --json-args '{"entity_type":"project"}'
workrally tools call recycle_bin_restore --json-args '{"entity_type":"project","entity_id":"<pid>"}'
workrally tools call recycle_bin_delete --json-args '{"entity_type":"project","entity_id":"<pid>"}' # 彻底删⚠️ CLIdelete命令不暴露--permanentflag,避免误删;如确需彻底删除,请显式调tools call recycle_bin_delete。
---
8. 易错点
| 错误 | 正确做法 |
|---|---|
直接 workrally tools call story_batch_update 漏字段 | 改用 shot update / shot update --batch,自动先查后改 |
用 generate image-models / video-models 给场次配模型 | 那是画布的;场次必须用 shot image-models / video-models(schema 不同) |
用 shot generate-video --model <provider> 临时覆盖 | 不接受;模型必须先 shot set-model --video-provider <N> 写入场次字段 |
shot generate-* 还想传 --project-id / --series-id | 不接受;下游 GenerateStoryAnimation 仅按 story_id 路由,只用 --story-ids + --count |
shot set-model --animation-model <provider> 只传 provider 数字 | 该字段要 "mode,provider" 字符串;推荐改用 --video-provider <N>,CLI 自动拼成 "9,N" |
shot generate-* 直接调,没 shot get 检查 | 后端会拒绝(缺 model/duration/ratio);先 shot get 验字段 → 缺则 shot set-model 写入 |
| 模型 ID 硬编码 | 必须先 shot image-models / shot video-models 动态获取 |
等待 shot generate-* 返回 task_id 然后用 generate task / canvas_get_task 轮询 | 场次生成接口 GenerateStoryAnimation 不返回 task_id;查结果必须用 `shot get-result --story-id <id> --type image\ |
用一次 shot get-result 同时查图片和视频 | image / video 是两条独立进度;必须分别用 --type image 和 --type video 各拉一次 |
想批量改场次编号但找不到 shot rename | 本期不提供;单条 shot update <id> --story-num "...",批量 shot update --batch '[{"story_id":"...","story_num":"..."}]' |
想增删图层但找不到 shot add-layer/delete-layer | 本期不提供;直接 workrally tools call layer_batch_add_update / layer_batch_delete |
| 把场次和分镜(图层)混淆 | 场次=story;分镜=layer。图层操作走 tools call layer_batch_* |
| 误删项目/剧集/场次 | delete 默认软删→回收站。用 tools call recycle_bin_list + recycle_bin_restore 恢复 |
| 想彻底删除项目/剧集 | 项目:tools call project_delete(软删)后如需彻底删用 recycle_bin_delete;剧集/场次:series delete / shot delete 仅软删;彻底删用 tools call recycle_bin_delete --json-args '{"entity_type":"project","entity_id":"..."}' 等 |
用 shot update --description 改描述 | story_description 已废弃,CLI 不暴露此参数;改用 --image-prompt / --animation-prompt |
仅填 image_prompt 后又调 generate-video | 该场次没填 animation_prompt,会被后端拒绝。要么补 animation_prompt 要么改用 generate-image |
---
9. 场次创作工作流 Skill 迁入
以下与主 SKILL.md 中的「关键工作流:场次创作」及「重要规则」第 10–15 条对齐,便于单文件查阅。
概念层级:项目 (project) → 剧集 (series) → 场次 (shot/story)。一个场次 = 一段连续画面,核心由提示词承载:图片提示词(image_prompt)和/或视频提示词(animation_prompt)+ 角色绑定。
⚠️ 场次描述(story_description)已废弃,前端不再展示。请用image_prompt和/或animation_prompt表达场次内容。
>
💡 按需填写:根据用户意图判断要图、要视频、还是图+视频;不强制两个都填。
# 步骤 1: 创建剧集(如已有可跳过)
workrally series create --project-id <pid> --name "第一集" -o json
# 步骤 2: 批量创建场次 — 三种典型用法
# A) 用户要静态图/漫画/插画 → 仅填 image_prompt
workrally shot create --series-id <sid> --json-list \
'[{"image_prompt":"古风庭院全景,月光皎洁"},
{"image_prompt":"两位侠客剑指对方,剑光交错"}]'
# B) 用户要短视频/动效 → 仅填 animation_prompt
workrally shot create --series-id <sid> --json-list \
'[{"animation_prompt":"镜头从院门缓推至中景"},
{"animation_prompt":"快速推近至脸部特写"}]'
# C) 漫剧(图+视频均要)→ 两个都填
workrally shot create --series-id <sid> --json-list \
'[{"image_prompt":"古风庭院全景","animation_prompt":"镜头缓推"},
{"image_prompt":"两位侠客对峙","animation_prompt":"推近脸部特写"}]'
# 步骤 3: 基于提示词自动识别角色(两路独立 fallback:填什么识别什么)
workrally shot recognize --project-id <pid> --series-id <sid>
# 步骤 4: 配置模型 — 与提示词一一对应(**必须先动态获取场次专用模型列表**)
# ⚠️ 场次的模型与 canvas 不同:
# - canvas 用 `workrally generate image-models / video-models`
# - shot 用 `workrally shot image-models / video-models`(schema 不同)
workrally shot image-models -o json # 拿到 models[].en_name(图片模型 ID)
workrally shot video-models -o json # 拿到 models[].provider(视频模型 provider 数字)
# 用法 A:仅图
workrally shot set-model --image-model <en_name> --aspect-ratio 16:9
# 用法 B:仅视频(推荐 --video-provider 数字,CLI 自动拼成 mode=9,provider)
workrally shot set-model --video-provider 1 --duration 5 --aspect-ratio 16:9
# 用法 C:图+视频
workrally shot set-model --image-model <en_name> --video-provider 1 --duration 5 --aspect-ratio 16:9
# 步骤 5: 多场次一起生图 / 一起生视频
# ⭐ **生成前先用 `shot get` 确认场次已配置模型/时长/比例**:
# - 生图前查 image_model / image_generate_width / image_generate_height
# - 生视频前查 animation_model(应为 "9,N" 格式)/ animation_duration / generate_width / generate_height
workrally shot get <story_id> --project-id <pid> -o json # 检查上述字段是否非空
# 缺字段时回到步骤 4 用 set-model 写入;都齐全后仅提交(无 --poll;接口不返回 task_id):
workrally shot generate-image --story-ids st_1,st_2,st_3 [--count 1] # 仅 --story-ids / --count / -o;模型从场次字段读
workrally shot generate-video --story-ids st_1,st_2,st_3 [--count 1] # 同上;勿传 --model / --duration / --aspect-ratio
# 进度与产物:按场次、按类型分别查(多场次可 shell 循环)
workrally shot get-result --story-id st_1 --type image --watch
workrally shot get-result --story-id st_1 --type video --watch多场次生成:--story-ids逗号分隔多个 ID,handler 内部并发提交;仅返回是否提交成功,不返回task_id,无 `--poll` 参数。查进度与产物必须用shot get-result --story-id <id> --type image|video(可加--watch)。本期不提供独立的batch-generate命令。
>
批量编辑提示词:shot update --batch '[{...}]'一次更新多个场次,比逐个shot update <id>高效得多。
>
批量改名: 多条shot update --batch '[{"story_id":"...","story_num":"EP01-SC01"}]'即可,本期不提供独立的rename命令。
>
删除 = 软删除: 项目用tools call project_delete;series delete/shot delete为 CLI 子命令。默认均移入回收站,可通过recycle_bin_*恢复或彻底删除。
场次侧没有 generate-* --poll;轮询与结果一律以本文 §5 的 shot get-result [--watch] 为准。
场次专项规则 10-15
10. 场次内容核心字段:image_prompt(决定关键帧)+ animation_prompt(决定动效)。不强制都填,按用户意图判断(仅图 / 仅视频 / 图+视频)。story_description 已废弃,CLI 不暴露 --description 11. 场次模型 ≠ 画布模型:
- 画布(canvas)用
workrally generate image-models / video-models - 场次(shot)用 `workrally shot image-models / video-models`(schema 不同,不要混用)
- 场次视频固定
mode=9 (SUBJECT_TO_VIDEO);CLI 用--video-provider <N>数字时会自动拼成"9,N"写入animation_model
12. 生成前必须先用 `shot get` 确认模型已配置:
- 生图前:
image_model、image_generate_width、image_generate_height都非空 - 生视频前:
animation_model("9,N" 格式)、animation_duration、generate_width、generate_height都非空 - 缺字段直接调
shot generate-*后端会拒绝;先shot set-model写入再生成
13. 多场次生成不要找 batch 命令:shot generate-image / generate-video 的 --story-ids 直接接 id1,id2,id3 即可一次性触发多个场次的生成任务,本期不提供 shot batch-generate 14. `shot generate-image / generate-video` 仅支持 `--story-ids`、`--count`、`-o`:无 --poll;不接受 --model / --duration / --aspect-ratio 等运行时覆盖(均从场次字段读,先用 shot set-model 写入)。提交后用 shot get-result --type image|video [--watch] 查结果 15. 删除是软删除:项目无 workrally project delete,用 tools call project_delete;series/shot 的 delete 子命令默认移入回收站,可通过 tools call recycle_bin_restore 恢复;彻底删除请用 tools call recycle_bin_delete
上传与素材管理指南
本文档帮助 AI Agent 正确执行文件上传和素材管理流程。WorkRally 有两套素材体系,理解它们的关系是正确操作的前提。
---
1. 两套素材体系
媒资库 (Asset) — 项目级文件池
- 管理命令:
workrally asset search/create/get/update - 本质: 扁平的文件列表,每个素材必须归属一个项目
- 特点: 视频/音频为私有读存储,必须入库后才能正常访问
- 何时使用: 所有素材都必须经过媒资库(
asset create)才能被系统使用
资产库 (Material) — 树形目录管理
- 管理命令:
workrally material list/add/update/get/breadcrumb - 本质: 树形文件夹结构,对媒资库素材的组织视图
- 三个预设根目录:
role_person(人物)、role_prop(道具)、role_scene(场景) - 附加根目录:
root(用户自建网盘文件夹) - 何时使用: 仅当用户要将素材"归档到角色/道具/场景/文件夹"时才需要
数据层次关系
资产 (material_type=0)
└─ 角色状态 (material_type=5)
├─ 图片素材 (material_type=2)
├─ 视频素材 (material_type=3)
└─ 音频素材 (material_type=4)---
2. 三步上传流程
这是 WorkRally 最核心的文件处理流程,严格按顺序执行:
步骤 1: 上传文件到 CDN
workrally upload ./character.png -o json返回:
{
"url": "https://cdn.example.com/path/to/file.png",
"original_url": "https://cdn.example.com/path/to/file.png",
"signed_url": "https://cdn.example.com/path/to/file.mp4?sign=..."
}URL 字段说明:
url— 可直接访问的地址。图片为公开 URL;音视频为临时访问 URLoriginal_url— 原始 CDN 路径(不含访问凭证),图片可直接访问,音视频无法直接访问signed_url— 仅音视频返回,与url相同
⚠️ 音视频文件为私有读存储,必须使用 `url` 或 `signed_url`,不要使用 original_url。步骤 2: 入媒资库(必须!)
🔒--url仅接受 WorkRally 官方媒资 URL(即upload返回值或媒资库 URL),详见 SKILL.md 规则 9。
workrally asset create --url <cdn_url> --project-id <project_id> -o json返回:
{
"id": "asset_abc123",
"asset_details": {
"url": "https://signed.url/...",
"download_url": "https://signed.download.url/...",
"width": 1024,
"height": 1024,
"format": "png"
}
}重要返回值:
id— 即asset_id,后续所有操作都需要这个 IDasset_details— 完整素材元数据,步骤 3 必须完整传入
⚠️asset_details.url和asset_details.download_url为临时访问 URL,过期后需通过workrally asset get重新获取。获取到的 URL 可直接作为其他工具的 URL 参数传入。
步骤 3: 挂载到资产库(按需)
workrally material add --json-list '[{
"material_id": "<asset_id>",
"material_name": "角色名_状态",
"material_type": 2,
"parent_id": "<目标位置的 material_id>",
"material_detail": <完整的 asset_details 对象>
}]' --project-ids <project_id>关键字段(JSON 数组中每个对象):
material_id— 必须传asset_id(步骤 2 返回的id)material_detail— 必须传完整的asset_details(步骤 2 返回的asset_details对象)material_type— 素材类型:2=图片,3=视频,4=音频,1=文件夹parent_id— 目标位置:role_person/role_prop/role_scene或已有文件夹/状态的material_id
⚠️ 步骤 3 如果 JSON 中缺少material_id或material_detail,素材不会在资产库列表中显示!
---
3. 判断需要几步
| 用户意图 | 所需步骤 | 说明 |
|---|---|---|
| "上传文件" / "上传图片" | 步骤 1 → 2 | 入媒资库即可在 web 端查看 |
| "上传到角色/道具/场景" | 步骤 1 → 2 → 3 | 还需挂载到资产库树形目录 |
| "上传到文件夹" | 步骤 1 → 2 → 3 | 同上,parent_id 为文件夹的 material_id |
| "把媒资素材添加到资产库" | 仅步骤 3 | 素材已在媒资库,只需挂载 |
| "在画布上放一张已有图" | 无需上传 | 直接 asset search 找到 asset_id → canvas build-draft |
| "上传并放到画布上" | 步骤 1 → 2 → build-draft | 入媒资库后用 build-draft 写入画布 |
---
4. 画布场景下的素材上传
画布素材需要同时关联项目和画布:
# 步骤 1: 上传
workrally upload ./file.png -o json
# 步骤 2: 入媒资库(必须传 project-id)
workrally asset create --url <cdn_url> --project-id <项目ID> -o json
# 步骤 3: 写入画布节点(使用返回的 asset_id)
workrally canvas build-draft <画布ID> --nodes '[
{"id":"node1","type":"image","position":{"x":0,"y":0},"data":{"asset":{"id":"<asset_id>"}},"style":{"width":512,"height":512}}
]'📌 项目 ID 通过 workrally project list 获取。用户未指定项目时,查找名为"默认项目"的项目。---
5. 资产库目录操作
查看各根目录下的内容
# 查看人物列表
workrally material list role_person -o json
# 查看道具列表
workrally material list role_prop -o json
# 查看场景列表
workrally material list role_scene -o json
# 查看网盘文件夹列表
workrally material list root -o json查看角色的状态列表
# parent-id 传角色的 material_id
workrally material list <角色的material_id> -o json查看某状态下的素材文件
# parent-id 传状态的 material_id
workrally material list <状态的material_id> -o json创建文件夹
workrally material add --json-list '[{"material_name":"新文件夹","material_type":1,"parent_id":"role_person"}]'获取角色详情(含 LoRA/提示词)
# 注意:role get 需要 role_id,不是 material_id
# material_id 格式如 "abc_0",role_id 格式如 "abc"
# 先通过 material get 获取 role_id
workrally material get <material_id> -o json
# 返回中有 role_id 字段,再查角色详情
workrally role get <role_id> -o json⚠️material_id(如 "abc_0",带_0后缀)≠role_id(如 "abc")。如果只有material_id,先通过material get获取role_id。
---
6. 素材 URL 访问说明
| 素材类型 | 存储策略 | URL 行为 |
|---|---|---|
| 图片 | 公开读 | url 可直接访问 |
| 视频 | 私有读 | url 为临时访问地址,过期后需重新获取 |
| 音频 | 私有读 | url 为临时访问地址,过期后需重新获取 |
📎 媒资 API 返回的素材 URL 可直接作为其他工具的 URL 参数传入,无需手动处理。如遇"非法或已过期"提示,通过下列命令重新获取即可。
过期后重新获取:
workrally asset get <asset_id> -o json
# 返回中的 url 和 download_url 为新的可访问地址---
7. 批量操作
批量创建素材到资产库
material add 支持 --json-list 参数传入 JSON 数组,一次添加多个素材。也可通过 tools call 直接调用底层 MCP 工具:
workrally tools call material_manage --json-args '{
"action": "add",
"material_list": [
{"material_id":"asset_id_1","material_name":"素材1","material_type":2,"parent_id":"<状态ID>","material_detail":{...}},
{"material_id":"asset_id_2","material_name":"素材2","material_type":3,"parent_id":"<状态ID>","material_detail":{...}}
],
"project_ids": ["<project_id>"],
"source": 1
}'批量获取素材详情
workrally asset get <id1> <id2> <id3> -o json
# 最多 50 个 ID搜索媒资库
workrally asset search --project-id <id> -o json
# 可选筛选: --keyword "关键词" --type image/video/audio