通过 XPolicyLab 评测
RoboDojo 的排行榜通过 XPolicyLab 评测策略:一个目录 XPolicyLab/policy/<Name>/,其中的 Model 响应官方客户端的 reset、update_obs 和 get_action。Harness Policy 并不是这种形态(模型的程序一次请求一个控制 tick;XPolicyLab 向策略请求动作块),因此支持分为三部分,每部分都可以单独使用:
| 部分 | 位置 | 作用 |
|---|---|---|
| 观测契约 | core/contract.py、runtime.contract |
开发运行看到的恰好是被评测策略看到的内容 |
| 连接器 | connectors/xpolicylab.py、connectors/package.py |
把 harness 作为 XPolicyLab 的 Model |
| 导出 | export/xpolicylab.py、harness export xpolicylab |
一个遵循 XPolicyLab 适配器标准的策略目录 |
运行时、skill 和服务都不知道 XPolicyLab 的存在;换一个评测方,就会有它自己的契约、连接器和导出。
1. agent 在契约下运行
Section titled “1. agent 在契约下运行”官方客户端交给策略的内容少于我们的模拟器 worker 报告的内容(对照 RoboDojo cb2a37d 和 2026-10-08 的排行榜协议核对过,在 2026-10-14 的协议中未变):
| worker 报告 | 官方客户端给出 | 在 contract = "xpolicylab" 下 |
|---|---|---|
| 实测的夹爪开度 | 最后一次下达的夹爪指令值 | 状态中携带指令值;pick 检查物体是否随夹爪一起升起(SAM 3),而 holding(arm) 或无法测量升起的 pick 会就腕部相机的画面询问 VLM;prompt 特性 measured_gripper 关闭 |
| 相机内参和外参 | 无 | 来自本体的标定(embodiments/arx_x5):头部相机固定在世界中,腕部相机固定在 link6 上 |
| 步数上限 | 无 | 不放入 profile 和状态;prompt 特性 step_limit 关闭;不带 max_seconds 的 run_policy 一直运行到 episode 结束或双臂停止运动 |
| 任务名 | 无(只有指令) | 没有任务描述(with-task-description 消融在仿真中加入任务描述,不导出) |
| 结果 | 无(由主机打分) | 策略从不读取 |
| fk、ik、plan | 无 | 运动学服务:不带模拟器的 RoboDojo 自己的 cuRobo 规划器(services/kinematics.toml) |
agent 默认在该契约下运行(configs/default.toml 中的 contract = "xpolicylab"),在开发 layout 上与在评测 layout 上一样:suite 以 --contract xpolicylab --embodiment arx_x5 启动其 worker,worker 过滤它返回的所有内容。因此开发结果就是导出的策略应当达到的结果。契约是 lock 的一部分;--set agent.runtime.contract=native 让开发运行看到模拟器测量的一切(另一个 identity)。
harness run configs/experiments/dev.toml --deploy mine --output runs/dev运动学服务的回答与模拟器 worker 完全一致(同一份规划器代码;在 general_pickup 上核对过:FK、IK 关节和规划出的路点完全相同)。
harness export xpolicylab --name HarnessPolicy \ --out <RoboDojo>/XPolicyLab/policy/HarnessPolicy --deploy mine [--vendor] \ [--check --gpu 5 --env harness-policy]agent(若未给出其他文件则为 configs/default.toml)严格解析(它指明的每个 skill 和服务都必须可运行),必须在契约下运行,并且不得使用任务描述。除非指定 --allow-dirty,导出会拒绝未提交的代码。它写出:
policy/HarnessPolicy/├── model.py Model(ModelTemplate) -> harness_policy.connectors.package.HarnessModel├── deploy.py, eval.sh, setup_eval_policy_server.sh, setup_eval_env_client.sh, __init__.py│ copied unchanged from demo_policy├── deploy.yml the standard keys (protocol ws, action_type joint, eval_batch false)│ and poll_seconds, result_dir, max_wall_seconds├── agent.json what the agent was resolved from (paths relative to the│ checkout), its lock and identity, the code fingerprint, the commit├── deploy.toml where weights are; optionally where a service runs instead├── install.sh clones the-harness at the commit (unless vendored), installs XPolicyLab├── download_checkpoints.sh `harness fetch` of the services' weights into checkpoints/├── README.md XPolicyLab's adapter template└── the-harness/ with --vendor: the files the agent was resolved from--check 运行 XPolicyLab 的 PR 检查:对每个脚本执行 bash -n、py_compile、model.py/deploy.py 中没有图像解码,以及 XPolicyLab 调试环境的闭环(EVAL_ENV_TYPE=debug、10 个 episode、来自 configs/scripts/xpolicylab_check.json 的脚本化模型回复、没有模型调用)。
3. 评测方机器上运行的内容
Section titled “3. 评测方机器上运行的内容”setup_policy_server.py 导入 policy/HarnessPolicy/model.py,其中的 Model 构建一个 HarnessModel:
- 针对为本实例写出的 deploy 文件再次严格解析
agent.json,identity 与导出时的不一致就拒绝运行;代码指纹不同时给出警告。托管模型缺少 API key 时在这里停止。 - 把服务放到服务器可见的 GPU 上(
policy_gpu_id,多块时用逗号分隔),依据其空闲显存,使用自己的端口(一台机器上可以运行几个实例)。全部放不下时:策略和世界模型在一个 swap group 中按需加载;再不行则除运动学以外的所有模型都按需加载。agent 的模型(运动学、SAM 3、Simate:23.2 GB)可以常驻在一块 24 GB 的 GPU 上;GPU 空间更小时,模型加载期间模拟器等待,因此只有墙钟时间改变。 - 启动常驻服务、按需服务的 broker,以及一个 reaper:服务器未清理就退出时,由它停止所有这些服务。
- 每个 episode 在
reset之后的第一个观测到来时:针对一个Bridge运行 driver(kernel、skill、模型循环),Bridge对会话而言是机器人 worker,对 XPolicyLab 而言是Model。在机器允许 user namespace 的地方,程序在 kernel 的沙箱中运行(isolation = "auto");在禁止它的容器中,kernel 内部的 guard 仍然把程序限制在其服务范围内并禁止创建进程。
bridge 连接两个循环:一个 tick 把一个动作交给 get_action,并等待它之后的观测(客户端在每个动作之后发送一个观测),因此反应层能看到每一个观测。在模型思考或模型加载期间,get_action 在 poll_seconds(90 s,低于客户端 120 s 的请求上限)之后返回一个空动作块;标准 episode 循环于是不执行动作并再次请求,模拟器不前进。程序结束后,双臂保持不动,直到客户端结束该 episode。reset 结束正在运行的程序的 tick(它们报告 episode 已结束)并立即返回。
每个实例把 trace 写到 results/<task>-<time>-<pid>/:实例的 deploy 文件、lock、服务日志,以及每个 episode 一个目录,内含模型请求、程序、事件和摘要。
已完成的检查(2026-10-12)
Section titled “已完成的检查(2026-10-12)”tests/test_contract.py:契约过滤器,以及按契约划分的 prompt 和解析。tests/test_xpolicylab.py:包的放置(4、2、1 块 GPU,显存不足,外部服务,互不相同的端口),标准循环下的 bridge(空动作块、保持、reset结束一个正在等待的 tick),导出,以及一个导出的策略在 XPolicyLab 的循环下运行三个 episode,带双重 reset,最后一个在程序中途停止。- 在一块 24 GB 的 GPU 上运行
harness export ... --check:所有检查通过;包自行放置到一块 GPU 上(运动学常驻,四个模型按需),完成了 10/10 个调试 episode。 - RoboDojo 的官方客户端(
eval.sh、Isaac Sim、grok-4.7 low)对导出的策略运行,使用一个作为评测 seed 9000 提供的开发 layout(未使用任何评测 layout):通过 bridge 完成 200/200 步,客户端结束了该 episode,episode 的摘要已写出,策略启动的每个服务都已停止。这是接线检查,不是结果(运行方法)。
针对 agent 1.4.1 完成的检查(2026-10-15)
Section titled “针对 agent 1.4.1 完成的检查(2026-10-15)”1.5.0 设为默认的配置(没有指点角色,没有世界模型),用 --vendor 和这两个 --set 导出:启动时核对了 identity,服务常驻放置在一块 GPU 上(运动学、SAM 3、Simate:23.2 GB)。
--check:XPolicyLab 的 PR 检查和调试闭环通过。- RoboDojo 的官方客户端配合 DeepSeek V4.1 Flash,每个任务使用一个作为评测 seed 9000 提供的开发 layout:
stack_bowls、general_pickup和make_toast成功,solve_equation未成功;没有请求达到客户端的 120 s 上限。 - 把传送带任务交给策略的 agent 1.4.2 以同样方式导出(identity
cf7c5c6cbaf6ed9d),用于通过官方客户端进行完整的本地评测。
提交到 RoboDojo 排行榜逐步讲解整个过程:在契约下开发、导出、检查、运行官方客户端,以及发起 pull request。