
An agent that measures the workspace and writes the motion, and a policy trained on your own demonstrations, cover different halves of the same problem. This article sets the two side by side with the numbers this platform runs on: episode minimums, what a cloud run costs and what the hours actually depend on, the joint limits and step clamps every written motion has to respect, and the speed ceiling a running policy is held to. It ends in a decision you can make before recording anything.
- •A written motion encodes geometry you already know. A trained policy acquires behaviour you cannot write down. Those are different jobs, and most tasks contain some of each.
- •On this stack the written path is joint space only: one absolute joint angle per command, clamped into that joint's range, and capped at 18 degrees of travel per command, 12 for the gripper.
- •The tool surface an agent sees on a locally connected arm has nine tools and none of them returns a camera image. A written motion here is blind by construction.
- •A policy costs demonstrations before it costs GPU time: 30 episodes for SmolVLA, 50 for ACT, Pi0.5, GR00T N1.5 and N1.7. The rented card is the cheap part at roughly 1 to 12 USD per run.
- •Training is step based, not epoch based. Recording a hundred episodes instead of fifty does not lengthen the run; it changes what each step samples from. The default schedules differ by a factor of fifty across the five models, from 2 000 steps to 100 000.
- •Time to first result differs by an order of magnitude. A written motion is an afternoon. A policy is a recording session, a training run of two to six hours, and an evaluation on the real arm.
Two different jobs that happen to share an arm
There are two ways to make a small arm do something useful, and they are usually discussed as rivals. One is to work out where things are and write the motion: joint angles, in order, driven to and verified. The other is to demonstrate the task a few dozen times and train a network that maps what the cameras see to the next joint command, which is what imitation learning means and what the five models on this platform do.
Framed as a rivalry the question has no answer. Framed as a division of labour it usually answers itself in a minute: a written motion is a way of stating knowledge you already have exactly, and a policy is a way of acquiring knowledge you cannot state. Nobody can write down how hard to squeeze a soft object, what a half-occluded cube looks like from the wrist camera, or when a grasp has already failed. Equally, nobody should record fifty demonstrations to teach an arm to travel between two coordinates it could simply be told.
What follows is the decision, with the numbers this platform actually runs on rather than in the abstract: what the written path can and cannot do on an SO-100 or SO-101, what a policy costs in episodes, hours and dollars, and six questions that in practice settle which side of the line a task falls on. The workflow is identical on both arms, so read SO-100 throughout as SO-100 or SO-101.
What writing the motion actually means on this hardware
The concrete form of the written path here is the local MCP server that ships with the CLI, started by ay-robots mcp. It hands an agent nine tools on the arm that is physically attached to that machine, and it is worth reading them as a list rather than as a description, because the list is the argument: get_status, list_devices, get_joint_positions, move_home, move_joint, start_recording, stop_recording, get_recording_status and list_local_datasets. The copy-paste blocks for wiring it into a client live on the MCP page and the full command list on the CLI reference; the walk through what an agent actually does with those nine is in driving an SO-100 over MCP, and none of it is repeated here.
The only motion primitive in that set is a single joint moved to a single absolute angle in degrees. There is no Cartesian target, no inverse kinematics on the robot side, and no trajectory object that can be stored and replayed. A sweep is a sequence of calls, and everything between them, the ordering, the waiting, the checking, is the agent's own loop. That is the honest shape of it: the platform does not hold a program, it executes one command at a time and reports back what happened.
Every one of those commands passes the same set of guards in the robot backend before it reaches a servo. They matter for a written motion because they are what makes a naive script produce a different result than the one on paper:
| Guard | What it does | What it means for a written motion |
|---|---|---|
| Joint range | Every target is clamped into that joint's range: shoulder pan and wrist roll to plus/minus 150 degrees, shoulder lift to plus/minus 90, elbow flex to plus/minus 120, wrist flex to plus/minus 100, the gripper from minus 160 to 100 | A target outside the range does not fail, it silently becomes the boundary |
| Step clamp | A single command may move a joint at most 18 degrees, and the gripper at most 12 | A 90 degree sweep is at least five commands. One big number gets you 18 degrees and no error |
| Rate limit | Two commands to the same joint closer together than 12 milliseconds: the second is dropped, not queued | A tight loop loses commands rather than moving faster |
| Applied position | The answer carries the angle that actually reached the servo, and whether it was applied at all | This is the field to read after every command. A clamped or dropped move is visible here and nowhere else |
The backend has a collision check function and it currently returns "safe" for every pose, by an explicit decision to allow all positions. Joint ranges are enforced, the arm hitting itself or the table is not. There is also a thermal watchdog polling servo temperatures every two seconds, which parks the arm and blocks motion at 65 degrees until it falls back to 55 - a pose held under load long enough will find it. If an agent is driving, clear the workspace and keep a hand near the power, exactly as you would with your own script.
One more property decides more than any of the above: none of the nine tools returns an image. The backend does serve camera frames and streams over HTTP, but no tool exposes them, so an agent driving through this surface is working from joint angles and whatever a human has told it. That is a deliberate boundary, and it is the single biggest reason a written motion cannot do a policy's job. The two motion tools also refuse to run at all without an explicit confirm flag, which is checked before any HTTP call leaves the process.
The run this article grew out of
In August 2026 Anthropic published the Model Hardware Standard, a specification for letting agents operate physical equipment, and opened a research preview. AY-Robots took part in that preview. In our run an agent measured the workspace of an SO-ARM101 itself and wrote the motion: no policy, no teleoperation, no demonstrations. Reported from that setup were 4.1 mm positioning accuracy and 3.0 mm placement accuracy, and the best run so far placed 12 bricks and formed all four colour groups.
A best run is not a success rate, and a fully hands-off run from start to finish has not happened yet. Nothing in the decision below rests on those numbers; they are here because they are the reason we started sorting tasks this way in the first place. The run itself is written up in moving an SO-ARM101 without a policy, the calibration procedure in our SO-ARM101 calibration report and its general form in hand-eye calibration without a checkerboard, and the specification itself in what MHS changes for your robot arm.
What a policy costs, in the units you actually pay in
The GPU bill is the part everyone asks about and the part that matters least. Five models can be trained from this platform, and the run itself is cheap on all of them. What differs is how much data each needs before it does anything useful, and how fast it answers once it is running.
| Model | Episodes before it is useful | Card the run needs | Typical run | Per action step | Dataset format |
|---|---|---|---|---|---|
| ACT | from about 50 | RTX 4090 or any 24 GB card | 2 to 5 hours, about 1 to 3 USD | 20 ms | LeRobot v3.0 |
| SmolVLA | from about 30 | RTX 4090 or any 24 GB card | 2 to 5 hours, about 1 to 3 USD | 245 ms | LeRobot v3.0 |
| GR00T N1.7 | from about 50 | A100 80 GB or H100 80 GB | 3 to 6 hours, about 4 to 12 USD | 152 ms | LeRobot v2.0 or v2.1 |
| GR00T N1.5 | from about 50 | A100 80 GB or H100 80 GB | 3 to 6 hours, about 4 to 12 USD | 165 ms | LeRobot v2.0 or v2.1 |
| Pi0.5 | from about 50 | A100 80 GB or H100 80 GB | 3 to 6 hours, about 4 to 12 USD | 485 ms | LeRobot v3.0 |
Those hourly figures are spot market ranges rather than a quote, because the training pool rents by the hour and picks a card by the VRAM the model needs. The same numbers are on the pricing page and the same table is what the hosted MCP server returns from its cost estimator, so an agent asked what a run will cost gives the answer the page gives. Per-step latency is worth a second look before choosing: at 485 ms Pi0.5 is visible as hesitation on fast motions, which is a property of the deployment and not of the training bill. The term is explained under inference latency.

