The AY-Robots teleoperator page inviting remote robot operators, next to a photo of the SO-100 arm they drive
teleoperationdata collectionimitation learninglerobotoperators

Hiring and Training Robot Teleoperators

AY-Robots ResearchAugust 23, 202617 min read

What to look for in a robot teleoperator, how long training really takes, and the measurable ways operator skill shows up in a LeRobot dataset. With real numbers.

What you need to know

  • Operator skill is measurable in the data, not in the interview. In the robomimic study, behavioral cloning on 100 demonstrations from two "better" operators scored 83.3% on Can and 58.7% on Square; the same budget from two "worse" operators scored 56.7% and 22.0%.
  • More data from weaker operators can be worse than less data from a good one: the 300-demonstration multi-human sets never beat the 200-demonstration single-operator sets on any task, and on Square they trailed 78.0% against 84.0% with BC-RNN.
  • Training a new operator takes hours, not weeks. RoboTurk onboarded 54 remote participants with a 5 minute tutorial and one supervised hour.
  • Episode length and its spread is the cheapest quality signal you have. In robomimic the "worse" group needed 304 frames on Can where the "better" group needed 143, at five times the spread.
  • The LeRobot dataset format has no operator field. Record one dataset per operator, judge each, then merge the survivors with lerobot-edit-dataset.
  • Hire for patience and consistency, but fix the control interface before you screen anyone. In the RoboTurk user study the interface alone moved mean completion time from 79.36 s on a VR controller to 151.45 s on a keyboard.

You have an SO-100 on the bench, a task worth automating, and a policy that needs 30 to 50 episodes before it is useful. The bottleneck is not the GPU or the model. It is the person driving the arm. Every frame of a LeRobot dataset records one human's motor habits, and imitation learning copies them faithfully, bad ones included.

This covers the human side of teleoperation: what to look for in an operator, how long training takes, and which numbers in the finished dataset tell you whether they were any good. The published evidence is thin but consistent.

The evidence: operator skill moves policy success by tens of points

The cleanest study is What Matters in Learning from Offline Human Demonstrations for Robot Manipulation (Mandlekar et al., CoRL 2021). Six operators recorded through RoboTurk in three tiers: two experienced ("better"), two adequate ("okay"), two inexperienced ("worse"), each providing 50 demonstrations per single-arm task. The tiers are size-matched, so the comparison isolates skill from volume. The success rates below are the paper's low-dimensional results, Table 2 for the operator mixtures and Table 1 for the single proficient operator; image observations are reported separately in its Table 3.

Data subsetDemosBC on CanBC on SquareBC-RNN on CanBC-RNN on Square
Two "better" operators10083.3%58.7%99.3%66.0%
Two "okay" operators10072.0%27.3%95.3%45.3%
Two "worse" operators10056.7%22.0%92.0%39.3%
Worse + okay mixed20074.7%28.7%98.7%55.3%
Worse + better mixed20076.0%46.7%100.0%73.3%
One proficient operator (PH)20095.3%78.7%100.0%84.0%

On the harder task (Square, where the arm picks a square nut and places it on a rod) the gap between best and worst tier is 36.7 points for plain behavioral cloning. A stronger algorithm absorbs some of it: BC-RNN nearly closes the gap on Can, and leaves 26.7 points open on Square. And 200 demonstrations from one proficient operator (84.0%) beat every 200-demonstration mixture containing a weak one.

The earlier Scaling Robot Supervision to Hundreds of Hours with RoboTurk (IROS 2019) hit the same wall from the other side: 111 hours across 54 users on three Sawyer arms in one week. Behavioral cloning on the full Laundry Layout set failed outright, and partial success came only after restricting training to the segments where the arm moves to a corner of the towel and lifts. Fifty-four people solving an open task in fifty-four ways produced a dataset close to untrainable as one policy. More in our RoboTurk write-up.

The practical reading

Operator variance hurts in two ways. Proficiency variance (shaky, hesitant) adds noise the policy reproduces. Strategy variance (two operators solving the task differently) adds multimodality the policy must average over, which is worse. Practice fixes the first. Writing the task down before anyone touches the arm fixes the second.

How operator skill shows up in the data

