How RLM Subagents Communicate with Parent Agents Using `rlm()` and `agent_message`
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, 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 (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) 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, 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). Other valid roles include "sibling" and "child", enabling peer-to-peer communication between subagents.
Implementation Examples
Parent Spawning a Subagent
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
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
# 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: Defines the_RLMCallabletype,rlm()spawning function,list_subagents(),delete_subagent(), the_subagent_from_payloadvalidation logic (lines 81‑102), and thehost_requestbridgeprime-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: Implementsagent_message.send()with role-based routing (lines 30‑38)prime-agent-runtime/test/test_subagent_registry.py: Validates the subagent lifecycle and registry behaviorpackages/coding-agent/test/system-prompt.test.ts: Confirmsrlmintegration andagent_messageskill presence
Summary
rlm()returns immediately: The spawn operation returns anRLMSpawnHandlewithout blocking for the child's completion, enabling concurrent subagent execution.- Explicit messaging required: Children must use
agent_message.send()withreceiver_role="parent"to communicate results; there is no implicit return value mechanism. - Host-mediated routing: All communication flows through the TypeScript host via
host_requestcalls, with the host managing session routing based on role parameters. - Subagent lifecycle management: Parents track active children via
list_subagents()and clean up resources withdelete_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, 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 (lines 81‑102). This function parses the raw host response and constructs RLMSubagent objects with validated fields for the parent agent to consume.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →