关于 huawei-cloud-cloudrobo-dispatch
此 Agent skill 通过 cloudrobo-service 管理机器人任务派发,适用于需要将自然语言指令交由具身机器人执行的场景。它涵盖创建、等待、监控、取消任务及获取结果,并要求设置执行停止条件。
主要功能
- 01创建机器人执行任务
- 02按会话筛选和查看任务
- 03等待任务结束
- 04取消运行中或待处理任务
- 05读取任务结果与日志
- 06设置运行时间和步数限制
适用场景
- 01派发机器人抓取与放置任务
- 02查看会话中机器人的任务状态
- 03等待任务完成并检查结果
- 04停止错误或不再需要的任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ huaweicloud/ huaweicloud-skills --skill huawei-cloud-cloudrobo-dispatch安装后在 Claude Code 中输入/huawei-cloud-cloudrobo-dispatch确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/acceptance-criteria.mdcli-installation-guide.mddataflow-diagram.mdiam-policies.mdvalidation-rules.mdverification-method.mdscripts/test-cli-commands.shtemplates/test-vars.json详细介绍
**Windows / PowerShell:**示例使用 bash 语法。要在 Windows PowerShell 中运行:
- 将
\续行符合并到一行,或在行尾使用反引号。- 使用
$env:NAME="value"设置环境变量,而不是export NAME="value"。- 单引号包裹的 JSON
'{"a":"b"}'可直接使用。
概述
cloudrobo-dispatch 技能通过 robo-dispatcher
服务管理具身任务调度。它允许 Agent 创建一个在机器人上运行的任务(由 robot_id 标识),该任务在会话(session_id)中依据执行模型(exec_model_id)运行;还可以监控和取消任务,并获取自然语言任务结果及日志条目。
适用场景:
- 任务调度——根据自然语言任务描述在机器人上创建任务;始终提供停止条件(
exec_constraints:默认max_run_time=10分钟、max_iter_num=100步) - 任务监控——列出或查看会话中的任务,并按状态、机器人或推理服务筛选
- 等待任务完成——阻塞,直到已调度任务退出
RUNNING状态,无需手动轮询(wait-task是等待任务完成的首选方式) - 任务取消——取消正在运行或等待中的任务
- 结果获取——获取已完成任务的结果(任务和
log_items) - 跨技能编排——将机器人(
cloudrobo-robot)和推理模型(cloudrobo-infer/cloudrobo-asset)组合成可在机器人上执行的具体任务。
架构:
Agent / LLM
│
├── CLI → cloudrobo dispatch <command>
└── SDK → DispatchClient (Python) — domain RoboDispatcherTaskManagement
│
▼
cloudrobo-service (REST API)
/v1/robo-dispatcher/sessions/{session_id}/tasks*
所有操作都面向 cloudrobo-service 后端,限定于一个 session_id,并且需要有效的 workspace_id。会话是稳定的执行上下文;可以在同一个会话中跨时间创建多个任务。
session_id:在当前版本中,
session_id与当前工作区的workspace_id相同。你可以通过读取当前工作区(cloudrobo workspace current)或已配置的workspace_id来获取,并直接将其用作--session-id。如果调用方明确提供了不同的session_id,建议先与当前工作区进行核对。
前置条件
- 有关 CLI 安装、AK/SK 身份验证和工作区配置,请参阅
references/cli-installation-guide.md。 - 所有任务操作都需要有效的
session_id。在当前版本中,session_id等于当前工作区的workspace_id——可通过cloudrobo workspace current读取,或使用已配置的workspace_id(没有单独的会话创建 API)。 - 有效的
robot_id(来自cloudrobo-robot)和用于驱动任务的受约束模型服务所对应的exec_model_id。任务运行要求机器人处于 ONLINE 状态(即其 R2C 边缘客户端已连接), 否则后端会以failure_reason: "Robot offline"拒绝任务。
如何获取
exec_model_id(重要)——exec_model_id是驱动任务的执行模型句柄。 不要将原始模型/资产 ID(例如8b804b51-…)填入此字段;后端无法解析资产 ID,任务将会失败。两种类型的
exec_model_id(已于 2026-08 在此平台上验证):
- 用户创建的推理服务(通过
cloudrobo-infer中的cloudrobo infer create部署):exec_model_id等于推理服务的service_id,也就是cloudrobo infer create和cloudrobo infer list返回的id。实际获取方式:运行cloudrobo infer list,选择已部署的服务(例如so101-real-demo-0828),并将其id(<uuid>)直接用作exec_model_id。用户部署的服务无需单独查询“模型服务 UUID”。- 平台预构建/外部模型服务会显示带
ext_前缀的不透明句柄,例如ext_2dcc1539e72040c78650c554102debaf(名称例如Claude-3.5-Updated)或ext_1ee0bcc7…(名称例如cloudrobo-real-rl-model-…)。这些不是 infer-list 服务;请从现有任务的constraints.model.exec_model_id中获取。你可以随时通过同一会话中的现有成功任务确认确切值:运行
cloudrobo dispatch list-tasks --session-id <sid> --content-match "<skill prompt>",并读取其constraints.model.exec_model_id(返回的exec_model_name与源服务名称相同)。
工作流
自然语言优先原则
以下每种工作流都从用户意图(1-2 句话)开始,而不是手动编排 CLI/SDK。 随后,技能会驱动相应的命令链并报告状态反馈。
任务派发工作流(模块 + 机器人 + 模型 + 工作区)
场景:“告诉机器人 A 去拿起红色方块并把它放进箱子里。”
- 解析会话 — 从当前工作区读取
session_id:在当前版本中,session_id == workspace_id(通过cloudrobo workspace current获取,或使用已配置的workspace_id)。 - 解析机器人和模型 — 获取
robot_id(来自机器人注册信息)和exec_model_id。exec_model_id是驱动任务的执行模型句柄——对于你部署的服务,它就是该服务的service_id(请参阅下方“如何解析exec_model_id”说明)。两者都必须在constraints中提供。 - 确认机器人可连接 — 目标机器人必须处于 ONLINE 状态(r2c 边缘客户端已连接)。
在离线或未连接的机器人上派发任务会失败,失败原因是
Robot offline。 请参阅cloudrobo-r2c,在派发任务前使(虚拟/真实)机器人上线。 - 描述任务 — 收集自然语言形式的
task文本(例如“拿起红色方块并把它放进箱子里”)以及name。如果推理服务部署时使用了strict:true,task文本必须与预定义的技能提示词匹配,否则服务会拒绝该请求。(请参阅cloudrobo-infer,了解如何使用skill_config.strict部署服务。) - 创建带停止条件的任务 —
cloudrobo dispatch create-task --session-id <sid> --name <name> --task "<task>" --constraints-json '<json>'。必须提供--constraints-json,其中包含model、robot_id和停止条件exec_constraints。务必设置停止条件 (max_run_time和max_iter_num),以免任务无限运行。如果用户未指定,默认值为:max_run_time=10(分钟),max_iter_num=100(步)。 提交前请确认(此操作会修改数据)。 - 等待完成(推荐) — 使用
cloudrobo dispatch wait-task --session-id <sid> --task-id <task_id> [--timeout <secs>]阻塞等待任务结束。 此命令每 5s 在内部轮询一次,并在任务状态不再为RUNNING时返回 (即状态变为COMPLETED/FAILED/CANCELLED或任何非RUNNING状态)。优先使用wait-task,而不是手动轮询show-task——它取代了旧的 20-30s 手动轮询循环。 - 获取结果 — 任务完成后,使用
cloudrobo dispatch show-task-result --session-id <sid> --task-id <task_id>读取自然语言结果和日志条目。
注意:
robot_id和exec_model_id必须包含在constraints中。不要将它们硬编码;应从机器人和推理/资产输出中解析。
如何解析
exec_model_id—exec_model_id不是模型资产 ID(即来自cloudrobo-asset的8b804b51-...样式资产 UUID)。它是任务所驱动的执行模型句柄。对于你通过cloudrobo infer create自行部署的服务,exec_model_id等于该服务的service_id(从cloudrobo infer list或create响应中读取)。平台预构建/外部模型服务则使用带ext_前缀的不透明句柄。按以下方式解析:
- 如果目标模型是你部署的推理服务之一 → 运行
cloudrobo infer list,将服务的id作为exec_model_id(已于 2026-08 验证两者等价)。- 否则,通过同一会话中的现有成功任务确认准确值:
cloudrobo dispatch list-tasks --session-id <sid> --content-match "<deployed skill prompt>",然后读取 其constraints.model.exec_model_id(exec_model_name是源服务名称,仅供参考)。 将原始资产 UUID 用作exec_model_id是导致派发失败的常见根本原因。
任务监控 / 查询工作流(模块 + 筛选条件)
场景:“我的会话中有哪些正在运行的任务?”
cloudrobo dispatch list-tasks --session-id <sid> [--status <status>] [--robot-id <rid>] [--infer-service-id <iid>] [--start-time <ms>] [--end-time <ms>] [--content-match <text>]支持分页(--limit/--offset)和排序(--sort-key/--sort-dir)。- 使用
cloudrobo dispatch show-task --session-id <sid> --task-id <task_id>查看详情。 - 报告任务状态、机器人、模型和内容。
任务结果获取工作流(模块)
场景:“给我看看那个抓取放置任务的结果。”
- 通过
wait-task等待任务完成(或通过show-task确认任务已进入终态)。 cloudrobo dispatch show-task-result --session-id <sid> --task-id <task_id>— 返回任务对象和log_items。支持使用--inverse、--limit、--offset分页。
任务取消工作流(模块)
场景:“中止那个任务——机器人拿错了物体。”
- 通过
show-task确认任务。 cloudrobo dispatch cancel-task --session-id <sid> --task-id <task_id>(会修改状态;请先确认)。- 通过
show-task验证任务已变为已取消状态。
会话上下文说明
- 任务始终在某个
session_id下创建。在当前版本中,session_id与当前工作区的workspace_id相同;可通过cloudrobo workspace current获取。你可以在一个会话中随时间创建多个任务。 - 停止条件:每个任务都应通过
constraints.exec_constraints设置停止条件,以确保任务按时停止——所需对象结构和默认值请参见“创建任务”一节。 - 严格服务:如果驱动推理服务部署时设置了
skill_config.strict:true,你传入的task必须匹配其预定义的技能提示词;不匹配的提示词会被拒绝。 - 旧版
create-session/exec_task/create-session-task接口已弃用,不得使用。所有操作都直接在任务端点上使用session_id。
CLI 命令格式规范
cloudrobo dispatch <command> [OPTIONS]
| 功能 | 说明 |
|---|---|
| 命令组 | dispatch |
| 子命令 | kebab-case:create-task、list-tasks、show-task、cancel-task、show-task-result、wait-task |
| 会话 | --session-id <id>(所有任务操作均需使用;当前版本中等于 workspace_id) |
| JSON 参数 | --constraints-json '<object>'(create-task;必填;包含 model/robot_id/exec_constraints) |
| 试运行 | --dry-run(create-task/cancel-task) |
| 结果分页 | --inverse、--limit、--offset(show-task-result) |
| 等待超时 | --timeout <secs>(wait-task;默认值为 600,IntRange 1–3600) |
完整覆盖:SDK 提供 6 个方法,CLI 提供 6 个命令(无遗漏)。 覆盖关系映射请参见
references/cli-installation-guide.md和验收标准。
核心命令
直接调用 SDK:CLI 不便使用时(例如处理动态 JSON、跨包查询),请直接使用 Python SDK。
DispatchClient(领域 RoboDispatcherTaskManagement)提供以下 6 个方法。
创建任务
cloudrobo dispatch create-task --session-id <session-id> --name <task-name> --task "<natural language task>" --constraints-json '{"model":{"exec_model_id":"<model-id>"},"robot_id":"<robot-id>","exec_constraints":{"max_run_time":10,"max_iter_num":100}}' [--dry-run]
实践中必须设置停止条件(
constraints.exec_constraints)。如果用户未指定值,默认设置max_run_time=10(分钟)和max_iter_num=100(步),以避免调试任务无界运行或长时间运行。有效范围:max_run_time为 1–300 分钟,max_iter_num为 1–300000 步。
model对象结构(重要)——在create-task的constraints.model中,只能包含exec_model_id。不要添加exec_model_name:创建 API 会因该参数返回400 Invalid parameter: exec_model_name。exec_model_name是仅在响应中出现的字段(存在于show-task/list-tasks/show-task-result的输出中),绝不能作为请求字段。关于exec_model_id的取值,请参见“如何解析exec_model_id”说明。
from cloudrobo_core.sdk import Config, HttpClient
from cloudrobo_dispatch import DispatchClient
config = Config()
http_client = HttpClient(config)
client = DispatchClient(http_client)
# session_id equals the current workspace_id in the current version
req = {
"name": "pick-red-cube",
"task": "pick up the red cube and place it in the bin",
"constraints": {
"model": {"exec_model_id": "<mid>"},
"robot_id": "<robot-id>",
# stop condition: use the given values, else default max_run_time=10, max_iter_num=100
"exec_constraints": {"max_run_time": 10, "max_iter_num": 100},
},
}
task = client.create_dispatcher_task("<session-id>", req)
print(task) # includes task_id
列出任务
cloudrobo dispatch list-tasks --session-id <sid> [--status <status>] [--limit 20] [--offset 0]
tasks = client.list_dispatcher_tasks("<session-id>", status="RUNNING")
for t in tasks.get("items", []):
print(t["id"], t["status"], t["name"])
显示任务详情
cloudrobo dispatch show-task --session-id <sid> --task-id <task-id>
task = client.show_dispatcher_task("<session-id>", "<task-id>")
print(task["name"], task["status"], task["robot_id"])
取消任务
cloudrobo dispatch cancel-task --session-id <sid> --task-id <task-id> [--dry-run]
client.cancel_dispatcher_task("<session-id>", "<task-id>")
显示任务结果
cloudrobo dispatch show-task-result --session-id <sid> --task-id <task-id> [--inverse] [--limit 100] [--offset 0]
result = client.show_dispatcher_task_result("<session-id>", "<task-id>")
print(result["task"]["result"])
for item in result.get("log_items", []):
print(item)
等待任务完成
用途:阻塞,直到已派发的任务完成(其状态不再是 RUNNING),这样就无需手动循环轮询 show-task。在非交互式 / 自动化场景中,这是等待任务的首选方式。
cloudrobo dispatch wait-task --session-id <sid> --task-id <task-id> [--timeout <seconds>]
result = client.wait_dispatcher_task("<session-id>", "<task-id>", timeout=600)
# result is the full task dict once status != "RUNNING" (e.g. COMPLETED / FAILED / CANCELLED)
status = (result.get("task") or {}).get("status")
行为(以源代码为准):
- 方法:
wait_dispatcher_task(session_id, task_id, timeout=600)。- 轮询:每 5 秒一次(
POLL_INTERVAL = 5);内部调用show_dispatcher_task(GET /v1/robo-dispatcher/sessions/{session_id}/tasks/{task_id})。- 返回条件:一旦
data["task"]["status"] != "RUNNING",即返回任务字典 ——无论状态是否变为COMPLETED、FAILED、CANCELLED或其他非RUNNING状态。终止状态:COMPLETED、FAILED、CANCELLED。- 默认超时:600 秒。
--timeout是IntRange(1, 3600)— 最长 3600 秒(1 小时)。- 超时时:客户端会抛出
TimeoutError;CLI 会向 stderr 打印[ERROR] <msg>并 以代码 1 退出。务必检查返回状态,以区分成功、失败和超时。- 没有独立的 REST API:
wait-task是客户端侧的轮询辅助工具,没有专用的后端端点, 只是对show-task的封装。- 必须先创建任务:
wait-task不会创建任务。先调用create-task获取task_id,然后再对其调用wait-task。
建议(何时使用 wait-task):
- 在
create-task后立即使用wait-task,然后通过show-task-result获取结果——这 可以取代过去每隔 20–30 秒手动轮询show-task的做法。 - 对于需要阻塞直到进入终止状态的非交互式 / 自动化流程,这是理想选择。
- 在需要观察中间状态的交互式流程中,仍可使用
show-task检查进度;但如果只需等待结果,请使用wait-task。
参数确认
| 参数 | 来源 | 必填 | 是否需要确认 |
|---|---|---|---|
--session-id | 当前工作区(workspace_id) | 是(全部) | 当前版本中 session_id == workspace_id;请通过 cloudrobo workspace current 核实 |
--task | 用户 | 是(创建) | 自然语言任务描述;如果是严格的服务,则必须与预定义的技能提示词一致 |
--name | 用户 | 是(创建) | 任务名称 |
--constraints-json | 用户 / 推导得出 | 是(创建) | JSON 对象 {model, robot_id, exec_constraints};包含停止条件 |
exec_constraints(在 --constraints-json 中) | 用户,否则使用默认值 | 实际上必填(创建) | 默认值为 max_run_time=10(分钟)、max_iter_num=100(步);范围为 1–300 / 1–300000 |
--task-id | 用户或先前输出 | 是(显示 / 取消 / 结果 / 等待) | 取消前请核实;使用 wait-task 前必须确认任务(由 create-task 创建)存在 |
--timeout | 可推导得出 | 否(等待) | wait-task 超时时间,单位为秒;默认值为 600,范围为 IntRange 1–3600 |
--dry-run | — | 否 | 预览但不执行 |
更改操作(create-task / cancel-task)必须在执行前征求用户确认。
参考文档
边界情况
| 场景 | 处理方式 |
|---|---|
缺少 session_id | 当前版本中,session_id == workspace_id;通过 cloudrobo workspace current 获取 |
缺少 robot_id / exec_model_id | create-task 要求两者都位于 constraints 中;从机器人和已部署的模型服务(而非资产 ID)获取 |
exec_model_id 错误(使用了资产 ID) | 对于你部署的服务,exec_model_id 等于该服务的 service_id(从 cloudrobo infer list 读取);使用原始资产 ID(8b804b51-...)是常见错误。预置/外部模型服务使用带 ext_ 前缀的句柄。通过 list-tasks --content-match "<prompt>" 对照现有成功任务进行验证 |
在 create 请求中传入 exec_model_name | 不要在 constraints.model 中包含 exec_model_name——create API 会返回 400 Invalid parameter: exec_model_name。exec_model_name 仅用于响应;删除该参数后,仅使用 exec_model_id 重试 |
| 机器人离线 / 未连接 | 对离线机器人的任务会以 failure_reason: "Robot offline" 失败。派发任务前,先通过 cloudrobo-r2c(虚拟/真实边缘客户端)将机器人设为 ONLINE |
| 缺少停止条件 | create-task 应设置 constraints.exec_constraints;默认 max_run_time=10、max_iter_num=100,以避免任务无界运行 |
| 任务时长过长 | 遵守范围:max_run_time 为 1–300 分钟,max_iter_num 为 1–300000 步;不要超出范围,以限制调试任务的运行时间 |
strict:true 服务 | 如果推理服务部署时使用了 skill_config.strict:true,则 task 必须匹配预定义的技能提示词,否则会被拒绝 |
| 未找到任务 | show/cancel/result 会返回 ResourceNotFoundError;请验证 task_id/session_id |
| 路径遍历 | validate_safe_id(session_id) / validate_safe_id(task_id) 会拦截 ../ 输入 |
| 取消已完成的任务 | 后端会拒绝;取消前请确认状态 |
| 长时间运行的任务 | 优先使用 wait-task(每 5 秒轮询一次,在状态不再为 RUNNING 时返回);仅使用 show-task 查看中间状态,不要手动密集循环调用 |
wait-task 超时 | --timeout 最大为 3600s(1 小时);超时时 CLI 会打印 [ERROR] 并以 1 退出——请告知用户并使用 show-task 重新检查 |
对终态任务调用 wait-task | 会立即返回(状态已不再是 RUNNING);任务完成后调用也是安全的 |
wait-task 需要已有任务 | 它不会创建任务——先调用 create-task 获取 task_id,否则遇到无效/未知任务时会失败 |
| 自然语言任务内容 | 清理内容并防范注入;不要将未经转义的原始内容回显到日志中 |
| 未设置 AK/SK | 操作会在 HTTP 签名时失败;请设置 HUAWEI_CLOUD_AK/HUAWEI_CLOUD_SK |
| 已弃用的接口 | 不要使用旧版 create-session/exec_task/create-session-task/list-sessions |
| session_id / task_id / robot_id / exec_model_id | 绝不能硬编码;应动态获取(session_id 从当前工作区获取) |
| 跨技能调用 | 此技能不会调用其他技能;它接收 robot_id(机器人)和 exec_model_id(推理/资产),并报告任务结果 |
| 有变更的操作 | create-task / cancel-task 应由用户确认 |
验证方法
规范符合性验证
bash scripts/test-cli-commands.sh
功能测试
bash scripts/test-cli-commands.sh
测试用例
完整的测试用例列表请参见 templates/test-vars.json,涵盖任务派发、监控、等待完成、取消、结果获取和安全场景。
验证清单
- 执行
create-task后,任务会以正确状态显示在list-tasks中 - 创建的任务带有停止条件(
exec_constraints.max_run_time/max_iter_num); 如果用户未指定,则默认为 10 分钟 / 100 步 - 使用的
session_id等于当前工作区的workspace_id - 当推理服务为
strict:true时,task与预定义的技能提示词匹配 - 执行
wait-task后,命令会阻塞(每 5s 轮询一次),并仅在状态不再为RUNNING时返回;未手动执行 20-30s 的轮询循环 - 使用显式
--timeout执行wait-task时,会遵守超时设置,并在超时后报告明确错误 - 调用
wait-task时使用的task_id已由create-task创建(它不会创建任务) - 执行
show-task后,详情会返回包含机器人 / 模型 / 状态的任务 - 执行
show-task-result后,会返回自然语言结果和log_items - 执行
cancel-task后,show-task会反映已取消状态 validate_safe_id会阻止路径遍历(../)- 未使用已弃用的接口(
create-session/exec_task) - 执行变更操作前会提示用户确认
最佳实践
- 始终从当前工作区解析
session_id(cloudrobo workspace current;在当前版本中,session_id == workspace_id),并动态解析robot_id/exec_model_id; 切勿硬编码 - 创建任务时,始终设置停止条件(
constraints.exec_constraints);如果用户 未指定,则使用默认值max_run_time=10(分钟)和max_iter_num=100(步),以限制 调试任务的运行范围(遵守 1–300 / 1–300000 的取值范围) - 如果用于驱动的推理服务以
strict:true部署,则让task与预定义的技能提示词匹配 - 执行
create-task(会触发真实机器人动作)和cancel-task前先确认 - 执行
create-task后,使用wait-task等待,而不要手动轮询show-task—— 它会阻塞(每 5s 轮询一次),直到状态不再为RUNNING,然后使用show-task-result获取结果。 仅在需要检查中间状态时使用show-task。在 Agent 环境中,将wait-task作为后台进程运行并等待其返回(任务进入终态后它会自行退出),而不是通过休眠 +show-task手动循环轮询。 - 任务可能运行较长时间时,为
wait-task设置显式--timeout;超时后,使用show-task重新检查状态并报告结果,而不要盲目重试 constraints.model只接受exec_model_id— 创建请求中切勿传入exec_model_name(会产生 400 错误);它是仅用于响应的字段- 对于由你部署的模型服务(
cloudrobo infer create),exec_model_id= 该服务的service_id(参见cloudrobo infer list);只有平台预置 / 外部模型服务使用ext_前缀的句柄。解析时优先使用cloudrobo infer list,不要猜测 - 在执行操作前,使用
create-task/cancel-task的--dry-run验证参数 - 使用
list-tasks筛选条件(--status、--robot-id、--infer-service-id、--content-match) 快速定位任务 - 清理自然语言
task内容;不要将未经转义的原始内容回显到日志中 - 结合机器人(
cloudrobo robot list/show)和推理(cloudrobo infer list)技能, 解析创建任务所需的机器人 / 模型 ID