Vai al contenuto principale

Tutorial su Supermemory: aggiungi memoria persistente agli agenti AI

Crea un trainer di esercizi in Python che registra gli allenamenti, ricorda la cronologia dell'utente con Supermemory e suggerisce sessioni personalizzate tra esecuzioni separate dell'agente AI.
Aggiornato 11 mag 2026  · 15 min leggi

La maggior parte degli agenti LLM riparte da zero a ogni esecuzione. Dimenticano il nome dell'utente, l'ultima conversazione e il file su cui stava lavorando. Qualsiasi elemento specifico dell'utente va ristabilito turno dopo turno.

Questo tutorial aggiunge la memoria persistente a un agente, così la prossima esecuzione riparte da dove era finita l'ultima. Il livello di memoria è Supermemory, un'API hostata che archivia fatti per utente e li restituisce con una sola chiamata. Costruirai un trainer personale per l'esercizio in Python. L'agente registra gli allenamenti, suggerisce la prossima sessione e ricorda preferenze e sollevamenti recenti tra esecuzioni separate dello script.

Lo stack è snello. Supermemory gestisce la memoria. L'SDK OpenAI Agents esegue il loop dell'agente. Il trainer consiste in due file Python e un file pyproject.toml.

Ti serviranno Python 3.10 o successivo, un account OpenAI, un account Supermemory e un po' di dimestichezza con la riga di comando.

Che cos'è Supermemory?

Supermemory può essere descritta al meglio come un'API di memoria AI per agenti. Quando passi a Supermemory stringhe sul tuo utente, in seguito restituisce una vista compatta di chi è quell'utente e cosa ha fatto di recente. Embedding, indicizzazione e recupero girano tutti dentro Supermemory, così il codice del tuo agente resta leggero.

Il benchmark LongMemEval testa quanto bene un sistema di memoria risponde a domande su una lunga cronologia di conversazione. Supermemory richiama l'81,6% dei fatti corretti. Zep, il sistema successivo per punteggio, arriva al 71,2%, un divario di 10 punti che si traduce in circa 1 risposta corretta in più ogni 10 domande dell'utente. Il repository open-source ha oltre 22k stelle su GitHub, un altro segnale di utilizzo reale.

Memoria vs RAG

La maggior parte dei lettori che cercano uno strumento di memoria per agenti ha già usato RAG. Il confronto con Supermemory aiuta a orientarsi. RAG e memoria risolvono problemi diversi e spesso convivono nello stesso agente.

Un sistema RAG punta a un corpus di documenti che lo sviluppatore prepara una volta sola. Manuali di prodotto, articoli di supporto, documentazione interna. Il corpus viene caricato al deploy, interrogato a runtime e raramente cambia. L'agente lo usa per rispondere a domande a cui il prodotto stesso sa già rispondere.

Un sistema di memoria punta all'utente. Supermemory scrive fatti specifici sull'utente man mano che l'agente parla con quell'utente, e l'archivio cresce con ogni conversazione. L'agente lo usa per rispondere a domande a cui solo l'utente può rispondere, come preferenze, cronologia e attività recenti.

Title: Memory vs. RAG: da dove provengono i dati - Description: Memory vs. RAG: da dove provengono i dati

In un prodotto reale, i due girano fianco a fianco. RAG su una knowledge base aziendale risponde a "qual è la nostra politica di rimborso?". Supermemory risponde alla domanda dell'utente, "Qual è stata la mia panca la settimana scorsa?" Stesso agente, due archivi dati, due lavori.

Profili utente: fatti statici e dinamici

L'idea principale di Supermemory è il profilo utente. Ogni log viene smistato in due bucket: fatti statici che cambiano di rado e fatti dinamici sull'attività corrente. Gli schemi ricorrenti vengono promossi tra gli statici. L'attività recente resta tra i dinamici.

Quando l'agente legge il profilo, una chiamata restituisce entrambi i bucket più i frammenti di memoria corrispondenti.

La divisione conta perché i fatti statici e dinamici rispondono a domande diverse sullo stesso utente:

Fatti statici

Fatti dinamici

Si allena a casa con manubri e sbarra per trazioni

Focus attuale: forza della parte superiore del corpo

Infortunio al ginocchio sinistro, niente squat profondi

