Memory¶
Long-term, semantic memory: facts that persist across conversations, not just within one (that
is a Session). Opt an agent in with memory:
"auto": the framework remembers for you¶
Before each run, Runa searches memory for anything relevant to the user's message and adds
it to context. After the run, it asks the model what's durably worth keeping and stores it. No
manual remember/search calls.
support = SupportAgent() # memory = "auto"
support.run_sync("I only speak Japanese.")
# ...later, a new run:
support.run_sync("What's my order status?") # sees "user speaks Japanese"
"llm": the model decides when to look¶
The model gets a search_memory tool and calls it itself. Nothing is written automatically.
Call memory.remember(...) from your own tools if you want the model's actions to persist.
Memory Directly¶
Reach for a Memory() instance when you need a non-default db_path/model/store, or want to
call remember/search/forget yourself, outside the run lifecycle:
from runa import Memory
memory = Memory()
await memory.remember("User prefers email over phone.", user_id="user-42")
matches = await memory.search("how should I contact this user?", user_id="user-42")
await memory.forget(matches[0].id, user_id="user-42")
Memory() means db/runa.db (the same file SQLiteSession uses), sqlite-vec, and OpenAI's
text-embedding-3-small. Nothing to configure for the common case. Every memory is scoped by
user_id, so one user's facts never surface in another's search.
Embedding is the one thing memory needs that the agent's own model doesn't cover: it goes to
OpenAI whatever that model is, so an agent with memory set needs OPENAI_API_KEY as well. See
Where embeddings go to send it through a gateway instead.
Remembering a near-duplicate of an existing memory skips the write and returns the existing id instead, so restating the same fact across conversations doesn't pile up duplicates.
A Different Store¶
A bare Memory() stores wherever runa.db resolves: the local db/runa.db, or the shared
Postgres once RUNA_DATABASE_URL is set. Going multi-replica needs no code change.
store= is for a backend Runa does not ship, and swaps storage without touching how embeddings
work. Note dimensions, which must match your embedding model:
from runa import Memory
from runa.memory.postgres import PostgresMemoryStore
memory = Memory(store=PostgresMemoryStore("postgresql://...", dimensions=1536))
Memory vs. Session vs. Knowledge¶
Three kinds of context are easy to mix up:
Session = this conversation's history
Memory = durable facts about a user, learned over many conversations
Knowledge = the application's own documents, not learned from conversations at all
For a plain get/set/delete/clear cache, with no embeddings and no user_id scoping, see
Cache instead. For application documents searched by meaning, see
Knowledge.
Example¶
More in examples/07_memory/.