Esegui mem0 su una base URL compatibile OpenAI personalizzata.

Updated 2026-07-29

Il provider OpenAI di mem0 accetta una chiave di configurazione openai_base_url. Impostala su https://api.apisrouter.com/v1, passa una chiave, e il modello che estrae e aggiorna le memorie può essere qualsiasi id del catalogo, Claude e DeepSeek inclusi, senza toccare il resto della tua pipeline di memoria.

Risposta rapida: una chiave di configurazione dentro il blocco llm.

Il provider LLM OpenAI di mem0 risolve il suo endpoint prima dalla config, poi dall'ambiente, infine dal default: self.config.openai_base_url, poi la variabile d'ambiente OPENAI_BASE_URL, poi https://api.openai.com/v1. Quindi l'override più pulito è una chiave nel dict di configurazione llm: imposta openai_base_url su https://api.apisrouter.com/v1, imposta api_key accanto ad essa (oppure esporta OPENAI_API_KEY), e ogni chiamata di estrazione della memoria si instrada attraverso il gateway. Questo è comportamento upstream di mem0, leggibile in mem0/llms/openai.py, non un fork. L'SDK TypeScript espone la stessa coppia in camelCase: openaiBaseUrl e apiKey. I valori nel dict di configurazione hanno la precedenza sulle variabili d'ambiente, che a loro volta hanno la precedenza sui default, quindi una base URL a livello di config vince anche su macchine dove OPENAI_BASE_URL punta altrove.

config = {
    "llm": {
        "provider": "openai",
        "config": {
            "model": "claude-sonnet-4-6",
            "openai_base_url": "https://api.apisrouter.com/v1",
            "api_key": os.environ["APISROUTER_API_KEY"],
        },
    }
}

Cosa fa davvero mem0 con il suo LLM.

mem0 (mem0ai su GitHub, circa 61K stelle) è un livello di memoria per agenti AI. Ogni chiamata add() esegue una pipeline: l'LLM legge i nuovi turni di conversazione, estrae memorie candidate, le confronta con quanto già memorizzato, e decide per ciascuna memoria se aggiungere, aggiornare, eliminare o saltare. Questo è vero lavoro di ragionamento, e avviene a ogni scrittura, quindi lo slot LLM si attiva molto più spesso di quanto la maggior parte delle persone si aspetti quando aggiunge la memoria a un agente in produzione. Il recupero è l'altra metà, e non usa affatto l'LLM: search() incorpora la query ed esegue una ricerca di similarità vettoriale contro lo store. Due client diversi, due modelli diversi, configurati in due blocchi diversi (llm ed embedder). Questa separazione è la cosa più importante da capire prima di reinstradare qualsiasi cosa, perché significa che puoi spostare il carico di estrazione su un gateway multi-fornitore mentre l'embedder mantiene il suo provider e il suo indice esistenti intatti. Il provider resta "openai" nella configurazione; mem0 passa il campo model come stringa semplice su /v1/chat/completions. Quando l'endpoint dietro openai_base_url serve più fornitori, quella stringa può essere un id Claude, GPT, DeepSeek o GLM, e cambiare il modello di estrazione diventa una modifica di configurazione di una riga invece di una migrazione di provider.

Configurazione completa: dict di configurazione o variabile d'ambiente.

Il percorso via dict di configurazione è quello preciso: sposta solo l'LLM. Costruisci il dict, passalo a Memory.from_config, e usa l'API di memoria normalmente. Il campo api_key tiene la chiave del gateway completamente fuori dalle impostazioni del vector-store e dell'embedder. Esiste anche il percorso via ambiente: le classi OpenAI di mem0 leggono OPENAI_BASE_URL quando la chiave di configurazione è assente. È una variabile esportata e zero modifiche al codice, ma nota l'ambito: la classe OpenAI dell'embedder legge le stesse variabili (rispetta anche il vecchio nome OPENAI_API_BASE, che la classe LLM non rispetta). Esporta OPENAI_BASE_URL e avrai spostato entrambi i componenti, il che è corretto solo se l'endpoint serve anche il tuo modello di embedding. Nel dubbio, preferisci il dict di configurazione e lascia stare l'ambiente.

import os
from mem0 import Memory

config = {
    "llm": {
        "provider": "openai",
        "config": {
            "model": "claude-sonnet-4-6",   # any catalog id
            "openai_base_url": "https://api.apisrouter.com/v1",
            "api_key": os.environ["APISROUTER_API_KEY"],
            "temperature": 0.1,
        },
    },
    # embedder block unchanged: keeps its own provider and key
}