Ultima panca: 4 serie da 5 ripetizioni a 185 lb

Vuole aggiungere 20 lb alla panca entro fine anno

Questa settimana lavora su trazioni "grease-the-groove"

Si allena solo di sera, mai al mattino

Ieri ha corso 5 km in 28 minuti

Leggi la prima riga. La parte statica dice come si allena l'utente: a casa, con l'attrezzatura che possiede. Non cambia di settimana in settimana. La parte dinamica dice su cosa sta lavorando adesso: parte superiore, in questo ciclo.

Un suggeritore di allenamenti ha bisogno di entrambe. La parte statica esclude gli esercizi solo da palestra, la parte dinamica sceglie la sessione di oggi.

Dietro quel profilo, Supermemory svolge quattro lavori che altrimenti costruiresti tu. Archivia le memorie grezze, genera embedding per ogni chunk, esegue la ricerca per similarità in lettura ed estrae i fatti del profilo dai contenuti registrati. Nessuno dei quattro appare nel tuo codice.

Title: Cosa gestisce Supermemory per te - Description: Cosa gestisce Supermemory per te

Ogni memoria è taggata con una stringa scelta dallo sviluppatore. Ogni lettura passa indietro la stessa stringa per limitare ciò che esce. Il trainer fissa un solo tag perché un utente basta a mostrare come funziona il profilo. Le app reali calcolano il tag dall'utente autenticato, ad esempio il suo JWT.

Configurare l'ambiente Supermemory

Il trainer richiede due chiavi API (Supermemory e OpenAI) e un progetto Python con tre dipendenze. Un rapido script di andata e ritorno dimostra che entrambe le chiavi funzionano, prima che qualsiasi codice dell'agente le utilizzi.

Ottenere le chiavi API

La chiave API di Supermemory si trova su console.supermemory.ai, NON app.supermemory.ai. Il sottodominio app è il prodotto consumer di memoria (per salvare note, esplorare il tuo spazio). Non ha una pagina per le chiavi API. Ignoralo e vai direttamente alla console.

Su console.supermemory.ai:

  1. Accedi.

  2. Fai clic su API Keys nella sidebar.

  3. Fai clic su Create API Key.

  4. Assegnale un nome (la demo del trainer usa datacamp-tutorial).

  5. Copia la chiave risultante. Inizia con sm_.

Title: Console sviluppatore di Supermemory che mostra la pagina API Keys - Description: Console sviluppatore di Supermemory che mostra la pagina API Keys

Ti serve anche una chiave OpenAI per le chiamate LLM dell'agente. Prendine una su platform.openai.com/api-keys se non ne hai già una.

Crea un file .env nella root del progetto con entrambe le chiavi. Non farne il commit.

SUPERMEMORY_API_KEY=sm_your_key_here
OPENAI_API_KEY=sk-your_key_here

Il piano gratuito di Supermemory copre questo tutorial senza inserire informazioni di pagamento. I limiti esatti sono sulla pagina dei prezzi.

Installare le dipendenze

Il tutorial usa uv per l'inizializzazione ed esecuzione del progetto. Se non hai uv, installalo una volta con la one-liner da astral.sh/uv.

Inizializza il progetto:

uv init supermemory-trainer
cd supermemory-trainer

Elimina il README.md generato automaticamente da uv init. Il hello.py generato verrà sovrascritto nel passaggio successivo, quindi per ora lascialo.

Aggiungi tre dipendenze:

  • supermemory==3.37.0 è il client di memoria, bloccato alla versione verificata per questo tutorial.

  • openai-agents è l'SDK OpenAI Agents. Il nome del pacchetto è con trattino, il path di import è agents.

  • python-dotenv legge il file .env che hai appena creato.

uv add supermemory==3.37.0 openai-agents python-dotenv

Il risultante pyproject.toml:

[project]
name = "supermemory-trainer"
version = "0.1.0"
description = "Personal exercise trainer agent built with Supermemory and the OpenAI Agents SDK."
requires-python = ">=3.10"
dependencies = [
	"openai-agents>=0.10.2",
	"python-dotenv>=1.2.1",
	"supermemory==3.37.0",
]

Verificare la configurazione

