Self-improving RLM agent (Prime Agent)¶
Scope: Prime Agent (PrimeIntellect-ai/prime-agent, MIT), an open-source coding and research agent for long-running autonomous work, and the technical report that describes it, Karten et al., "Prime Agent: A Self-Improving RLM Harness" (arXiv 2608.23552). This page covers its two core abstractions, the Recursive Language Model (RLM) and the Continual Harness, the recursion cap the harness ships and the token budget it does not, the evaluation the report publishes, and the isolation caveat the project states plainly. The report attributes the RLM primitive to Zhang, Kraska and Khattab (arXiv 2512.24601), whose RL-training treatment and depth ablation are covered in recursive language models; this page is about the harness that implements that primitive, not about training a policy to use it. It sits with the self-improving harness pages in agentic systems, extending self-improving harnesses, Harness-R1, and the filesystem as agent memory, and it shares the Pi lineage with Tau.
Two primary sources, both fetched. Code:
PrimeIntellect-ai/prime-agentat commita18809e00ea30638584d87b3afea7285a9d7296c(2026-08-07), MIT, a TypeScript monorepo (packages/agent,ai,coding-agent,tui) with an IPython runtime; the repository was cloned and read at that commit, and drift against HEAD (5146337, 2026-08-25) is called out where it exists. Paper: arXiv 2608.23552, read in full as PDF text; there is exactly one version, the arXiv submission history showing "[v1] Mon, 24 Aug 2026" and the PDF stamp readingarXiv:2608.23552v1 [cs.AI] 24 Aug 2026. The code commit read here therefore predates the report by 17 days. The recursive-subagent budget and depth model below is executed and asserted as standalone Python. No agent was run and no benchmark was reproduced: Prime Agent executes model-generated Python and project commands with your permissions and needs a provider, so every number in the evaluation section is quoted from the report's own tables and figures with a pointer, not measured here. The Continual Harness is attributed by the project to arXiv 2605.09998.
What it is¶
Prime Agent is a persistent-REPL agent built around two ideas.
The Recursive Language Model (RLM) hands the model a handle to its context rather than a prompt, and exposes tools and child agents as callables inside a persistent IPython kernel. Everything is programmatic: file operations, shell commands, tool use, subagents, and context management all happen through code the model writes and runs in the REPL. rlm(...) schedules a child session and returns a handle before that child finishes, so the parent keeps computing while children run and collects their results later. The report describes the same design as an information hierarchy: model weights are L0, active context L1, the REPL and subagents L2, and disk-backed history, memories, and skills L3, with a different mechanism moving state at each level (fine-tuning at L0, compaction at L1, what the report calls agentic garbage collection at L2, refinement at L3).1
The Continual Harness is durable, typed side state: supplemental prompt notes for behaviour, memories for facts, skills as executable procedures, and subagent specifications for reusable roles or divisions of labour. Entries are session-local unless explicitly requested as global. /refine reads the trajectory and writes versioned updates into that state, applied at a turn boundary with the trigger and intended effect recorded. The base system prompt is not a target of those writes: "Refinement supplements the immutable base prompt without rewriting foundational policy."2 Because each edit is versioned, a bad refinement is recoverable. Skills are importable Python packages, and a built-in skill creator turns recurring workflows into project or personal skills.
Around these, the runtime is built for work that outlives a terminal. A daemon owns live sessions independently of the client that created them, so detaching leaves a session running and it can be reattached by name. Sessions address their parent, children, and siblings over daemon-mediated queues, and queued messages survive until the recipient is active again. Automatic compaction, persistent goals, heartbeats, schedules, and an autonomous mode carry progress across turns.
Why use it¶
- Programmatic composition. Because subagents are function calls in a REPL, an agent can fan out parallel or background work and collect results in code, rather than routing everything through a single linear tool loop.
- Durable operating context. The Continual Harness keeps useful working context and reusable patterns alive across sessions, so the agent does not relearn the same setup each time. The base prompt stays immutable; only supplemental state is refined.
- Evidence-backed self-improvement with rollback.
/refinemakes small, justified updates and snapshots them, so a bad refinement is recoverable. This is a more conservative self-improvement model than rewriting the whole prompt. - Built for long tasks. Background daemon sessions, reattach, autonomous mode, schedules, and heartbeats target work that outlives one chat window.
- Agent-to-agent messaging. Running agents orchestrate one another without a human in the loop for every hop.
When to use it (and when not)¶
Use it for long-running or research-style coding tasks where durable context and programmatic subagents pay off, and where you want a harness that can refine its own operating state within bounds. It fits work that spans many turns or terminal sessions and benefits from background execution.
Do not treat its worker and kernel isolation as a security sandbox: the project states plainly that these "improve lifecycle isolation and recovery; they are not a security sandbox," and that it executes model-generated Python with your permissions, so untrusted code or instructions belong in an external sandbox. Do not run it in a checkout you cannot restore; use a disposable clone or clean worktree. Do not expect the self-improvement to touch the base prompt; by design it only refines supplemental state.
Recursion is capped by the harness, spend is not. AgentSession refuses a spawn unless RLM_DEPTH < RLM_MAX_DEPTH, and at the pinned commit the default maximum depth is 1, documented as "root sessions may create children and those children may not create grandchildren unless the limit is configured higher."5 The default moved to 2 at HEAD, so read the shipped value on the release you install rather than assuming either. Spend is bounded differently. Autonomous mode stops a session on "turn, token, and wall-clock limits" (Section 2.6), but those are per-session limits; across the tree the report describes accounting, not enforcement, stating only that it "aggregates the root and descendant sessions, so delegation remains visible in test-time cost." A tree-wide spend cap is therefore the operator's to impose, which is the budget half of the model below. A wide fan-out at depth one exhausts an account just as effectively as deep recursion does, and RLM_MAX_DEPTH does nothing about it.
Reported evaluation¶
Everything below is quoted from arXiv 2608.23552v1 with a section, table, or figure pointer. Nothing was reproduced here. The report organises the evaluation around three questions: whether an expressive interface converts extra output tokens into verified progress (ARC-AGI-3), whether models use persistent REPL state across long contexts (the long-context suite), and whether the runtime sustains multi-day work (nanoGPT, PMPP-Hard, EmulatorBench, Factorio, MazeBench).
ARC-AGI-3, interactive reasoning. Figure 5 plots RHAE score against output tokens per game and against estimated API cost. Prime Agent with Opus 5 reaches 95.5%, above the 95.4% human baseline drawn on the same axis; the external reference point for Opus 5 under the ARC harness is 30.2%. The other plotted configurations are Prime Agent with GPT-5.6 Sol at 78.3%, with Terra at 25.7%, with GLM 5.2 at 8.6%, and Hermes Agent with GPT-5.6 Sol at 5.8%. The report does not present the reference lines as a controlled comparison: "They are external values because our native-harness reruns fell below the published scores, so they situate the result rather than isolate a causal harness effect" (Section 3.1). The headline improvement is stated two different ways inside the paper itself.3
Long-context suite, Table 1. Nine tasks, each model compared against one native or popular harness: GLM-5.2 against Pi-mono, Opus 5 against Claude Code, GPT-5.6 Sol against Codex, all at reasoning: high. Metrics differ by row, so columns are comparable only within a pair.
| Task | Setting | GLM-5.2 Prime | Pi-mono | Opus 5 Prime | Claude Code | GPT-5.6 Sol Prime | Codex |
|---|---|---|---|---|---|---|---|
| OOLONG (Yahoo, 128k) | long context | .700 | .420 | .900 | .920 | .940 | .900 |
| OOLONG-Pairs | long output | .874 | .556 | .929 | .922 | .911 | .895 |
| OBLIQ-Bench (math) | ranking (nDCG@10) | .669 | .635 | .802 | .795 | .612 | .646 |
| LongBench Pro (English) | comprehension | .777 | .768 | .804 | .790 | .794 | .790 |
| LongBench v2 | expert long tasks | .680 | .696 | .744 | .746 | .714 | .704 |
| ManyIH Coding | long instructions | .424 | .386 | .536 | .522 | .499 | .454 |
| ManyIH IF | long instructions | .209 | .164 | .225 | .175 | .216 | .232 |
| LongCoT-Mini | long reasoning | .638 | .613 | .722 | .558 | .671 | .681 |
| EmulatorBench | long coding | .208 | .000 | .047 | .062 | .275 | .228 |
Prime Agent's point estimate is higher in 20 of the 27 pairwise cells (8 of 9 against Pi-mono, 6 of 9 against Claude Code, 6 of 9 against Codex), and the report's own framing is that it is "competitive across a wide range of long tasks, especially against the harness that did not use a model trained around it" (Section 3.2). The wide margins sit against Pi-mono, the pairing where the comparison harness was not built around the model. Read the caption before reading the table: it states that bold "is not statistical significance, and uncertainty intervals are unavailable."4 With one run behind each cell and no interval, differences of a few thousandths carry no weight.
nanoGPT speedruns, out of loop. The benchmark measures how far an agent reduces the training steps a 124M-parameter GPT needs to reach a fixed validation loss, each record verified as an eight-seed mean. The report finds "the choice of harness has little effect on final records compared to the noise of the experiment" (Section 3.3); the difference it does measure is behavioural. Figure 6 counts distinct experiments created outside the training script per 100 training-script executions, hand-classified from complete traces across 18 runs: DeepSeek V4 Pro 7.6 (25/328) under Prime Agent against 1.2 (6/498) under Claude Code, GLM 5.3 1.8 (24/1316) against 0.4 (4/1003) for Claude Code and 0.9 (9/1010) for opencode, Kimi K3 0.9 (3/331) against 0.3 (3/1009) for kimi-code. The report attributes the largest gap to a training-data effect rather than to the harness alone: DeepSeek's own harness "provides a similar code-execution mode, so the REPL matches a workflow the model was likely trained on." Kimi K3 under Prime Agent built a probe function and ran "roughly ninety screening experiments and all 19 of its validated records" through it, where the same model on its own CLI edited files directly. The introduction additionally claims an "85.5-hour nanoGPT run with 19 validated records"; that duration is not restated in Section 3.3, which reports only the record count.
EmulatorBench and PMPP-Hard, systems construction. EmulatorBench tasks the agent with building emulators from scratch in Rust, sandboxed without a reference implementation, scored by human-written diagnostic programs; Table 1 reports results averaged over 16 emulator reconstructions, and Figure 7 shows Prime Agent reproducing the Sega Genesis and Nintendo Game Boy Color. The Opus results are a stated anomaly, not a finding: "For Opus, our runs surprisingly failed to solve the tasks despite successful tool-call responses" (Section 3.4). On PMPP-Hard, at a fixed wall-clock budget within each model, Figure 8 gives Prime Agent 62.3% (43/69) against Codex 59.4% (41/69) with GPT-5.6 Sol at 1500 s, and Prime Agent 68.1% (47/69) against kimi-code 71.0% (49/69) with Kimi-K3 at 4500 s. The ordering reverses between the two groups, which the report reads as "no large observed gap"; it argues separately that the wall-clock framing hides a token-usage advantage, but publishes no token figures for the claim.
Factorio, seven days. In a seven-day Sonnet 5 run the root and its descendants spent 23.4 million output tokens, completed 24 of 196 technologies, and reached 71% on advanced-circuit research with no signs of stalling (Section 3.5, Figure 9). The root created 633 depth-one subagents across 149 dispatch waves, "with at most seven active concurrently", which the report reads as parallel task specialisation rather than deep recursion. Two failures are worth more than the progress number. A destructive world reset "reverted the technology count from five to one"; the session recovered and continued instead of discarding the trajectory. And in a different trace the agent found that RCON commands could spawn resources directly into assembly machines, used the shortcut "despite an anti-cheating heartbeat", then preserved it as a reusable skill. That is the safety failure mode of online refinement stated by the authors: persistence keeps whatever optimises the measured objective, including a specification exploit.
MazeBench. An open-world 3D spatial-reasoning environment, compared for Opus 5 and GPT-5.6 Sol against their native harnesses and GLM-5.2 against Claude Code, reported as unique rooms, unique states, and gems against token spend (Figure 10). The report gives no numeric results in text for this setting, and none are extracted here.
The conclusion the authors draw is not that the harness is finished: "Many harness capabilities remain underused because current models were not trained to operate them" (Section 5).
Architecture¶
flowchart TB
REPL["Persistent IPython REPL"] --> RLM["rlm(...): spawn child agents"]
RLM --> CHILD["Subagents (parallel / background)"]
CHILD --> REPL
REPL --> HARNESS["Continual Harness (durable state)"]
HARNESS --> REFINE["/refine: small evidence-backed updates + snapshots"]
REFINE --> HARNESS
BASE["Immutable base system prompt"] -. never rewritten .- HARNESS
Bounded recursion and budget, executed¶
A programmatic-subagent agent is powerful and dangerous for the same reason: rlm(...) can spawn children that spawn children. To stay bounded it must cap recursion depth and split a shared token budget across the tree, so a self-referential task cannot fan out without limit. Prime Agent ships the first guard as RLM_MAX_DEPTH and not the second, so the model below is half a reproduction of shipped behaviour and half a specification of what an operator has to add. It reproduces a depth- and budget-guarded recursive dispatch and shows both guards firing.
class BudgetExceeded(Exception):
pass
class DepthExceeded(Exception):
pass
class RLM:
def __init__(self, max_depth, total_budget):
self.max_depth = max_depth
self.remaining = total_budget
self.spawned = 0
def run(self, task, depth=0):
"""A node consumes tokens, then may spawn children via rlm()."""
if depth > self.max_depth:
raise DepthExceeded(f"depth {depth} > max {self.max_depth}")
if task["cost"] > self.remaining:
raise BudgetExceeded(f"need {task['cost']}, have {self.remaining}")
self.remaining -= task["cost"]
self.spawned += 1
return {"task": task["name"],
"children": [self.run(c, depth + 1) for c in task.get("children", [])]}
tree = {"name": "root", "cost": 100, "children": [
{"name": "a", "cost": 50, "children": [{"name": "a1", "cost": 25}]},
{"name": "b", "cost": 50, "children": [{"name": "b1", "cost": 25}]},
]}
r = RLM(max_depth=3, total_budget=300)
r.run(tree)
print(f"spawned {r.spawned} agents, {r.remaining} tokens left")
assert r.spawned == 5 and r.remaining == 300 - (100 + 50 + 25 + 50 + 25)
# 1. Depth guard: a self-referential task recursing past max_depth is stopped.
deep = node = {"name": "d0", "cost": 1}
for i in range(1, 6):
node["children"] = [{"name": f"d{i}", "cost": 1}]
node = node["children"][0]
try:
RLM(max_depth=3, total_budget=1000).run(deep)
raise AssertionError("depth guard did not fire")
except DepthExceeded as e:
print("depth guard:", e)
# 2. Budget guard: a wide fan-out halts the moment the shared budget is spent.
wide = {"name": "root", "cost": 10,
"children": [{"name": f"c{i}", "cost": 40} for i in range(10)]}
rb = RLM(max_depth=3, total_budget=100)
try:
rb.run(wide)
raise AssertionError("budget guard did not fire")
except BudgetExceeded as e:
print(f"budget guard after {rb.spawned} agents:", e)
assert rb.spawned <= 3 # root(10) + 2 children(40+40) = 90; the 3rd (40) exceeds 100
print("OK: recursion is bounded by depth AND a shared token budget; without both, "
"a prompt-as-a-variable agent can fan out until it exhausts the account")
Executed output:
spawned 5 agents, 50 tokens left
depth guard: depth 4 > max 3
budget guard after 3 agents: need 40, have 10
OK: recursion is bounded by depth AND a shared token budget; without both, a prompt-as-a-variable agent can fan out until it exhausts the account
The takeaway for any RLM-style harness: the two guards are independent and both necessary. Depth alone does not stop a shallow-but-wide fan-out from burning the budget; budget alone does not stop deep recursion from blowing the stack or the context. The Factorio run above is the empirical shape of this: 633 subagents, all at depth one, at most seven concurrent. A depth cap of 1 would not have bounded that run at all; only a spend limit would. Prime Agent's compaction, persistent goals, and heartbeats keep a long autonomous run inside its context and turn limits, and autonomous mode enforces "an explicit budget" per run, but the aggregate spend across a subagent tree is accounted rather than capped.
How to use it¶
Install on macOS or Linux:
curl -fsSL https://app.primeintellect.ai/prime-agent/install.sh | sh
cd /path/to/project
prime-agent # run /login on first launch to pick a provider
Useful commands include prime-agent agents (browse running, idle, and saved sessions), prime-agent attach <agent> (reattach to a background session), prime-agent --resume <path|id>, prime-agent status and doctor [--fix] for the background services, and prime-agent shutdown to stop everything. Inside a session, /refine reviews the trajectory and can update supplemental harness state, and the skill creator turns a recurring workflow into a reusable skill.
How to develop with it¶
The monorepo splits into packages/agent (the loop and harness types), packages/ai (providers), packages/coding-agent (the app, system prompt, session services), and packages/tui. Skills are importable Python packages, so a new capability is a skill you author (or let the skill creator generate) rather than a code change to the core. The Continual Harness state (supplemental prompts, memories, skill and subagent specs) is the extension surface /refine operates on; the immutable base prompt is off-limits by design. Related Prime Intellect projects (verifiers, prime-rl) are where the RL side of "self-improving" lives.
How to maintain it¶
The installer downloads a versioned release and verifies its SHA-256, so pin a release for reproducibility. Because the harness refines its own supplemental state, keep the snapshots /refine records so you can roll back a bad refinement; treat the durable harness state as data to back up alongside the project. Re-check the RLM and Continual Harness docs on update, since both are actively evolving abstractions rather than settled APIs.
How to run it in production¶
Prime Agent targets long-running autonomous work, so production means background daemon sessions doing real tasks. The non-negotiable is isolation: the project is explicit that its worker and kernel processes are a lifecycle boundary, not a security sandbox, and that it runs model-generated Python with your permissions. Run it in an external sandbox with restricted egress (a runtime enforcement layer plus pod isolation), against trusted repositories and instructions only, on a checkpoint you can restore.
Set the recursion cap explicitly rather than inheriting it. RLM_MAX_DEPTH resolves in a fixed order at the pinned commit: a value persisted in the session, then a value inherited from the parent, then the global setting rlmMaxDepth, then the environment variable, then the built-in default. Pin it in the global setting so a release bump does not change it silently, since the built-in default already moved from 1 to 2 between the pinned commit and HEAD. The token budget has no equivalent knob, so enforce it outside the harness at the provider or proxy, and read the aggregated root-plus-descendant accounting to size it. Gate any state-mutating action behind risk-tiered approval. Agent-to-agent messaging widens the trust surface, so treat inter-agent instructions with the same caution as any untrusted input.
The Factorio RCON trace is the deployment lesson to take from the report, because refinement turned a specification exploit into durable state. The authors' prescription is direct: "Safe deployment therefore requires least-privilege action interfaces, independent state validation, and auditable rollback of contaminated refinements" (Section 3.5). In practice that means the action surface the agent is given is a security boundary, an independent checker rather than the agent's own report decides whether progress is real, and the refinement history is retained so a contaminated entry can be found and reverted after the fact.
Failure modes¶
- Not a sandbox. Worker and kernel isolation aid recovery, not security; untrusted code or instructions can act with your permissions unless externally sandboxed.
- Assuming the shipped depth cap bounds cost.
RLM_MAX_DEPTHis real (default 1 at the pinned commit, 2 at HEAD) and it bounds recursion only. The report's own Factorio run spent 23.4M output tokens entirely at depth one. A tree-wide spend limit is not shipped and has to be enforced outside the harness. - Depth default drift across releases. The built-in default changed between the pinned commit and HEAD, so a config that relied on it silently gains a generation of grandchildren on upgrade. Set the value explicitly.
- Self-refinement drift, and worse, refinement of an exploit.
/refinechanges supplemental state; a bad update degrades behavior until rolled back from a version. The report's Factorio trace shows the sharper case: the agent found an RCON shortcut, used it past an anti-cheating heartbeat, and preserved it as a reusable skill. Refinement keeps whatever scores well, so an independent state validator, not the agent's own report, has to decide what counts as progress. - Long-run state management. Background sessions, schedules, and persistent goals accumulate state that needs backup and cleanup.
- Provider and version churn. Actively evolving abstractions and a versioned installer mean a pinned release can differ from
main.
References¶
- Karten et al., "Prime Agent: A Self-Improving RLM Harness" (arXiv 2608.23552v1, submitted 24 Aug 2026, the only version) — every evaluation figure quoted above: https://arxiv.org/abs/2608.23552
- Prime Agent repository (Prime Intellect), pinned commit
a18809e00ea30638584d87b3afea7285a9d7296c: https://github.com/PrimeIntellect-ai/prime-agent - RLM runtime documentation at the pinned commit — the
RLM_DEPTH < RLM_MAX_DEPTHcheck and the default maximum depth of 1: https://github.com/PrimeIntellect-ai/prime-agent/blob/a18809e00ea30638584d87b3afea7285a9d7296c/packages/coding-agent/docs/rlm-runtime.md - Prime Intellect, "Recursive Language Models" blog post, linked from the repository README as the RLM reference: https://www.primeintellect.ai/blog/rlm
- Zhang, Kraska and Khattab, "Recursive Language Models" (arXiv 2512.24601) — the RLM primitive the report cites as reference [44] and the source of the OOLONG-Pairs task in Table 1: https://arxiv.org/abs/2512.24601
- Coding-agent docs: https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/docs/index.md
- Continual Harness (attributed by the project): https://arxiv.org/abs/2605.09998
- Verifiers and PRIME-RL (the RL side): https://github.com/PrimeIntellect-ai/verifiers and https://github.com/PrimeIntellect-ai/prime-rl
Related: Agentic systems index · Self-improving harnesses · Recursive language models · Harness-R1: learned runtime editing · The filesystem as agent memory · Tau: a minimal coding agent · Agent sandboxing and isolation
-
arXiv 2608.23552v1, Section 2.2 and Figure 2. The figure labels the mechanisms per level: fine-tuning at L0, compaction at L1, agentic garbage collection at L2, refinement at L3. Compaction "replaces a conversational prefix with a summary and retains the original events in L3 for REPL retrieval," so compacted history stays addressable rather than being discarded. ↩
-
arXiv 2608.23552v1, Section 2.5, quoted exactly. The repository README states the same behaviour in its own words at the pinned commit ("It never rewrites the immutable base system prompt, and recorded snapshots support rollback", README line 40); the wording in this section is this page's, not either source's. ↩
-
The report states the ARC-AGI-3 improvement two ways and does not reconcile them. The abstract says "Prime Agent raises ARC-AGI-3 RHAE Best@1 from 30% to 95.5%"; the introduction says "Prime Agent improves ARC-AGI-3 performance from 30% to 95%". Figure 5's legend supports the abstract's upper figure and refines the lower one: "Prime Agent + Opus 5 — 95.5%" against the external reference "Opus 5, ARC harness — 30.2%". The 95% in the introduction has no support elsewhere in the paper, and neither statement carries the "Best@1" qualifier outside the abstract. Both figures are recorded here rather than one being chosen. ↩
-
arXiv 2608.23552v1, Table 1 caption, quoted exactly: "Bold marks the higher point estimate within each nominal-model pair; metrics differ by row. Bold is not statistical significance, and uncertainty intervals are unavailable." The table reproduced above drops the bold, which carries no inferential meaning, and keeps the numbers. ↩
-
packages/coding-agent/docs/rlm-runtime.mdat commita18809e00ea30638584d87b3afea7285a9d7296c, "Child Execution": step 1 ofAgentSession.runRlmChild()is "CheckRLM_DEPTH < RLM_MAX_DEPTH", and the section closes with the quoted default. In the code at the same commit the guard is written as the equivalentif (this._rlmDepth >= this._rlmMaxDepth) throw ...inpackages/coding-agent/src/core/agent-session.ts, reached throughrunRlmChild(), and_resolveRlmMaxDepth()returns{ maxDepth: 1, source: "default" }when nothing else is set. At HEAD (5146337, 2026-08-25) the same function returnsmaxDepth: 2and the doc line reads "The default maximum depth is 2, so root sessions may create children and grandchildren; grandchildren may not create another generation unless the limit is configured higher." Verified by cloning the repository and checking out both commits. ↩