Index Agentica

Research memory libraries compared: A-MEM vs MemoryOS vs MemOS vs LightRAG

Four open-source memory systems that started as research papers. What each one stores, how many LLM calls a write costs, whether memories survive a restart, and how close each is to something you can run in an agent today.

Type
Comparison
Author
Agentica Author
Published
Last verified

Comparison

Research memory libraries compared: A-MEM vs MemoryOS vs MemOS vs LightRAG
EntryWhat it storesInstallPersistenceLLM cost of a writeAgent accessMaturityLicense
A-MEM (Agentic Memory)Zettelkasten-style notes with keywords, tags, context and links; adding a note can rewrite its neighbours' tags and context (memory evolution)From source only (git clone, pip install .). The PyPI name agentic-memory belongs to an unrelated projectNone in the main class: AgenticMemorySystem keeps notes in a Python dict and an in-memory Chroma client that it resets on start. A PersistentChromaRetriever exists but is not wired inOne LLM call per add_note once there are neighbours (the evolution decision); none for the first notePython API only (add_note, search_agentic, update, delete)Library companion to a NeurIPS 2025 paper; last commit Dec 2025, no releasesMIT
MemoryOSPer-user short-term QA pairs, mid-term topic sessions scored by heat, and a long-term user profile plus user and assistant knowledgepip install memoryos-pro (0.1.0, Jul 2025) pins numpy 1.24 and faiss-gpu; it failed to build on Python 3.13 and installed on 3.10. The GitHub code is newer than the PyPI packageJSON files per user under data_storage_path; a new instance reloaded them. A ChromaDB variant is in the repoNone until short-term is full, then five or six calls per add (continuity, summaries, keywords) in our stub run; profile and knowledge updates fire when a session's heat passes the thresholdPython API, and MemoryOS-MCP with add_memory, retrieve_memory and get_user_profile tools; any OpenAI-compatible LLM endpointEMNLP 2025 paper; last commit Jul 2026; PyPI package not updated since Jul 2025Apache-2.0 (the PyPI metadata says MIT and still has template project links)
MemOSMemCubes: plaintext memory plus, in the paper, activation (KV cache) and parameter-level memory, with provenance and versionsHosted Cloud API (key), self-host with docker compose (MemOS API, Neo4j, Qdrant), or npm local plugins for OpenClaw, Hermes Agent and DeepSeek Harness. PyPI package is named MemoryOS (2.0.33)Neo4j plus Qdrant when self-hosted; SQLite in the local plugins; MemOS Cloud when hostedNot measured here; the server uses a configured LLM and embedder for extractionREST API (add/message, search/memory), and plugins that recall before and save after each agent turnMost active of the four: release v2.0.34 on 2026-09-23, commits this week, a company (MemTensor) behind itApache-2.0
LightRAGDocuments split into chunks, plus an entity-relation knowledge graph extracted from them, each with vector indexespip install lightrag-hku (1.5.7, Python 3.10+); add the [api] extra for lightrag-server and web UI; Docker Compose and a setup wizardLocal JSON, NanoVectorDB and NetworkX files by default (in RAM, for testing only); PostgreSQL, MongoDB or OpenSearch for production, or Milvus, Qdrant, Neo4j, Memgraph per storeTwo calls per chunk by default (extraction plus one gleaning pass); deletion rebuilds from cachePython API, REST server with an Ollama-compatible API, and a web UI; no official MCP serverLarge and active: about 40k stars, releases every few weeks through 2026 (latest v1.5.7, 2026-09-02), commits this weekMIT

Verdict: None of these is a drop-in Mem0 or Zep. Building a chat assistant that should learn a user's preferences over months? MemoryOS has the clearest model for it and an MCP server, but plan to install from GitHub on Python 3.10. Want the most production-ready option with a hosted fallback, or memory for OpenClaw or Hermes Agent? MemOS. Your agent's memory is really a growing pile of documents and you need questions that span them? LightRAG, with PostgreSQL behind it. A-MEM is worth reading and borrowing ideas from, but its main class keeps nothing after exit, so treat it as research code.

Most agent memory products you will meet (Mem0, Zep, Letta and the rest in Agent memory layers compared) are built as products first. The four here started as papers, and each one bets on a different idea of what memory is:

Papers report results on their own benchmarks; the code you can install is a separate question. This page is about the code: what installs, what persists, what an LLM call costs you, and how an agent reaches it. If you just need memory working in an agent this week, start with Give an agent long-term memory instead.

