What Mem0 asks a model
You cannot write a stand-in for something without knowing what it is asked. Mem0 sends a model one long instruction, and the fastest way to see it is to print it.
A model in Mem0 is any LangChain chat model, which means any class with a _generate method. This one prints what it was given and then says it found nothing.
from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.messages import AIMessage
from langchain_core.outputs import ChatGeneration, ChatResultclass SpyModel(BaseChatModel):
"""Writes down what Mem0 asked, then says it found nothing."""
@property
def _llm_type(self):
return "spy"
def _generate(self, messages, stop=None, run_manager=None, **kwargs):
print(str(messages[-1].content))
return ChatResult(generations=[ChatGeneration(
message=AIMessage(content='{"memory": []}'))])Wiring it in needs the configuration from lesson 7, which is shown here in full and explained there. Read it as: use this model, this embedder, and a store in a temporary directory.
import tempfile
from mem0 import Memory
from spy_model import SpyModel
from pretend_mem0 import PretendEmbedder
spy = Memory.from_config({
"llm": {"provider": "langchain", "config": {"model": SpyModel()}},
"embedder": {"provider": "langchain", "config": {"model": PretendEmbedder()}},
"vector_store": {"provider": "qdrant", "config": {
"path": tempfile.mkdtemp(), "embedding_model_dims": 64, "on_disk": False}},
})
spy.add("I prefer email updates, not SMS.", user_id="ravi")That is the whole instruction, and it is worth reading properly.
What it is asking for
It sends the conversation, not a question. The block under New Messages is what the customer just said. Everything above it is instructions about how to treat it.
It sends what it already knows. Existing Memories and Recently Extracted Memories are there so the model does not store the same fact twice. On a first call both are empty; on the tenth they are not, and that is how Mem0 avoids a pile of duplicates.
It wants one specific shape back. A JSON object with a memory list, each entry carrying an id, the text to store, and any existing memories it relates to.
{"memory": [
{"id": "0", "text": "User prefers email updates over SMS", "linked_memory_ids": []}
]}{"facts": [...]}. Return that to 2.0 and add() returns {'results': []}, with no error and no warning. A silent empty result is the symptom; the wrong key is the cause.- Print
messages[0].contentas well, to see the system instruction in full. - Add a second sentence to the conversation and see how the New Messages block changes.
- Return
{"facts": []}from the spy and confirm that nothing is stored and nothing complains.
This is what real progress feels like.