Skip to content
Markdown

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. This page covers its two core abstractions, the Recursive Language Model (RLM) and the Continual Harness, the recursion and budget bounds a programmatic-subagent model needs, and the isolation caveat the project states plainly. 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.

Examined at commit a18809e0 (2026-08-07) of PrimeIntellect-ai/prime-agent, MIT, a TypeScript monorepo (packages/agent, ai, coding-agent, tui) with an IPython runtime. The recursive-subagent budget and depth model below is executed and asserted as standalone Python. No agent was run: Prime Agent executes model-generated Python and project commands with your permissions and needs a provider, so its capability claims are read from the code and docs, not benchmarked here. The Continual Harness is attributed by the project to arXiv 2605.09998; the RLM concept to Prime Intellect's own blog.

What it is

Prime Agent is a persistent-REPL agent built around two ideas.

The Recursive Language Model (RLM) treats context as variables (prompt-as-a-variable) and treats tools, including recursive subagents, as function calls inside a persistent IPython environment. 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(...) spawns real child agents for parallel or background work and returns their results programmatically, so an agent composes other agents the way a program composes function calls.

The Continual Harness stores supplemental prompts, memories, skill descriptions, and reusable subagent specifications as durable state that the agent can refine through small, evidence-backed updates, local to the session by default. /refine reviews the current trajectory and can apply those updates; it never rewrites the immutable base system prompt, and recorded snapshots support rollback. Skills are importable Python packages, and a built-in skill creator turns recurring workflows into project or personal skills.

Around these, the agent is built for long-running work: daemon-backed sessions keep running when the terminal disconnects and can be reattached, running agents can message each other, and automatic compaction, persistent goals, heartbeats, schedules, and an autonomous mode preserve progress across turns and terminal sessions.

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. /refine makes 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 let a recursive-subagent agent run unbounded: as the model below shows, recursion needs a depth cap and a shared budget, or a self-referential task fans out until it exhausts the account. Do not expect the self-improvement to touch the base prompt; by design it only refines supplemental state.

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. The model below 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. Prime Agent's compaction, persistent goals, and heartbeats are the mechanisms that keep a long autonomous run inside those bounds over time.

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. Bound recursion depth and token budget for autonomous runs, and 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.

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.
  • Unbounded recursion or fan-out. Without both a depth cap and a shared budget, an RLM agent can exhaust the stack, the context, or the account. Set both.
  • Self-refinement drift. /refine changes supplemental state; a bad update degrades behavior until rolled back from a snapshot. Keep the snapshots.
  • 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

  • Prime Agent repository (Prime Intellect), pinned commit a18809e0: https://github.com/PrimeIntellect-ai/prime-agent
  • 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 · Harness-R1: learned runtime editing · The filesystem as agent memory · Tau: a minimal coding agent · Agent sandboxing and isolation