An all-in-one long-term memory solution for AI agents

更新时间:
复制 MD 格式

Large language models (LLMs) often forget conversation history due to context window limitations, which leads to an inconsistent user experience. PolarDB for PostgreSQL provides a long-term memory solution based on the Mem0 framework that integrates a vector database engine and a Graph Database engine. This allows an AI agent to store and retrieve user preferences and history across sessions, enabling a truly intelligent experience with long-term memory.

Features

The core of this solution is to use the Mem0 framework to build a unified memory layer for an AI agent. Mem0 can transform conversation information into structured or unstructured memories and store them in a backend database. As the underlying data engine, PolarDB for PostgreSQL offers two implementation paths:

  • Vector-only database solution This solution uses the built-in pgvector (vector database engine) in PolarDB for PostgreSQL to convert key information from conversations into vectors and store them. When the AI agent needs to recall information, it quickly retrieves related memories through vector similarity search. This solution is simple to implement and cost-effective. It is suitable for scenarios that require fast semantic retrieval, such as online customer service and real-time chatbots.

  • Vector and graph database solution This solution combines the built-in pgvector (vector database engine) and polar_age (Graph Database engine) plugins in PolarDB for PostgreSQL. This stores not only the semantic information of conversations but also the complex relationships between entities as graph structure trituples (entity1-relationship-entity2). For example, when a user says, "I like the movie Interstellar, directed by Nolan," the system not only remembers this sentence but also establishes the entity relationships "I-like-Interstellar" and "Nolan-directed-Interstellar". This solution is suitable for scenarios that require long-term personalized services (such as intelligent cockpit AI assistants and AI companions), complex relationship inference (such as medical diagnosis and travel planning), and tracking the evolution and association of complex entities (such as enterprise knowledge bases and dynamic risk control rule bases in finance).

The two solutions complement each other. The vector and graph database solution can handle complex relationships, but its retrieval efficiency can be more challenging to optimize. The vector-only database solution is more efficient in simple scenarios but lacks the ability to model deep relationships. During actual deployment, you can design a hybrid architecture based on your business complexity and real-time requirements.

Solution architecture

The all-in-one long-term memory solution based on PolarDB for PostgreSQL includes the following five main components:

image
  • Memory engine: The Mem0 framework is used as the memory engine. This is an advanced memory framework designed for AI agents. It not only merges long-term and short-term memory but also categorizes information into types such as working, factual, and episodic. It already supports the vector database and Graph Database engine capabilities of PolarDB.

  • Base data engine: PolarDB for PostgreSQL natively integrates the pgvector vector engine and an Apache AGE-compatible graph engine. This all-in-one architecture avoids the complexity of piecing together multiple systems and relies on cloud-native capabilities to ensure excellent performance and scalability.

  • Model service: The large language model in this solution is responsible for automatically extracting, transforming, and vectorizing key information from conversations. You can add AI nodes with GPU specifications directly in PolarDB to achieve tight coupling between data and model inference, which greatly improves processing efficiency.

  • AI application building platform: The Mem0 framework can be easily integrated as a plugin into mainstream AI application development frameworks, such as Dify and LangChain, to build more powerful overall solutions.

  • KV cache enhancement: For scenarios with extremely high real-time requirements, PolarDB for PostgreSQL supports a distributed KV Cache that can be enabled as a context cache acceleration layer. This effectively reduces redundant computations and significantly stabilizes and lowers inference latency.

Advantages

  • All-in-one solution: PolarDB for PostgreSQL provides both a high-performance vector database engine and a Graph Database engine in a single product. Compared to solutions that require purchasing and maintaining multiple separate database products, this solution can reduce your procurement costs by at least 50%. It also significantly simplifies the system architecture, lowering O&M complexity and project risks.

  • High scalability: Based on a cloud-native distributed architecture, both vector storage and graph data management support a scale of tens of billions of records, effectively handling business growth. There is no risk of out-of-memory (OOM) errors during vector index creation and search. The Graph Database engine can manage large graphs with tens of billions of vertices and edges and supports graph searches with scalability of over 10,000 queries per second (QPS). Additionally, the system supports automatic lifecycle management for Time to Live (TTL) records and provides a console feature to enable a control plane node for visual management.

  • High performance: The solution supports real-time writes and queries for vector and graph data (data is queryable immediately after writing), with query response time (RT) as low as 50 milliseconds. If you use an AI node for local model inference, efficiency can be doubled or tripled. With the addition of a distributed KV Cache, inference speed can be further increased by a factor of more than five, while reducing GPU memory usage by 30% to 50%.