You do not need a supervisor at the operator's shoulder. The signal is in the dataset. The robomimic authors published average trajectory lengths per tier, and the pattern is blunt enough to use as a screening rule.

Operator tierLift (frames)Can (frames)Square (frames)Transport (frames)
Better72 +/- 24143 +/- 29185 +/- 46461 +/- 56
Okay94 +/- 30181 +/- 47265 +/- 78636 +/- 128
Worse145 +/- 40304 +/- 148357 +/- 150778 +/- 221

The weaker tier takes roughly twice as long, but the standard deviation is the sharper signal: on Can it goes from 29 frames to 148. A good operator does the same thing every time. A weak one improvises, and improvisation is the multimodality that makes a policy hesitate at the grasp. Compute one number per operator, and make it the coefficient of variation of episode length.

SignalWhere it comes fromWhat a weak operator looks like
Median episode lengthmeta/episodes length columnLong, from re-approaches and corrections
Spread of episode lengthsame column, standard deviationWide: every episode is a different plan
Achieved recording ratethe cadence line lerobot-record printsDrifts below the fps target
Re-record ratehow often they press the left arrowNear zero (they keep bad takes) or very high
Gripper transitions per episodesign changes on the gripper joint in the action columnMany, from repeated open-close attempts
python
# Rank operators by episode-length consistency across per-operator datasets.
# Verified against lerobot 0.6.2 (LeRobotDatasetMetadata.episodes has a "length" column).
import statistics
from lerobot.datasets import LeRobotDatasetMetadata

REPOS = {
    "anna":  "my-org/pick-cube-anna",
    "bruno": "my-org/pick-cube-bruno",
    "chen":  "my-org/pick-cube-chen",
}

for operator, repo_id in REPOS.items():
    meta = LeRobotDatasetMetadata(repo_id)
    lengths = list(meta.episodes["length"])
    median = statistics.median(lengths)
    sd = statistics.pstdev(lengths)
    print(f"{operator:6s} n={len(lengths):3d} "
          f"median={median:6.1f} frames ({median / meta.fps:5.1f} s) "
          f"sd={sd:6.1f} cv={sd / median:.2f}")
Run this before training, not after. The operator with the lowest cv is usually the one whose data trains.

An honest limitation: none of these separate a slow operator from a hard task instance. A 300-frame episode might be a fumbled grasp, or the one initialisation where the cube started at the far edge. Use the statistics to pick who to watch, then watch the video.

What to look for when you hire an operator

The list below is short because the published evidence supports very little. The original RoboTurk user study reports only that its 8 participants were university students aged 18 to 30; no aptitude screening is described. What it did measure, across those 8 participants and four interfaces, is that the interface dominates: the phone (mean 89.97 seconds on the picking task) and the VR controller (79.36 seconds) were statistically indistinguishable, and both were significantly faster than the 3D mouse (112.57 seconds) and the keyboard (151.45 seconds). Fix the interface before screening people. On an SO-100 that means a calibrated leader-follower pair, not an on-screen pad.

What to look forWhy it mattersHow to test it in 30 minutes
Tolerance for repetitionA usable dataset is 50 to 200 near-identical episodesAsk for 20 episodes of one grasp; does episode 20 look like episode 3
Consistency of approachStrategy variance is the damage algorithms cannot repairOverlay the gripper trajectories of those 20 episodes
Willingness to discard a takeA bad episode kept is worse than one not recordedCount left-arrow presses. Zero is a red flag
Camera-frame awarenessThe policy sees only the cameras, never the roomHave them work from the rerun window, not the arm
Reporting faults instead of compensatingA drifting servo silently becomes training dataDetune one joint; do they stop or work around it
Steady hands under a lagRemote links add delay operators compensate for badlyRun one block over the real network, not on LAN
The AY-Robots teleoperator page showing the call for remote robot operators next to a photo of the SO-100 arm they drive
The /teleoperator page. Remote operator work is the entry point for people without hardware of their own, on the same class of arm the datasets are recorded on.
Two or three dedicated operators, or many casual ones
A small dedicated team
  • Strategy variance stays low, which is the variance that hurts most
  • Skill compounds: RoboTurk measured completion times falling with experience
  • Attribution is trivial, because one operator maps to one dataset
  • Matches the robomimic finding that 200 proficient demos beat 300 mixed ones
