- Configurazione di un ecosistema di memoria persistente utilizzando Ollama come motore di ragionamento e gli embedding.
- Implementazione di database vettoriali locali utilizzando Qdrant o ChromaDB per evitare la dipendenza dal cloud.
- Ottimizzazione dell'estrazione dei fatti tramite la sincronizzazione di specifiche dimensioni vettoriali.
I modelli linguistici non ricordano automaticamente cosa è successo nelle conversazioni precedenti. Quando chiudi un'applicazione, cambi sessione o elimini i vecchi messaggi dalla finestra di contesto, il modello perde queste informazioni.
Un modo per superare questa limitazione è Collega Memo con OllamaOllama esegue localmente il modello generativo e il modello di embedding, mentre Mem0 estrae informazioni utili dalle conversazioni, le organizza e ne consente il recupero quando diventano nuovamente rilevanti.
Anziché inviare sempre l'intera cronologia al modello, l'applicazione può recuperare alcuni dati relativi alla query corrente e inserirli nel prompt. Ciò riduce la quantità di contesto e consente di mantenere preferenze, obiettivi o informazioni importanti tra una sessione e l'altra.
L'installazione può funzionare interamente all'interno della vostra infrastruttura se utilizzate Ollama, Mem0 OSS e un database locale. Tuttavia, la massima privacy dipenderà da tutti i componenti connessi. Se aggiungete un modello esterno, un algoritmo di reranking, un database o un servizio gestito, alcuni dati potrebbero uscire dal vostro sistema.
Che cosa fa Mem0 e qual è la funzione di Ollama?

Mem0 e Ollama risolvono problemi diversi. Ollama è responsabile della gestione dei modellimentre Mem0 fornisce le operazioni necessarie per aggiungere, cercare, interrogare, aggiornare ed eliminare le memorie.
Durante il salvataggio, Mem0 può analizzare una conversazione ed estrarre informazioni che potrebbero essere utili in seguito. Ad esempio:
- L'utente preferisce risposte brevi.
- Sta sviluppando un'applicazione in Rust.
- Non vuole consigli su film horror.
- Il loro obiettivo è completare una gara in meno di quattro ore.
Mem0 converte ogni memoria in una rappresentazione numerica utilizzando il modello di embedding e la memorizza insieme al suo contenuto e ai metadati. Quando esegue una ricerca, combina la query con filtri come l'identificativo dell'utente e restituisce le memorie più pertinenti.
Le versioni attuali di Mem0 utilizzano principalmente l'estrazione additiva. Ciò significa che è possibile memorizzare nuove informazioni senza eliminare automaticamente i dati precedenti. Se i dati sono obsoleti e devono essere corretti, l'applicazione può utilizzare esplicitamente le operazioni appropriate. update() o delete().
Mem0 non sostituisce il modello conversazionale. L'applicazione deve recuperare le memorie, incorporarle nel messaggio o nel contesto di sistema e chiedere a Ollama di generare la risposta.
Componenti necessari per collegare Mem0 con Ollama
Per costruire un sistema locale sono necessari i seguenti componenti:
- Nota OSS: Gestisce l'estrazione, l'archiviazione e il recupero dei ricordi.
- Ollama: Esegue il modello generativo e il modello di embedding.
- Un modello linguistico: Interpreta le conversazioni e genera le risposte.
- Un modello di embedding: trasforma memorie e query in vettori.
- Un magazzino vettoriale: Conserva i vettori e consente di cercare ricordi correlati.
- Una domanda di ammissione: Collega conversazione, recupero e salvataggio della memoria.
Qdrant e Chroma sono due opzioni di archiviazione comuni:
| Negozio | Uso consigliato |
|---|---|
| Qdrant | Servizi persistenti, applicazioni multiple e implementazioni tramite Docker |
| Cromo | Test locali e piccole applicazioni con archiviazione in cartella |
Qdrant fornisce un'API separata e semplifica la separazione del database vettoriale dall'applicazione. Chroma può utilizzare un percorso locale, semplificando i test iniziali.
Come installare Mem0, Ollam e Qdrant
Innanzitutto, installa Ollama e verifica che il servizio sia in esecuzione. Dopodiché, scarica un modello linguistico e un modello di embedding:
ollama pull llama3.1:latest
ollama pull nomic-embed-text:latest
llama3.1:latest Questo è il modello utilizzato nell'esempio ufficiale di Mem0, ma è possibile sostituirlo con un altro modello didattico compatibile con Ollama. I modelli più piccoli consumano meno memoria, sebbene possano estrarre i dati con minore precisione o aderire meno bene al formato previsto.
Installa le dipendenze Python:
pip install mem0ai qdrant-client openai ollama
Per eseguire Qdrant in Docker e preservare i dati utilizzando un volume, utilizzare:
docker volume create qdrant_storage
docker run -d \
--name qdrant \
-p 6333:6333 \
-p 6334:6334 \
-v qdrant_storage:/qdrant/storage \
qdrant/qdrant
Il porto 6333 fornisce l'API HTTP e 6334 Viene utilizzato per gRPC. In questo esempio, Mem0 si connette utilizzando l'API HTTP.
Verifica che Ollama risponda:
curl http://localhost:11434/api/tags
È possibile controllare Qdrant aprendo:
http://localhost:6333/dashboard
Non esporre queste porte direttamente a Internet. Se i servizi sono in esecuzione su computer diversi, utilizza una rete privata, una VPN o regole firewall che consentano solo le connessioni necessarie.
Configurazione locale di Mem0 con Ollama e Qdrant

La configurazione deve specificare esplicitamente che Ollama verrà utilizzato come LLM e come fornitore di embedding. Deve inoltre definire la posizione di Qdrant e le dimensioni che generano gli embedding.
from mem0 import Memory
OLLAMA_URL = "http://localhost:11434"
CHAT_MODEL = "llama3.1:latest"
EMBEDDING_MODEL = "nomic-embed-text:latest"
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"collection_name": "memoria_agente",
"host": "localhost",
"port": 6333,
"embedding_model_dims": 768,
},
},
"llm": {
"provider": "ollama",
"config": {
"model": CHAT_MODEL,
"temperature": 0,
"max_tokens": 2000,
"ollama_base_url": OLLAMA_URL,
},
},
"embedder": {
"provider": "ollama",
"config": {
"model": EMBEDDING_MODEL,
"ollama_base_url": OLLAMA_URL,
},
},
"history_db_path": "./mem0_history.db",
"custom_instructions": """
Extrae únicamente información que pueda ser útil en conversaciones futuras:
- Preferencias estables
- Objetivos y proyectos
- Restricciones importantes
- Decisiones confirmadas
Ignora saludos, conversación casual y hechos temporales sin importancia.
Devuelve un objeto JSON con la clave facts y una lista de recuerdos.
""",
}
memory = Memory.from_config(config)
Memory.from_config() Costringe Mem0 a utilizzare i provider specificati. Il costruttore Memory() Non si connette automaticamente a Mem0 Cloud, ma può applicare componenti predefiniti basati su OpenAI e richiedere una chiave se non li sostituisci.
custom_instructions Consente di determinare quali informazioni devono essere memorizzate. Deve essere inclusa come proprietà di primo livello prima della creazione dell'istanza. Memory.
Perché le dimensioni di inserimento devono corrispondere
Il modello nomic-embed-text produce vettori di 768 dimensioniPertanto, la raccolta Qdrant viene configurata utilizzando:
embedding_model_dims=768
Se il sistema di archiviazione si aspetta vettori di dimensioni diverse, Qdrant rifiuterà i dati e Mem0 non sarà in grado di salvare o interrogare correttamente le memorie.
Quando modifichi il modello di embedding, controlla le sue dimensioni prima di modificare le impostazioni. Potrebbe anche essere necessario creare una nuova collezione e rigenerare tutti i vettori esistenti.
Non mescolare gli embedding prodotti da modelli diversi all'interno della stessa collezione. Anche se due modelli generano vettori con dimensioni identiche, i loro spazi semantici potrebbero non essere compatibili.
Come salvare e recuperare i ricordi