m = Memory.from_config(config)
m.add("I prefer window seats and vegetarian meals.", user_id="alice")
print(m.search("seat preference?", user_id="alice"))

Scegliere il modello di estrazione.

Il ciclo pratico: mantieni fisso il tuo embedder, esegui gli stessi fixture di conversazione attraverso due o tre modelli di estrazione, e confronta le memorie memorizzate. Dietro un unico endpoint quel confronto è una modifica della stringa di configurazione per candidato, e il log di utilizzo per chiave prezza per te l'esecuzione di ogni candidato.

  • La qualità dell'estrazione è la qualità della memoria. L'LLM decide cosa vale la pena ricordare e se le nuove informazioni contraddicono quelle vecchie; un modello che manca un aggiornamento inquina il recupero per ogni sessione futura. claude-sonnet-4-6 e gpt-5.5 sono la via di mezzo affidabile in questo compromesso.
  • Il volume è su ogni scrittura. Un prodotto di chat che chiama add() dopo ogni scambio esegue l'estrazione migliaia di volte al giorno, ed è qui che un id veloce come claude-haiku-4-5-20251001 o deepseek-v4-flash impedisce al livello di memoria di dominare il conto dei token.
  • I domini ricchi di contraddizioni (preferenze che cambiano, fatti che scadono) beneficiano di un modello più potente su add() anche se costa di più per chiamata, perché una decisione di aggiornamento sbagliata è costosa da individuare più tardi.
  • La temperature dovrebbe restare bassa. L'estrazione è un compito di decisione strutturata, non scrittura creativa; mem0 espone temperature nello stesso blocco di configurazione, e un valore intorno a 0.1 mantiene coerenti le decisioni add/update/delete.

Pagamento a consumo · sotto i prezzi ufficiali

Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.

ModelloPrezzo ufficialeIl nostro prezzo
Claude Sonnet 4.6$3.00 / $15.00 per M$2.40 / $12.00 per M
GPT-5.5$5.00 / $30.00 per M$4.00 / $24.00 per M
Claude Haiku 4.5 20251001$1.00 / $5.00 per M$0.80 / $4.00 per M
DeepSeek V4 Flash$0.14 / $0.28 per M$0.10 / $0.30 per M
GLM-5.2$1.14 / $4.00 per M$1.10 / $4.00 per M

Le modalità di errore specifiche di mem0.

Una OPENROUTER_API_KEY rimasta per sbaglio dirotta l'instradamento. La classe LLM OpenAI di mem0 tratta quella variabile come caso speciale: quando è impostata, la classe passa all'endpoint di OpenRouter e ignora la tua intenzione. Se le richieste non raggiungono la base URL che hai configurato, controlla prima questa variabile e rimuovila. La variabile d'ambiente sposta più di quanto intendessi. OPENAI_BASE_URL viene letta sia dall'LLM che dall'embedder. Se il gateway non serve il tuo modello di embedding, un override a livello di ambiente rompe search() mentre add() continua a funzionare, il che si presenta come "le scritture in memoria funzionano ma il recupero è vuoto o dà errore". Limita l'override al blocco di configurazione llm e l'embedder non se ne accorgerà mai. Le chiavi di configurazione sono per-SDK. Python usa snake_case (openai_base_url, api_key); TypeScript usa camelCase (openaiBaseUrl, apiKey). Una chiave camelCase in un dict Python viene ignorata silenziosamente e ricadi sull'endpoint predefinito, il che sembra esattamente come l'override che "non funziona". Gli id dei modelli sono stringhe esatte. mem0 non valida il campo model; lo inoltra soltanto. Un errore di battitura emerge come errore model-not-found dal gateway al primo add(), e l'elenco /v1/models è la grafia autorevole. Cambiare l'embedder è una decisione sull'indice, non una decisione di configurazione. Gli embedding di modelli diversi vivono in spazi vettoriali diversi, quindi ripuntare l'embedder invalida la similarità rispetto ai vettori esistenti. Spostare l'LLM è gratuito; spostare l'embedder significa dover ri-embeddare lo store. Pianificali come migrazioni separate.

