用 Strands Agents 和 LeRobot 从 Hugging Face Hub 走到机器人硬件
From the HF Mirror Hub to robot hardware with Strands Agents and LeRobot
AWS 开源的 Strands Robots SDK 将 LeRobot 相关的数据录制、策略推理和机器人抽象封装成 AgentTools,可组合成单个 Strands agent,把 Hub 上的数据集一路走到物理机器人。
完整走通从 Hub 数据集到真机的一条 Agent 流水线,说明仿真与硬件数据共用同一格式后,训练脚本可以不加改动地互换使用。
逐步讲解 Strands Robots 中的 LeRobot 集成——一个智能体循环,从 Hub 数据集到物理机器人,仿真到现实数据集采用相同的磁盘格式,策略只需换一个字符串即可替换。
你有一台机器人、一个存放在 Hugging Face Hub 上的演示数据文件夹,以及一个你想让它学习的新任务。如今这需要五套独立的工具:一个用来录制新演示,一个用来训练,第三个用来在仿真中测试,还有定制代码用于部署到硬件上,再加上一个在你有不止一台机器人时负责协调。这些部分各自都能工作,但它们彼此之间不通信。
Strands Robots 是来自 AWS 的开源 SDK(Apache 2.0),它将机器人抽象、仿真以及 LeRobot 栈暴露为 AgentTools,你可以将它们组合成一个 Strands 智能体。这种集成是刻意做得很薄的:LeRobot 自己的脚本负责硬件录制和校准,而 Strands AgentTools 则介入智能体真正编排的那些部分。仿真工具以与 LeRobot 在硬件上写入相同的格式记录 LeRobotDatasets。GR00T 和 LerobotLocal 在统一接口背后提供策略推理,而 MolmoAct2 检查点则通过 LerobotLocal 路径运行。对等网格将智能体分发到远程机器人。数据集格式完全保持 LeRobot 写入时的样子;智能体循环是粘合剂。
本文带你走过单个智能体内部的五个步骤:在 LeRobot AgentTools 之上构建智能体,在仿真中将演示录制为 LeRobotDataset,在同一台机器人上运行策略,只需更改一个关键字参数就把相同的智能体代码部署到物理 SO-101 上,以及通过 Zenoh 网格在机群中广播命令。读完本文,你可以从 GitHub 克隆可运行的示例应用,并在笔记本电脑上以仿真方式运行它。默认路径无需硬件、无需 GPU、无需 Hugging Face 凭证。本文的可运行配套内容位于 examples/lerobot/hub_to_hardware.py 和 hub_to_hardware.ipynb。该 notebook 默认仅仿真且使用 Mock 策略。
你将构建什么
Strands Robots SDK 将 LeRobot 栈暴露为 AgentTools,你可以将它们组合成一个 Strands 智能体。本文中的示例智能体做四件事:在仿真中录制新演示,将结果作为 LeRobotDataset 推送到 Hub,在仿真中针对相同格式运行策略,以及只需更改一个关键字参数就把相同的智能体代码部署到物理机器人上。当你有不止一台机器人时,智能体可以通过内置的对等网格协调整个机群。对于硬件录制和校准,LeRobot 自己的 CLI(lerobot-record、lerobot-calibrate)负责启动;智能体从那里接手。
图 1。Robot("so100") 默认使用 MuJoCo 支持的仿真;mode="real" 返回由 LeRobot 驱动的硬件机器人。两种模式共享相同的 DatasetRecorder 和相同的策略提供者,因此在仿真中采集的数据集和在硬件上采集的数据集使用相同的磁盘 LeRobotDataset 格式。
两个设计选择让这一点成为可能。首先,Robot("so100") 默认返回一个仿真环境(无需硬件,无风险),而 mode="real" 返回由 LeRobot 驱动的硬件机器人。两种模式下的 agent 代码完全相同。其次,用于写入 LeRobotDataset 的 DatasetRecorder 在仿真路径与 LeRobot 自身的硬件录制之间是共享的,因此在 MuJoCo 中采集的数据集与从物理 SO-101 采集的数据集格式一致。
整个工作流程只需五行 Python:
from strands_robots import Robot
from strands import Agent
arm = Robot("so100") # mode="sim" (default - safe, no hardware)
agent = Agent(tools=[arm])
agent("Pick up the red cube")
接下来是这次调用内部实际逐步发生的事情。
前置条件
最小化(默认仿真路径)
- Python 3.12+,运行在 Linux 或 macOS 上(MuJoCo 后端支持 Apple Silicon)。
- 为 agent 推理提供一个与 Strands 兼容的模型提供方。使用带有 AWS 凭证的 Amazon Bedrock、Anthropic API、OpenAI,或本地运行的 Ollama。
- 安装带有附加组件的 Strands Robots:
uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
就这些。本文中的示例只需这三项即可在笔记本电脑上端到端运行。
进阶(硬件部署、真实策略、Hub 推送)
- 一个具有写入权限的 Hugging Face 账户和 token,用于推送数据集以及从 Hub 拉取策略检查点。
- 对于硬件路径:一对 SO-101 follower 和 leader,或任何其他 LeRobot 支持的机器人。两个设备都需要在
~/.cache/huggingface/lerobot/calibration/下有校准文件。 - 对于本地 GR00T 推理:一块至少有 16 GB 显存的 NVIDIA GPU,并安装 Docker。本文使用 gr00t_inference 工具的 lifecycle="full" 操作,它会在一次调用中拉取镜像、下载检查点并启动容器。
步骤 1 - 设置示例
安装 Strands Robots 并获取示例文件:
uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
git clone https://github.com/strands-labs/robots.git
cd robots
如果你希望 agent 从 Hub 推送数据集或拉取策略,请导出你的 Hugging Face token。对于本文中的默认仿真路径来说这是可选的;该示例使用 Mock 策略端到端运行,并将数据集写入本地缓存,无需访问 Hub。
export HF_TOKEN=hf_...
可运行的示例位于 examples/lerobot/hub_to_hardware.py(Python 脚本)和 hub_to_hardware.ipynb(notebook),在 strands-labs/robots 仓库中,与 MuJoCo 和 LIBERO 示例放在一起。推荐从 notebook 开始:在 JupyterLab 中打开它,在仿真模式下自上而下运行单元格,无需连接任何硬件。
步骤 2 - 录制演示并推送到 Hub
仿真工具以 LeRobot 在硬件上写入的相同格式录制 LeRobotDatasets。无需硬件。Simulation 工具的 start_recording 操作通过同一个 DatasetRecorder 类写入:关节状态和动作使用相同的 parquet schema,每个摄像头使用相同的 MP4 布局。agent 提示几乎完全相同:
from strands import Agent
from strands_robots import Robot
robot = Robot("so100") # mode="sim" by default
agent = Agent(tools=[robot])
agent(
"Record a demonstration of 'pick the red cube and place it in the box' "
"using the Mock policy provider at FPS 30. Write the dataset to "
"my_user/cube_picking_sim and push to the Hub when done."
)
图 2。MuJoCo 仿真中的录制场景:SO-100 机械臂伸向地面平面上的红色方块,并被采集到 LeRobotDataset。对于这条默认路径,无需硬件、无需 GPU、无需 Hugging Face 凭证。
Mock 策略是有意为之的:它生成占位的关节动作,让工作流在没有训练好的检查点的情况下也能端到端运行。机器人会执行随机运动,而不是完成抓取,录制的数据在结构上是完整的(有效的关节状态、有效的相机帧、格式正确的 LeRobotDataset 片段),但演示本身作为训练数据并没有用处。下面的步骤 3 会换成 GR00T 或 LerobotLocal 来实现真正的抓取行为。要在此步骤中看到实际的方块拾取,请运行 --policy lerobot_local --checkpoint allenai/MolmoAct2-SO100_101(一个 MolmoAct2 检查点,会从其 config.json 中自动检测,并通过 LerobotLocal 路径路由);提示词、数据集格式和智能体代码保持不变。
证据在于接下来发生的事。LeRobot 自带的数据集加载器能够读取模拟录制的数据,无需任何 Strands 专用代码路径:
from lerobot.datasets.lerobot_dataset import LeRobotDataset
dataset = LeRobotDataset("my_user/cube_picking_sim")
print(dataset.features)
# {'observation.state': Sequence(...),
# 'observation.images.front': VideoFrame(...),
# 'action': Sequence(...),
# 'episode_index': Value(...), 'frame_index': Value(...), ...}
这个 features 字典的形状与 Hub 上的任何 LeRobot 数据集完全相同:相同的列名、相同的 parquet+MP4 布局、相同的加载器路径。消费硬件录制数据的训练脚本无需修改即可消费模拟录制的数据。如果你愿意,从模拟推送的数据集可以与硬件录制一起放在同一个 Hub 仓库中。
来自已录制 LeRobotDataset 的单个片段,从录制器写入的每相机 MP4 回放,这正是训练脚本读取的磁盘上的视频。
在硬件上录制
要在物理 SO-101 而非仿真中录制演示,请直接使用 LeRobot 的 record CLI。Strands 集成没有把该命令包装为 AgentTool,因为 LeRobot 已经把这件工作做得很干净:
lerobot-calibrate --robot.type=so101_follower --robot.id=my_follower
lerobot-calibrate --robot.type=so101_leader --robot.id=my_leader
lerobot-record \
--robot.type=so101_follower --robot.id=my_follower \
--teleop.type=so101_leader --teleop.id=my_leader \
--dataset.repo_id=my_user/cube_picking \
--dataset.single_task='Pick up the red cube and place it in the box' \
--dataset.num_episodes=25 \
--dataset.push_to_hub=true
此命令推送到 Hub 的数据集与模拟录制的格式相同。要在其上微调策略,请运行 LeRobot 的训练 CLI(lerobot-train);训练本身超出了本文的范围,遵循标准的 LeRobot 工作流。从步骤 3 开始,智能体可以互换地使用原始检查点或微调后的检查点。有关 SO-101 硬件的完整设置、校准演练和故障排除,请参阅示例文件夹中的 README。
步骤 3 - 在仿真中运行策略
数据集已在 Hub 上,下一步是运行策略。示例在其默认 sim 模式下使用 Robot() 工厂,然后附加 gr00t_inference,以便智能体可以管理推理容器:
from strands import Agent
from strands_robots import Robot, gr00t_inference
robot = Robot("so100") # mode="sim" by default
agent = Agent(tools=[robot, gr00t_inference])
agent(
"Start GR00T inference on port 5555 with the cube-picking checkpoint "
"from my_user/cube-picker. Then ask the robot to pick up the red cube."
)
在底层,智能体运行 gr00t_inference(action="lifecycle", lifecycle="full", ...) 拉取 GR00T 容器镜像、从 Hub 下载检查点并启动推理服务。然后它在仿真机器人上运行 run_policy 动作,并使用 policy_provider="groot",在 policy_config 字典中传入 GR00T 服务的主机和端口(容器可在端口 5555 上访问)。仿真会按策略的动作块逐步推进,结果渲染可通过 Simulation.render 获取。
图 3。使用训练好的策略(GR00T 或 MolmoAct2 检查点),智能体驱动机器人 SO-100 在仿真中抓取红色方块,这正是 Mock 策略所代替的行为。
对于偏好进程内推理(无容器、无 ZeroMQ (ZMQ))的开发者,请将 gr00t_inference 换成从 Hub 仓库加载的 LerobotLocalPolicy 实例。提供方会将 lerobot/ 组织下的任何模型 ID 路由到进程内路径:
from strands_robots.policies import create_policy
policy = create_policy("lerobot/act_aloha_sim_transfer_cube_human")
LerobotLocalPolicy 支持 ACT、Diffusion Policy、SmolVLA、π0 和 π0.5,即 LeRobot 自身策略注册表能从 config.json 解析的任何内容。Real-Time Chunking 会自动为附带 rtc_config 的流匹配策略(π0、SmolVLA)开启。
NVIDIA 最近发布的 Cosmos 3 也可作为策略提供方在同一个接口后面使用,因此无论你指向哪个提供方,智能体代码都保持不变。
注意:LerobotLocalPolicy 以 trust_remote_code=True 加载 Hugging Face 模型。设置 STRANDS_TRUST_REMOTE_CODE=1 以选择启用,并且只加载来自你信任的组织的检查点。
第 4 步 - 将策略部署到物理硬件
这与第 3 步的代码相同,只是更改了一个关键字参数。Robot 工厂返回一个由 LeRobot 的 make_robot_from_config 驱动的硬件支持的机器人:
robot = Robot(
"so100",
mode="real",
port="/dev/ttyACM0",
data_config="so100_dualcam",
cameras={
"front": {"type": "opencv", "index_or_path": "/dev/video0", "fps": 30},
"wrist": {"type": "opencv", "index_or_path": "/dev/video2", "fps": 30},
},
)
agent = Agent(tools=[robot, gr00t_inference])
agent(
"Start GR00T inference on port 5555 with the cube-picking checkpoint "
"from my_user/cube-picker. Then ask the robot to pick up the red cube."
)
同一个智能体提示词现在可以对一条物理机械臂运行。硬件路径使用 LeRobot 的机器人抽象来进行关节指令和摄像头读取,而可在端口 5555 访问的 GR00T 容器则生成动作块。
在针对你的 SO-101 运行之前,从动臂和主动臂的校准都必须就位。对每个设备运行一次 LeRobot 的校准命令(lerobot-calibrate);这些文件会落在 ~/.cache/huggingface/lerobot/calibration/ 下,任何涉及硬件的 Strands 代码路径都会从那里读取它们。如果缺少校准,智能体会从 LeRobot 驱动层抛出错误。
第 5 步 - 使用网格协调多个机器人
到目前为止,我们一次只驱动一个机器人。网格是 Strands Robots 处理多个机器人的方式。想象一下,你桌上的主动臂遥操作另一个房间里的从动臂,或者五台 SO-101 并行运行同一个仓库任务,又或者一个人形机器人与移动底座协调。所有这些都是网格模式。网格构建在 Zenoh 之上,这是一种开源的点对点协议,你无需管理 IP 地址、编写发现代码或选择代理;新机器人一启动就会出现在网格上,智能体可以同时与它们所有人通信。
每个 Robot() 和每个 Simulation() 都会自动加入 Zenoh 对等网格。robot_mesh 工具为智能体提供了一套用于集群操作的词汇,例如发现、结构化命令、广播和紧急停止:
agent = Agent(tools=[robot_mesh])
agent(
"List every robot and simulation on the mesh. "
"Then send 'go to home pose' to each one in parallel."
)
智能体调用 robot_mesh(action="peers") 来枚举本地节点和已发现的对等节点,然后调用 robot_mesh(action="broadcast", ...) 向每个对等节点发送带超时的结构化命令。添加 [mesh-iot] 额外组件可通过 AWS IoT Core 为此流量路由,以支持跨网络集群。项目文档中 robot_mesh 工具的操作参考涵盖了完整词汇:subscribe、watch、inbox 以及结构化点对点命令。
默认情况下,每个物理致动的网格操作在运行前都会暂停以等待人工审批中断:包括全集群广播和 emergency_stop,以及单对等节点的 tell、send 和 stop。你可以通过 STRANDS_MESH_HITL_ACTIONS 环境变量来调整这一集合(将其设置为 all、none 或以逗号分隔的子集)。第一次运行此示例时,你会在终端中看到 robot_mesh-broadcast-approval 提示;输入 y(或 yes / approve)以授权广播。该审批在 LLM 工具参数之外带外传递,因此试图将审批标志偷偷塞入命令体的提示注入攻击无法绕过这道关卡。
传输层可以扩展而无需改动智能体代码。内置的 Zenoh 网格是自动回退方案:在局域网上,Zenoh 组播无需代理即可处理对等节点发现;添加 [mesh-iot] 额外组件后,可通过 AWS IoT Core(使用 mTLS 的 MQTT5)为云端集群路由流量,并用 BridgeTransport 将局域网和云端汇聚在同一个 API 后面(通过 STRANDS_MESH_BACKEND=bridge 选择它)。
对于生产环境中的机器人集群,Device Connect 是与 Arm 合作开发的设备感知网络层,负责处理发现、在线状态、结构化 RPC、事件路由和安全。同一个 robot_mesh 工具在可用时通过 Device Connect 进行分发,否则回退到内置的 Zenoh mesh,因此本文中的 agent 代码在两种情况下都无需更改。有关设置方法和当前可用性,请参阅 Device Connect 文档。
使用示例应用程序试试看
完整示例位于 GitHub 上的 strands-labs/robots,在 examples/lerobot/ 文件夹中。它将全部五个步骤打包为一个 CLI 脚本(hub_to_hardware.py)和一个 notebook(hub_to_hardware.ipynb)。CLI 默认使用 Mock 策略在模拟环境中端到端运行。无需 GPU、无需 Docker、无需 Hugging Face 凭据。
uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
git clone https://github.com/strands-labs/robots.git
cd robots
export STRANDS_MESH_LOCAL_DEV=1
python examples/lerobot/hub_to_hardware.py
录制好的数据集会存放在 ~/.cache/huggingface/lerobot/local/strands-cube-pick/。如果要推送到 Hugging Face Hub 而不是保留在本地,请在使用 write 权限导出 HF_TOKEN 后传入 --hf-user <your-user>。要在步骤 3 中获得真实的抓取行为,请传入 --policy groot --checkpoint <hf_repo>(需要 Docker + NVIDIA GPU)或 --policy lerobot_local --checkpoint <hf_repo>(需要 GPU 和 STRANDS_TRUST_REMOTE_CODE=1)。
该 notebook(examples/lerobot/hub_to_hardware.ipynb)会逐单元格讲解相同的工作流程,并在每个步骤之间附带说明。在 JupyterLab 中打开它,并在模拟模式下从上到下运行即可。
安全注意事项
本设置中展示的代码片段代表了一个使用 HuggingFace 设置 Strands Robots 的“hello world”示例。对于更严肃、可投入生产的使用场景,用户应注意一些重要事项:
提示注入
将不受信任的数据提供给 agent 可能导致提示注入,即不可信的上下文被当作 LLM 指令来处理。考虑到这些机器人在物理空间中的执行动作,这是一个需要跟踪的重要风险。为了缓解这种行为,开发者应谨慎,只向机器人提供来自可信来源的数据。如果并非所有输入数据都可信任,开发者应限制 agent 可用的工具,以防止机器人执行安全关键操作。
Robot Mesh 认证行为
本博客代码片段中共享的 STRANDS_MESH_LOCAL_DEV=1 设置会在没有身份验证或访问控制的情况下初始化 Robot Mesh。这意味着同一网络上的任何设备都可以向机器人集群发送命令。这对于受信任的开发环境是可以接受的,但不适用于不受信任的网络或生产环境。对于这些使用场景,需要使用 STRANDS_MESH_AUTH_MODE=mtls。
面向整个机器人集群操作的人工审批
robot_mesh 工具中会实际执行动作的操作会影响网络中的对等节点:broadcast 和 emergency_stop 会触及每个对等节点,而 tell、send 和 stop 只会触及单个目标对等节点。为了防止 agent 自主发出这些命令(或在提示注入下发出),默认情况下这五个命令都通过 human-in-the-loop 中断进行门控。当 agent 调用受门控的操作时,Strands 运行时会暂停 agent 循环,并要求操作员在 LLM 的工具参数之外进行批准。你可以使用 STRANDS_MESH_HITL_ACTIONS 环境变量调整受门控的集合(all、none 或以逗号分隔的子集)。逐操作速率限制、命令验证和审计追踪会与中断一起运行。在 agent 循环之外(裸脚本或单元测试),受门控的操作会以失败关闭的方式处理。
清理
前面的工作流会启动一个 GR00T 容器、打开硬件上的串口,并写入本地数据集缓存。要将环境恢复到干净状态:
- 停止 GR00T 推理容器:
agent.tool.gr00t_inference(action="stop", port=5555),或使用lifecycle="teardown"同时删除该容器。 - 释放串口:如果你走了硬件路径,请断开 SO-101 follower 和 leader。
- 可选:删除本地数据集缓存:录制的数据集位于
~/.cache/huggingface/lerobot/<repo_id>下。你推送到 Hub 的数据集不受影响。
各部分如何协同
该集成的核心设计选择是:Strands Robots 不会重新实现 LeRobot 已经提供的功能。硬件抽象、校准和数据集格式仍由上游负责。Strands 增加了 AgentTool 接口层,使它们可以通过自然语言进行组合。
由此产生两个结果。对用户而言,Hub 上的每个数据集都是 agent 可以扩展、微调并直接部署的资产,无需任何转换步骤。对开发者而言,仿真数据和硬件数据共享同一种文件格式,因此为其中一方编写的训练脚本可以原封不动地用于另一方。仿真与真实之间的界线变成了部署细节,而非架构上的鸿沟。
接下来做什么
图 4。Strands Robots 目录涵盖机械臂、人形机器人、四足机器人和手部,全部处于同一 MuJoCo 仿真中,并位于同一个 Robot() 工厂之后。本文中的 SO-100 是众多受支持本体之一。
完整的 Strands Robots 文档深入介绍了机器人目录、仿真、策略提供程序、mesh 和 Device Connect。对于更大的工作负载,strands-labs/robots-sim 仓库托管了更重的仿真后端,包括 Isaac Sim 和 Newton,以及一个 LIBERO 基准示例。两个后端都接入本文所示的同一个 Robot 抽象,因此随着规模扩大,agent 代码保持不变。
欢迎在 Apache 2.0 许可下贡献代码。如果你用这套工作流构建了什么东西,请开一个 issue,说明哪些地方好用、哪些地方不好用。当开发者反馈直接落到需要改进的地方时,SDK 的改进速度最快。
资源
- Strands Robots(SDK、AgentTools、Robot 工厂):github.com/strands-labs/robots,Apache 2.0
- Strands Robots 文档(完整文档):strands-labs.github.io/robots
- Strands Robots Sim(示例、仿真后端):github.com/strands-labs/robots-sim
- 示例:examples/lerobot/hub_to_hardware.py 和 hub_to_hardware.ipynb
- 如何构建物理 AI Agent:面向真实世界机器人的自然语言:直播和博客
- 深入探索物理 AI | S1E4 | 使用 NVIDIA NeMo Agent Toolkit 和 Bedrock AgentCore 实现自动化:直播
- LeRobot:github.com/huggingface/lerobot - 数据集、策略、硬件驱动
- Strands Agents SDK:github.com/strands-agents/harness-sdk
- SmolVLA:SmolVLA
- Pi0:Pi0
- NVIDIA Isaac-GR00T N1.7:GR00T N1.7
- NVIDIA Cosmos3 Nano:Cosmos 3 Nano
作者
Cagatay Cali 是 AWS 的研究工程师,专注于 Agentic AI 和机器人技术。他设计连接 AI 智能体与物理机器人的接口,使开发者能够通过自然语言控制机器人系统,让任何技能水平的构建者都能接触智能体和机器人开发。
Sundar Raghavan 是 AWS Agentic AI Foundations 团队的高级解决方案架构师。他负责 Amazon Bedrock AgentCore 的开发者体验,掌管 SDK 和 CLI,并推动框架与生态集成战略。他关注开发者如何在 AWS 上构建、部署和扩展生产级 AI 智能体。他目前正将这一关注扩展到物理 AI,合作开展 Strands Robots,将同样的智能体开发者体验带入机器人领域。
来源:Hugging Face Blog · hf-mirror.com