More episodes do not make the run longer
The question that follows the table immediately: if fifty episodes cost two to five hours, does a hundred cost twice that? No. Training here is step based rather than epoch based, so the episode count does not change how long a run takes; it changes what each step samples from. The cost estimator on the hosted server states that in its own answer rather than leaving it to be inferred, which is the reason to call it before renting anything. Asked about ACT with thirty episodes, it returns this:
{
"policy": { "slug": "act", "name": "ACT", "trainer": "act" },
"gpu_tier": "RTX_4090",
"gpu": "RTX 4090 or any card with 24 GB",
"steps": { "used": 100000, "model_default": 100000, "scale_factor": 1 },
"estimate": {
"hourly_usd": "0.30 to 0.60 USD",
"duration": "2 to 5 hours",
"total": "about 1 to 3 USD"
},
"episodes": {
"given": 30,
"minimum_for_this_model": 50,
"verdict": "30 episodes is below the 50 this model usually needs. The run costs the same either way; it is the success rate that suffers."
},
"assumptions": [
"Training is step based, not epoch based, so the episode count does not change how long a run takes. It changes what each step samples from.",
"Duration and total are for a single run at 100000 steps on the RTX 4090 or any card with 24 GB tier.",
"Scaling with the step count is linear, which holds for the training loop but ignores queue time and checkpoint uploads."
]
}The step count, not the episode count, is what the duration hangs on, and the five models do not share a default schedule. That is the number to look at before assuming two runs on the same card cost the same:
| Model | Default step schedule | Batch size | Learning rate |
|---|---|---|---|
| ACT | 100 000 steps | 8 | 1e-5 |
| Pi0.5 | 30 000 steps | 1 | 5e-5 |
| GR00T N1.7 | 20 000 steps | 32 | 1e-4 |
| SmolVLA | 20 000 steps | 2 | 1e-4 |
| GR00T N1.5 | 2 000 steps | 1 | 1e-5 |
Two of those batch sizes need a footnote before anyone reads them as a hardware statement. The training form suggests a gradient accumulation value next to the batch size, 16 for Pi0.5 and GR00T N1.5 and 8 for SmolVLA, but it only actually reaches the trainer on the two GR00T entry points. For ACT, SmolVLA and Pi0.5 the batch size in the table is the batch size that trains.
The two to five hours and the three to six hours come from the GPU tier alone. ACT and SmolVLA therefore carry the same label although ACT's default schedule is five times longer, and GR00T N1.5 carries the 80 GB label on a 2 000 step default. Read the range as the order of magnitude for that tier, and pass an explicit step count to the estimator whenever you deviate from a model's default, where the arithmetic does scale linearly.