Billing

The Alibaba Cloud products involved in this solution are paid services. The billing details are as follows:

Instructions

This tutorial guides you through building a long-term memory system for an AI agent. You will use the vector-only database and the vector and graph database solutions of PolarDB for PostgreSQL, Alibaba Cloud Model Studio, and the Mem0 framework.

Note

The open source version of the Mem0 framework is currently compatible with the pgvector (vector database engine) of PolarDB for PostgreSQL, but is not yet compatible with the polar_age (Graph Database engine). To experience the all-in-one AI agent long-term memory solution, please submit a ticket to contact us and obtain the compatible version of the Mem0 framework.

Preparations

  1. A PolarDB PostgreSQL 16 cluster and an ECS instance. For optimal performance, the cluster and the instance should be located within the same virtual private cloud (VPC) and vSwitch.

  2. Obtain the endpoint and port from the PolarDB for PostgreSQL cluster and create a corresponding database account.

  3. Activate Alibaba Cloud Model Studio, and obtain and configure an API key.

Step 1: Configure the ECS environment

  1. Log on to the ECS instance. You can choose a suitable tool to connect to the instance as needed.

  2. Check the Python environment and version. This solution requires Python 3.11 or later. The following instructions use the Alibaba Cloud Linux 3.2104 LTS 64-bit operating system as an example.

    1. Check if a Python environment exists and verify its version.

      python --version
    2. If it is not installed or the version is too low, you can execute the following command to install or update it.

      1. Update the system packages.

        sudo yum update -y
      2. List all available but uninstalled Python packages.

        sudo yum list available | grep '^python3\([0-9]\|\.[0-3]\+\)\.\(x86_64|aarch64\)*'
      3. From the available Python packages, select and install a version that meets the Python 3.11 requirement.

        sudo yum install python3.11.x86_64 -y
      4. Verify the environment.

        python3.11 --version
  3. Upload the Mem0 framework for PolarDB for PostgreSQL that you obtained by submitting a ticket to an ECS instance and unzip it. In this example, the framework is uploaded to the /home directory. You can choose a method to upload the ZIP package as needed.

    Note

    If the unzip tool is not installed in your ECS environment, first run the sudo yum install -y unzip command to install it.

    cd /home
    unzip mem0.zip 
  4. Set the Alibaba Cloud Model Studio API key as an environment variable. Replace <YOUR_DASHSCOPE_API_KEY> with your API key.

    echo "export DASHSCOPE_API_KEY='<YOUR_DASHSCOPE_API_KEY>'" >> ~/.bashrc
    source ~/.bashrc
  5. Configure the Python environment as an environment variable. Replace <mem0_src> with your code directory. For example, if you followed the previous step, set it to /home/mem0.

    export PYTHONPATH=<mem0_src>:<mem0_src>/mem0:/home/postgres/.local/lib/python3.11/site-packages/

