Back to Devoured - September 28, 2026
DEVOURED
Robotics Harness Optimization on Graph-as-Policy

Robotics Harness Optimization on Graph-as-Policy

Data Kael Tech Blog
Evolutionary optimization of 'Graph-as-Policy' robot controllers improved throughput by 5.27x without human demonstrations or editing existing skill code.
What: Researcher Karim Elmaaroufi used Robotics Harness Optimization (RHO) on 50 generations of a Graph-as-Policy robot controller. By allowing a coding agent to rewire nodes in a LIBERO grocery-packing simulator, the system increased successful task throughput from 16.6 to 87.6 per hour.
Why it matters: This demonstrates that complex robot behaviors can be improved through iterative code-generation and simulation testing, abstracting away the need for manually curated expert demonstration data.
Deep dive
  • RHO uses evolutionary search to optimize source code policies for robots.
  • Tests compared a 'Compose-Only' approach (rewiring) against 'Compose-and-Edit' (rewiring and rewriting skills).
  • The Compose-Only approach achieved higher throughput (5.27x) by adding a task-context resolver and an early completion check.
  • Coding agents interacted with a simulated Franka Panda arm environment.
  • Search agents used GPT-5.6 Terra and codex for mutations.
  • The system identified hardcoded strings as a performance bottleneck that human designers missed.
  • RHO successfully transferred zero-shot to real Franka and Kinova Gen3 hardware.
Decoder
  • Graph-as-Policy (GaP): A robot control architecture where policy logic is represented as a directed graph of modular skill nodes, making the controller inspectable as source code.
  • LIBERO: A benchmark suite and simulator for robot manipulation tasks.
  • Forward-deployed engineer (FDE): N/A
  • RHO: Robotics Harness Optimization, an evolutionary method to improve whole code repositories for robot control policies.
Original article

Earlier this year, I wrote a paper introducing Robotics Harness Optimization (RHO). In RHO, we use evolutionary search to improve robot policies that are whole code repositories. We tested it on repositories that both excluded and included LLMs at inference. The former are static codebases and are akin to what robotics engineers ship to companies as integration solutions while the latter are what researchers have been exploring through Code-as-Policies (CaP).

A few weeks after we released RHO, a new approach came out: Graph-as-Policy (GaP). In GaP, humans write skills (nodes) and LLMs merely have to stitch them together (connect them with edges). So naturally I was asked: can RHO optimize a graph? 🤔

In the rest of this post, I’ll share what happened when I applied RHO for fifty generations over an example graph from the GaP codebase. TLDR:

  • 5.27× Throughput gain over the baseline
  • 4.17 → 1 Grasps per trial
  • $37 Total search cost, both experiments

Graph-as-Policy

Graph-as-Policy (Chen et al., arXiv:2607.05369) replaces end-to-end policies (think RL trained policy or a VLA) with a directed computation graph whose nodes are individually meaningful skills: observe, perceive, compute a grasp, move, release. Their project page puts it plainly: the graph is the policy.

These graphs, like CaP before them, exhibit some interesting properties. First, the policy is source code you can read and diff, so a change can be quoted in lines. Next, failures localise to a named stage instead of somewhere unknown in a neural network. Lastly, edits are cheap, local, and searchable. Our evolutionary search process can propose “add a node” and score it without needing to collect demonstrations.

The starting graph from the GaP repo has twenty nodes (eighteen inside three subgraphs, plus the done and abort terminals), wired by conditional edges that route on each subgraph’s exit value.

And here is the query it perceives with:

# seed/graphs/grocery_packing/workflow.json, perceive_item node inputs
"object_name":        "grocery item",
"object_description": "a packaged grocery product such as a can, box,
                       carton, jar, or bottle. Never the wicker basket
                       or storage container that the items are being
                       packed into."

The experiment

