Record, train, and deploy from one place with Strands Agents, LeRobot, and Hugging Face Storage Buckets
Back to Articles Record, train, and deploy from one place with Strands Agents, LeRobot, and Hugging Face Storage Buckets Enterprise Article Published August 13, 2026 Upvote 5 Sundar Raghavan rsundaraws Follow amazon Steven Palma imstevenpmwork Follow amazon Cagatay Cali cagataydev Follow amazon AWS…
Back to Articles Record, train, and deploy from one place with Strands Agents, LeRobot, and Hugging Face Storage Buckets Enterprise Article Published August 13, 2026 Upvote 5 Sundar Raghavan rsundaraws Follow amazon Steven Palma imstevenpmwork Follow amazon Cagatay Cali cagataydev Follow amazon AWS Arron awsarron Follow amazon Yin Song yinsong1986 Follow amazon A walkthrough of the streaming data loop in Strands Robots, one agent loop that records robot demonstrations, trains on them by reading straight from the Hub, and deploys the policy back to hardware, with the dataset in the same on-disk LeRobot format the whole way through. You have an agent that can already record a demonstration and push it to the Hugging Face Hub. Now you want to run that loop continuously: collect episodes through the day, train a policy on the growing dataset, deploy it, and pull the next batch back to improve it. Run that loop once and every piece works. Run it every day and you start paying for the same byte transfers over and over. The recordings you upload keep growing, each training run copies the whole dataset to the GPUs before it starts, and every new checkpoint ships out while the next batch of recordings comes back. The first post in this series introduced Strands Robots, an open source SDK from AWS (Apache 2.0) that exposes robot abstractions, simulation, and the LeRobot stack as AgentTools you compose into a single Strands agent. It covered the Robot() factory, recording a demonstration in simulation, running a policy, and deploying the same agent code to a physical SO-101. That factory resolves a name against a registry of arms, humanoids, mobile bases, and hands, so the SO-100 used throughout this post is one of many supported embodiments. The robot catalog lists every robot the factory knows about. LeRobot's dataset format is already used by over 90,000 datasets and models on the Hub from more than 8,000 publishers (LeRobot Project Pulse). A Strands Robots recording is one more of them, so anything built to read LeRobot data can read it without conversion. If you are new to Strands Robots, start there; this post assumes that setup. That post followed the agent loop in one direction, from a Hub dataset to a physical robot. This one follows the data the other way, from the first recorded frame back to the deployed policy, over Hugging Face Storage Buckets - a mutable, non-versioned, Xet-backed object-storage repository type announced in March 2026. A bucket sits beside your dataset repositories in the same hf:// namespace and uses the hf CLI you already have, so it becomes the working layer that holds your data between the day you record it and the day you train on it. Someone has to decide which episodes to keep, when the scene has drifted far enough to re-record, whether today's batch is enough to train on, and which checkpoint replaces the one on the arm. Each of those decisions comes up dozens of times over a collection campaign, and each one needs a look at what came back before the next command goes out. That is the work an agent is for. This post walks you through the data loop inside a single agent: record a demonstration into a Storage Bucket, store it so that each sync uploads only the bytes that changed, train by streaming the dataset straight from the Hub instead of downloading it, and deploy the checkpoint back to hardware with one keyword argument change. The runnable companion to this post lives at examples/notebooks/05_streaming_data_loop.ipynb. What you'll build Where the first post recorded a dataset and pushed it to the Hub, the agent you build here records a LeRobotDataset from a natural-language prompt, syncs it into a Storage Bucket, and streams that same dataset back frame by frame, decoding camera video on the fly, with no local copy. You read it back in the same process that wrote it: the same Strands Robots Robot() that recorded the dataset streams it. Your trained checkpoint then deploys to that same Robot() with one keyword argument change, and the demonstrations it records on hardware return to the same bucket. Figure 1. The four stages share one backend. Robot("so100") records a LeRobotDataset through the shared DatasetRecorder; sync_dataset_to_bucket(...) syncs it into a Storage Bucket; stream_dataset(...) reads it back over the Hub with no full download; and the trained checkpoint deploys to the same Robot with mode="real". The on-disk format stays exactly as LeRobot wrote it. Because one Robot() both records a dataset and reads it back, collecting data and training on it are two methods on one object over one backend. The agent decides to run an episode and invokes one tool; the rollout then proceeds at the robot's control frequency until the episode ends, with the trained policy producing every action. The whole loop, in a handful of lines: from strands import Agent from strands_robots import Robot sim = Robot("so100") # mode="sim" (default - safe, no hardware) agent = Agent(tools=[sim]) # Record a demonstration and sync it to a bucket. agent("Record a pick-the-cube demo and sync it to my-org/robot-fave.") # Stream it back from the bucket to train, without downloading it first. for batch in sim.stream_dataset("my-org/robot-fave/cube_pick", repo_type="bucket").dataloader(batch_size=64): ... What follows is what's actually happening inside that loop, step by step. Prerequisites Minimal (default simulation path) Python 3.12+, on Linux or macOS (Apple Silicon supported for the MuJoCo backend). A Strands-compatible model provider for the agent's reasoning. Amazon Bedrock with AWS credentials, the Anthropic API, OpenAI, or Ollama running locally. Strands Robots with the dataset extras: uv pip install -U "strands-robots[sim-mujoco,lerobot]>=0.5.1". The lerobot extra pulls in LeRobot (>=0.6.1), datasets, av, and torchcodec, so recording and video decode both work without further setup. Refer to installation guide. That's it. Every stage in this post runs on a laptop with these three. What runs is the loop, not a working policy: the default path uses a mock policy, which records a valid dataset but not a useful one. Advanced (buckets, hardware, real policies) A Hugging Face account and a token with write permission, plus the hf CLI for creating buckets and syncing datasets: pip install -U "huggingface-hub>=1.6.0,=0.5.1" jupyter notebook examples/notebooks/05_streaming_data_loop.ipynb Run the cells top to bottom. The recorded dataset lands under /tmp/nb5_dataset. To sync it to a bucket, set BUCKET = "my-org/robot-fave" in the first cell (after hf auth login); the neighboring RUN_ID names the folder inside the bucket, and the notebook streams back from f"{BUCKET}/{RUN_ID}". To train on a GPU, raise steps to 500 and set device="cuda". The agent-driven version of the same loop lives at examples/06_agent_collect_and_stream.py. Security Considerations The snippets here are a "hello world" of the Strands Robots data loop. Five things change once you run it against real data. Prompt injection. Supplying untrusted data to an agent can lead to prompt injection, where untrustworthy context is treated as LLM instructions. These agents actuate robots and now also write to and read from shared storage, so this is an important risk to track. Feed the agent only data from trusted sources. If not all input can be trusted, restrict the tools available to the agent so it cannot take safety-critical actions or overwrite bucket contents. Training data is a trust boundary. An agent that can write into the collection bucket can also write episodes that a policy later trains on, and that policy drives a physical arm. Keep the credential that writes collection data separate from the one a training job reads with, sync each run under its own run_id so an episode can be traced to the run that produced it and removed on its own, and treat the versioned dataset repository as the reviewed artifact, because the bucket keeps no revisions to audit against. Bucket credentials and scope. sync_dataset_to_bucket(...), stop_recording(bucket=...), and sync_to_bucket upload through the hf CLI using the token from hf auth login. Use a token scoped to the specific namespace you are writing to, prefer --private buckets for collection data, and keep the bucket distinct from the versioned dataset repository you push_to_hub and share. Overwrite in place keeps no revisions. A bucket overwrites in place and retains no revisions, which is what makes it a working layer and also means a repeated run_id replaces the run already stored there. Pass an explicit run_id per collection run, as in sync_dataset_to_bucket("./recordings", "my-org/robot-fave", run_id="run-021"). For anything you need to be able to return to, push_to_hub() to a versioned dataset repository, where every revision is retained. Only use trusted Hugging Face orgs. The local inference path loads Hugging Face models with trust_remote_code=True. Set STRANDS_TRUST_REMOTE_CODE=1 to opt in, and only load checkpoints from organizations you trust. When loading pre-trained weights from the Hub (e.g., via pretrained_name_or_path), verify the organization is trusted before loading. Model weights can contain arbitrary code (pickle-based checkpoints). Prefer safetensors-format checkpoints where available. Clean up The loop leaves a bucket, datasets under /tmp, and a checkpoint on disk. Bucket contents count toward your stored volume, so remove what you no longer need: hf buckets rm my-org/robot-fave/cube_pick/ --recursive --dry-run # lists, removes nothing hf buckets rm my-org/robot-fave/cube_pick/ --recursive # --yes skips the prompt hf buckets delete my-org/robot-fave # takes everything in it rm -rf /tmp/cube_pick /tmp/cube_pick_ft /tmp/nb5_dataset /tmp/nb5_ft Stop any training process still on a GPU instance, and stop the instance. If you ran the notebook, substitute its RUN_ID (nb5_demo by default) for cube_pick. Anything you published with push_to_hub() is in a versioned repository and is untouched. Where to go from here The Strands Robots documentation covers the robot catalog, simulation, policy providers, recording, and the mesh in depth. The recording and datasets guide documents the DatasetRecorder API, sync_dataset_to_bucket / sync_to_bucket, and stream_dataset in full. If you collect from more than one robot, give each one its own run_id and they write into the same bucket in parallel. The multi-robot mesh fans one agent out across those robots, so the same loop becomes a fleet collecting through the day into shared storage. A streaming reader reads one run at a time. The recording and datasets guide describes how to train across several of them. If you want a larger policy than ACT, the TrainSpec and Trainer lifecycle from Step 3 covers GR00T and Cosmos 3 behind their own provider names, so fine-tuning a VLA on the dataset you just streamed is the same calls with a different provider string and a base model. Running the result is where the paths diverge, because a VLA checkpoint deploys to hardware rather than to the simulator you trained from. For heavier simulation to generate that data, the Newton (sim-newton) and Isaac Sim (isaac) backends sit behind the same Robot() factory, so the agent code does not change as you scale up. Bucket streaming reached LeRobot through contributions from both the Strands Robots and LeRobot teams, upstream in LeRobot itself, so the datasets your agent collects are readable by every tool in that ecosystem. That runs both ways: the reader in Step 3 opens any of the LeRobot datasets already published on the Hub, so an agent can replay and evaluate against existing demonstrations before it records one of its own. Contributions are welcome under Apache 2.0. If you build something with this loop, open an issue with what worked and what didn't. Resources Strands Robots SDK, AgentTools, and the Robot() factory: github.com/strands-labs/robots, Apache 2.0 Documentation: strands-labs.github.io/robots Recording and datasets guide: strands-labs.github.io/robots/recording The notebook for this post: examples/notebooks/05_streaming_data_loop.ipynb - run the full loop cell by cell Strands Agents SDK: github.com/strands-agents/harness-sdk LeRobot and the Hub LeRobot: github.com/huggingface/lerobot - datasets, policies, hardware drivers Hugging Face Storage Buckets: Storage Buckets documentation Xet deduplication: From Files to Chunks A pick-and-place dataset in the format this post records: lerobot/svla_so101_pickplace Policies SmolVLA: lerobot/smolvla_base Pi0: lerobot/pi0_base NVIDIA Isaac-GR00T N1.7: nvidia/GR00T-N1.7-3B NVIDIA Cosmos 3 Nano: nvidia/Cosmos3-Nano MolmoAct2, trained for the SO-100/101: allenai/MolmoAct2-SO100_101 - loads through lerobot_local, needs the molmoact2 extra Background First post in this series: From the Hugging Face Hub to robot hardware with Strands Agents and LeRobot The physical-AI data loop that this workflow follows: The Physical AI Data Loop, Steven Palma, Hugging Face, 2026 Bucket throughput and dedup measurements: hf-buckets-benchmark Models mentioned in this article 5 Datasets mentioned in this article 1 Spaces mentioned in this article 3 More from this author From Hugging Face to Amazon SageMaker Studio in one click 20 July 7, 2026 From the Hugging Face Hub to robot hardware with Strands Agents and LeRobot 17 June 17, 2026 Community EditPreview Upload images, audio, and videos by dragging in the text input, pasting, or clicking here. Tap or paste here to upload images Comment · Sign up or log in to comment Upvote 5 Models mentioned in this article 5 Datasets mentioned in this article 1 Spaces mentioned in this article 3Source: Hugging Face — Published — Category: Models