The real cost is the row on the left. Fifty kept episodes means teleoperating the same task over and over, and the recording guide deliberately splits that across sittings: three sessions of twenty produce better data than one session of sixty, because demonstration quality drops measurably once you are bored. The discipline that goes with it is the rest of the cost: cameras fixed so they cannot be nudged, constant lighting, the same task sentence every time, the object position varied but the strategy not, and every failed attempt discarded rather than kept. The step-by-step version is in record your first dataset, and the reasoning behind the discipline in data collection for the SO-100. A failed grasp in the training set is not a neutral data point; it teaches the policy to fail.
GR00T N1.7 and N1.5 read LeRobot v2.0 and v2.1 and reject a v3.0 dataset. ACT, SmolVLA and Pi0.5 go through lerobot, which reads only v3.0. The desktop client records v2.0, so a fresh recording trains GR00T directly and needs a converted copy for the other three. The hosted MCP server has a compatibility check for exactly this, because a mismatch otherwise kills the run minutes in, with the GPU already rented.
The check answers in the dashboard's own words, which are German, and the three sentences it can return are worth recognising before a run rather than after one:
ACT kann diesen Datensatz nicht verwenden: Er liegt im LeRobot-Format v2.1,
ACT, SmolVLA und Pi0.5 benötigen v3.0. Nimm GR00T N1.7 oder N1.5 - oder
konvertiere den Datensatz nach v3.0.
GR00T N1.7 kann diesen Datensatz nicht verwenden: Er liegt im LeRobot-Format
v3.0, GR00T benötigt v2.1. Nimm die v2.1-Fassung dieses Datensatzes.
Liegt im LeRobot-v2.1-Format (GR00T) und nicht auf HuggingFace - ACT, SmolVLA
und Pi0.5 benötigen v3.0 vom Hub.The first of the three is the one nobody expects, because it fires on datasets that are demonstrably on the Hugging Face Hub. What the check measures is codebase_version in meta/info.json, not whether the repository resolves: a v2.1 tree that exists on the Hub is exactly what a Pi0.5 run once died on, with lerobot raising a backward-compatibility error the moment it opened the dataset. The third message covers the mirror image, a dataset whose format could not be measured and that is provably not on the Hub, which is how a copy that lives only in the bucket fails four or five minutes in with a repository-not-found error, by which time the card is rented and billing. Everything unclear in between deliberately passes: when the format cannot be measured at all, the dataset counts as compatible and the guard in the start route stays the last line of defence.
Conversion runs in one direction on its own. The lerobot package converts upward, v2.1 to v3.0; going back down to the GR00T layout is a separate script on the training server rather than a button. The practical rule is to upload the converted copy under a new name instead of replacing the original, then re-read total_episodes on the copy, because a conversion that silently dropped episodes does not announce itself. The full procedure, both directions and the checks, is on the fix page for a rejected dataset version.
Training has no CLI command, which surprises people who look for one: it runs on the rented card and is started from the web dashboard or through the hosted server's training tool. The commands that do exist are the ones around it, recording, listing, uploading, and running a finished policy back on the arm.
The two paths are not allowed the same speed
Neither table above shows this, and for some tasks it decides more than the latency column does: the same backend holds a written motion and a running policy to different speed limits, and the policy's are the tighter ones. Per action step a policy is quick, 20 milliseconds for ACT. Per second of travel on the arm it is the slower of the two, and deliberately so.
| Written motion, one command at a time | Running policy, inference loop | |
|---|---|---|
| Cap per command or per tick | 18 degrees per command, 12 for the gripper | a per-tick cap derived from the control rate rather than fixed; at 30 Hz it works out at about 1.3 degrees |
| Degrees per second | no explicit ceiling. What bounds it is the step size, the 12 millisecond minimum gap between two commands to the same joint on the same arm, and the servo's own speed and acceleration settings, which default to 350 of 1023 and 80 of 254 | a hard ceiling of 40 degrees per second, enforced independently of the control rate |
| What the cap is measured against | the last position read back from that arm | the last command the backend sent, not the last position it read |
| Where the setting lives | ROBOTAPP_MAX_STEP_DEG, ROBOTAPP_GRIPPER_MAX_STEP_DEG, ROBOTAPP_MOTOR_MIN_INTERVAL_MS | AYR_INFER_MAX_DEG_S and AYR_INFER_MAX_STEP_DEG; a per-run value may only tighten the cap, never widen it |
Two details in that right-hand column are worth understanding rather than memorising. The degrees-per-second ceiling is invariant to the control rate on purpose: raising the loop from 30 Hz to 60 Hz shrinks the per-tick cap in the same proportion, so a faster loop buys smoother motion and never a faster arm. And the cap is measured against the last command sent rather than the last position read, because during inference the state read contends with the write path and can go stale. A clamp that compares against a stale position is a clamp that has stopped clamping, which is the failure this construction is built to avoid.
For the decision the consequence is narrow but real. If the uncertain part of your task has to happen faster than 40 degrees per second, that is a property of how the policy is deployed here and not of the policy you trained, and no amount of demonstrations changes it. If the geometric part of your task is a long transit, the written path will cross it faster than a policy will. It is one more reason why the seam described further down tends to fall where it does.
Six questions that settle it
Sorted by task property rather than by technology, most cases decide themselves. The last column is the part worth doing before the argument, because it is cheaper than either approach.
| Question | Points to a written motion | Points to a trained policy | How to answer it cheaply |
|---|---|---|---|
| What kind of task is it? | Geometry. Reach a known pose, move between fixed stations, feed a fixture, return home after a fault | Contact and compliance. Grasping something soft, irregular, deformable or unfamiliar | Ask whether the goal can be written down as six joint angles. If it can, it is geometry |
| How much does the scene vary between runs? | The object arrives in a fixture, a slot or a marked position every time | Position, orientation or the object itself changes from run to run | Run the setup ten times without touching anything and write down what moved anyway |
| How many repetitions do you need? | A handful to a few dozen, or a one-off that has to be exact | Enough runs that an afternoon of recording and one training run amortise | Multiply the gain per run by the number of runs and compare it against that afternoon |
| What data do you already have? | None, and you are not planning to record any | An existing LeRobot dataset of this task, your own or bought | ay-robots datasets list --local, and read codebase_version in meta/info.json before you count on it |
| How exact does it have to be? | The same coordinate every time. Repeatability comes from the numbers you wrote | Exactness that depends on what the arm sees, not on a fixed coordinate | Drive to a pose, read the joint positions back, repeat ten times and look at the spread |
| How long until the first result? | Minutes to an afternoon. Nothing to record, nothing to train | A recording session, a run of two to six hours, then an evaluation on the real arm | Take the run duration for the model you would pick from the table above and add the recording day |
Two rows pulling in opposite directions is the normal case, not a failure of the table. It usually means the task has a geometric half and an uncertain half, and that the interesting question is where the seam runs rather than which column wins.
Where a written motion runs out
The limits are not a matter of effort. They follow from what the approach is:
- Anything compliant or deformable. There is no coordinate for how far a cable has slid in the gripper or how a cloth has folded. A joint angle cannot express it, so a written motion cannot aim at it.
- Anything that has to react to the camera at control rate. Reacting to an image is what a policy is; a sequence of joint targets is not a feedback loop, and on this tool surface the agent does not receive images at all.
- Variation the author did not anticipate. Every new case is another branch somebody has to write. The branch does not exist until it is written, and the arm does not know that.
- Perception the agent does not have. If a written motion is to pick up an object that moves, something else has to say where it is, and the quality of the whole thing is the quality of that step.
There is a useful external data point on how far the approach reaches when the perception problem is taken away. Demonstration-Free Robotic Control via LLM Agents runs an unmodified frontier agent framework on the LIBERO, ManiSkill3 and MetaWorld benchmarks and reports success rates of 84.9, 85.7 and 96 percent, with privileged environment state access, which the paper says approaches VLA models trained on fewer than 100 demonstrations per task. The qualifier is the whole point. Those are simulated benchmarks in which the agent is handed the state of the world. On a desk, nothing hands you the state; establishing it is the work.
The other half is written into the problem statement of the ACT paper, which opens by asking whether learning can enable low-cost, imprecise hardware to perform fine manipulation tasks such as threading cable ties or slotting a battery, tasks it describes as requiring precision, careful coordination of contact forces, and closed-loop visual feedback. Two of those three are things a written motion has no way of producing.
Where a policy is expensive
The costs run in the opposite direction and they are mostly human:
- Collecting the data. Thirty to fifty consistent episodes of one task, driven by hand. This is the bill, and it is paid in attention rather than money.
- Keeping the recordings clean. A nudged camera invalidates everything recorded before it was nudged, because the policy learns pixel positions. Lighting, background and the task sentence have to hold still too.
- The training run. Two to six hours during which you learn nothing about whether it worked, because the loss curve is a smoke signal rather than a measure of success.
- Evaluation on hardware. Success rate on physical attempts is the only metric that counts, and producing it means running the arm again and counting.
- The second round. Where it fails, you record more demonstrations of exactly that situation. Targeted data beats more data, but it is another session on the arm either way.
That last point deserves the qualifier that the papers themselves put on it. The DAgger paper states the underlying problem plainly: in sequential prediction, future observations depend on previous actions, which violates the assumptions of ordinary statistical learning and leads to poor performance in theory and often in practice. The ACT authors name the same effect from the practical side, that errors in the policy can compound over time. A trained policy drifts in exactly the states that were thin in your data, and no amount of GPU fixes that. Correcting a running policy and feeding those corrections back is the DAgger loop, which is the one part of this territory that runs on the platform today.
The platform's own guide to imitation learning on the SO-100 sorts the same ground into what works and what struggles, and its "struggles" column is worth reading before committing an afternoon: millimetre precision, long-horizon tasks with many sub-goals, situations far outside the demonstrations, and anything needing force feedback the arm cannot sense. The SO-100 has no force-torque sensing, which is the reason the last item is on the list. The data half of that bill, from the first recorded episode to a dataset somebody else can download, is in from first recording to a listed LeRobot dataset.