A large casual pool
  • Scene and object diversity is bounded by however many settings your team can reach
  • One person's idiosyncratic grasp becomes the policy's only grasp
  • Illness or churn stops data collection entirely
  • DROID reached 564 scenes only by using 50 collectors across 13 institutions

The fix used by DROID is worth copying at any scale: a shared written protocol. Collectors chose their own scenes, but a GUI prompted them with a randomly sampled task per episode so collection would not drift toward the easy objects, periodically demanded scene augmentations such as moving a camera or changing the lighting, and recorded a data collector ID per trajectory. Collectors marked each episode successful or not: the release holds 76k successful episodes plus roughly 16k labelled unsuccessful. See the DROID article for the rest.

How long training an operator actually takes

Shorter than most people assume. RoboTurk's 54 participants got a 5 minute tutorial plus one supervised hour, then collected unsupervised. The learning curve backs that up: completion time fell steadily with previous trials, while measured effort, the squared L2 norm of their phone translations, stayed flat and the orientation change they commanded went up. Operators got faster by rotating the controller more, not by moving it faster.

Here is a curriculum for an SO-100 that mirrors those findings: two hours, ending in a dataset you can train on. Commands are LeRobot 0.6.2 entry points, and the same ground is covered in the operator guide.

  1. 1
    Calibrate both arms first, once, together

    A first session should not be spent fighting a bad calibration. Run this with the operator watching, so they know what a correct range of motion looks like. See calibration for what the file holds.

    bash
    lerobot-calibrate --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a
    lerobot-calibrate --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a
  2. 2
    Fifteen minutes of free teleoperation, nothing recorded

    No task, no target, no dataset. Let them find the workspace limits and discover that the gripper closes slower than they expect. The highest-return part of the curriculum.

    bash
    lerobot-teleoperate \
      --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \
      --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a
  3. 3
    Fifteen minutes driving from the camera view only

    Turn on the visualiser and have them turn their chair away from the robot. The LeRobot docs put it well: you should be able to do the task yourself by only looking at the camera images. If they cannot, the camera placement is wrong, not the operator.

    bash
    lerobot-teleoperate \
      --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \
      --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} }" \
      --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a \
      --display_data=true
  4. 4
    Five throwaway episodes that never reach the Hub

    The point is the control flow, not the data. Right arrow or n ends an episode early, left arrow or r cancels and re-records it, Escape or q stops the session. Make them use all three.

    bash
    lerobot-record \
      --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \
      --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} }" \
      --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a \
      --display_data=true \
      --dataset.repo_id=my-org/warmup-anna \
      --dataset.single_task="Pick up the red cube and put it in the bin" \
      --dataset.num_episodes=5 \
      --dataset.episode_time_s=25 \
      --dataset.reset_time_s=15 \
      --dataset.push_to_hub=false
  5. 5
    Read the cadence report out loud

    lerobot-record prints an achieved-rate line after every episode and a session summary. If the effective cadence is below the fps target, fix it before recording anything real.

    text
    Cadence (episode 0): 29.88 Hz vs 30 Hz target - 600 ticks, 20.0 s measured
      8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms)
  6. 6
    Record the first real block under their own name

    One dataset per operator, named after the operator. This is the workaround for the missing operator field, and it is free on day one. lerobot-record appends a date-time tag to the repo id unless you pass --dataset.no_stamp=true, and the merge step below expects the name you actually typed.

    bash
    lerobot-record \
      --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \
      --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} }" \
      --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a \
      --dataset.repo_id=my-org/pick-cube-anna \
      --dataset.no_stamp=true \
      --dataset.single_task="Pick up the red cube and put it in the bin" \
      --dataset.num_episodes=30 \
      --dataset.tags='["operator:anna","session:2026-08-24"]'
The trap that eats a day: a dataset that lies about its own frame rate

