Strands Robots SDK:用单一智能体打通 Hugging Face Hub 到物理机器人
阅读原文· huggingface.coAWS 的 Strands Robots 把 LeRobot 仿真和硬件部署装进同一个 Agent 里,代码几乎不变就能从模拟切到物理机器人,对具身智能开发者是省掉胶水代码的实用工具。
AWS(Apache 2.0)开源的 Strands Robots SDK 将 LeRobot 栈封装为 AgentTools,构建统一智能体。默认用 MuJoCo 模拟(无需硬件),mode="real" 切换至真实机器人。可记录演示数据为 LeRobotDataset 并推送 Hugging Face Hub,运行 GR00T 或 LerobotLocal 策略推理,经 Zenoh mesh 广播命令到多台机器人。模拟与硬件代码完全一致,只需改一个关键字参数。示例可在笔记本(Python 3.12+,Linux/macOS)无硬件、无 GPU 运行。
从 Hugging Face Hub 到机器⼈硬件:借助 Strands Agents 和 LeRobot
你有一台机器⼈、一个放在 Hugging Face Hub 上的演示数据文件夹,以及一个想要让它学习的新任务。目前你得用五个不同的工具:一个录制新演示,一个训练,一个在模拟器中测试,自定义代码部署到硬件上,当你有不止一台机器⼈时还要另一个工具来协调。每个工具各自独立工作,它们之间不会互相通信。
Strands Robots 是 AWS 推出的一个开源 SDK(Apache 2.0),它将机器⼈抽象、模拟环境以及 LeRobot 栈暴露为 AgentTools,你可以把它们组合成一个单一的 Strands agent。这个集成设计得刻意很薄:LeRobot 自己的脚本处理硬件录制和标定,而 Strands AgentTools 只负责 agent 实际编排的那些部分。模拟工具录制的 LeRobotDataset 格式与 LeRobot 在硬件上写入的格式完全相同。GR00T 和 LerobotLocal 通过统一的接口提供策略推理,MolmoAct2 检查点则经由 LerobotLocal 路径运行。一个对等网格(peer mesh)将 agent 扩展到远程机器⼈。数据集格式完全保持 LeRobot 原有的样子;agent 循环就是把它们粘合起来的胶水。
这篇博文带你走完单个 agent 内的五个步骤:基于 LeRobot AgentTools 构建 agent,在模拟器中录制一个演示作为 LeRobotDataset,在同一个机器⼈上运行策略,只需修改一个关键词参数就把同样的 agent 代码部署到物理 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 驱动的硬件机器人。两种模式下的智能体代码完全相同。第二,用于写入 LeRobotDataset 的 DatasetRecorder 在仿真路径和 LeRobot 自身的硬件录制之间共享,因此在 MuJoCo 中捕获的数据集与从物理 SO-101 机器人捕获的数据集格式相同。
整个工作流程只需五行 Python 代码:
from strands_robots import Robot
from strands import Agent
arm = Robot("so100")
agent = Agent(tools=[arm])
agent("Pick up the red cube")
接下来将逐步介绍该调用内部实际发生的情况。
先决条件
最小配置(默认仿真路径)
- Python 3.12+,Linux 或 macOS(MuJoCo 后端支持 Apple Silicon)。
- 一个兼容 Strands 的模型提供者,用于智能体的推理。可选用带有 AWS 凭证的 Amazon Bedrock、Anthropic API、OpenAI 或本地运行的 Ollama。
- 使用额外安装选项安装 Strands Robots:uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
仅此而已。本文中的示例在具备上述三项条件的笔记本电脑上端到端运行。
高级配置(硬件部署、真实策略、推送到 Hub)
- 一个具有写入权限的 Hugging Face 账户和令牌,用于从 Hub 推送数据集和拉取策略检查点。
- 在硬件路径方面:需要一个 SO-101 从跟随器和主控制器对,或其他任何 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
如果你希望智能体将数据集推送到 Hub 或从 Hub 拉取策略,则需要导出你的 Hugging Face token。对于本文中的默认模拟路径而言,这一步是可选的;该示例使用 Mock 策略端到端运行,并将数据集写入本地缓存,无需访问 Hub。
export HF_TOKEN=hf_...
可运行的示例位于 `strands-labs/robots` 仓库下的 `examples/lerobot/hub_to_hardware.py`(Python 脚本)和 `hub_to_hardware.ipynb`(Notebook),该仓库中还包含 MuJoCo 与 LIBERO 示例。推荐从 Notebook 开始:在 JupyterLab 中打开它,在模拟模式下从上到下运行单元格,无需连接任何硬件。
步骤 2——录制演示并推送到 Hub
模拟工具会录制 LeRobotDataset,其格式与 LeRobot 在硬件上写入的格式一致。不需要任何硬件。模拟工具的 `start_recording` 动作通过同一个 `DatasetRecorder` 类写入数据:关节状态和动作使用相同的 parquet 模式,每个摄像头使用相同的 MP4 布局。智能体提示几乎相同:
from strands import Agent
from strands_robots import Robot
robot = Robot("so100")
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)
这个特征字典在结构上与 Hub 上的任何 LeRobot 数据集完全相同:相同的列名、相同的 parquet+MP4 布局、相同的加载器路径。原本用于消费硬件录制数据的训练脚本,无需修改即可消费模拟记录的数据。如果希望如此,从模拟环境推送的数据集可以放在同一个 Hub 仓库中,与硬件录制的数据并列。
来自录制的 LeRobotDataset 的单个片段,从记录器写入的每个相机的 MP4 文件回放,与训练脚本读取的磁盘视频文件相同。
在硬件上录制
要在物理 SO-101 上录制演示而非在模拟环境中,请直接使用 LeRobot 的录制 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 上准备好之后,下一步就是运行策略。示例使用了 Robot() 工厂的默认 sim 模式,然后附加 gr00t_inference,让智能体能够管理推理容器:
from strands import Agent
from strands_robots import Robot, gr00t_inference
robot = Robot("so100")
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 解析的模型都支持。对于自带 rtc_config 的流匹配策略(π0、SmolVLA),实时分块功能会自动启用。
NVIDIA 近期发布的 Cosmos 3 也可作为同一接口下的策略提供器,因此无论你指向哪个提供器,智能体代码都保持不变。
注意:LerobotLocalPolicy 加载 Hugging Face 模型时需设置 trust_remote_code=True。请设置 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 容器则生成动作块。
在执行此操作之前,需要先完成从端(follower)和主端(leader)的校准。你需要对每台设备运行一次 LeRobot 的校准命令(`lerobot-calibrate`);生成的校准文件会存放在 `~/.cache/huggingface/lerobot/calibration/` 目录下,任何涉及硬件的 Strands 代码路径都会从该目录读取这些文件。如果缺少校准文件,智能体(agent)会在 LeRobot 驱动层抛出错误。
第 5 步 - 利用网格(mesh)协调多台机器人
到目前为止,我们一次只驱动一台机器人。而网格正是 Strands Robots 处理多台机器人协作的方式。想象一下:你办公桌上的主端手臂(leader arm)远程操控另一房间的从端手臂(follower arm);或者五台 SO-101 同时执行同一仓库任务;又或者一台人形机器人与移动底座协同工作——所有这些都属于网格模式。该网格基于开源点对点协议 Zenoh 构建,你无需管理 IP 地址、编写发现代码或选择代理(broker);新机器人一上线就会自动出现在网格中,且智能体可以同时与所有机器人通信。
每一个 `Robot()` 和每一个 `Simulation()` 都会自动加入到一个 Zenoh 点对点网格中。`robot_mesh` 工具为智能体提供了执行机群操作的能力,例如发现(discovery)、结构化指令、广播和紧急停止:
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")` 来枚举本地及已发现的伙伴(peers),然后通过 `robot_mesh(action="broadcast", ...)` 向所有伙伴发送带超时设置的结构化指令。如需跨网络机群路由该流量,可以添加 `[mesh-iot]` 扩展名,使其通过 AWS IoT Core 传输。项目文档中 `robot_mesh` 工具的 action 参考部分涵盖了完整的指令词汇:subscribe(订阅)、watch(监视)、inbox(收件箱)和结构化点对点指令。
默认情况下,每个实际执行物理动作的网格操作在运行前都会暂停,等待人工审批中断:包括整个机群的广播和紧急停止,以及单节点通信、发送和停止。你可以通过 `STRANDS_MESH_HITL_ACTIONS` 环境变量(设置为 all、none 或逗号分隔的子集)来调整这一集合。当你首次运行此示例时,终端中会出现 `robot_mesh-broadcast-approval` 提示;输入 `y`(或 yes / approve)以授权广播。该审批在大语言模型的工具参数带外进行,因此试图将审批标志混入命令体的提示注入攻击无法绕过这一关卡。
传输层无需改动智能体代码即可扩展。内置的 Zenoh 网格是自动回退方案:在局域网中,Zenoh 多播无需代理即可完成节点发现;添加 `[mesh-iot]` 扩展选项后,可通过 AWS IoT Core(采用 mTLS 的 MQTT5)将流量路由到云端机群,并借助 BridgeTransport 将局域网和云端流量整合在单一 API 背后(通过 `STRANDS_MESH_BACKEND=bridge` 选择该后端)。
对于生产级机群,Device Connect(与 Arm 合作开发的、面向设备的网络层)负责处理节点发现、在线状态、结构化 RPC、事件路由和安全性。同样的 `robot_mesh` 工具在 Device Connect 可用时会通过它进行分发,否则回退到内置的 Zenoh 网格,因此本文中的智能体代码无需任何改动。请参阅 Device Connect 文档了解其设置和当前可用性。
通过示例应用程序进行尝试
完整示例位于 GitHub 上的 strands-labs/robots 仓库的 examples/lerobot/ 文件夹中。它将所有五个步骤打包成一个 CLI 脚本(`hub_to_hardware.py`)和一个笔记本(`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 而不是保存在本地,请在导出具有写入权限的 `HF_TOKEN` 后,加上参数 `--hf-user <your-user>`。对于第三步中的实际抓取行为,请传递参数 `--policy groot --checkpoint <hf_repo>`(需要 Docker + NVIDIA GPU)或 `--policy lerobot_local --checkpoint <hf_repo>`(需要 GPU 并设置 `STRANDS_TRUST_REMOTE_CODE=1`)。
该笔记本 (`examples/lerobot/hub_to_hardware.ipynb`) 会逐步演示相同的工作流程,每一步之间都有说明文字。在 JupyterLab 中打开它,然后在模拟模式下从头到尾运行。
安全注意事项
本配置指南中展示的代码片段,只是一个将 Strands Robots 与 HuggingFace 集成的“hello world”示例。对于更严肃、面向生产环境的用例,用户需要注意以下一些重要事项:
提示词注入
向 AI 智能体提供不可信数据可能会导致提示词注入,即将不可信的上下文当作大语言模型的指令来处理。考虑到这些机器人是在物理空间中运动的,这是一个需要追踪的重要风险。为了缓解这种行为,开发者应小心地只向机器人提供来自可信来源的数据。如果无法确保所有输入数据都可信,开发者应限制 AI 智能体可使用的工具,以防止机器人执行关键安全操作。
机器人网格身份验证行为
本博客代码片段中分享的 `STRANDS_MESH_LOCAL_DEV=1` 设置,会在不进行身份验证或访问控制的情况下初始化机器人网格。这意味着同一网络中的任何设备都可以向机器人集群发送指令。这对于受信任的开发环境是可以接受的,但不适用于不受信任的网络或生产环境。对于这些用例,必须使用 `STRANDS_MESH_AUTH_MODE=mtls`。
集群范围操作需获得操作员批准
robot_mesh 工具的物理执行动作会影响网络上的其他对等节点:broadcast 和 emergency_stop 会到达所有对等节点,而 tell、send 和 stop 仅到达单个目标对等节点。为防止智能体自主(或在提示注入下)发出这些命令,默认情况下,所有五个动作都通过人工介入中断进行拦截。当智能体调用一个被拦截的动作时,Strands 运行时暂停智能体循环,并要求操作员在大语言模型的工具参数之外进行批准。您可以通过 `STRANDS_MESH_HITL_ACTIONS` 环境变量(可选值:all、none,或逗号分隔的子集)来调整被拦截的动作集合。每个动作都有速率限制、命令验证和审计跟踪,与中断机制并行运行。在智能体循环之外(例如裸脚本或单元测试中),被拦截的动作将故障安全关闭。
清理
上述工作流会启动一个 GR00T 容器,打开硬件上的串行端口,并写入本地数据集缓存。要将环境恢复到干净状态,请执行以下操作:
- 停止 GR00T 推理容器:`agent.tool.gr00t_inference(action="stop", port=5555)`,或者使用 `lifecycle="teardown"` 同时移除容器。
- 释放串行端口:如果您运行了硬件路径,请断开 SO-101 从端和主端的连接。
- 可选地移除本地数据集缓存:录制后的数据集位于 `~/.cache/huggingface/lerobot/<repo_id>` 下。您推送到 Hub 的数据集不受影响。
各组件如何协同工作
该集成的核心设计原则是:Strand Robots 不会重新实现 LeRobot 已有的功能。硬件抽象、标定和数据集格式均保留在上游。Strands 新增了 AgentTool 接口,使其能够通过自然语言组合使用。
由此产生两个结果。对于用户而言,Hub 上的每个数据集都是一项资产,智能体可以直接扩展、微调并部署,无需任何转换步骤。对于开发者而言,仿真数据和硬件数据共享单一文件格式,因此为其中一种数据编写的训练脚本可直接用于另一种数据。仿真与现实之间的界限变成了部署细节,而非架构上的鸿沟。
后续方向
图 4:Strands Robots 目录包含手臂、人形机器人、四足机器人和机械手,全部运行在同一个 MuJoCo 模拟环境中,并通过同一个 `Robot()` 工厂调用。本文中的 SO-100 是所支持的多种实体之一。
完整的 Strands Robots 文档深入介绍了机器人目录、仿真、策略引擎、网格和 Device Connect。对于更大规模的工作负载,`strands-labs/robots-sim` 仓库托管了更重量级的仿真后端,包括 Isaac Sim 和 Newton,以及一个 LIBERO 基准测试示例。这两个后端都接入本文介绍的同一个 `Robot` 抽象层,因此在扩展规模时,智能体代码保持不变。
欢迎在 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 智能体:面向真实世界机器人的自然语言——直播与博客
- 深入探讨物理 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 的研究工程师,专注于智能体 AI 和机器人技术。他负责设计连接 AI 智能体与物理机器人的接口,使开发者能够通过自然语言控制机器人系统,并让不同技能水平的构建者都能轻松上手智能体与机器人开发。
Sundar Raghavan 是 AWS 智能体 AI 基础团队的资深解决方案架构师。他负责 Amazon Bedrock AgentCore 的开发者体验,掌管 SDK 和 CLI,并主导框架与生态集成策略。他专注于开发者如何在 AWS 上构建、部署和规模化生产级 AI 智能体。目前,他将这一关注点扩展到物理 AI 领域,与 Strands Robots 合作,将相同的智能体开发者体验引入机器人技术。
本文提及的模型:5 个
社区
· 或发表评论