Prima di scrivere qualsiasi codice dell'agente, guarda Supermemory all'opera una volta su una singola frase. Lo script qui sotto invia un fatto a Supermemory, attende la pipeline e poi legge di nuovo il profilo. Se gira correttamente, le chiavi funzionano e l'SDK è raggiungibile. L'output ti dà anche un primo sguardo a ciò che Supermemory fa con testo grezzo.

Apri hello.py nella root del progetto e sostituisci il corpo generato automaticamente con gli import e una chiamata di scrittura:

import time
 
from dotenv import load_dotenv
from supermemory import Supermemory
 
load_dotenv()
 
client = Supermemory()
USER_ID = "demo_warmup"
 
response = client.add(
	content="The user is learning Supermemory by building a personal trainer agent.",
	container_tag=USER_ID,
)
print(f"client.add() -> id={response.id} status={response.status}")

load_dotenv() legge la chiave API da .env nell'ambiente prima che Supermemory() venga costruito. Il client rileva SUPERMEMORY_API_KEY automaticamente. Il valore container_tag="demo_warmup" limita questo singolo fatto a un utente usa e getta.

Ora aggiungi l'attesa e la lettura in fondo allo stesso file:

print("Waiting 20 seconds for processing...")
time.sleep(20)
 
prof = client.profile(container_tag=USER_ID, q="learning")
print(f"profile.static  ({len(prof.profile.static)}): {prof.profile.static}")
print(f"profile.dynamic ({len(prof.profile.dynamic)}): {prof.profile.dynamic}")
print(f"search_results.results ({len(prof.search_results.results)}):")
for r in prof.search_results.results[:3]:
	print(f"  - {r['memory']} (similarity={r['similarity']:.3f})")

L'attesa di 20 secondi dà il tempo alla pipeline di embedding ed estrazione di Supermemory di elaborare la nuova memoria. Senza, la lettura non restituisce nulla e lo script sembrerebbe rotto, anche se non lo è.

Esegui il file:

uv run python hello.py

Output atteso:

client.add() -> id=zNLsJBrY1PZupAeZ3Qn6EL status=queued
Waiting 20 seconds for processing...
profile.static  (0): []
profile.dynamic (1): ['Building a personal trainer agent to learn Supermemory.']
search_results.results (1):
  - Building a personal trainer agent to learn Supermemory. (similarity=0.650)

Tre dettagli contano in questo output. client.add() restituisce immediatamente con status="queued", perché Supermemory elabora i documenti in modo asincrono. I 20 secondi di attesa coprono la pipeline di embedding ed estrazione. Quando parte la lettura, la frase grezza è già un chunk di memoria ricercabile.

La riga interessante è profile.dynamic. L'input era la frase "The user is learning Supermemory by building a personal trainer agent." L'output è il fatto dinamico 'Building a personal trainer agent to learn Supermemory.'. Supermemory ha riscritto una frase in terza persona in un fatto in prima persona sull'utente. È l'estrattore di profilo che fa il suo lavoro.

profile.static è una lista vuota. I fatti statici si consolidano lentamente, dopo che si accumula una manciata di log correlati, quindi una singola scrittura di warm-up non ne produce. Lo strumento di suggerimenti del trainer tiene conto di questo e tratta static come un bonus, non una garanzia.

Costruire un agente Supermemory: trainer personale in Python

Il trainer incapsula client.add() e client.profile() in due tool dell'agente, così letture e scritture avvengono automaticamente mentre l'utente chatta. La cronologia degli allenamenti si presta bene alla memoria. Attrezzatura, infortuni e sollevamenti recenti non vivono nei dati di training dell'LLM e si accumulano sessione dopo sessione.

Title: Dove si inserisce Supermemory nel loop dell'agente - Description: Dove si inserisce Supermemory nel loop dell'agente

Struttura del progetto e agente

Il trainer è abbastanza piccolo da stare in due file Python più il pyproject.toml che hai già:

supermemory-trainer/
├── .env            	# your real keys (gitignored)
├── .env.example    	# placeholders, committed
├── .gitignore
├── .python-version
├── main.py         	# agent definition, system prompt, REPL loop
├── pyproject.toml
└── tools.py        	# log_workout and suggest_next_session

tools.py contiene i due tool basati su memoria che scriverai a breve. log_workout scrive un allenamento in Supermemory tramite client.add(). suggest_next_session legge il profilo dell'utente tramite client.profile(). main.py importa entrambi e collega l'agente.

Gran parte di main.py è boilerplate dell'SDK OpenAI Agents. Una frase nel system prompt svolge il lavoro di Supermemory: ogni fatto sull'utente deve tornare attraverso chiamate ai tool. All'agente viene detto che non ha memoria propria. Questa singola regola è ciò che rende il trainer basato su memoria.

Apri main.py e inizia con gli import e il system prompt:

import asyncio
 
from agents import Agent, Runner, SQLiteSession
 
from tools import log_workout, suggest_next_session
 
SYSTEM_PROMPT = """You are a personal exercise trainer who logs the user's
workouts and recommends what to do next.
 
You have no memory of the user's history on your own. Every fact about the
user lives in Supermemory and reaches you only through tool calls.
 
Two rules, no exceptions:
 
1. Whenever the user reports completing a workout, call log_workout immediately, before responding. Extract the exercise, sets, reps, weight, and any notes from what they said. If a value is missing, ask one short follow-up question instead of guessing. After logging, confirm in one short sentence and stop. Do NOT recommend the next session unless the user asks for one.
 
2. When the user explicitly asks what to do next (or asks for a recommendation, suggestion, or plan), call suggest_next_session first. Never recommend from your own training data. The tool returns the user's
 recent activity, stable preferences, and matching past sessions. Reference those facts directly in your reply.
 
Keep replies concise (2-4 sentences). Be specific: name the exercise, sets, reps, and weight. Honor any injuries or equipment constraints the tool surfaces.
"""

Entrambe le regole nel system prompt instradano il modello attraverso Supermemory. 

La regola 1 forza una chiamata a log_workout ogni volta che l'utente riporta un allenamento, così ogni allenamento arriva all'archivio di memoria. La regola 2 forza una lettura suggest_next_session prima di qualsiasi raccomandazione, così ogni suggerimento è fondato su ciò che Supermemory sa. 

Salta quelle regole e l'agente risponderà dai suoi dati di training, vanificando il senso di un livello di memoria.

Ora definisci l'agente e il loop di chat nello stesso file:

def build_agent() -> Agent:
	return Agent(
    	name="Trainer",
    	instructions=SYSTEM_PROMPT,
    	tools=[log_workout, suggest_next_session],
    	model="gpt-5",
	)
 
 
async def chat() -> None:
	agent = build_agent()
	session = SQLiteSession(session_id="trainer-cli")
 
	print("Trainer ready. Type a message, or 'exit' to quit.\n")
	while True:
    	try:
        	message = input("You: ").strip()
    	except (EOFError, KeyboardInterrupt):
        	print()
        	break
    	if not message:
        	continue
    	if message.lower() in {"exit", "quit"}:
        	break
 
    	result = await Runner.run(agent, message, session=session)
    	print(f"\nTrainer: {result.final_output}\n")
 
 
if __name__ == "__main__":
	asyncio.run(chat())

Due righe in quel blocco meritano di essere citate. tools=[log_workout, suggest_next_session] registra i due tool basati su memoria. Il decorator @function_tool su ciascuno (in tools.py) dice all'SDK che sono chiamabili. Senza il decorator, l'agente non ha tool a runtime, anche se la costruzione ha successo.

SQLiteSession(session_id="trainer-cli") mantiene la cronologia a breve termine dei turni all'interno del processo Python in esecuzione. Supermemory tiene i fatti a lungo termine sull'utente tra processi. Uccidere il processo Python elimina la sessione SQLite, ma i dati in Supermemory restano.

Importante: Esegui main.py come script, non in una cella Jupyter, perché l'event loop di Jupyter confligge con asyncio.run(). Il client sincrono Supermemory() funziona dentro funzioni tool async perché l'SDK Agents esegue i tool in un thread pool. Per saperne di più sull'SDK, vedi il tutorial sull'SDK OpenAI Agents.

Scrivere il tool di registrazione allenamenti

log_workout è il lato scrittura della memoria dell'agente. La funzione prende argomenti strutturati dall'agente: nome esercizio, serie, ripetizioni, peso e note opzionali. Li trasforma in una breve frase in inglese e passa la frase a Supermemory tramite client.add(). La pipeline di embedding ed estrazione gira dentro Supermemory e non richiede altro dal trainer.