A LeRobot frame's timestamp is derived from its index, so a session that actually ran at 25 Hz still produces a dataset claiming 30 Hz. Nothing errors. The recorded motion is simply faster than reality, and a policy trained on it overshoots. A new operator on a laptop with two USB cameras is the likeliest person to trigger it, because the extra camera decode pushes the loop over budget. Read the cadence summary after every session, and if pacing headroom is near zero, drop a camera resolution first. Related: policy only works in one setup, dataset rejected.

LeRobot has no operator field, so build one out of repo ids

This surprises people, so state it plainly. In the LeRobot v3.0 format, meta/episodes holds per-episode records with fields such as episode_index, task_index, length, from_timestamp and to_timestamp. There is no demonstrator identity. DROID stores a collector ID per trajectory; LeRobot does not. Record five operators into one repo id and their data is mixed permanently.

  1. Give every operator their own --dataset.repo_id, for example my-org/pick-cube-anna, with --dataset.no_stamp=true so the name survives verbatim.
  2. Add --dataset.tags with an operator tag so the provenance survives a push to the Hub.
  3. Score each dataset separately with the length statistics above, and watch the three longest episodes of each.
  4. Delete the episodes that fail review: lerobot-edit-dataset --repo_id my-org/pick-cube-anna --operation.type delete_episodes --operation.episode_indices "[3, 11, 27]"
  5. Merge only the datasets that survived: lerobot-edit-dataset --new_repo_id my-org/pick-cube-merged --operation.type merge --operation.repo_ids "['my-org/pick-cube-anna','my-org/pick-cube-chen']"
  6. Keep the rejected datasets. They are how you check that your review process does anything.

If manual review does not scale, Demo-SCORE (Chen et al., 2025) automates the same decision: train an initial policy on everything, roll it out, train a classifier separating successful rollouts from failed ones, then filter the demonstrations with it. The paper reports over 15 to 35 percent higher absolute success rate than training on all the data, at the cost of robot time for the rollouts.

Getting from an untrained operator to a trained policy

You own the arm, cameras, machine and GPU. Everything above runs locally, and the only external dependency is the Hugging Face Hub, which you can turn off with --dataset.push_to_hub=false.

  • Buy or build an SO-100 leader-follower pair, roughly 110 to 150 EUR per arm.
  • Install LeRobot from the upstream repo and calibrate both arms.
  • Run the two-hour curriculum above with each new operator.
  • Record one dataset per operator, review, delete, merge.
  • Train with lerobot-train --policy.type=act on a 24 GB card, or rent one.
bash
lerobot-train \
  --dataset.repo_id=my-org/pick-cube-merged \
  --policy.type=act \
  --policy.device=cuda \
  --output_dir=outputs/train/act_pick_cube \
  --job_name=act_pick_cube
The upstream ACT training command. Nothing here knows or cares who recorded the data.
What this path costs you

Time. Port discovery, calibration drift, camera indices that shift between reboots, an evening lost to a USB serial adapter. The upside: you keep every raw frame and owe nobody an account.

The per-operator training run is the honest version of all of this. Length statistics are a proxy; a trained policy evaluated on the real arm is the answer. At the prices on the 24 GB tier, running ACT on SO-100 once per operator is a rounding error against the recording time.

The AY-Robots pricing page showing GPU tiers and what a single fine-tuning run costs
The pricing page. Per-operator comparison is practical because a run on the 24 GB tier is a single-digit dollar amount.
The AY-Robots public dataset directory listing LeRobot datasets available for training
The /directory page. Public datasets work as a calibration reference for your operator's median episode length.

The other job: correcting a policy instead of demonstrating from scratch

Once a first policy exists, the job changes. BC-Z (Jang et al., CoRL 2021) ran this at scale: 7 operators across 12 robots collected 25,877 demonstrations, 125 hours of robot time. Of those, 11,108 were expert-only demonstrations seeding the initial policies and 14,769 were shared-autonomy episodes over 16 rounds, where the policy attempted the task and the human gripped an override switch to correct it. At equal episode count, the correction data helped.

BC-Z also produced the most useful operator metric in the literature: the intervention rate, the average takeovers per episode, correlates negatively with policy success rate. It is a live evaluation signal that costs nothing, because the operator is already there. LeRobot exposes the same mode through lerobot-rollout --strategy.type=dagger.

A cheap habit worth adopting