Splitting one task along the seam
Nothing described here is an offering. There is no handover mechanism on the platform: the motion tools on the local server and the policy runner started by ay-robots run are separate paths, and no product feature moves control between them mid-task. What follows is how we would split a task by hand, written down because it is the useful part of the comparison.
Most tabletop tasks are not uniformly hard. Approach, retreat, moving between stations, homing after a fault, driving to a fixed start pose before an evaluation: geometry, all of it, and all of it cheaper to write than to demonstrate. The part where the arm touches something uncertain is usually a few seconds long and is the part worth spending demonstrations and GPU hours on. Recording an operator driving a straight line between two known coordinates fifty times spends the expensive resource on the cheap half of the problem.
Splitting deliberately along that seam also improves the dataset, because every episode then contains the part that actually needs to be learned. Whether the split is worth the extra machinery depends on how long the uncertain segment is relative to the whole task. If the whole task is uncertain, there is no seam and the policy does all of it. If none of it is, there was never a reason to record.
The half of the task that has no coordinate
Recording episodes on an SO-100 or SO-101, reviewing them, and training ACT, SmolVLA, Pi0.5 or GR00T on rented GPUs is what this platform does. The training guides list every supported model against every supported arm, with the defaults the training backend really sends.
See the training guidesIf you are unsure, do it in this order
The cheapest sequence is the one that spends the reversible effort first. Every step here either answers the question or produces something the next step needs.
- 1Check what the machine actually sees
Arms and cameras first. If a camera is missing here, everything downstream of it is guesswork, and it is worth fixing before anything else.
bashay-robots devices - 2Set the zero point
Guide the joints to the neutral pose and press Enter. Every joint angle after this, written or learned, is relative to what you capture here, which is why it comes before both paths.
bashay-robots calibrate - 3Try the geometry by hand
Drive the poses your task needs, one joint at a time, and read the positions back between commands. If the task falls out of this in an afternoon, you are done and no dataset was needed. If it does not, you now know precisely which part resisted, which is the part to record.
- 4Record only that part
Aim for fifty kept episodes, thirty if you are starting with SmolVLA. Record appends to a dataset that already exists, so create it first in the web interface, on the Manual Control recording card or on the Datasets page. Enter ends an episode, Ctrl-C throws away the one in progress.
bashay-robots record --dataset red_cube_pick --task "pick up the red cube and place it in the bowl" --episodes 10 ay-robots datasets list --local - 5Upload and train the small model first
Upload takes the dataset id, not a path. Then train SmolVLA or ACT before anything larger: a foundation model on thirty inconsistent episodes performs worse than ACT on the same data and takes far longer to tell you so. Training itself is started in the dashboard or through the hosted MCP server, not from the CLI.
bashay-robots datasets upload red_cube_pick --name "SO-100 red cube pick v1" - 6Run it back and count
Without a checkpoint this runs the base model, which is a useful smoke test before your own policy exists. With one, it is the only measurement that means anything. ay-robots stop ends the policy and leaves the backend up.
bashay-robots run --model act --checkpoint <hf-repo-id-or-s3-uri> --task "pick up the red cube and place it in the bowl"

