Memorie Persistentă pentru Agenți AI în Python: Ghid Practic cu Mem0 și ChromaDB

Învață cum să construiești memorie persistentă pentru agenți AI în Python cu Mem0 și ChromaDB. Ghid pas cu pas cu exemple de cod, comparații între memorie vectorială și grafică, și integrări cu LangGraph și CrewAI.

Agenții AI moderni fac lucruri impresionante — rezolvă probleme complexe, generează cod, automatizează fluxuri întregi. Dar au un punct slab pe care mulți îl ignoră până dau de el: memoria. Fiecare sesiune e un nou început. Agentul nu știe cine ești, ce preferi sau ce ați discutat ultima oară. E ca și cum ai lucra cu un coleg care suferă de amnezie la fiecare pauză de cafea.

În acest ghid, o să-ți arăt cum poți construi memorie persistentă pentru agenții tăi AI folosind Mem0 și ChromaDB — două dintre cele mai solide soluții din ecosistemul Python în 2026.

De Ce Au Nevoie Agenții AI de Memorie Persistentă

Modelele LLM sunt fără stare (stateless) prin design. Fiecare apel API este complet independent — modelul nu reține absolut nimic din conversațiile anterioare. Produse precum ChatGPT sau Claude adaugă straturi de memorie deasupra modelului de bază, dar când îți construiești propriul agent, trebuie să implementezi tu acest strat. Și sincer, nu e chiar banal.

Un agent cu memorie persistentă poate:

  • Reține preferințele utilizatorului — limbajul preferat, stilul de comunicare, proiecte active
  • Evită repetarea informațiilor — nu mai trebuie să te prezinți de fiecare dată
  • Îmbunătățește calitatea răspunsurilor — folosind contextul acumulat din interacțiunile trecute
  • Construiește relații pe termen lung — transformând agentul dintr-un simplu instrument într-un asistent care chiar te cunoaște

Tipuri de Memorie în Agenții AI

Înainte să scriem cod, hai să clarificăm cele patru tipuri de memorie pe care le poate avea un agent. Fiecare servește un scop diferit.

Memorie de Lucru (Working Memory)

Gestionează contextul imediat din conversația curentă — inputul utilizatorului, ultimele replici și variabilele temporare. Gândește-te la ea ca la memoria RAM a agentului.

Memorie Episodică

Stochează interacțiuni specifice din sesiunile anterioare. Când un utilizator întreabă „Ce am discutat marția trecută?", memoria episodică furnizează răspunsul. E practic jurnalul conversațiilor.

Memorie Semantică

Reține cunoștințe factuale structurate — fapte, definiții, reguli și preferințe generalizate. Spre deosebire de memoria episodică, aceasta nu e legată de un eveniment specific, ci de informații extrase și consolidate în timp.

Memorie Procedurală

Stochează abilități și comportamente învățate. Agentul execută secvențe complexe de acțiuni fără să raționeze explicit de fiecare dată — similar cu modul în care mergi pe bicicletă fără să te gândești la fiecare mișcare.

Construiește Memorie Vectorială de la Zero cu ChromaDB

ChromaDB este (pe bună dreptate) cea mai populară bază de date vectorială open-source pentru Python. În loc să stocheze text brut, convertește informațiile în embedding-uri — reprezentări numerice care captează sensul semantic. Căutarea se face pe bază de similaritate, nu pe potrivire exactă de cuvinte cheie.

Hai să vedem cum funcționează în practică.

Instalare și Configurare

pip install chromadb sentence-transformers openai

Clasa SemanticMemory — Sistem Complet

import chromadb
from sentence_transformers import SentenceTransformer
from datetime import datetime
import json

class SemanticMemory:
    def __init__(self, persist_path: str = "./memory_db"):
        self.client = chromadb.PersistentClient(path=persist_path)
        self.collection = self.client.get_or_create_collection(
            name="agent_memories",
            metadata={"hnsw:space": "cosine"}
        )
        self.embedder = SentenceTransformer("all-MiniLM-L6-v2")

    def store(self, content: str, user_id: str, memory_type: str = "general"):
        embedding = self.embedder.encode(content).tolist()
        memory_id = f"{user_id}_{int(datetime.now().timestamp() * 1000)}"
        self.collection.add(
            embeddings=[embedding],
            documents=[content],
            metadatas=[{
                "user_id": user_id,
                "memory_type": memory_type,
                "timestamp": datetime.utcnow().isoformat(),
            }],
            ids=[memory_id]
        )
        return memory_id

    def recall(self, query: str, user_id: str, n_results: int = 5):
        query_embedding = self.embedder.encode(query).tolist()
        results = self.collection.query(
            query_embeddings=[query_embedding],
            n_results=n_results,
            where={"user_id": user_id}
        )
        return results["documents"][0] if results["documents"] else []

    def forget(self, memory_id: str):
        self.collection.delete(ids=[memory_id])

Câteva lucruri de notat aici: folosim modelul all-MiniLM-L6-v2 pentru embedding-uri fiindcă e rapid și suficient de bun pentru majoritatea cazurilor. Distanța cosine e alegerea standard pentru similaritate semantică. Iar PersistentClient se ocupă automat de salvarea pe disc.

Utilizare Practică

memory = SemanticMemory()

# Stochează preferințe
memory.store("Utilizatorul preferă Python pentru backend", user_id="ana")
memory.store("Proiectul curent: migrare de la Flask la FastAPI", user_id="ana")
memory.store("Preferă explicații concise, cu exemple de cod", user_id="ana")

# Caută amintiri relevante
results = memory.recall("Ce framework web folosește?", user_id="ana")
print(results)
# ['Proiectul curent: migrare de la Flask la FastAPI',
#  'Utilizatorul preferă Python pentru backend']

Datele persistă pe disc. Când repornești aplicația, toate amintirile sunt acolo — nu trebuie să faci nimic special.

Integrare cu un Agent Conversațional

Acum vine partea interesantă: să conectăm memoria la un agent real care folosește API-ul OpenAI.

from openai import OpenAI

openai_client = OpenAI()
memory = SemanticMemory()

def chat_with_memory(message: str, user_id: str) -> str:
    # 1. Recuperează amintirile relevante
    memories = memory.recall(query=message, user_id=user_id, n_results=3)
    memories_context = "\n".join(f"- {m}" for m in memories) if memories else "Nicio amintire."

    # 2. Construiește promptul cu context
    system_prompt = f\"\"\"Ești un asistent AI cu memorie pe termen lung.
Informații cunoscute despre utilizator:
{memories_context}

Folosește aceste informații pentru a personaliza răspunsurile.\"\"\"

    # 3. Generează răspunsul
    response = openai_client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": message}
        ]
    )
    reply = response.choices[0].message.content

    # 4. Stochează noua interacțiune
    memory.store(
        content=f"Utilizator: {message} | Asistent: {reply[:200]}",
        user_id=user_id,
        memory_type="episodic"
    )
    return reply

Observă fluxul: la fiecare mesaj, agentul caută mai întâi amintirile relevante, le include în prompt, generează răspunsul și apoi salvează interacțiunea. Simplu, dar eficient.

Mem0 — Memorie Plug-and-Play pentru Agenți AI

Dacă nu vrei să construiești totul de la zero (și onest, pentru producție de cele mai multe ori nu merită), Mem0 oferă un strat de memorie gata de producție. Vine cu extragere automată a faptelor, actualizare inteligentă a amintirilor fără duplicate și suport pentru memorie grafică. Cu aproximativ 48.000 de stele pe GitHub, e cel mai adoptat framework de memorie pentru agenți AI din 2026.

Instalare

pip install mem0ai

Mod Self-Hosted (Open Source)

from mem0 import Memory

# Configurare cu LLM-ul tău preferat
config = {
    "llm": {
        "provider": "openai",
        "config": {
            "model": "gpt-4.1-mini",
            "temperature": 0.1,
        }
    },
    "embedder": {
        "provider": "openai",
        "config": {
            "model": "text-embedding-3-small"
        }
    }
}

memory = Memory.from_config(config)

# Adaugă o conversație
messages = [
    {"role": "user", "content": "Sunt inginer software și lucrez cu Python și TypeScript."},
    {"role": "assistant", "content": "Am reținut! Cum te pot ajuta cu proiectele tale?"}
]
memory.add(messages, user_id="mihai")

# Caută amintiri
results = memory.search("Ce limbaje de programare cunoaște?", user_id="mihai")
for r in results["results"]:
    print(r["memory"])
# Inginer software. Programează în Python și TypeScript.

Actualizare Inteligentă vs. Duplicare

Ăsta e probabil cel mai mare avantaj al Mem0 față de soluțiile construite manual: actualizarea adaptivă. Când un utilizator își corectează o preferință, Mem0 actualizează amintirea existentă în loc să creeze un duplicat. Pare un detaliu mic, dar în producție face o diferență enormă.

# Prima interacțiune
memory.add("Prefer să lucrez cu Flask", user_id="mihai")

# Ulterior, utilizatorul se corectează
memory.add("M-am mutat pe FastAPI, nu mai folosesc Flask", user_id="mihai")

# Mem0 actualizează automat amintirea existentă
results = memory.search("Ce framework web folosește?", user_id="mihai")
# Rezultat: "Folosește FastAPI (a trecut de la Flask)"

Mod Platform (API Cloud)

from mem0 import MemoryClient

client = MemoryClient(api_key="your-api-key")

# Același API, dar gestionat în cloud
client.add("Prefer dark mode și font monospaced.", user_id="ana")
results = client.search("Ce preferințe de interfață are?", user_id="ana")
print(results)

Memorie Vectorială vs. Memorie Grafică

O tendință importantă în 2026 e apariția memoriei grafice ca alternativă (sau complement) la cea vectorială. Diferența merită înțeleasă:

Caracteristică Memorie Vectorială Memorie Grafică
Mod de căutare Similaritate semantică Traversare relații
Exemplu de interogare „Ce limbaj folosește acest utilizator?" „Cu cine colaborează și pe ce proiecte?"
Puncte forte Regăsire rapidă a faptelor similare Înțelegerea relațiilor complexe între entități
Cazuri de utilizare FAQ, preferințe, context general CRM, rețele de cunoștințe, analiză organizațională
Complexitate implementare Scăzută — ChromaDB, câteva linii de cod Medie-Ridicată — necesită Neo4j sau echivalent

Mem0g (varianta cu graf a Mem0) combină ambele abordări: construiește un graf de cunoștințe direcționat alături de baza vectorială. Un extractor de entități identifică nodurile, un generator de relații inferă muchiile etichetate, iar un detector de conflicte semnalează când informații noi contrazic cele existente. E o combinație elegantă, deși nu toate proiectele au nevoie de ea.

Integrare cu LangGraph și CrewAI

Dacă deja folosești framework-uri de agenți precum LangGraph sau CrewAI, vestea bună e că Mem0 se integrează nativ cu ele.

Mem0 + LangGraph

from langgraph.graph import StateGraph
from mem0 import Memory

memory = Memory()

def agent_node(state):
    user_msg = state["messages"][-1]["content"]
    user_id = state.get("user_id", "default")

    # Recuperează contextul din memorie
    relevant = memory.search(user_msg, user_id=user_id)
    memories_str = "\n".join(r["memory"] for r in relevant["results"])

    # Adaugă la contextul agentului
    state["memory_context"] = memories_str

    # După generarea răspunsului, salvează în memorie
    memory.add(state["messages"], user_id=user_id)
    return state

Mem0 + CrewAI

from crewai import Agent, Task, Crew
from mem0 import Memory

memory = Memory()

def create_memory_aware_agent(user_id: str):
    # Recuperează profilul utilizatorului
    profile = memory.search("profil utilizator preferințe", user_id=user_id)
    context = "\n".join(r["memory"] for r in profile["results"])

    return Agent(
        role="Asistent Personal",
        goal="Ajută utilizatorul ținând cont de preferințele și istoricul său",
        backstory=f"Cunoști următoarele despre utilizator:\n{context}",
        verbose=True
    )

Integrarea e destul de directă în ambele cazuri — injectezi contextul din memorie fie în state (LangGraph), fie în backstory (CrewAI).

Bune Practici pentru Memorie în Producție

1. Implementează Degradarea Memoriei (Memory Decay)

Nu toate amintirile merită aceeași retenție. Amintirile vechi și neaccesate ar trebui să piardă din importanță treptat:

import math
from datetime import datetime

def calculate_relevance(memory_timestamp: str, access_count: int) -> float:
    age_hours = (datetime.utcnow() - datetime.fromisoformat(memory_timestamp)).total_seconds() / 3600
    time_decay = math.exp(-0.01 * age_hours)  # Degradare exponențială
    frequency_boost = math.log(1 + access_count)  # Bonus pentru accesări frecvente
    return time_decay * frequency_boost

2. Separare pe Nivele de Memorie

Folosește un model ierarhic: fereastra de context a LLM-ului pentru memorie imediată, un sistem RAG vectorial pentru memorie semantică pe termen lung, și o bază de date structurată (PostgreSQL) pentru date declarative precum profilurile utilizatorilor. Nu încerca să rezolvi totul cu un singur layer.

3. Securitate și Multi-Tenancy

Implementează namespace-uri per utilizator, criptează amintirile sensibile și folosește control al accesului bazat pe roluri. Nu amesteca niciodată amintirile între utilizatori diferiți — e genul de bug care distruge încrederea instant.

4. Monitorizare și Costuri

Urmărește volumul de embedding-uri (fiecare fragment necesită 1-4 KB), latența căutărilor semantice și consumul de token-uri LLM. Mem0 oferă o reducere de aproximativ 90% a consumului de token-uri față de trimiterea întregului istoric în fereastra de context.

Comparație: ChromaDB Manual vs. Mem0

Aspect ChromaDB (manual) Mem0
Complexitate setup Scăzută — control total Foarte scăzută — plug-and-play
Extragerea faptelor Manuală — tu decizi ce se salvează Automată — LLM extrage faptele cheie
Actualizare amintiri Trebuie implementată manual Automată — detectează și actualizează
Memorie grafică Necesită integrare separată Inclusă nativ (Mem0g)
Cost Gratuit, self-hosted Open-source self-hosted sau cloud plătit
Flexibilitate Maximă Limitată la API-ul Mem0
Recomandare Proiecte personalizate, educație Producție, prototipare rapidă

Părerea mea? Începe cu ChromaDB dacă vrei să înțelegi cum funcționează lucrurile sub capotă. Apoi, când treci la producție, migrează la Mem0 — vei economisi timp considerabil.

Întrebări Frecvente

Ce diferență este între memoria unui agent AI și RAG?

RAG (Retrieval-Augmented Generation) recuperează informații din documente externe statice, pe când memoria agentului se construiește dinamic din interacțiunile cu utilizatorul. Un sistem complet le combină pe amândouă: RAG pentru baza de cunoștințe, memorie pentru personalizare și context conversațional.

Cât spațiu de stocare necesită memoria unui agent AI?

Depinde de caz. Orientativ, memoria pe termen scurt necesită 10-100 MB, iar cea pe termen lung 1-10 GB per utilizator. Fiecare fragment de memorie vectorială ocupă 1-4 KB. Poți reduce spațiul cu vreo 75% folosind tehnici de cuantizare, menținând 95% din acuratețea căutării.

Mem0 funcționează cu alte modele în afară de OpenAI?

Da, absolut. Mem0 suportă Anthropic Claude, Google Gemini, modele locale prin Ollama sau orice provider compatibil OpenAI. Modelul implicit e gpt-4.1-nano, dar se schimbă ușor din configurare.

Cum previn degradarea calității pe măsură ce memoria crește?

Implementează mecanisme de degradare temporală (memory decay) care reduc ponderea amintirilor vechi, folosește vacuuming periodic pentru a elimina datele redundante și limitează numărul de amintiri returnate la căutare. De regulă, 3-5 rezultate sunt suficiente — mai multe tind să dilueze contextul.

Pot folosi memoria agentului cu LangGraph sau CrewAI?

Da, Mem0 oferă integrări native cu LangGraph, CrewAI, AutoGen și alte framework-uri populare. Poți injecta contextul din memorie în starea agentului sau în backstory-ul acestuia, așa cum am arătat în exemplele de mai sus.

Despre Autor Editorial Team

Our team of expert writers and editors.