mem0ai / mem0

The Memory layer for your AI apps
https://mem0.ai
Apache License 2.0
23.12k stars 2.14k forks source link

Adding just a simple test Memory doesn't work at all (script and explanation) #2062

Open fireYtail opened 5 days ago

fireYtail commented 5 days ago

🐛 Describe the bug

On a clean Python install, I ran "pip install mem0ai", then save this simple test script as a .py file and run it, doesn't work. Script:

from openai import OpenAI
from mem0 import Memory

os.environ["OPENAI_API_BASE"] = "http://localhost:1234/v1"
os.environ["OPENAI_API_KEY"] = "lm-studio"

config = {
    "llm": {
        "provider": "openai",
        "config": {
            "model": "Orenguteng/Llama-3.1-8B-Lexi-Uncensored-V2-GGUF",
        }
    },
    "version": "v1.1",
}

client = OpenAI(base_url="http://localhost:1234/v1", api_key="lm-studio")
m = Memory.from_config(config)
result = m.add("I am working on improving my tennis skills. Suggest some online courses.", user_id="test", metadata={"category": "hobbies"})

Of course, I have verbose logging enabled on my local LM-Studio server. It receives the following message in the user role:

You are a smart memory manager which controls the memory of a system.
You can perform four operations: (1) add into the memory, (2) update the memory, (3) delete from the memory, and (4) no change.
Based on the above four operations, the memory will change.
Compare newly retrieved facts with the existing memory. For each new fact, decide whether to:
- ADD: Add it to the memory as a new element
- UPDATE: Update an existing memory element
- DELETE: Delete an existing memory element
- NONE: Make no change (if the fact is already present or irrelevant)
There are specific guidelines to select which operation to perform:
1. **Add**: If the retrieved facts contain new information not present in the memory, then you have to add it by generating a new ID in the id field.
- **Example**:
- Old Memory:
[
{
"id" : "0",
"text" : "User is a software engineer"
}
]
- Retrieved facts: ["Name is John"]
- New Memory:
{
"memory" : [
{
"id" : "0",
"text" : "User is a software engineer",
"event" : "NONE"
},
{
"id" : "1",
"text" : "Name is John",
"event" : "ADD"
}
]

}

2. **Update**: If the retrieved facts contain information that is already present in the memory but the information is totally different, then you have to update it.
If the retrieved fact contains information that conveys the same thing as the elements present in the memory, then you have to keep the fact which has the most information.
Example (a) -- if the memory contains "User likes to play cricket" and the retrieved fact is "Loves to play cricket with friends", then update the memory with the retrieved facts.
Example (b) -- if the memory contains "Likes cheese pizza" and the retrieved fact is "Loves cheese pizza", then you do not need to update it because they convey the same information.
If the direction is to update the memory, then you have to update it.
Please keep in mind while updating you have to keep the same ID.
Please note to return the IDs in the output from the input IDs only and do not generate any new ID.
- **Example**:
- Old Memory:
[
{
"id" : "0",
"text" : "I really like cheese pizza"
},
{
"id" : "1",
"text" : "User is a software engineer"
},
{
"id" : "2",
"text" : "User likes to play cricket"
}
]
- Retrieved facts: ["Loves chicken pizza", "Loves to play cricket with friends"]
- New Memory:
{
"memory" : [
{
"id" : "0",
"text" : "Loves cheese and chicken pizza",
"event" : "UPDATE",
"old_memory" : "I really like cheese pizza"
},
{
"id" : "1",
"text" : "User is a software engineer",
"event" : "NONE"
},
{
"id" : "2",
"text" : "Loves to play cricket with friends",
"event" : "UPDATE",
"old_memory" : "User likes to play cricket"
}
]
}

3. **Delete**: If the retrieved facts contain information that contradicts the information present in the memory, then you have to delete it. Or if the direction is to delete the memory, then you have to delete it.
Please note to return the IDs in the output from the input IDs only and do not generate any new ID.
- **Example**:
- Old Memory:
[
{
"id" : "0",
"text" : "Name is John"
},
{
"id" : "1",
"text" : "Loves cheese pizza"
}
]
- Retrieved facts: ["Dislikes cheese pizza"]
- New Memory:
{
"memory" : [
{
"id" : "0",
"text" : "Name is John",
"event" : "NONE"
},
{
"id" : "1",
"text" : "Loves cheese pizza",
"event" : "DELETE"
}
]
}