Apri tools.py e inizia con gli import e un singolo client condiviso:

from agents import function_tool
from dotenv import load_dotenv
from supermemory import Supermemory
 
load_dotenv()
 
USER_ID = "demo_user"
 
client = Supermemory()

load_dotenv() gira all'import, così SUPERMEMORY_API_KEY è nell'ambiente prima che Supermemory() venga costruito. Se costruisci il client prima di caricare l'env, ottieni un client non autenticato. La prima chiamata restituirà quindi un 401 fuorviante. Entrambe le funzioni tool in questo file condividono quel client e la costante USER_ID.

Aggiungi lo strumento di logging sotto il client:

@function_tool
def log_workout(
	exercise: str,
	sets: int,
	reps: int,
	weight: float,
	notes: str = "",
) -> str:
	"""Log a completed workout to the user's memory.
 
	Args:
    	exercise: Name of the exercise.
    	sets: Number of sets performed.
    	reps: Number of reps per set.
    	weight: Weight in pounds. Pass 0 for bodyweight or cardio.
    	notes: Optional notes about the session.
	"""
	print(f"[log_workout] {exercise=} {sets=} {reps=} {weight=} {notes=}")
 
	content = f"Performed {exercise}: {sets} sets of {reps} reps at {weight} lbs."
	if notes:
    	content += f" Notes: {notes}"
 
	response = client.add(content=content, container_tag=USER_ID)
	print(f"[log_workout] -> id={response.id} status={response.status}")
	return f"Logged {exercise} ({sets}x{reps} @ {weight} lb)."

La docstring di @function_tool è ciò che l'LLM vede quando decide se chiamare il tool. Il blocco Args: mappa le descrizioni per parametro. Entrambi fanno parte del contratto dell'agente con la funzione.

Lo strumento invia una semplice frase a client.add(), non JSON. L'estrattore di profilo di Supermemory legge il linguaggio naturale e ne deduce i fatti. Tecnicamente il JSON funziona, ma la qualità dell'estrazione cala perché al modello manca una narrazione da riassumere. "Performed bench press: 4 sets of 5 reps at 185.0 lbs" dà all'estrattore una frase pulita su cui lavorare.

Le due chiamate print() scrivono ogni invocazione del tool nel terminale: prima gli argomenti analizzati, poi la risposta.

[log_workout] exercise='bench press' sets=4 reps=5 weight=185.0 notes=''
[log_workout] -> id=xY7AK3qLzBPx5Vd2HnRf1M status=queued

Il valore status="queued" corrisponde a quanto restituito dallo script di warm-up. Il log grezzo è archiviato, ma client.profile() non lo restituirà come risultato di ricerca finché la pipeline non è finita. Aggiungerai più avanti uno step di verifica che attende la stabilizzazione.

Scrivere il tool di suggerimento allenamenti

suggest_next_session è il lato lettura, ed è qui che la divisione statico-dinamico ripaga. Una chiamata client.profile(container_tag=USER_ID, q=focus) restituisce tre viste dell'utente in un solo round trip. 

Le preferenze stabili tornano come profile.static, l'attività corrente come profile.dynamic e i ricordi passati più vicini come search_results.results. Il compito del tool è appiattire queste tre viste in un unico blocco di contesto che l'agente può citare.

Dopo alcuni allenamenti, lo strumento produce un output come questo:

Recent activity:
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
Closest matching past entries:
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press

L'agente legge quel blocco e scrive una raccomandazione fondata sulla cronologia reale dell'utente. Senza il profilo di Supermemory, costruiresti tu lo stesso contesto. Vorrebbe dire una ricerca semantica separata, un tuo archivio di profilo e l'unione dei risultati. La singola chiamata client.profile() sostituisce tutti e tre.

Aggiungi questo a tools.py sotto log_workout:

@function_tool
def suggest_next_session(focus: str) -> str:
	"""Fetch the user's training history and preferences for a given focus.
 
	Returns a context string the agent can use to recommend the next session.
	The agent is responsible for the actual recommendation. This tool only
	surfaces what Supermemory knows about the user.
 
	Args:
    	focus: What the user wants to train next (e.g. "upper body", "legs",
        	"cardio", "today"). Drives semantic search against past logs.
	"""
	print(f"[suggest_next_session] focus={focus!r}")
	profile = client.profile(container_tag=USER_ID, q=focus)
 
	static_facts = profile.profile.static
	dynamic_facts = profile.profile.dynamic
	matches = profile.search_results.results
 
	print(
    	f"[suggest_next_session] static={len(static_facts)} "
    	f"dynamic={len(dynamic_facts)} matches={len(matches)}"
	)
 
	sections = []
	if static_facts:
    	sections.append("Stable preferences and constraints:")
    	sections.extend(f"- {fact}" for fact in static_facts)
	if dynamic_facts:
    	sections.append("Recent activity:")
    	sections.extend(f"- {fact}" for fact in dynamic_facts)
	if matches:
    	sections.append("Closest matching past entries:")
    	for r in matches[:5]:
        	sections.append(f"- {r['memory']}")
 
	if not sections:
    	return (
        	"No prior training history found for this user. "
        	"Ask the user about their goals, equipment, and recent training."
    	)
	return "\n".join(sections)

client.profile(container_tag=USER_ID, q=focus) restituisce un oggetto ProfileResponse. Dopo 5 brevi log, i tre campi letti dal tool appaiono così:

profile.profile.static        	# [] (list[str])
profile.profile.dynamic       	# ["Performed bench press: 4 sets of 5 reps at 185.0 lbs", ...]
profile.search_results.results	# [{"memory": "...", "similarity": 0.631, ...}, ...] (list[dict])

Ogni risultato di ricerca è un dizionario Python, non un oggetto Pydantic. Usa r["memory"] per il testo e r["similarity"] per lo score. Il dict completo ha le seguenti chiavi:

  • id

  • memory

  • rootMemoryId

  • metadata

  • updatedAt

  • version

  • similarity

  • filepath

  • documents

Lo snippet r.memory or r.chunk dalla pagina d'integrazione dell'SDK OpenAI Agents di Supermemory solleva AttributeError con supermemory==3.37.0. Usa l'accesso con parentesi.

static qui è vuoto, per questo lo strumento dirama su if static_facts:. I rami dynamic e search_results fanno il lavoro reale per la prima dozzina di log.

Supermemory applica anche una soglia di similarità di default. Un fatto menzionato una volta potrebbe non tornare per ogni query. I 5 log sopra sono tornati tutti per q="today", ma una stringa di query più specifica potrebbe restituirne meno. Il guard if matches: lo gestisce senza fallire.

Esecuzione sessione 1: registrare allenamenti

Avvia la sessione 1 e registra alcuni allenamenti per riempire Supermemory di qualcosa da leggere più tardi. Esegui lo script:

uv run python main.py

Registra panca piana, poi una corsa da 5 km, poi stacco, più un'affermazione di preferenza: "Mi alleno solo a casa, niente palestra." L'agente attiva log_workout una volta per allenamento e le righe print() del tool rendono visibile ogni chiamata nel terminale.

Title: Terminale della sessione 1 che mostra tre chiamate a log_workout - Description: Terminale della sessione 1 che mostra tre chiamate a log_workout

Output di esempio. La formulazione esatta del tuo agente varierà perché il modello è non deterministico.

Le tre righe status=queued sono il momento in cui Supermemory prende in carico. Ciascuna corrisponde a un documento che attraversa la pipeline di embedding ed estrazione sul lato Supermemory. Per log di testo brevi come questi, il documento diventa ricercabile tramite client.profile() in ~12 secondi.

Nel codice del trainer non c'è nulla che attenda questo. L'agente prosegue e Supermemory finisce il lavoro in background.

Ogni log attiva esattamente una chiamata a log_workout e l'agente si ferma. Niente raccomandazioni proattive, niente chiamate extra ai tool, niente suggerimenti di follow-up. Lo fa la prima regola del system prompt. Senza la regola, l'agente suggerirebbe una sessione successiva dopo ogni log, raddoppiando le chiamate ai tool.

Digita exit per chiudere la sessione 1. Il processo Python termina e la SQLiteSession se ne va con lui. I log degli allenamenti e l'affermazione di preferenza ora vivono in Supermemory sotto container_tag="demo_user", separati dallo script che li ha scritti.