Two points where the sequence refuses instead of guessing
Most of what can go wrong on the hardware side is the same list for any way of driving this arm, and it is written out message by message in driving an SO-100 over MCP. Two refusals belong to this sequence in particular, because they sit at the two points where it commits to something that is awkward to undo.
| Where | What comes back | Why it is built that way |
|---|---|---|
| Step 2, calibrate with the arm unpowered or unplugged | error: the arm reported no motor positions - nothing was saved. Check that the arm is connected and powered with `ay-robots devices`. | The capture returned an empty position table and the save was skipped rather than sent. Writing an empty table over working home offsets is the more expensive of the two failures, so the command refuses instead. Your previous calibration survives untouched |
| Step 4, record into a dataset name that does not exist | 409 Datensatz '<id>' existiert nicht - erst anlegen | Recording only ever appends to an existing dataset. Before this was checked at the start, a typo surfaced only when the episode was saved, and the take was gone by then |
The third thing that can go wrong here is not on the arm at all, and it is the expensive one: a dataset in the wrong LeRobot version. The compatibility check above catches it before a card is rented and the start route refuses it afterwards, which is worth using rather than trusting, because this is the one step in the sequence that rents a GPU by the hour.
If you have no arm yet, the order collapses to one step: a real SO-100 hangs on the live page and can be driven from the browser without an account or an install, which is enough to see what the geometric half of any of this feels like. The client itself is on the download page, and the walk through the whole chain from a bare arm to a running policy is under run your first policy.