Step 2: Initialize the PolarDB database

  1. Log on to the PolarDB for PostgreSQL cluster. From your ECS instance, use PolarDB's PolarDB-Tools to connect to your cluster.

    Note

    To log on to the cluster from an ECS instance, you must first add the IP address of the ECS instance or its security group to the cluster's whitelist.

  2. Enter the default postgres database, and run the following SQL statements to create the test database and required plugins.

    1. Create the test database mem0.

      CREATE DATABASE mem0;
      ALTER DATABASE mem0 SET session_preload_libraries TO 'polar_age';
    2. Switch to the mem0 database.

      \c mem0
    3. Create the required plugins.

      -- Create the Graph Database plugin
      CREATE EXTENSION polar_age;
      
      -- Create the vector database plugin
      CREATE EXTENSION vector;
    4. You can create a graph.

      -- Create a graph named mem0
      SELECT ag_catalog.create_graph('mem0');
      
      -- Add a 1536-dimension vector column to the vertex table of the graph for hybrid retrieval
      -- Note: The 1536 dimensions must match the output dimension of your chosen embedding model (such as text-embedding-v2 from Model Studio)
      ALTER TABLE mem0._ag_label_vertex ADD COLUMN embedding vector(1536);
      Note

      PolarDB for PostgreSQL adds a vector field to the vertex table of a graph to enable hybrid graph and vector retrieval at the underlying layer.

    5. Set the plugins to load permanently.

      ALTER DATABASE mem0 SET search_path = public,ag_catalog,mem0;
      ALTER DATABASE mem0 SET session_preload_libraries TO 'polar_age';
      Note

      Note that there might be compatibility issues when setting search_path using the Data Management (DMS) client.

  3. Use the exit; command to exit the database.