4. **No Change**: If the retrieved facts contain information that is already present in the memory, then you do not need to make any changes.
- **Example**:
- Old Memory:
[
{
"id" : "0",
"text" : "Name is John"
},
{
"id" : "1",
"text" : "Loves cheese pizza"
}
]
- Retrieved facts: ["Name is John"]
- New Memory:
{
"memory" : [
{
"id" : "0",
"text" : "Name is John",
"event" : "NONE"
},
{
"id" : "1",
"text" : "Loves cheese pizza",
"event" : "NONE"
}
]
}

Below is the current content of my memory which I have collected till now. You have to update it in the following format only:
``
[]
``

The new retrieved facts are mentioned in the triple backticks. You have to analyze the new retrieved facts and determine whether these facts should be added, updated, or deleted in the memory.

``
[]
``

Follow the instruction mentioned below:
- Do not return anything from the custom few shot prompts provided above.
- If the current memory is empty, then you have to add the new retrieved facts to the memory.
- You should return the updated memory in only JSON format as shown below. The memory key should be the same if no changes are made.
- If there is an addition, generate a new key and add the new memory corresponding to it.
- If there is a deletion, the memory key-value pair should be removed from the memory.
- If there is an update, the ID key should remain the same and only the value needs to be updated.

Do not return anything except the JSON format.

Obviously this user role message is wrong, as the task to do below the examples is just blank. Since you offer no means to customize this automatic message (at least, not without altering Mem0 internal files), this is a dead-end. Also, I have another problem. In your Memory API documentation you indicate that infer and output_format are valid arguments, but if I add them to the script, this happens:

TypeError: Memory.add() got an unexpected keyword argument 'infer'
TypeError: Memory.add() got an unexpected keyword argument 'output_format'

These two problems, combined, leave me stuck, as Mem0 is basically useless if I cannot even add a simple test memory. Finally, you mention the following in the readme:

We collect anonymous usage metrics to enhance our package's quality and user experience.
This includes data like feature usage frequency and system info, but never personal details.
The data helps us prioritize improvements and ensure compatibility.
If you wish to opt-out, set the environment variable MEM0_TELEMETRY=false.
We prioritize data security and don't share this data externally.

But if I add the following line to my script...

os.environ["MEM0_TELEMETRY"] = "false"

... it does absolutely nothing. Every time I run the script, it's still connecting to "us.i.posthog.com". So the "opt-out of spying me" is a lie.

Cirr0e commented 4 days ago

I see the problems with your Mem0 implementation. Let me address each issue and provide solutions:

  1. Memory Not Working: The empty memory template issue appears to be a bug in the current implementation. As a workaround, you'll need to upgrade to the latest version of Mem0 where this has been addressed:
pip install --upgrade mem0ai
  1. API Parameter Discrepancy: There appears to be a mismatch between the documentation and implementation. The infer and output_format parameters aren't actually implemented in the current version, despite being in the docs. Maybe one of the collaborators can confirm but seems to be a documentation inconsistency.

For now, here's the way I would add a memory:

result = m.add(
    text="I am working on improving my tennis skills. Suggest some online courses.",
    user_id="test",
    metadata={"category": "hobbies"}
)
  1. Telemetry Opt-Out Issue: Looking at the telemetry implementation in mem0/memory/telemetry.py, I can see why the opt-out isn't working. The environment variable needs to be set before importing mem0. Here's the correct way to disable telemetry:
import os
os.environ["MEM0_TELEMETRY"] = "false"  # Must be before importing mem0

import mem0
from mem0 import Memory
from openai import OpenAI

The issue is that the telemetry configuration is read during module import, so setting it after importing won't affect the already-initialized telemetry system.

References:

Important considerations:

Let me know if you need any clarification or run into other issues!