跳到主要内容

Async-First Agent Harnesses: What Unreal Agent Changes

高级

On September 22, 2026, Unreal Labs released Unreal Agent — an MIT-licensed agent harness written in Go — and published benchmark runs showing it matching Codex's pass rate on Terminal-Bench 4.0 for $1,428 against $2,350. Same model, same tasks, same score, 39% less money.

The interesting part is not the number. It is where the money went. Unreal Agent's central claim is that a large slice of what you pay a coding agent is not reasoning at all — it is the model sitting in the loop managing its own waiting. This page is about that mechanism, because it transfers to any harness you build or buy, including ones that have nothing to do with Unreal Labs.

What you'll learn
  • Understand the async tool-call event flow: what gets appended to the session log, when, and what the model actually sees
  • Learn why turn count — not output length — is the unit that drives agent cost, and how to measure it in your own loop
  • Read the published cost table honestly: what the dollar figures cover and what they do not
  • Know the three designs Unreal Labs deliberately refused to build (sub-agents, workflows, harness-level security hooks) and the argument for each
  • Apply the transferable rules to your own agent, whichever harness you already use

The one-sentence version​

Unreal Agent is an MIT-licensed Go harness that appends every tool call to an append-only session log as an in-progress event and lets execution continue in the background, so the model never blocks and never polls — which cuts turns, and turns are what you actually pay for.

The mechanism, precisely​

Here is a normal synchronous agent turn:

  1. Model emits a tool call.
  2. Harness runs the tool. The loop is suspended.
  3. Tool returns. Harness appends the result.
  4. Harness calls the model again with the full transcript.

Now the same turn in Unreal Agent:

  1. Model emits a tool call.
  2. Harness immediately appends an event to the session log saying the call is in progress, and starts execution in the background.
  3. Execution continues. The model is free to issue more calls.
  4. When the tool completes, its result is appended to the log — and that append is what triggers the next model call.

The model sees the running state and then the final result, in order, in its own transcript. It never has to encode "wait for this", never issues a poll, never carries heartbeat bookkeeping in its reasoning. Unreal Labs' framing: the harness lets the model "issue more heavy tool calls per model turn without wasting tokens on polling or waiting for them."

That is the whole idea. It is small. It is also the part most harnesses get wrong, because a synchronous loop is the obvious thing to write.

Why this shows up as money​

Every model turn re-sends the accumulated transcript. A 30-turn agent run does not cost 30× a single call — it costs roughly the sum of a growing context across 30 calls. Turn count is therefore closer to a quadratic cost driver than a linear one, and it dominates anything you save by trimming the system prompt.

Look at what the published runs report alongside the dollars:

BenchmarkPass rateUnreal AgentTurnsCodexPiPi turns
Terminal-Bench 4.057.9%$1,42828$2,350$1,82744
SWE-Atlas Codebase QnA65.8%$93616$1,303$1,033—
DeepSWE 1.172.4%$1,36726$1,633$1,584—
ALE-CLI30.0% full pass$217————

On Terminal-Bench 4.0 the comparison is 28 turns versus Pi's 44 — a 36% reduction in turns for a 22% reduction in cost against Pi, and 39% against Codex. The turn column is the causal one; the dollar column is the consequence.

This is the same lesson AILmanac covers from the other direction in why agents burn tokens: the expensive thing in an agent is not the answer, it is the re-reading.

Pro tip
  • Instrument turn count before you instrument anything else. If you only log tokens, you will optimise prompts and miss the loop.
  • A useful diagnostic: count how many of your agent's turns produced no tool call and no user-visible output. Those are pure loop overhead — waiting, checking, re-planning — and they are what an async harness removes.
  • Parallel-capable tools amplify the effect. If your three slowest tools can run concurrently, a synchronous loop pays for all three serially in wall-clock AND in turns.

Three things they deliberately did not build​

The rationale matters more than the code, because these are arguments you can apply to whatever harness you already run.

1. No sub-agents, no workflows​

Unreal Labs chose "a straightforward asynchronous tool-calling model" over sub-agent delegation and predefined workflows. The reasoning is that once tool calls are genuinely async, most of what sub-agents were for — running things in parallel without stalling the parent — is already handled by the loop. Sub-agents then add context-splitting, result-merging and their own turn overhead for a problem you no longer have.

This is a real position, not the only one. Multi-agent designs still win where you genuinely want isolated context, not just parallelism. But "we need sub-agents to do two things at once" is a claim worth re-testing against an async loop first.

2. No harness-level security hooks​

This is the sharpest argument in the launch post, and it is worth quoting the shape of it: security and approvals that rely on harness hooks "tend to require more maintenance and be less robust than deterministic environment or sandbox constraints, outside the harness."

What they recommend instead: allowed and disallowed hosts, granular access tokens, and proxies with approval gates. In other words, put the control where the agent physically cannot reach it.

The logic is straightforward once stated. A harness hook is code running in the same process as the agent loop, gating a tool the agent can already invoke. A sandbox boundary is enforced by the kernel or the network, below the agent entirely. If your agent has a bash tool — and Unreal Agent's does — an in-process allowlist is a speed bump, not a wall. AILmanac's securing local and hybrid agents covers how to build the outer boundary.

3. No vendor agent SDK​