Per salvare una conversazione, passa un elenco di messaggi a memory.add() e indica un identificatore stabile per l'utente:
mensajes = [
{
"role": "user",
"content": "Estoy desarrollando una aplicación en Rust"
},
{
"role": "assistant",
"content": "Lo recordaré para adaptar los próximos ejemplos"
}
]
resultado = memory.add(
mensajes,
user_id="usuario_001"
)
print(resultado)
Con infer=TruePer impostazione predefinita, Mem0 utilizza il modello per estrarre memorie strutturate. Se si desidera preservare il contenuto senza applicare questa estrazione, è possibile utilizzare infer=False.
Per trovare informazioni correlate:
recuerdos = memory.search(
"¿Qué lenguaje utiliza en su proyecto?",
filters={"user_id": "usuario_001"},
top_k=5
)
for recuerdo in recuerdos["results"]:
print(recuerdo["memory"])
Il filtro per user_id Questo è fondamentale. Se un'applicazione utilizzata da più persone effettua una ricerca senza applicare correttamente l'identificativo, potrebbe recuperare i ricordi appartenenti a un altro utente.
Puoi anche usare agent_id per separare la memoria di agenti diversi e run_id per suddividere conversazioni, progetti o processi specifici.
Come creare una chat completa con Ollama e Mem0