Step 3: Configure and run the Mem0 sample code

  1. Install the PostgreSQL development toolkit.

    # This command installs pg_config and other tools required to build psycopg2
    sudo yum install -y postgresql-devel
  2. In the /home/mem0 code directory, create a virtual environment (venv) to isolate project dependencies and avoid affecting the global Python environment.

    cd /home/mem0
    python3.11 -m venv myenv
  3. Activate the virtual environment.

    source myenv/bin/activate
  4. Upgrade pip to the latest version.

    python -m pip install --upgrade pip
  5. Install the Mem0 framework and its required Python dependencies.

    pip install .
    pip install rank_bm25
    pip install psycopg2-binary
  6. Test the long-term memory solution.

    Real-time Q&A memory experience

    Vector-only database

    1. In the project root directory, create a run_memory_test.py file.

      touch run_memory_test.py
      vi run_memory_test.py
    2. Copy the following code into the file. Replace the placeholders in the code (such as <polardb-host>, <polardb-port>, <polardb-username>, and <polardb-password>) with your cluster information.

      from mem0 import Memory
      
      # This example must connect to a PolarDB for PostgreSQL instance with a 1536-dimension vector specified.
      config = {
          "llm": {
              "provider": "bailian",
              "config": {"model": "qwen-plus"},
          },
          "embedder": {
              "provider": "bailian",
              "config": {"model": "text-embedding-v4", "embedding_dims": 1536},
          },
          "vector_store": {
              "provider": "pgvector",
              "config": {
                  "host": "<polardb-host>",
                  "port": <polardb-port>,
                  "dbname": "mem0",
                  "user": "<polardb-username>",
                  "password": "<polardb-password>",
                  "collection_name": "memories"
              }
          }
      }
      
      m = Memory.from_config(config_dict=config)
      
      debug = True
      # Using only user_id
      result = m.add("I like pizza", user_id="alice")
      if debug:
          print(result)
      
      result = m.add("I hate pizza", user_id="alice")
      if debug:
          print(result)
      
      result = m.add("I like football", user_id="alice", metadata={"category": "hobbies"})
      if debug:
          print(result)
      
      # Using both user_id and agent_id
      result = m.add("I like pizza", user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
      
      # Get all memories for a user
      result = m.get_all(user_id="alice")
      if debug:
          print(result)
      
      # Get all memories for a specific agent belonging to a user
      result = m.get_all(user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
      
      # Search memories for a user
      result = m.search("tell me my name.", user_id="alice")
      if debug:
          print(result)
      
      # Search memories for a specific agent belonging to a user
      result = m.search("tell me my name.", user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
      
      # Search memories for a user
      result = m.search("what food do you like.", user_id="alice")
      if debug:
          print(result)
      
      # Search memories for a user
      result = m.search("what sport do you like.", user_id="alice")
      if debug:
          print(result)
      
      # Delete all memories for a user
      result = m.delete_all(user_id="alice")
      if debug:
          print(result)
      
      # Delete all memories for a specific agent belonging to a user
      result = m.delete_all(user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
    3. Save the file and run the script.

      python run_memory_test.py
    4. Observe the command-line output. You will see the entire process of memories being added, searched, queried, and deleted.

      {'results': []}
      {'results': [{'id': '7f5af484-e8a5-4cae-b53e-e8be53beaa76', 'memory': 'I like pizza', 'event': 'DELETE'}]}
      {'results': [{'id': '96ec8a90-5a22-4413-98a6-ff91aeacb3c7', 'memory': 'I like football', 'event': 'ADD'}]}
      {'results': [{'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'event': 'ADD'}]}
      {'results': [{'id': '96ec8a90-5a22-4413-98a6-ff91aeacb3c7', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'created_at': '2025-08-07T03:48:23.367894-07:00', 'updated_at': None, 'user_id': 'alice'}, {'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'created_at': '2025-08-07T03:48:25.510270-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}]}
      {'results': [{'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'created_at': '2025-08-07T03:48:25.510270-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}]}
      {'results': [{'id': '96ec8a90-5a22-4413-98a6-ff91aeacb3c7', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'score': 0.696223974227903, 'created_at': '2025-08-07T03:48:23.367894-07:00', 'updated_at': None, 'user_id': 'alice'}, {'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.707332858224723, 'created_at': '2025-08-07T03:48:25.510270-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}]}
      {'results': [{'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.707332858224723, 'created_at': '2025-08-07T03:48:25.510270-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}]}
      {'results': [{'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.413298897746297, 'created_at': '2025-08-07T03:48:25.510270-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}, {'id': '96ec8a90-5a22-4413-98a6-ff91aeacb3c7', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'score': 0.458641203722873, 'created_at': '2025-08-07T03:48:23.367894-07:00', 'updated_at': None, 'user_id': 'alice'}]}
      {'results': [{'id': '96ec8a90-5a22-4413-98a6-ff91aeacb3c7', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'score': 0.278534250172033, 'created_at': '2025-08-07T03:48:23.367894-07:00', 'updated_at': None, 'user_id': 'alice'}, {'id': 'c2282f35-f84e-4bcd-ad8f-bcfdd47c5185', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.483608051645996, 'created_at': '2025-08-07T03:48:25.510270-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}]}
      {'message': 'Memories deleted successfully!'}
      {'message': 'Memories deleted successfully!'}

    Vector and graph database

    1. In the project root directory, create a run_memory_graph_test.py file.

      touch run_memory_graph_test.py
      vi run_memory_graph_test.py
    2. Copy the following code into the file. Replace the placeholders in the code (such as <polardb-host>, <polardb-port>, <polardb-username>, and <polardb-password>) with your cluster information.

      from mem0 import Memory
      
      # This example must connect to a PolarDB for PostgreSQL instance with a 1536-dimension vector specified.
      config = {
          "llm": {
              "provider": "bailian",
              "config": {"model": "qwen-plus"},
          },
          "embedder": {
              "provider": "bailian",
              "config": {"model": "text-embedding-v4", "embedding_dims": 1536},
          },
          "vector_store": {
              "provider": "pgvector",
              "config": {
                  "host": "<polardb-host>",
                  "port": <polardb-port>,
                  "dbname": "mem0",
                  "user": "<polardb-username>",
                  "password": "<polardb-password>",
                  "collection_name": "memories"
              }
          },
          "graph_store": {
              "provider": "polardb",
              "config": {
                  "url": "<polardb-host>",
                  "port": <polardb-port>,
                  "database": "mem0",
                  "username": "<polardb-username>",
                  "password": "<polardb-password>",
                  "graphname": "mem0",
              },
          }
      }
      
      m = Memory.from_config(config_dict=config)
      
      debug = True
      # Using only user_id
      result = m.add("I like pizza", user_id="alice")
      if debug:
          print(result)
      
      result = m.add("I hate pizza", user_id="alice")
      if debug:
          print(result)
      
      result = m.add("I like football", user_id="alice", metadata={"category": "hobbies"})
      if debug:
          print(result)
      
      # Using both user_id and agent_id
      result = m.add("I like pizza", user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
      
      # Get all memories for a user
      result = m.get_all(user_id="alice")
      if debug:
          print(result)
      
      # Get all memories for a specific agent belonging to a user
      result = m.get_all(user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
      
      # Search memories for a user
      result = m.search("tell me my name.", user_id="alice")
      if debug:
          print(result)
      
      # Search memories for a specific agent belonging to a user
      result = m.search("tell me my name.", user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
      
      # Search memories for a user
      result = m.search("what food do you like.", user_id="alice")
      if debug:
          print(result)
      
      # Search memories for a user
      result = m.search("what sport do you like.", user_id="alice")
      if debug:
          print(result)
      
      # Delete all memories for a user
      result = m.delete_all(user_id="alice")
      if debug:
          print(result)
      
      # Delete all memories for a specific agent belonging to a user
      result = m.delete_all(user_id="alice", agent_id="food-assistant")
      if debug:
          print(result)
    3. Save the file and run the script.

      python run_memory_graph_test.py
    4. Observe the command-line output. You will see the entire process of memories being added, searched, queried, and deleted, along with the JSON data returned after each operation, which includes vector search results (results) and graph relationships (relations). This visually demonstrates how the AI agent stores and recalls information.

      {'results': [{'id': '5d2007c2-b5b7-4632-a6c7-7f3672f6bf8f', 'memory': 'I like pizza', 'event': 'ADD'}], 'relations': {'deleted_entities': [], 'added_entities': [[{'source': 'user_id:_alice', 'relationship': 'likes', 'target': 'pizza', 'source_id': '3_53', 'destination_id': '3_54', 'relationship_id': '31_1'}]]}}
      {'results': [{'id': '5d2007c2-b5b7-4632-a6c7-7f3672f6bf8f', 'memory': 'Hate pizza', 'event': 'DELETE'}], 'relations': {'deleted_entities': [[{'source': 'user_id:_alice', 'target': 'pizza', 'relationship': 'likes'}]], 'added_entities': [[{'source': 'user_id:_alice', 'relationship': 'hates', 'target': 'pizza'}]]}}
      {'results': [{'id': '38dfb9a3-82e2-48d7-a8ab-2905aa40854e', 'memory': 'I like football', 'event': 'ADD'}], 'relations': {'deleted_entities': [], 'added_entities': [[{'source': 'alice', 'relationship': 'likes', 'target': 'football', 'source_id': '3_55', 'destination_id': '3_56', 'relationship_id': '31_2'}]]}}
      {'results': [{'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'event': 'ADD'}], 'relations': {'deleted_entities': [], 'added_entities': [[{'source': 'i', 'relationship': 'likes', 'target': 'pizza', 'source_id': '3_57', 'destination_id': '3_58', 'relationship_id': '31_3'}]]}}
      {'results': [{'id': '38dfb9a3-82e2-48d7-a8ab-2905aa40854e', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'created_at': '2025-08-07T19:12:10.363695-07:00', 'updated_at': None, 'user_id': 'alice'}, {'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'created_at': '2025-08-07T19:12:16.148090-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}], 'relations': [{'source': 'user_id:_alice', 'relationship': 'hates', 'target': 'pizza'}, {'source': 'alice', 'relationship': 'likes', 'target': 'football'}, {'source': 'i', 'relationship': 'likes', 'target': 'pizza'}]}
      {'results': [{'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'created_at': '2025-08-07T19:12:16.148090-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}], 'relations': []}
      {'results': [{'id': '38dfb9a3-82e2-48d7-a8ab-2905aa40854e', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'score': 0.6962242450914439, 'created_at': '2025-08-07T19:12:10.363695-07:00', 'updated_at': None, 'user_id': 'alice'}, {'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.7073326554295456, 'created_at': '2025-08-07T19:12:16.148090-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}], 'relations': [{'source': '"alice"', 'relationship': 'likes', 'destination': '"football"'}]}
      {'results': [{'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.7073326554295456, 'created_at': '2025-08-07T19:12:16.148090-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}], 'relations': []}
      {'results': [{'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.4132988460683351, 'created_at': '2025-08-07T19:12:16.148090-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}, {'id': '38dfb9a3-82e2-48d7-a8ab-2905aa40854e', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'score': 0.45864128080397715, 'created_at': '2025-08-07T19:12:10.363695-07:00', 'updated_at': None, 'user_id': 'alice'}], 'relations': []}
      {'results': [{'id': '38dfb9a3-82e2-48d7-a8ab-2905aa40854e', 'memory': 'I like football', 'hash': 'db38eb7ce206333d12734e4251d964c1', 'metadata': {'category': 'hobbies'}, 'score': 0.27853412116386245, 'created_at': '2025-08-07T19:12:10.363695-07:00', 'updated_at': None, 'user_id': 'alice'}, {'id': '1b469b78-7caa-4fc4-8195-17860dfb5458', 'memory': 'I like pizza', 'hash': '3acb2fb7961d7f09e42b99b96b605f3f', 'metadata': None, 'score': 0.4836079842249751, 'created_at': '2025-08-07T19:12:16.148090-07:00', 'updated_at': None, 'user_id': 'alice', 'agent_id': 'food-assistant'}], 'relations': [{'source': '"alice"', 'relationship': 'likes', 'destination': '"football"'}]}
      {'message': 'Memories deleted successfully!'}
      {'message': 'Memories deleted successfully!'}

    Memory classification and tagging experience

    Vector-only database

    1. In the project root directory, create a run_memory_category_test.py file.

      touch run_memory_category_test.py
      vi run_memory_category_test.py
    2. Copy the following code into the file. Replace the placeholders in the code (such as <polardb-host>, <polardb-port>, <polardb-username>, and <polardb-password>) with your cluster information.

      import json
      from mem0 import Memory
      from mem0.configs.base import MemoryConfig, LlmConfig, EmbedderConfig
      
      # This example must connect to a PolarDB for PostgreSQL instance with a 1536-dimension vector specified.
      config = {
          "llm" : {
              "provider": "bailian",
              "config": {"model": "qwen-plus",  "temperature": 0.2, "max_tokens": 2000, "top_p": 1.0},
          },
          "embedder": {
              "provider": "bailian",
              "config": {"model": "text-embedding-v4", "embedding_dims": 1536},
          },
          "vector_store": {
              "provider": "pgvector",
              "config": {
                  "host": "<polardb-host>",
                  "port": <polardb-port>,
                  "dbname": "mem0",
                  "user": "<polardb-username>",
                  "password": "<polardb-password>",
                  "collection_name": "memories"
              },
          },
          "reset_vector_store": True
      }
      
      m = Memory.from_config(config_dict=config)
      
      # Add conversation memories
      messages = [
          {"role": "user", "content": "I like sci-fi movies, especially Interstellar."},
          {"role": "assistant", "content": "Interstellar is indeed a classic sci-fi movie! I'll remember that you like this type of film."},
          {"role": "user", "content": "I also like other movies by Christopher Nolan."},
          {"role": "assistant", "content": "Nolan's works are indeed excellent! Besides 'Interstellar', he also directed classics like 'Inception', 'Tenet', and 'Memento'. Do you have any particular thoughts on these movies?"},
      ]
      
      # Add memories and attach metadata
      m.add(messages, user_id="alice", metadata={"category": "movies", "tags": ["sci-fi", "preferences"], "importance": "high"})
      
      # Retrieve memories
      memories = m.search(query="Recommend a movie I might like", user_id="alice", filters={"category": "movies"})
      print(json.dumps(memories, indent=2, ensure_ascii=False))
      
      # Get all memories
      all_memories = m.get_all(user_id="alice")
      print(json.dumps(all_memories, indent=2, ensure_ascii=False))
      
      # Delete all memories for a user
      result = m.delete_all(user_id="alice")
      print(result)
      
    3. Save the file and run the script.

      python run_memory_category_test.py
    4. Observe the command-line output. You will see the entire process of searching, querying, and deleting conversation memories after they have been classified and tagged.

      {
        "results": [
          {
            "id": "5e4a357a-ca3e-4769-9f80-06c9e74c53f3",
            "memory": "I like sci-fi movies, especially Interstellar",
            "hash": "d3747e8081810fc535f641ee28207d90",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "score": 0.366387451646842,
            "created_at": "2025-08-07T18:43:39.167113-07:00",
            "updated_at": null,
            "user_id": "alice"
          },
          {
            "id": "68393dda-e498-430d-bfdb-af4552196478",
            "memory": "I also like other movies by Christopher Nolan",
            "hash": "77408cade088bfad20138a6b405f9e65",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "score": 0.451759159564968,
            "created_at": "2025-08-07T18:43:39.178665-07:00",
            "updated_at": null,
            "user_id": "alice"
          }
        ]
      }
      {
        "results": [
          {
            "id": "5e4a357a-ca3e-4769-9f80-06c9e74c53f3",
            "memory": "I like sci-fi movies, especially Interstellar",
            "hash": "d3747e8081810fc535f641ee28207d90",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "created_at": "2025-08-07T18:43:39.167113-07:00",
            "updated_at": null,
            "user_id": "alice"
          },
          {
            "id": "68393dda-e498-430d-bfdb-af4552196478",
            "memory": "I also like other movies by Christopher Nolan",
            "hash": "77408cade088bfad20138a6b405f9e65",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "created_at": "2025-08-07T18:43:39.178665-07:00",
            "updated_at": null,
            "user_id": "alice"
          }
        ]
      }
      {'message': 'Memories deleted successfully!'}

    Vector and graph database

    1. In the project root directory, create a run_memory_category_graph_test.py file.

      touch run_memory_category_graph_test.py
      vi run_memory_category_graph_test.py
    2. Copy the following code into the file. Replace the placeholders in the code (such as <polardb-host>, <polardb-port>, <polardb-username>, and <polardb-password>) with your cluster information.

      import json
      from mem0 import Memory
      from mem0.configs.base import MemoryConfig, LlmConfig, EmbedderConfig
      
      # This example must connect to a PolarDB for PostgreSQL instance with a 1536-dimension vector specified.
      config = {
          "llm" : {
              "provider": "bailian",
              "config": {"model": "qwen-plus",  "temperature": 0.2, "max_tokens": 2000, "top_p": 1.0},
          },
          "embedder": {
              "provider": "bailian",
              "config": {"model": "text-embedding-v4", "embedding_dims": 1536},
          },
          "vector_store": {
              "provider": "pgvector",
              "config": {
                  "host": "<polardb-host>",
                  "port": <polardb-port>,
                  "dbname": "mem0",
                  "user": "<polardb-username>",
                  "password": "<polardb-password>",
                  "collection_name": "memories"
              },
          },
          "graph_store": {
              "provider": "polardb",
              "config": {
                  "url": "<polardb-host>",
                  "port": <polardb-port>,
                  "database": "mem0",
                  "username": "<polardb-username>",
                  "password": "<polardb-password>",
                  "graphname": "mem0",
              },
          },
          "reset_vector_store": True
      }
      
      m = Memory.from_config(config_dict=config)
      
      # Add conversation memories
      messages = [
          {"role": "user", "content": "I like sci-fi movies, especially Interstellar."},
          {"role": "assistant", "content": "Interstellar is indeed a classic sci-fi movie! I'll remember that you like this type of film."},
          {"role": "user", "content": "I also like other movies by Christopher Nolan."},
          {"role": "assistant", "content": "Nolan's works are indeed excellent! Besides 'Interstellar', he also directed classics like 'Inception', 'Tenet', and 'Memento'. Do you have any particular thoughts on these movies?"}
      ]
      
      # Add memories and attach metadata
      m.add(messages, user_id="alice", metadata={"category": "movies", "tags": ["sci-fi", "preferences"], "importance": "high"})
      
      # Retrieve memories
      memories = m.search(query="Recommend a movie I might like", user_id="alice", filters={"category": "movies"})
      print(json.dumps(memories, indent=2, ensure_ascii=False))
      
      # Get all memories
      all_memories = m.get_all(user_id="alice")
      print(json.dumps(all_memories, indent=2, ensure_ascii=False))
      
      # Delete all memories for a user
      result = m.delete_all(user_id="alice")
      print(result)
    3. Save the file and run the script.

      python run_memory_category_graph_test.py
    4. Observe the command-line output. You will see the entire process of searching, querying, and deleting conversation memories after they have been classified and tagged, along with the JSON data returned after each operation, which includes vector search results (results) and graph relationships (relations). This visually demonstrates how the AI agent stores and recalls information.

      {
        "results": [
          {
            "id": "ec8d0528-35f0-43ae-9ff1-ef1a93e6a017",
            "memory": "I like sci-fi movies, especially Interstellar",
            "hash": "d3747e8081810fc535f641ee28207d90",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "score": 0.36638870038909743,
            "created_at": "2025-08-05T23:22:16.354730-07:00",
            "updated_at": null,
            "user_id": "alice"
          },
          {
            "id": "d55c9188-e2a4-402b-b59c-658f640ab01b",
            "memory": "I also like other movies by Christopher Nolan",
            "hash": "77408cade088bfad20138a6b405f9e65",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "score": 0.4517598055411187,
            "created_at": "2025-08-05T23:22:16.367098-07:00",
            "updated_at": null,
            "user_id": "alice"
          }
        ],
        "relations": []
      }
      {
        "results": [
          {
            "id": "ec8d0528-35f0-43ae-9ff1-ef1a93e6a017",
            "memory": "I like sci-fi movies, especially Interstellar",
            "hash": "d3747e8081810fc535f641ee28207d90",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "created_at": "2025-08-05T23:22:16.354730-07:00",
            "updated_at": null,
            "user_id": "alice"
          },
          {
            "id": "d55c9188-e2a4-402b-b59c-658f640ab01b",
            "memory": "I also like other movies by Christopher Nolan",
            "hash": "77408cade088bfad20138a6b405f9e65",
            "metadata": {
              "tags": [
                "sci-fi",
                "preferences"
              ],
              "category": "movies",
              "importance": "high"
            },
            "created_at": "2025-08-05T23:22:16.367098-07:00",
            "updated_at": null,
            "user_id": "alice"
          }
        ],
        "relations": [
          {
            "source": "user_id:_alice",
            "relationship": "likes",
            "target": "Christopher Nolan's movies"
          },
          {
            "source": "user_id:_alice",
            "relationship": "likes",
            "target": "sci-fi movies"
          },
          {
            "source": "Interstellar",
            "relationship": "is a",
            "target": "sci-fi movie"
          },
          {
            "source": "user_id:_alice",
            "relationship": "likes",
            "target": "other movies by Christopher Nolan"
          },
          {
            "source": "user_id:_alice",
            "relationship": "likes",
            "target": "Interstellar"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Interstellar"
          },
          {
            "source": "user_id:_alice",
            "relationship": "likes",
            "target": "sci-fi movies"
          },
          {
            "source": "Interstellar",
            "relationship": "is a",
            "target": "sci-fi movie"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Interstellar"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Inception"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Inception"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Tenet"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Tenet"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Memento"
          },
          {
            "source": "Christopher Nolan",
            "relationship": "directed",
            "target": "Memento"
          }
        ]
      }
      {'message': 'Memories deleted successfully!'}

Conclusion

This topic describes the integrated long-term memory solution for AI agents based on PolarDB for PostgreSQL and the Mem0 framework. This solution not only combines the immediacy of short-term memory with the persistence of long-term memory, but also stands out in a competitive market due to the unique advantages of PolarDB. Compared to similar solutions, the core advantages of this solution are:

  • Unified architecture and seamless integration: It combines vector database and Graph Database capabilities, eliminating the need for complex multi-system integration. This significantly reduces development and O&M costs.

  • Cloud-native high performance: It deeply integrates cloud-native elasticity, model inference acceleration, and distributed KV Cache technology. This ensures that the AI agent can provide responses with millisecond-level latency, even when handling complex tasks.

  • Enterprise-grade scalability and maturity: Relying on the proven stability and excellent horizontal scalability of PolarDB, this solution provides a solid and reliable foundation for the large-scale deployment of AI applications.