The example from the GaP is grocery packing with a simulated Franka Panda arm. It uses a LIBERO scene with a table of groceries, one wicker basket, and a sentence as the input task/prompt statement: “Pick the cream cheese and place it in the basket.” In this LIBERO setup, the hard part is object localization: the products are 20–40 pixels across in the camera image and several look alike. The robot has no privileged access to where anything is. It gets wrist and exterior color and depth cameras, and the sole prompt sentence.

Besides this introductory task, we look at the full benchmark which has eleven instructions. Ten of them name a single item: alphabet soup, cream cheese, salad dressing, BBQ sauce, ketchup, tomato sauce, butter, milk, chocolate pudding, and orange juice. The job is to put that one item in the basket. Nothing else. The eleventh says “Pick all the objects and place them in the basket,” and it’s played across ten different table layouts.

Here’s the interesting thing. The exemplar graph never actually reads the instruction. Its perception node is hardcoded to query for “a grocery item,” so it finds one, carries it to the basket, fails the completion test, and loops around to try another. It’s basically playing process of elimination. On the ten single-item instructions it grasps an average of 4.17 objects to complete a task that needs exactly one.

To see what RHO would do with this, I ran two searches of fifty generations each over that same starting graph. In the first experiment, Compose-Only, I allow the agent to only add new nodes and rewire the graph, but has to use the human-written skills as given. Compose-and-Edit can do all of that and also rewrite the skills themselves.

In HELIX, we can express the difference of the two experiments in three lines of configuration:

# Experiment 1 - Compose-Only: may rewire the graph, may not edit the shared skills
registries = ["…/open-robot-skills"]

# Experiment 2 - Compose-and-Edit: same freedoms, plus its own writable skill copy first
registries = [".", "…/open-robot-skills"]

Results

Following the GaP paper, I report throughput: successes per hour, or success rate divided by cycle time.

Policy Success rate Cycle time Successes/hr vs. baseline
Baseline 67/100 144.9 s 16.6 1.00×
Compose-and-Edit 97/100 68.0 s 51.3 3.08×
Compose-Only 96/100 39.4 s 87.6 5.27×

The two RHO experiments are indistinguishable on accuracy; their success-rate intervals overlap almost completely. However, their throughputs tell a different story.

Why it’s faster

Look at the pass count. Per-iteration cost is worse for both searched policies: 28.8 seconds for the baseline against 33.8 and 37.9. They made the loop run fewer times, while spending slightly more inside each pass. The baseline’s pass count has a long right tail: a mean of 5.04, with trials running out to eighteen passes. Both searched policies are single spikes.

Artifact one: disambiguation, worth roughly four grasps

The baseline asks for a generic grocery item, so it picks an arbitrary one. Compose-Only added a node that runs before perception and resolves the target out of the instruction.

Artifact two: the completion check, worth the gap between the two searched policies

Only Compose-Only found this one. The baseline and Compose-and-Edit have no equivalent at this point in the graph. Having placed the right item, they loop back and run a whole additional perception cycle (about 34 seconds) before their completion check can fire. Compose-Only asks, gets an answer, and exits.

The part that only works in simulation

The completion check calls sim.check_success, the simulator’s own goal predicate. The starting graph already polls it after every perception pass, so all three policies use it; Compose-Only just calls it earlier. A real robot has no such oracle. Without it, Compose-Only would take one extra perception pass per trial (about 38 seconds), which puts it at roughly ≈2.8× the baseline instead of 5.27×.

What I take from this

The main lesson for me is that it doesn’t much matter what form the robot policy takes, as long as it’s code. The same RHO loop has now worked on three pretty different kinds: repositories on CaP-Bench, an LLM agent’s harness on RAI, and a Graph-as-Policy here.

The recipe is the same every time: hand a coding agent the policy’s source, score what it writes in simulation, and keep what works. The best part is that in all cases, we are using RHO to improve robotics policies without the need for human demonstration data.

Explore all 67 articles in today's digest

Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi