EvoBot
Agent + Skill:Agent 决定做什么、按什么顺序做,技能库负责执行
在 LIBERO 基准的 30 个任务上经过多轮迭代,成功率 83%(25 / 30)。
不用强化学习 · 不用视觉-语言-动作模型 · 不用世界模型 · 运行时不需要调用大模型
一个完整回合:抓起黑碗,放到盘子上(LIBERO libero_spatial:0,第 1 次尝试成功,共 2965 个仿真步)
这是什么
EvoBot 跑 LIBERO 机器人操作基准,分两层:Agent 决定做什么、按什么顺序做,技能库负责执行。技能是带参数、可复用的动作单元(抓取、放置、推动、开合抽屉柜门与炉灶旋钮);失败时不只报"失败",还给出原因(被挡住、够不到、打滑),Agent 据此换参数、换抓取位置或换做法。
执行顺序不让模型每次现场发挥:把 LIBERO 任务自带的定义文件解析成结构化数据,离线让模型读一遍、排好子目标顺序(含"要不要先开抽屉"这类前置判断),结果写成 YAML 提交进仓库;运行时只读这份 YAML,不调模型,所以同一任务的顺序每次都一样。模型只能排列顺序、从给定候选里挑前置动作,不能改目标、不能指定技能、不能给参数;结果过校验,不通过就退回按依赖关系自动排序。
一条轨迹用仿真步数截断而不是实际耗时,结果不受机器负载影响;每个任务都从示范轨迹的初始状态开始,不同次运行才可比。
评测结果
在 LIBERO 的 libero_spatial、libero_object、libero_goal 三个任务集共 30 个任务上完成全量评测,25 / 30 通过(每个任务单独运行,每次最多 8 次尝试)。
复现方式:
bash scripts/verify_30.sh 8 verify
设计文档
| 编号 | 文档 | 内容 |
|---|---|---|
| 01 | 感知 | 物体位姿与抓取候选的来源:真值采样与模型推理两条路径 |
| 02 | 任务定义与规划 | 任务定义 → 有序子目标 → 技能序列,以及离线的一次分解 |
| 03 | 技能库 | 技能清单与统一约定 |
| 04 | 失败分类与恢复 | 失败原因分类与对应的处理方式 |
| 05 | 环境适配层 | 统一动作接口、固定初始状态、任务步数上限的接管与截断 |
| 06 | 逆运动学、末端伺服与运动控制 | 末端目标位姿如何变成关节动作 |
环境要求
- Python 3.10(conda 环境;3.12 无法运行 robosuite 及其依赖)
- LIBERO 源码,需要加到
PYTHONPATH - MuJoCo + robosuite(LIBERO 自带);无显示器的机器上需要设置
MUJOCO_GL=egl - 依赖清单见
requirements.txt与requirements-extra.txt(录像、轨迹规划)
conda create -n darwin python=3.10 -y && conda activate darwin pip install -e . # 安装本项目 pip install mujoco h5py numpy pyyaml # 基础运行依赖 # 按 LIBERO 官方说明安装 LIBERO 及其依赖,然后: export PYTHONPATH=$PWD:/path/to/LIBERO export MUJOCO_GL=egl
快速开始
# 1) 跑单个任务(常驻仿真进程 + 逐步学习,默认最多尝试 30 次) PYTHONPATH=$PWD:/path/to/LIBERO MUJOCO_GL=egl python -u scripts/ipc_learn.py \ libero_spatial:0 --max-attempts 30 --sock /tmp/libero.sock # 2) 跑 agent runner:会读取进度记录,自动跳过已经通过的任务 PYTHONPATH=$PWD:/path/to/LIBERO MUJOCO_GL=egl python -u -m darwin.agents.libero_runner \ --suites libero_spatial,libero_object,libero_goal # 3) 跑全部 30 个任务做验收 bash scripts/verify_30.sh 8 verify # 参数:每个任务的尝试次数、结果标签
常用参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--suites / --tasks |
libero_spatial,libero_object,libero_goal |
要跑哪些任务集,或直接列出 任务集:编号 |
--attempt-steps |
7000 |
单条轨迹的仿真步数上限,主要的中断标准 |
--attempt-timeout |
300 |
墙钟时间上限(秒),只在程序卡住不动时才可能先触发 |
--no-video |
— | 不录制视频 |
每个任务的尝试结果会记录在 logs/libero_agent_progress.json,键名形如 libero:<任务集>:<编号>;已经通过的任务下次会跳过。
任务定义与生成
每个任务的定义是一份自描述 YAML,存放在 darwin/skills/configs/task_specs/:
language: put the bowl on top of the cabinet source: llm # llm 表示由模型分解,deterministic 表示自动排序 formal: # 结构化的任务定义 items: # 任务里要求达成的每一条,带固定编号 - {id: p0, predicate: On, kind: place, object: akita_black_bowl_1, target: wooden_cabinet_1_top_side} implicit_candidates: # 允许插入的前置动作 - {id: 'open:wooden_cabinet_1_top_side', predicate: Open, target: ...} vocabulary: {objects: [...], targets: [...], fixtures: {...}} skills: [...] # 可用技能的说明 reference_order: [...] # 自动排序给出的参考顺序,用于对比 llm: # 这次分解的原始记录 order: [p0] add: [] rationale: 把碗放到柜子顶面,不需要打开柜门或抽屉。 subgoals: [...] # 最终结果,runner 直接使用
重新生成(需要 DEEPSEEK_API_KEY;没有设置时会自动退回确定性排序):
python scripts/gen_task_specs.py # 全部 30 个任务 python scripts/gen_task_specs.py --tasks libero_goal:7 python scripts/gen_task_specs.py --no-llm # 只用自动排序,不调用模型 python scripts/gen_task_specs.py --model deepseek-v4-pro --force
许可
本项目使用 Apache-2.0 许可,详见 LICENSE。