What we have not established
We have not run the two approaches against each other on the same task under the same conditions, and until that exists any statement about which is more reliable on a given task is an opinion. The figures from our own run are a best case on one setup, not a success rate. The episode minimums in the table are the thresholds this platform uses, drawn from what these models need in practice, not measurements from a controlled study. And the seam described above is a way of thinking about a task, not something the software does for you.
What is solid is the shape of the trade: geometry is cheap to write and expensive to demonstrate, contact is impossible to write and learnable from demonstration, and the cost of finding out which one your task is amounts to an afternoon with the arm.
Do I need to train a policy at all to make an SO-100 move?▾
No. The arm can be driven from the desktop client, from the web cockpit, and by an agent through the local MCP server, none of which involves a trained model. Training is for the part of a task you cannot write down as joint angles.
How many demonstrations before training is worth it?▾
SmolVLA is listed at about 30 episodes, ACT, Pi0.5, GR00T N1.5 and GR00T N1.7 at about 50. Below that the run costs the same and the success rate suffers. The recording guide on this site targets fifty kept episodes for a first dataset, with failures discarded rather than saved.
What does one training run cost?▾
On the 24 GB tier, which ACT and SmolVLA use, roughly 2 to 5 hours at 0.30 to 0.60 USD per hour, so about 1 to 3 USD. On the 80 GB tier, which GR00T N1.5, GR00T N1.7 and Pi0.5 use, roughly 3 to 6 hours at 1.20 to 2.00 USD per hour, so about 4 to 12 USD. These are spot market ranges, not a quote.
Can an agent see the camera image while it drives the arm?▾
Not through the local MCP tools. The nine tools return status, devices, joint positions, recording state and the local dataset list. The robot backend does serve camera frames and streams over HTTP, but no tool exposes them, so an agent working through that surface is driving on joint angles and whatever a human tells it.
Will a trained policy move the arm as fast as a written motion?▾
Not on this backend, and that is a deployment property rather than a property of your policy. The inference loop is held to a hard ceiling of 40 degrees per second, derived per tick from the control rate so that a faster loop gives smoother motion rather than a faster arm. A written motion has no degrees-per-second ceiling at all; it is bounded by the 18 degree step per command, the 12 millisecond minimum gap between two commands to the same joint, and the servo's own speed and acceleration settings. If the uncertain part of your task has to happen faster than that, demonstrations will not fix it.
Can I start with a written motion and add a policy later?▾
Nothing is wasted if you do: calibration, camera placement and the fixtures carry over, and the recording path is independent of how you have been driving the arm so far. What does not exist is a handover feature. The motion tools and the policy runner are separate paths, and switching between them mid-task is not something the platform does.
Which model should I start with?▾
SmolVLA is the platform's default first run: cheap enough to iterate on and good enough to tell you whether your data is any good. ACT is the other reasonable start, with no pretraining and no language conditioning, learning exactly your task and nothing else at 20 ms per action step. Compare the five on the policies pages before renting the larger card.
The next concrete step depends on which column your task landed in. If it is geometry, the local server and the command reference are what you need and nothing has to be recorded. If it is contact, start at recording a dataset and pick a model from the policy pages once you know what you have.
Sources
- Anthropic (27 Aug 2026): Previewing the Model Hardware Standard
- Demonstration-Free Robotic Control via LLM Agents (FAEA)
- Zhao, Kumar, Levine, Finn (2023): Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware (ACT)
- Ross, Gordon & Bagnell (2011): A Reduction of Imitation Learning and Structured Prediction to No-Regret Online Learning (DAgger)
- Shukor et al. (2025): SmolVLA — A Vision-Language-Action Model for Affordable and Efficient Robotics
- Physical Intelligence (2025): pi-0.5 — a Vision-Language-Action Model with Open-World Generalization
- NVIDIA (2025): GR00T N1 — An Open Foundation Model for Generalist Humanoid Robots
- Hugging Face LeRobot — SO-101 assembly and calibration guide
- Hugging Face LeRobot — models, datasets and tools for real-world robotics in PyTorch
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started