Log takeovers per episode from the first correction session. Two columns, no extra time, and you get a policy-quality trend line weeks before you have enough rollouts for a real success rate. See the teleoperation docs for how sessions work here.

Where remote operators and this platform do not help

Three limits, stated plainly, because pretending otherwise wastes money.

Network delay is baked into the demonstrations

An operator compensates for lag with slow, over-damped increments, and that compensation is recorded as ground truth. RoboTurk stopped running teleoperation servers on cloud infrastructure and spawned them on machines in close physical proximity to the robots, to minimise the latency of the control commands sent to the arms. The same applies at inference time: the control loop is 20 ms per action step for ACT and up to 485 ms for Pi0.5, and a public-internet round trip on top turns a working policy into a hesitant one. Remote inference suits slow pick-and-place, not fast reactive motion.

  • No amount of GPU fixes a bad demonstration. Fine-tuning reproduces what is in the data. If the operator missed the grasp 40% of the time, the policy will too.
  • The platform does not judge your operators. There is no per-operator quality score in the product. The repo-id-per-operator discipline above is manual, and it is the part you cannot outsource.
  • Diversity has to be deliberate. One operator in one room produces a policy that works in one room. DROID needed 50 collectors in 52 buildings for scene diversity, and no cloud service substitutes for that.

Still choosing a model for the dataset? The policy comparison puts the five trainable options side by side with parameters, GPU tier and minimum episodes, and the arena holds 85 VLA models with 332 benchmark results. On collection specifically, our data-collection guide and the record your first dataset walkthrough go deeper.

How long does it take to train a robot teleoperator?

Basic competence arrives fast. RoboTurk gave 54 remote participants a 5 minute tutorial plus one supervised hour before letting them collect unsupervised. For an SO-100 with a leader-follower pair, budget two hours: calibration, fifteen minutes of free driving, fifteen minutes driving from the camera feed only, five throwaway episodes, then a first real block of 30. Skill keeps improving after that through more controller rotation, not faster movement.

Does operator skill really change how well a policy trains?

Yes, by tens of percentage points. In the robomimic study, behavioral cloning on 100 demonstrations from two experienced operators scored 58.7% on Square, against 22.0% for the same budget from two inexperienced operators. On the easier Can task the gap was 83.3% against 56.7%. BC-RNN narrowed the Can gap to 7.3 points but left 26.7 open on Square.

Should I just collect more data instead of finding better operators?

Not blindly. In the same study, 200 demonstrations from one proficient operator scored 84.0% on Square with BC-RNN, higher than any 200-demonstration mixture containing a weak operator, and the 300-demonstration multi-human sets never beat the 200-demonstration single-operator sets on any task. Scale helps once quality is controlled, not instead.

How do I tell which operator recorded which episodes?

You cannot, after the fact. The LeRobot v3.0 per-episode metadata holds episode_index, task_index, length and timestamps, with no demonstrator identity. Record one dataset per operator with its own repo id, add an operator tag via --dataset.tags, review each separately, then merge the survivors with lerobot-edit-dataset --operation.type merge. DROID stores a collector ID per trajectory, which is what LeRobot would need to automate this.

What is the single cheapest quality check on an operator's data?

The spread of episode length. In the robomimic trajectory-length table the weaker tier took roughly twice as long per episode, but the standard deviation grew about five-fold on Can, from 29 frames to 148. Consistency is the signal. Compute the coefficient of variation per operator, then watch the three longest episodes before deleting anything.

Is remote teleoperation good enough for training data, or does the lag ruin it?

Good enough for slow tasks, with care. The RoboTurk user study found that poor network conditions, low bandwidth and high delay links, did not substantially affect remote users' ability to perform demonstrations successfully; the real-robot follow-up then collected over 111 hours across 54 remote users in one week. But that follow-up also moved teleoperation servers off cloud infrastructure onto machines close to the robots. The risk is subtler than failure: operators compensate for lag with slow over-damped motion, and that is recorded as ground truth. Test on the real network before recording a full block.

Drive a real robot arm from wherever you are

Operator work is the way into robot learning that needs no hardware of your own. See what the job involves and how the data you record gets used.

Become an operator

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started