Unreal Labs moved away from vendor SDKs (Anthropic's Agent SDK is named) because those assume "local sessions, subprocesses, and resource limits that don't translate neatly into production use."

That is a deployment-shape argument, not a quality one. An SDK modelled on a local CLI session assumes one process, one machine, one lifetime. A production agent fleet wants sessions that outlive a process and can be resumed on a different box — which is exactly what Unreal Agent's append-only, versioned session store provides, including forking a session to branch a run.

If you are building a product on top of an agent loop, this is the question to ask of any SDK: can a session survive the process that created it?

The architecture, briefly​

The harness is deliberately small and explicitly composable — eight replaceable components behind documented interfaces:

  • Session inbox — deduplicates inputs. Every input carries a globally unique, stable caller ID, so retries do not double-apply.
  • Coordinator — owns LLM turns and dispatches operations.
  • Session store — append-only persisted history, supports forking, versioned.
  • Context builder — assembles the model input. Performs no I/O.
  • LLM adapter — talks to the provider.
  • Tool registry and translators — validate calls synchronously and must "perform no I/O or suspend the loop".
  • Operation manager — runs the durable background work.

Two constraints in that list do the heavy lifting and are easy to miss: the context builder and tool translators are forbidden from doing I/O. That is what keeps the coordinator's hot path deterministic and non-blocking — all latency is pushed into operations, which are the things designed to be async. If you build your own harness, this is the rule to steal.

Storage formats and operations are versioned, and an unsupported session version errors explicitly on resume rather than half-loading. That is the correct failure mode for durable state, and it is rarer than it should be.

The built-in tool surface is three tools: Bash, ViewImage, and Skill-use — the last of which hooks into the portable skill format AILmanac covers in SKILL.md as an open standard. Three tools is the point: a small, token-cheap tool surface is part of the cost story.

Running it​

Guided walkthrough1 of 5
  1. Go 1.27+ toolchain, then go install the runner from the cmd/ path, or clone and use the bundled Makefile (make build, make test).

Install and run (from Unreal Labs' documented usage)

go install github.com/unreallabsai/unreal-agent/cmd/unreal-agent-runner@latest

export OPENAI_API_KEY="..."
unreal-agent-runner -p 'Inspect this project and explain how to run its tests.'

Point it at a different provider and keep the transcript

export UNREAL_HARNESS_LLM_PROVIDER=openrouter
export UNREAL_HARNESS_LLM_MODEL=<model-id>

unreal-agent-runner \
-workspace ./my-project \
-p 'Summarize this project.' > run.jsonl

Reading the benchmark table honestly​

Four caveats, because the numbers are good enough that they deserve scrutiny:

  • Every run is the vendor's own. No third party had replicated them at the time of writing.
  • One model. All published runs used GPT-6 Astra at xhigh reasoning. The async advantage should generalise — it is a loop property, not a model property — but "should" is not "was measured".
  • The dollars are whole-suite totals, not per-task costs. They are comparable to each other and not to your workload.
  • Pass rates are matched, not improved. The claim is explicitly same score, less money. On DeepSWE 1.1 Unreal Agent reports 72.4% at $1,367 against Codex's $1,633 — a 19% saving, notably smaller than the 39% on Terminal-Bench. The advantage scales with how tool-heavy and how long-running your tasks are. On short tasks with few tool calls, expect close to nothing.

That last point is the practical one. If your agent does three tool calls and finishes, async buys you almost nothing. If it does sixty over half an hour, it buys you the difference between the two columns.

What transfers to your own agent​

You do not have to adopt Unreal Agent to use any of this:

  • Measure turns. It is the cost variable most teams do not log.
  • Make slow tools non-blocking, even if your harness is otherwise synchronous. Returning a handle immediately and delivering the result as a later event is a change you can make inside most loops.
  • Keep the hot path I/O-free. Context assembly and tool-call validation should never wait on the network.
  • Move approvals out of the process. Network policy, scoped credentials and a gating proxy beat an in-process allowlist that lives next to a bash tool.
  • Shrink the tool surface. Three good tools cost fewer tokens per turn than fifteen mediocre ones, on every single turn.

Check yourself

0/5
  1. In Unreal Agent, what happens the instant the model emits a tool call?
  2. Why does cutting turn count save more money than cutting output length in an agent loop?
  3. Why does Unreal Labs argue against implementing approvals as harness hooks?
  4. The context builder and tool translators are forbidden from performing I/O. What does that constraint buy?
  5. On which kind of workload should you expect the async advantage to be smallest?
按 Enter 或空格键翻转卡片。使用左右方向键在卡片之间切换。已显示术语。
1 / 8
Key takeaways
  • Turn count, not token count, is the cost variable in an agent loop. Instrument it first.
  • Making tool calls non-blocking removes polling and waiting turns — 28 turns vs 44 for the same Terminal-Bench 4.0 pass rate is the whole argument.
  • The advantage is proportional to tool-heaviness: 39% on Terminal-Bench, 19% on DeepSWE, ~0 on a three-call task.
  • Security belongs outside the harness. An in-process approval hook next to a bash tool is a speed bump; a sandbox and a gating proxy are a boundary.
  • Keep context assembly and tool validation I/O-free. Push every wait into a durable operation.
  • All published numbers are vendor runs on one model. Treat them as a well-argued hypothesis about your workload, not a measurement of it.

Sources & further reading​

Next​