Affinché Ollama possa utilizzare i ricordi, l'applicazione deve eseguire quattro passaggi:
- Ricevi la domanda dell'utente.
- Cerca memorie correlate utilizzando Mem0.
- Aggiungili al contesto inviato a Ollama.
- Salva la domanda e la risposta come nuova interazione.
Ollama fornisce un'API compatibile con il formato OpenAI. Possiamo usarla per creare il ciclo completo:
from openai import OpenAI
ollama_chat = OpenAI(
base_url=f"{OLLAMA_URL}/v1",
api_key="ollama"
)
def chat(mensaje_usuario, user_id):
resultado = memory.search(
mensaje_usuario,
filters={"user_id": user_id},
top_k=5
)
recuerdos = [
item["memory"]
for item in resultado["results"]
]
contexto = "\n".join(
f"- {recuerdo}" for recuerdo in recuerdos
)
respuesta = ollama_chat.chat.completions.create(
model=CHAT_MODEL,
messages=[
{
"role": "system",
"content": (
"Eres un asistente útil. Utiliza los recuerdos "
"solo cuando sean relevantes.\n\n"
f"Recuerdos del usuario:\n{contexto}"
),
},
{
"role": "user",
"content": mensaje_usuario,
},
],
).choices[0].message.content
memory.add(
[
{
"role": "user",
"content": mensaje_usuario,
},
{
"role": "assistant",
"content": respuesta,
},
],
user_id=user_id,
)
return respuesta
Ora puoi iniziare una conversazione:
print(
chat(
"Estoy creando un programa de escritorio en Rust",
user_id="usuario_001"
)
)
Dopo aver riavviato l'applicazione, lo stesso utente potrebbe chiedere:
print(
chat(
"¿Qué lenguaje estoy utilizando en mi proyecto?",
user_id="usuario_001"
)
)
Se la memoria è stata memorizzata correttamente, Mem0 recupererà le informazioni e Ollama sarà in grado di utilizzarle per rispondere.
Come utilizzare Chroma al posto di Qdrant
Per un piccolo test locale, puoi sostituire Qdrant con Chroma. Il nome del provider corretto su Mem0 è chroma:
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "memoria_agente",
"path": "./chroma_db",
},
}
La cartella indicata in path Contiene i dati permanenti di Chroma. È necessario includerlo nei backup ed evitare di eliminarlo durante gli aggiornamenti dell'applicazione.
Il pacchetto Python utilizzato dal progetto continua ad essere chiamato chromadbMa l'identificatore che devi scrivere nella configurazione Mem0 è chroma.
Come correggere o eliminare i ricordi obsoleti
La memoria di un assistente non dovrebbe essere considerata una fonte infallibile. Il modello potrebbe memorizzare un fatto interpretato erroneamente, conservare informazioni non più valide o generare diversi ricordi simili.
È possibile visualizzare tutti i ricordi associati a un utente:
resultado = memory.get_all(
filters={"user_id": "usuario_001"}
)
for recuerdo in resultado["results"]:
print(recuerdo["id"], recuerdo["memory"])
Per correggere un ricordo specifico:
memory.update(
memory_id="ID_DEL_RECUERDO",
data="El usuario está desarrollando una aplicación en Python"
)
Per rimuoverlo:
memory.delete(
memory_id="ID_DEL_RECUERDO"
)
Un'applicazione destinata agli utenti finali dovrebbe fornire controlli per visualizzare, correggere ed eliminare i dati memorizzati. È inoltre consigliabile stabilire una politica di scadenza per le informazioni temporanee.
Come migliorare la qualità dei ricordi
La qualità dipende dal modello, dalle istruzioni, dalla conversazione e dalla quantità di informazioni inviate. Utilizzare sempre un modello più grande non garantisce risultati migliori, sebbene i modelli molto piccoli possano non cogliere alcune sfumature o restituire formati errati.
Queste pratiche contribuiscono a migliorare la memoria:
- Utilizzare una bassa temperatura per rendere l'estrazione più stabile.
- Definisci chiaramente quali categorie vale la pena ricordare.
- Escludere saluti, ripetizioni e conversazioni irrilevanti.
- Salva sia il messaggio dell'utente che la risposta dell'agente.
- Utilizzare identificatori diversi per utenti, agenti e progetti.
- Limita il numero di ricordi recuperati in modo da non sovraccaricare il contesto.
- Rivedi periodicamente i ricordi errati, duplicati o obsoleti.
- Prima di implementare il sistema in produzione, testa le ricerche con query reali.
Non presentare i ricordi come comandi prioritari. Trattali come informazioni contestuali, potenzialmente incomplete o obsolete. Questo riduce il rischio che un ricordo manipolato alteri il comportamento complessivo dell'agente.
Ottimizzazione delle prestazioni
Ogni chiamata a memory.add() È possibile eseguire il modello per estrarre i dati che devono essere memorizzati. Tuttavia, il risparmio di memoria aumenta la latenza e il consumo di risorse.
In una piccola applicazione, è possibile salvare la conversazione dopo aver generato la risposta. Nei servizi con più richieste simultanee, è preferibile utilizzare Memoria asincronaun worker in background o una coda di attività.
Mem0 fornisce un'interfaccia asincrona per evitare di bloccare le applicazioni create con asyncio oppure FastAPI:
from mem0 import AsyncMemory
memory = AsyncMemory.from_config(config)
resultado = await memory.search(
"proyecto actual",
filters={"user_id": "usuario_001"},
top_k=5
)
await memory.add(
mensajes,
user_id="usuario_001"
)
Non passare il lavoro a un thread secondario senza gestirne le eccezioni. Se il programma si chiude prima del completamento del salvataggio, la conversazione potrebbe non essere registrata. Una coda persistente consente di ritentare le operazioni non riuscite.
È possibile utilizzare modelli diversi per la conversazione e l'estrazione dei dati. Un modello generativo più potente può gestire le risposte, mentre uno più semplice può elaborare la memoria. Prima di procedere, è necessario verificare che il secondo modello segua correttamente le istruzioni e il formato richiesto.
Errori comuni durante la connessione di Mem0 con Ollama
Mem0 richiede una chiave OpenAI
La configurazione è incompleta e alcuni componenti utilizzano ancora il provider predefinito. Verifica di aver configurato entrambi llm COME embedder con il fornitore ollama.
Impossibile connettersi a Ollam
Verifica che l'API stia rispondendo:
curl http://localhost:11434/api/tags
Se Mem0 è in esecuzione all'interno di Docker, localhost Questo si riferisce al container, non al computer host. In Docker Desktop, potrebbe essere necessario utilizzare:
http://host.docker.internal:11434
Qdrant rifiuta i vettori
La raccolta e il modello di incorporamento utilizzano dimensioni diverse. Con nomic-embed-text, configura 768 dimensioni e crea una nuova collezione se quella esistente è stata generata con una dimensione diversa.
Le ricerche non restituiscono ricordi
Verifica di utilizzare lo stesso user_id durante il salvataggio e la ricerca. Controlla anche il nome del modello di incorporamento, i filtri e il contenuto di resultado["results"].
Mem0 memorizza informazioni irrilevanti
Anatra custom_instructionsRiduce la temperatura e definisce quali categorie includere o escludere. Inoltre, verifica se il modello scelto è in grado di seguire istruzioni strutturate.
I ricordi contraddicono le informazioni più recenti
Le versioni attuali possono conservare i dati precedenti invece di sovrascriverli automaticamente. Aggiungi date o metadati e utilizza update() o delete() quando è necessario correggere le informazioni.
La memoria scompare quando Qdrant viene sostituito
Verificare che il contenitore utilizzi un volume montato in /qdrant/storageRiavviare un container non è la stessa cosa che eliminarlo, ma ricrearlo senza storage persistente può comportare la perdita di dati nella nuova distribuzione.
Privacy e backup
Un'installazione locale evita di dover dipendere obbligatoriamente dalle API gestite di Mem0, OpenAI o altri fornitori. Ciononostante, è necessario proteggere l'infrastruttura come qualsiasi altra applicazione che memorizza informazioni personali.
- Non esporre Ollama o Qdrant direttamente a Internet.
- Crittografa i dischi e i backup che contengono dati privati.
- Applicare i controlli di autenticazione e accesso all'applicazione.
- Separare le memorie utilizzando identificatori utente affidabili.
- Consente di visualizzare ed eliminare le informazioni memorizzate.
- Non conservare password, chiavi API o dati bancari come souvenir.
- Registra gli errori senza includere conversazioni complete o ricordi.
- Verificare se il trattamento dei dati deve essere conforme al GDPR.
Con Qdrant è necessario eseguire il backup del volume qdrant_storage e il file definito da history_db_pathCon Chroma devi copiare la cartella configurata in path e il database storico.
Collegando Mem0 a Ollama è possibile creare un assistente che conserva le informazioni tra una sessione e l'altra senza necessariamente dipendere da servizi esterni. Ollama esegue i modelli, Mem0 estrae e recupera i dati memorizzati e Qdrant o Chroma forniscono la memoria persistente.
La chiave non sta semplicemente nel salvare le conversazioni. L'applicazione deve recuperare i ricordi rilevanti, fornire il contesto, limitarne l'ambito tramite identificatori e offrire meccanismi per correggere o eliminare le informazioni. Con queste precauzioni, è possibile costruire una memoria locale utile, persistente e controllabile.
Sono un appassionato di tecnologia che ha trasformato i suoi interessi "geek" in una professione. Ho trascorso più di 10 anni della mia vita utilizzando tecnologie all'avanguardia e armeggiando con tutti i tipi di programmi per pura curiosità. Ora mi sono specializzato in informatica e videogiochi. Questo perché da più di 5 anni scrivo per vari siti web di tecnologia e videogiochi, creando articoli che cercano di darti le informazioni di cui hai bisogno in un linguaggio comprensibile a tutti.
In caso di domande, le mie conoscenze spaziano da tutto ciò che riguarda il sistema operativo Windows e Android per telefoni cellulari. E il mio impegno è nei tuoi confronti, sono sempre disposto a dedicare qualche minuto e aiutarti a risolvere qualsiasi domanda tu possa avere in questo mondo di Internet.
