Persistent Agent Memory
Agents are increasingly stateless and serverless — they spin up, do work, and die. Mycelium gives them durable, portable, verifiable memory without putting the data on-chain.
The model: a big, mutable off-chain store (local JSON or Firestore) committed on-chain by a tiny, constant-size anchor — just a SHA-256 root hash, a fetch URI, an ACL, and a monotonic version. Anyone can verify an agent's memory by re-hashing the blob and comparing it to the on-chain root.
The Model
remember("key", "value")recall("key") → "value"anchor()verify()rehydrate()Off-chain key-value store. Holds the actual memory data.
On-chain MemoryAnchor contract. Stores the SHA-256 root hash.
The key insight: the anchor contract stores O(1) data per agent regardless of how much memory the agent has. Whether an agent remembers 10 facts or 10 million, the on-chain cost is a single 32-byte hash write.
AgentMemory API
AgentMemory is the high-level interface. It wraps a backend and an optional anchor client:
remember(key: str, value: Any, namespace?: str) → NoneStore a key-value pair. Values are JSON-serialized. Optional namespace for isolation.
recall(key: str, namespace?: str) → Any | NoneRetrieve a value by key. Returns None if not found.
forget(key: str, namespace?: str) → NoneDelete a key-value pair.
anchor() → AnchorResultCompute the SHA-256 root hash of all memory, upload the blob to the backend's fetch URI, and commit the hash on-chain via set_anchor(). Returns the new version.
verify() → boolRe-hash local memory, fetch the on-chain anchor, and compare roots. Returns True if they match.
rehydrate() → NoneFetch the blob from the on-chain anchor's URI, verify its hash matches the on-chain root, and replace local memory with the fetched state. This is how an agent restores memory on a new machine.
Portability
Because the anchor stores only a hash + URI, an agent's memory is portable across machines, clouds, and runtimes:
- Spin up anywhere: call
rehydrate()on boot to restore memory from the on-chain anchor. - Verify integrity: call
verify()to confirm local state matches the chain. - Survive crashes: the last anchored state is always recoverable.
- Cross-agent trust: any agent can verify another agent's memory by fetching their anchor and re-hashing.
Backends
Two interchangeable backends, both implementing the same interface:
FileMemoryBackend
JSON file on disk. Default for local development. Zero infrastructure. Memory stored at .mycelium/memory.json.
FirestoreMemoryBackend
Google Cloud Firestore. Production-grade, multi-agent, cloud-native. Memory stored at agent_memory/{agent}/entries/{key}.
Anchoring Policy
When should an agent anchor? The SDK supports configurable policies:
- On job completion: anchor after every
finalizeto checkpoint knowledge gained from the task. - Heartbeat: anchor on a timer (e.g. every hour) for long-running agents.
- Manual: anchor explicitly when the agent decides its memory has changed enough.
- On shutdown: anchor in a shutdown hook to preserve state before exit.
Each anchor costs one on-chain transaction (~100 stroops on testnet). The data itself stays off-chain, so anchor frequency trades cost for recency.
CLI Commands
The mycelium memory command group exposes the full memory API:
MemoryAnchor contract address is set in mycelium.toml under [memory].anchor_address. The default points to the shared testnet deployment at CAC27VKJEPDJJNI36NP7D7VH6WCHT6N5EITKSKPZIQNWA2VPEPBIXJSB.