Verificare il richiamo ed eseguire la sessione 2

Prima della sessione 2, conferma che i fatti della sessione 1 siano interrogabili. Apri un nuovo REPL Python o salva questo come breve script:

from dotenv import load_dotenv
from supermemory import Supermemory
 
load_dotenv()
client = Supermemory()
 
prof = client.profile(container_tag="demo_user", q="training")
print(f"static  ({len(prof.profile.static)}): {prof.profile.static}")
print(f"dynamic ({len(prof.profile.dynamic)}):")
for fact in prof.profile.dynamic:
	print(f"  - {fact}")
print(f"matches ({len(prof.search_results.results)}):")
for r in prof.search_results.results[:5]:
	print(f"  - {r['memory']} (similarity={r['similarity']:.3f})")

Output reale catturato tra le due sessioni:

static  (0): []
dynamic (5):
  - Trains at home instead of a gym
  - Performed deadlift: 3 sets of 5 reps at 225.0 lbs
  - Performed 5k run in 26 minutes
  - Reports no knee pain during bench press
  - Performed bench press: 4 sets of 5 reps at 185.0 lbs
matches (5):
  - Trains at home instead of a gym (similarity=0.682)
  - Performed deadlift: 3 sets of 5 reps at 225.0 lbs (similarity=0.643)
  - Performed bench press: 4 sets of 5 reps at 185.0 lbs (similarity=0.631)
  - Performed 5k run in 26 minutes (similarity=0.585)
  - Reports no knee pain during bench press (similarity=0.585)

Guarda cosa ha prodotto l'estrattore di Supermemory. L'utente ha detto una volta: "Mi alleno solo a casa, niente palestra". L'estrattore l'ha trasformato nel fatto dinamico "Trains at home instead of a gym".

Il log della panca includeva un campo note sull'assenza di dolore al ginocchio. L'estrattore ha diviso quel singolo log in due fatti dinamici: uno per l'allenamento, uno per l'assenza di dolore.

Quattro log sono diventati cinque fatti dinamici normalizzati più cinque chunk di memoria corrispondenti con punteggi di similarità tra 0,585 e 0,682. Nessuna di quelle suddivisioni, normalizzazioni o corrispondenze è avvenuta nel codice del trainer. Se dynamic è vuoto per te, aspetta altri 10 secondi e riesegui lo snippet. La coda di elaborazione occasionalmente si intasa.

Ora avvia la sessione 2 in un processo completamente nuovo:

uv run python main.py

Questo è un interprete Python fresco. Nessuna memoria condivisa con la sessione 1. Nessuna cache calda. Qualsiasi cosa l'agente richiami proviene da Supermemory.

Invia un solo messaggio: "Cosa dovrei fare per l'allenamento di oggi?"

Title: Terminale della sessione 2 in un nuovo processo che richiama allenamenti precedenti - Description: Terminale della sessione 2 in un nuovo processo che richiama allenamenti precedenti

Output di esempio. Stesso archivio di memoria, nuovo processo Python.

L'agente chiama suggest_next_session("today"). Il tool stampa static=0 dynamic=5 matches=5. L'esecuzione catturata ha risposto con una sessione per la parte inferiore del corpo a casa (squat, affondi, step-up).

La raccomandazione è risultata coerente con i log precedenti perché il profilo di Supermemory ha detto all'agente cosa fossero. Panca, stacco e un 5k erano parte superiore o cardio, e l'utente si allenava solo a casa. Entrambi i fatti sono tornati dalla stessa chiamata client.profile(). La tua esecuzione formulerà diversamente perché il modello è non deterministico, ma il percorso di richiamo è lo stesso.

Prossimi passi per il tuo agente Supermemory

La demo riguarda un utente, due tool e una CLI. Una versione reale del trainer si estende in tre direzioni modellate da Supermemory prima ancora di toccare il loop dell'agente.

Isola la memoria per ogni utente reale. La costante USER_ID = "demo_user" funziona per una sola persona. Le app in produzione calcolano il tag dall'ID dell'utente autenticato, come container_tag="user_sarah" o container_tag=customer_id. La memoria tra utenti resta separata perché ogni lettura rimanda il tag. Una modifica in tools.py, nient'altro si muove.