Chi instrada mem0 tramite un gateway.

  • Sviluppatori di agenti che aggiungono memoria persistente agli assistenti. L'estrazione viene eseguita a ogni scrittura, quindi un'unica superficie di fatturazione con utilizzo per chiave batte una seconda dashboard fornitore incollata allo stack.
  • Team che vogliono un'estrazione di qualità Claude dietro una configurazione in stile OpenAI. La stringa del provider resta "openai"; cambiano solo la base URL e l'id del modello.
  • Prodotti di chat ad alto volume che controllano il costo unitario del livello di memoria abbinando un modello di chat di frontiera a un id di estrazione veloce, ciascuno indirizzabile tramite lo stesso endpoint.
  • Sviluppatori che valutano modelli di estrazione fianco a fianco. Ogni candidato è una stringa di modello contro fixture fissi, non una nuova integrazione di provider per fornitore.
  • Sviluppatori senza accesso alla fatturazione di un dato fornitore. L'accesso basato su ricarica senza obbligo di carta rimuove la dipendenza dalla registrazione per provider.

Verifica l'endpoint e fai debug del primo add().

Conferma che il gateway elenchi il modello che hai configurato prima di eseguire la pipeline; il campo model deve corrispondere esattamente a un id servito. I fallimenti alla prima esecuzione seguono uno schema. Un 401 significa che la chiave risolta dall'LLM è sbagliata per l'endpoint risolto, e poiché entrambi provengono da una cascata config-su-ambiente, stampa entrambi i valori effettivi invece di supporre; un api_key da config con una base URL da ambiente (o il contrario) è un classico disallineamento. Un errore model-not-found è un errore di battitura nell'id. Richieste che vanno visibilmente verso openrouter.ai significano che è scattato il caso speciale di OPENROUTER_API_KEY. E se add() ha successo mentre search() fallisce, hai spostato l'embedder per errore tramite l'ambiente; limita la base URL al blocco llm. Una volta che le memorie fluiscono, la console di APIsRouter mostra modello per richiesta, conteggi dei token e spesa. Le chiamate di estrazione sono piccole ma incessanti, e la vista di utilizzo è il modo per vedere quanto costa davvero il livello di memoria ogni mille scritture invece di stimarlo.

curl -s https://api.apisrouter.com/v1/models \
  -H "Authorization: Bearer $APISROUTER_API_KEY" | head -50

Domande frequenti

Quale chiave di configurazione punta mem0 verso un endpoint compatibile OpenAI personalizzato?

openai_base_url dentro la configurazione del provider llm in Python (openaiBaseUrl in TypeScript). I valori di configurazione hanno la precedenza sulla variabile d'ambiente OPENAI_BASE_URL, che a sua volta ha la precedenza sul default https://api.openai.com/v1, quindi il dict di configurazione è il posto più deterministico dove impostarlo.

mem0 può estrarre memorie con modelli Claude o DeepSeek con questa configurazione?

Sì. Il provider resta "openai" e mem0 inoltra il campo model come stringa semplice su /v1/chat/completions. Funziona qualsiasi id servito dall'endpoint dietro openai_base_url, inclusi gli id Claude, DeepSeek e GLM.

Impostare OPENAI_BASE_URL influisce anche sull'embedder?

Sì. L'embedder OpenAI di mem0 legge le stesse variabili d'ambiente (oltre al vecchio nome OPENAI_API_BASE). Se vuoi spostare solo l'LLM, imposta openai_base_url dentro il blocco di configurazione llm e lascia intatto l'ambiente.

Devo cambiare il mio embedder o vector store per usare questo?

No. I blocchi llm ed embedder sono client indipendenti. L'LLM di estrazione può instradarsi attraverso il gateway mentre l'embedder mantiene il suo provider attuale e i tuoi vettori esistenti restano validi. Ripuntare l'embedder è una migrazione separata che richiede di ri-embeddare lo store.

Perché le mie richieste mem0 vanno verso OpenRouter invece che verso la mia base URL?

La classe LLM OpenAI di mem0 tratta come caso speciale la variabile d'ambiente OPENROUTER_API_KEY: quando è impostata, reindirizza verso OpenRouter indipendentemente dalla tua base URL. Rimuovi quella variabile e la configurazione openai_base_url avrà effetto.

Questo si applica alla piattaforma Mem0 hosted o all'SDK open-source?

L'SDK open-source (Memory / Memory.from_config), dove controlli la configurazione dell'LLM. La piattaforma Mem0 hosted gestisce le proprie chiamate al modello lato server, quindi una base URL personalizzata si applica quando ospiti tu stesso il livello di memoria.