Chapter 2 ยท CORE

MemoryService (The Central Brain)

๐Ÿ“„ 02_memoryservice__the_central_brain_.md ๐Ÿท Core

Chapter 2: MemoryService (The Central Brain)

Welcome back! In the previous chapter, Hierarchical Data Model (The Memory File System), we learned how memU organizes memories into files (Items) and folders (Categories).

But having a filing cabinet isn't enough. You need a librarian. You need someone to read the incoming documents, decide which folder they belong to, file them away, and later go fetch them when you ask a question.

In memU, that librarian is the MemoryService.

The Motivation: The Conductor

Building an AI memory system involves many moving parts:

  1. Database: To store the data.
  2. Vector Store: To search by meaning.
  3. LLM Client: To generate summaries and embeddings.
  4. File System: To read raw files.

Without a central manager, your code would look like a messy tangle of wires connecting all these things manually.

The MemoryService is the "Operating System" of memU. You configure it once, and it manages all the resources for you. When you want to save something, you don't talk to the database; you talk to the Service.

Setting Up the Brain

To start using memU, you simply instantiate the MemoryService. It requires one main thing: LLM Profiles (credentials to talk to AI models like OpenAI).

Here is the simplest way to start the brain:

import os
from memu.app import MemoryService

# 1. Get your API Key
api_key = os.getenv("OPENAI_API_KEY")

# 2. Configure the Service
service = MemoryService(
    llm_profiles={
        "default": {
            "api_key": api_key,
            "chat_model": "gpt-4o-mini",
        }
    }
)

What just happened?

The "Swiss Army Knife" Pattern (Mixins)

The MemoryService is designed using a pattern called Mixins. Think of the Service as the handle of a Swiss Army Knife, and the Mixins as the different tools attached to it.

The Service combines three main skill sets into one class:

  1. MemorizeMixin: The ability to ingest data.
  2. RetrieveMixin: The ability to recall data.
  3. CRUDMixin: The ability to manually Edit/Delete memories.

Because of this, you can access all features directly from the service object.

1. Skill: Memorize

You hand the service a file (like a chat log or PDF), and it handles the rest.

# The Service acts as the "Ingestion Engine"
await service.memorize(
    resource_url="my_chat_log.json", 
    modality="conversation"
)

2. Skill: Retrieve

You ask a question, and the service finds the answer based on what it remembers.

# The Service acts as the "Search Engine"
response = await service.retrieve(
    query="Does the user like coffee?",
    user_id="user_123"
)
print(response.answer)

Internal Implementation: How It Works

How does the MemoryService manage all this without getting confused? It acts as an Orchestrator. It doesn't do the heavy lifting itself; it delegates tasks to specialized components.

Here is the flow when you start the service:

sequenceDiagram participant User participant Service as MemoryService participant DB as Database Factory participant Pipes as Pipeline Manager User->>Service: Initialize(config) Service->>DB: Build Database (SQL/Vector) DB-->>Service: Database Ready Service->>Pipes: Register Workflows Note right of Pipes: Loads "Memorize" & "Retrieve" recipes Service-->>User: Ready to serve

Under the Hood: service.py

Let's look at a simplified version of src/memu/app/service.py to see how it stitches everything together.

# Simplified view of the MemoryService class
class MemoryService(MemorizeMixin, RetrieveMixin, CRUDMixin):
    
    def __init__(self, llm_profiles, database_config=None, ...):
        # 1. Validate the Configuration
        self.llm_profiles = self._validate_config(llm_profiles)
        
        # 2. Build the Database (The Filing Cabinet)
        # It decides whether to use SQLite, Postgres, or In-Memory
        self.database = build_database(
            config=database_config,
            user_model=self.user_model
        )

        # 3. Setup the Workflow Engine (The Assembly Line)
        self._pipelines = PipelineManager(...)
        self._register_pipelines()

Key Takeaways from the Code:

  1. Inheritance: Notice class MemoryService(MemorizeMixin, RetrieveMixin...). This is how it gains its powers.
  2. build_database: The service calls a factory to create the storage. It abstracts away whether you are using a simple file on your laptop or a giant server in the cloud.
  3. _register_pipelines: The service loads the "recipes" for how to process data. We will learn about these recipes in the next chapters.

Configuration: LLM Profiles

One of the most powerful features of the MemoryService is the LLM Profile system. You usually don't want to use the most expensive AI model for everything.

You can configure different "personalities" for the brain:

service = MemoryService(
    llm_profiles={
        # Smart but expensive (for chatting)
        "default": {"chat_model": "gpt-4o"},
        
        # Fast and cheap (for reading raw files)
        "summarizer": {"chat_model": "gpt-4o-mini"},
        
        # Specialized (for vector math)
        "embedding": {"embed_model": "text-embedding-3-small"}
    }
)

The Service holds these profiles in its pocket and hands the correct one to the correct worker when needed.

Summary

The MemoryService is the entry point to the entire memU framework.

  1. It initializes the Database and LLM Clients.
  2. It uses Mixins to provide a simple API (memorize, retrieve).
  3. It orchestrates the complex logic hidden underneath.

Now that we have our Central Brain set up, it's time to feed it information. How exactly does the Service take a raw text file and turn it into structured memories?

It uses the Memorize Pipeline.

Next Chapter: Memorize Pipeline (The Digestion System)


Generated by Code IQ