# How RLM Subagents Communicate with Parent Agents Using `rlm()` and `agent_message`

> Learn how RLM subagents communicate with parent agents using rlm() and agent_message in Prime Agent. Discover the asynchronous spawn-and-message pattern for efficient agent interaction.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: internals
- Published: 2026-08-18

---

**Prime Agent implements an asynchronous spawn-and-message pattern where parent agents spawn child subagents via the `rlm()` callable and receive results through the `agent_message` skill, rather than blocking for return values.**

The PrimeIntellect-ai/prime-agent framework provides a Recursive Language Model (RLM) kernel that enables hierarchical agent execution. Understanding how parent agents spawn children and exchange messages without blocking is essential for building complex multi-agent workflows. This guide examines the specific implementation details found in the runtime source code.

## The RLM Subagent Lifecycle

### Spawning Child Agents with `rlm()`

In [`prime-agent-runtime/src/rlm/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/__init__.py), the `rlm()` function (exposed as the `_RLMCallable` type) provides the entry point for creating subagents. When a parent calls `await rlm(prompt)`, the system sends an `"rlm.run"` request to the TypeScript host via the internal `host_request` function.

The host admits the child and immediately returns an **`RLMSpawnHandle`** containing the child's unique `rlm_child_id`, assigned name, session directory, and model configuration. This handle allows the parent to reference the child, but crucially, the child's actual output is **not** returned here. As documented in [`prime-agent-runtime/src/rlm/harness.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/harness.py) (lines 30‑35), results arrive only through explicit `agent_message` replies.

### Managing Active Subagents with `list_subagents()` and `delete_subagent()`

Parents can query the host for current children using `rlm.list_subagents()`, which translates to an `"rlm.list_subagents"` host request. The raw response is processed by `_subagent_from_payload` (lines 81‑102 in [`rlm/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/rlm/__init__.py)) and wrapped into **`RLMSubagent`** objects.

To terminate a child session, the parent calls `rlm.delete_subagent(target)`, dispatching an `"rlm.delete_subagent"` request to the host. The target can be an `RLMSubagent` instance or the string `rlm_child_id`.

## Child-to-Parent Communication via `agent_message`

### Sending Results with `agent_message.send()`

Located in [`packages/coding-agent/skills/agent-message/src/agent_message/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/skills/agent-message/src/agent_message/__init__.py), the **`agent_message.send`** function enables child subagents to push results back to their parent asynchronously. The skill constructs a payload containing the message content, `receiver_role`, and optional `receiver_name`, then dispatches it via `host_request("agent_message.send", ...)`.

### Routing Roles and Message Delivery

The host routes messages according to the `receiver_role` parameter. When a child specifies `receiver_role="parent"`, the host directs the message to the spawning parent session (see lines 30‑38 in [`agent_message/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/agent_message/__init__.py)). Other valid roles include `"sibling"` and `"child"`, enabling peer-to-peer communication between subagents.

## Implementation Examples

### Parent Spawning a Subagent

```python
from rlm import rlm

# Spawn a child subagent for document summarization

handle = await rlm("Summarize the attached document")
print(f"Subagent spawned with ID: {handle.rlm_child_id}")

# Parent continues execution immediately; results arrive via message handler

```

### Child Replying to Parent

```python
from agent_message import send

# Inside the child subagent execution context

await send(
    "Here is the completed summary.",
    receiver_role="parent"  # Critical: routes to the spawning parent

)

```

### Listing and Cleaning Up Subagents

```python

# Retrieve all active children as RLMSubagent objects

children = await rlm.list_subagents()
for child in children:
    print(f"ID: {child.rlm_child_id}, Status: {child.status}")

# Terminate a specific subagent by passing the object or ID string

await rlm.delete_subagent(children[0])

```

## Key Source Files and Functions

The RLM subagent communication protocol is implemented across these critical locations in the PrimeIntellect-ai/prime-agent repository:

- **[`prime-agent-runtime/src/rlm/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/__init__.py)**: Defines the `_RLMCallable` type, `rlm()` spawning function, `list_subagents()`, `delete_subagent()`, the `_subagent_from_payload` validation logic (lines 81‑102), and the `host_request` bridge
- **[`prime-agent-runtime/src/rlm/harness.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/harness.py)**: Documents the expected spawn-and-message usage pattern (lines 30‑35)
- **[`packages/coding-agent/skills/agent-message/src/agent_message/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/skills/agent-message/src/agent_message/__init__.py)**: Implements `agent_message.send()` with role-based routing (lines 30‑38)
- **[`prime-agent-runtime/test/test_subagent_registry.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/test/test_subagent_registry.py)**: Validates the subagent lifecycle and registry behavior
- **[`packages/coding-agent/test/system-prompt.test.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/test/system-prompt.test.ts)**: Confirms `rlm` integration and `agent_message` skill presence

## Summary

- **`rlm()` returns immediately**: The spawn operation returns an `RLMSpawnHandle` without blocking for the child's completion, enabling concurrent subagent execution.
- **Explicit messaging required**: Children must use `agent_message.send()` with `receiver_role="parent"` to communicate results; there is no implicit return value mechanism.
- **Host-mediated routing**: All communication flows through the TypeScript host via `host_request` calls, with the host managing session routing based on role parameters.
- **Subagent lifecycle management**: Parents track active children via `list_subagents()` and clean up resources with `delete_subagent()`.

## Frequently Asked Questions

### How does `rlm()` differ from a standard Python function call?

Unlike standard function calls that block until a return value is received, `rlm()` returns an `RLMSpawnHandle` immediately after the host creates the child session. The actual results are delivered asynchronously through the `agent_message` system, allowing the parent to continue processing or spawn additional subagents concurrently.

### What information does the `RLMSpawnHandle` contain?

According to the source in [`rlm/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/rlm/__init__.py), the handle contains the child's unique identifier (`rlm_child_id`), the assigned name, the session directory path, and the model configuration. This metadata allows the parent to reference and manage the child throughout its lifecycle without waiting for the child's execution to complete.

### Can subagents communicate with siblings instead of the parent?

Yes. The `agent_message.send()` function accepts a `receiver_role` parameter that can be set to `"sibling"` or `"child"` in addition to `"parent"`. The host routes these messages accordingly, enabling direct peer-to-peer communication between subagents spawned from the same parent session.

### Where is the subagent payload validated in the source code?

Payload validation and object construction occur in the `_subagent_from_payload` function within [`prime-agent-runtime/src/rlm/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/__init__.py) (lines 81‑102). This function parses the raw host response and constructs `RLMSubagent` objects with validated fields for the parent agent to consume.