Aggiungi più tool basati su memoria. Settimane di scarico, tracciamento PR e promemoria di mobilità settimanali. Ognuno è un'altra funzione @function_tool che chiama client.add() per scrivere e client.profile() per leggere sullo stesso container_tag. La forma del tool resta la stessa. Cambia solo ciò che l'agente registra e chiede.

Gestisci i guasti di Supermemory. Incapsula client.add() e client.profile() in try/except supermemory.APIError così i guasti transitori di Supermemory non mandano in crash l'agente. Imposta timeout per richiesta se il tuo agente gira in un ambiente vincolato.

Il lato del loop dell'agente è indipendente da Supermemory e può cambiare dopo. Metti davanti alla CLI Telegram, Discord o Slack, così l'utente invia via testo un allenamento e il bot chiama Runner.run(). Oppure cambia framework. Supermemory ha un' integrazione con LangChain se il tuo stack è già su agenti LangChain, e il codice della memoria non cambia.

La divisione statico-dinamico si adatta anche ad altri domini. 

  • Agente di supporto clienti: statico = problemi noti e preferenze dell'account, dinamico = ticket aperti e contatti recenti. 
  • Agente di coding: statico = linguaggi e framework preferiti, dinamico = attività corrente e file toccati di recente. 

La divisione regge ogni volta che l'utente è la fonte di verità.

Conclusione

Hai appena costruito un trainer Python con due tool e memoria persistente tra processi. client.add() scrive gli allenamenti. client.profile() legge l'utente come fatti statici, fatti dinamici e corrispondenze semantiche in una chiamata, tutto delimitato da container_tag. Supermemory fa il chunking, l'embedding, la ricerca e l'estrazione del profilo che la demo non ha dovuto scrivere.

Abbinalo a RAG, e lo stesso agente risponde a domande sull'utente e sul prodotto. LLM Agents Explained copre pattern di agenti più ampi e il percorso Associate AI Engineer for Developers affonda ulteriormente negli agenti con memoria.

Supermemory FAQ

Che cos'è Supermemory?

Supermemory è un'API di memoria hostata che archivia, indicizza e recupera contesto a lungo termine per agenti AI, così possono ricordare gli utenti tra le sessioni.

In che cosa Supermemory è diversa dai semplici database vettoriali?

Supermemory aggiunge embedding, indicizzazione, ricerca semantica ed estrazione di fatti in stile profilo sopra lo storage, così ottieni memorie utilizzabili con una sola chiamata API.

Supermemory può gestire sia RAG sia la memoria utente?

Sì, supporta RAG in stile documento su file e URL oltre alle memorie centrate sull'utente, permettendo alla stessa API di gestire conoscenza di prodotto e cronologia personale.

Devo gestire i miei modelli di embedding con Supermemory?

No, Supermemory esegue per te la pipeline di embedding e retrieval; invii testo o contenuto grezzo e lo interroghi più tardi senza gestire modelli o indici in prima persona.

Esiste un piano gratuito per provare Supermemory?

Sì, c'è un piano gratuito pensato per test e piccoli progetti, con limiti mensili su token e query, così puoi integrare e sperimentare prima di fare upgrade.


Bex Tuychiev's photo
Author
Bex Tuychiev
LinkedIn

Sono un creator di contenuti sulla data science con oltre 2 anni di esperienza e uno dei profili con più seguito su Medium. Mi piace scrivere articoli dettagliati su AI e ML con un pizzico di sarcasmo, perché qualcosa bisogna pur fare per renderli un po' meno noiosi. Ho pubblicato più di 130 articoli e anche un corso su DataCamp, con un altro in arrivo. I miei contenuti sono stati visti da oltre 5 milioni di occhi, e 20.000 di loro sono diventati follower sia su Medium che su LinkedIn. 

Argomenti

Impara l'AI Engineering con DataCamp!

Programma

Ingegnere AI associato per sviluppatori

26 h
Scopri come integrare l'intelligenza artificiale nelle applicazioni software utilizzando API e librerie open-source. Inizia oggi il tuo percorso per diventare un ingegnere AI!
Vedi dettagliRight Arrow
Inizia il corso
Mostra altroRight Arrow
Correlato

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

Mostra altroMostra altro