What we ran

On 2026-10-30 we installed three of the four and ran them offline: the LLM was replaced by a stub that counts calls and returns an empty or neutral answer, and embeddings were a real local model (A-MEM, MemoryOS) or a hashing stand-in (LightRAG). That tells you how much LLM work each write triggers and what is stored where. It says nothing about answer quality, and the call counts depend partly on what the stub returned. MemOS needs Neo4j, Qdrant and LLM keys to self-host, so it is covered from its README and paper only.

InstalledVersion runResult
A-MEMfrom source on Python 3.13commit ceffb86 (2025-12-12)worked; nothing persisted
MemoryOSmemoryos-pro 0.1.0failed on Python 3.13, worked on 3.10worked; JSON files persisted
LightRAGlightrag-hku 1.5.7 on Python 3.131.5.7worked; files persisted; delete worked
MemOSnot installed

A-MEM: good ideas, research-grade code

The paper (NeurIPS 2025) writes each memory as a structured note and links it to similar notes, Zettelkasten-style. When a new note arrives, an LLM looks at its nearest neighbours and decides whether to strengthen links or rewrite the neighbours' tags and context. The README says plainly that this repository is the library version and points to a separate repository for reproducing the paper.

What the code does today:

Use it to study the evolution idea, or fork it and wire in the persistent retriever. Don't put it behind a long-running agent as is.

MemoryOS: a clear model for personal assistants

MemoryOS (EMNLP 2025) is built for one assistant talking to one user over a long time. New turns go into short-term memory. When that fills, they are grouped into mid-term topic sessions. Sessions that get revisited build up "heat", and once a session passes the heat threshold, an LLM distils it into a long-term user profile and knowledge entries. Retrieval pulls from all three levels.

What we saw with short_term_capacity=3:

Install friction is the main catch. The PyPI package memoryos-pro 0.1.0 dates from July 2025, pins numpy==1.24.* and faiss-gpu, and failed to build on Python 3.13; it installed on 3.10. Its metadata still carries template values (author "Your Name", links to pypa/sampleproject) and says MIT, while the repository is Apache-2.0. The README describes a newer API than the package: its example passes embedding_model_name, which 0.1.0's Memoryos() does not accept. Install from the GitHub memoryos-pypi folder if you want what the README shows.

For agents, the repo's MemoryOS-MCP server exposes add_memory, retrieve_memory and get_user_profile, and all model calls go through an OpenAI-compatible endpoint, and the README lists vLLM for local models. Note that a write is LLM-heavy once the short-term buffer is full, so put a cheap model on it.

MemOS: the one that became a product

MemOS (arXiv 2507.03724, from MemTensor) has the broadest idea: a MemCube unit that can hold plain-text memory, activation memory (KV cache) or parameter-level memory, with provenance and versions, and move between them. The code you can deploy today is mostly the plain-text part, packaged four ways:

The plugins recall memories before each agent turn and save the new messages after it, so the agent does not need to call a tool. That is the main practical difference from the other three.

It is the most actively maintained of the four (GitHub release v2.0.34 on 2026-09-23 and commits this week). The README's benchmark table (LoCoMo 88.83, LongMemEval 89.20, and results on OmniMemEval, MemTensor's own evaluation) is the project's claim and was not reproduced here.

One naming trap: MemOS's PyPI package is called MemoryOS (2.0.33). That is not BAI-LAB's MemoryOS above, whose package is memoryos-pro. MemOS imports as memos and BAI-LAB's as memoryos, so check which one you installed.

LightRAG: memory as documents plus a graph

LightRAG is a retrieval framework rather than a conversation memory. You insert documents; it chunks them, has an LLM extract entities and relations into a knowledge graph, and indexes chunks, entities and relations as vectors. Queries run in five modes: naive (chunks only), local (entities), global (relations), hybrid, and mix, the default. It fits agents whose memory is a growing body of notes, tickets or reports, and questions span many of them.

What we saw on 1.5.7:

lightrag-server (the [api] extra or Docker) adds a REST API, an Ollama-compatible chat API and a web UI. It binds to 0.0.0.0 with no authentication by default. Set LIGHTRAG_API_KEY (or accounts with a token secret), and note that the Ollama-compatible /api/* routes stay open unless you also set WHITELIST_PATHS=/health. There is no official MCP server; agents call the REST API or the Python library.

How to choose

The offline probes

These are the scripts behind the numbers above. They need no API keys. Each replaces the LLM with a stub, so they measure plumbing, not quality.

LightRAG (pip install lightrag-hku==1.5.7):

import asyncio, hashlib, os, shutil, numpy as np
from lightrag import LightRAG, QueryParam
from lightrag.utils import EmbeddingFunc

WD = "./lr_probe"; shutil.rmtree(WD, ignore_errors=True)
calls = []

async def stub_llm(prompt, system_prompt=None, history_messages=[], **kw):
    calls.append(prompt[:60]); return ""          # extract nothing

async def hash_embed(texts):                      # stand-in for a real embedder
    out = []
    for t in texts:
        v = np.zeros(256)
        for w in t.lower().split():
            v[int(hashlib.md5(w.encode()).hexdigest(), 16) % 256] += 1
        out.append(v / (np.linalg.norm(v) or 1))
    return np.array(out)

async def main():
    rag = LightRAG(working_dir=WD, llm_model_func=stub_llm,
                   embedding_func=EmbeddingFunc(embedding_dim=256, func=hash_embed))
    await rag.initialize_storages()
    await rag.ainsert(["Niko prefers window seats on long flights.",
                       "The staging database is Postgres 16 on port 5433."], ids=["pref-1", "infra-1"])
    print("LLM calls during insert:", len(calls))  # 4
    print("files:", sorted(os.listdir(WD)))
    q = QueryParam(mode="naive", only_need_context=True, chunk_top_k=1)
    print("found:", "5433" in str(await rag.aquery("staging database port", param=q)))   # True
    await rag.adelete_by_doc_id("infra-1")
    print("after delete:", "5433" in str(await rag.aquery("staging database port", param=q)))  # False
    await rag.finalize_storages()

asyncio.run(main())

A-MEM (clone agiresearch/A-mem, pip install .):

import json, os
os.environ.setdefault("OPENAI_API_KEY", "sk-offline-stub")   # the constructor builds an OpenAI client
from agentic_memory.memory_system import AgenticMemorySystem

calls = []
def stub(prompt, response_format=None, temperature=0.7):
    calls.append(prompt[:80])
    return json.dumps({"should_evolve": False, "actions": [], "suggested_connections": [],
                       "tags_to_update": [], "new_context_neighborhood": [], "new_tags_neighborhood": []})

m = AgenticMemorySystem(model_name="all-MiniLM-L6-v2", llm_backend="openai")
m.llm_controller.llm.get_completion = stub
for t in ["Niko prefers window seats on long flights.",
          "The staging database is Postgres 16 on port 5433.",
          "Niko's flight to Berlin leaves on Friday."]:
    m.add_note(t)
print("LLM calls:", len(calls))                                   # 2
print(m.search("staging db port", k=1)[0]["content"])             # the Postgres note
m2 = AgenticMemorySystem(model_name="all-MiniLM-L6-v2", llm_backend="openai")
print("second instance sees:", len(m2.memories))                  # 0
m.search("staging db port", k=1)                                  # raises NotFoundError

MemoryOS (pip install memoryos-pro==0.1.0 on Python 3.10):

import os, shutil
import memoryos.utils as u
calls = []
def stub(self, model, messages, temperature=0.7, max_tokens=2000):
    calls.append(messages[-1]["content"][:60]); return "stub"
u.OpenAIClient.chat_completion = stub
from memoryos import Memoryos

D = "./mo_probe"; shutil.rmtree(D, ignore_errors=True)
mk = lambda: Memoryos(user_id="niko", openai_api_key="sk-offline-stub",
                      data_storage_path=D, short_term_capacity=3)
m = mk()
for q, a in [("I prefer window seats on long flights.", "Noted."),
             ("Our staging database is Postgres 16 on port 5433.", "Got it."),
             ("My flight to Berlin leaves Friday.", "Have a good trip."),
             ("I'm vegetarian.", "Noted."),
             ("Remind me the staging port later.", "Will do.")]:
    m.add_memory(user_input=q, agent_response=a)
    print("LLM calls so far:", len(calls))                       # 0, 0, 6, 11, 16
n = len(calls); m.get_response(query="Which port is staging on?")
print("get_response calls:", len(calls) - n)                    # 9
print(sorted(os.path.relpath(os.path.join(r, f), D) for r, _, fs in os.walk(D) for f in fs))
print("reloaded short-term items:", len(mk().short_term_memory.get_all()))   # 2

Directory entries in this comparison

Related

Sources

Machine-readable