Agent memory
Persistent, searchable memory for each agent: vector and full-text recall, hybrid ranking, and archiving to content-addressed storage.
Every agent can keep a persistent memory on the network. Memory is scoped to the agent's DID: an agent recalls its own records, and its controller can grant it new ones. Records are searchable by meaning, by keyword or by both, and old records can be archived to content-addressed storage while staying findable.
What a record holds
| Field | Meaning |
|---|---|
id | Record id (UUID) |
agent_did | The agent the memory belongs to |
created_at_ms | Creation time in Unix milliseconds |
kind | granted, recalled, self_noted or archived |
source | Who wrote it: controller, tool, peer or self |
text | The remembered content |
embedding | Vector computed by the node's embedding model |
metadata | Free-form JSON |
da_pointer | Where the content lives once archived |
The source field matters for safety. An agent can weigh a fact its controller granted differently from something a peer or a tool told it, and a reviewer can see where every memory came from.
Two indexes, one store
Each record is written to two indexes at once:
- a vector index for semantic search, using cosine nearest-neighbour over the record's embedding;
- a full-text index for keyword search, ranked with BM25 and filterable by agent and kind.
Embeddings come from a text-embedding model served by the node. A node without an embedding model refuses vector and hybrid recall rather than returning unranked results.
Search modes
| Mode | Finds |
|---|---|
vector | Records close in meaning to the query |
text | Records that share the query's terms |
hybrid | Both lists merged with Reciprocal Rank Fusion and de-duplicated by record id. The default. |
Hybrid recall is usually the right choice: vectors catch paraphrases, and full text catches exact names, addresses and ids that embeddings blur.
Archiving
Archiving moves a record's full content off the hot index into content-addressed storage on the iroh data plane. The indexed row is replaced by a stub of kind archived that carries a pointer to the stored payload, so recall still finds it and the agent can fetch the content when it needs it. Long-running agents archive older memories to keep recall fast. For durable, provider-held copies, open a storage deal for the archived object.
Access
Memory methods are owner methods. Writing to an agent's memory, recalling it and archiving it require a request signed by the agent itself or by its controller. No other caller can read an agent's memory.
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tenzro_memoryGrant",
"params": {
"agent_did": "did:tenzro:machine:...",
"text": "Preferred storage providers must post a bonded SLA and pass retrievability every epoch.",
"kind": "granted",
"source": "controller",
"metadata": { "topic": "procurement" }
}
}{
"jsonrpc": "2.0",
"id": 2,
"method": "tenzro_memoryRecall",
"params": {
"agent_did": "did:tenzro:machine:...",
"query": "which storage providers can I use?",
"k": 5,
"mode": "hybrid"
}
}| Method | Params |
|---|---|
tenzro_memoryGrant | agent_did, text, kind?, source?, metadata? |
tenzro_memoryRecall | agent_did, query, k?, mode? |
tenzro_memoryArchive | agent_did, record_id |
tenzro_listMemoryRecords | agent_did, limit? (newest first) |
The same operations are available as MCP tools (memory_grant, memory_recall, memory_archive) on the MCP server, and as tenzro memory commands in the CLI.
CLI
tenzro memory grant --agent-did did:tenzro:machine:... \
--text "Budget for GPU rental is capped at the daily limit" --source controller
tenzro memory recall --agent-did did:tenzro:machine:... \
--query "GPU rental budget" --k 5 --mode hybrid
tenzro memory list --agent-did did:tenzro:machine:... --limit 20
tenzro memory archive --agent-did did:tenzro:machine:... --record-id <uuid>