Memory
create_memory(strategy) returns a memory backend. Pick a strategy by what you
need to remember: raw turns, important events, facts, skills, or an entity graph.
from largestack.memory import create_memory
mem = create_memory("buffer") # default
Strategies
create_memory(strategy, **kwargs) accepts these strategy strings:
strategy |
Backend | What it does | Status |
|---|---|---|---|
"buffer" |
ConversationMemory |
Keep every message (no eviction) | works |
"sliding_window" |
ConversationMemory |
Keep the last max_messages (default 20) |
works |
"token_limited" |
ConversationMemory |
Keep recent messages within max_tokens (default 4000, ~4 chars/token estimate) |
works |
"episodic" |
EpisodicMemory |
Timestamped events scored by recency + importance + word-overlap relevance | works |
"semantic" |
SemanticMemory |
Similarity recall of facts. Default embedder is a token-overlap hash vector (not real embeddings) | works; real embeddings opt-in |
"procedural" |
ProceduralMemory |
Reusable skills (name/procedure/trigger) with keyword search + success tracking | works |
"observational" |
ObservationalMemory |
Observer/Reflector notes extracted from messages (heuristic; LLM optional) | works; heuristic |
"graph" |
GraphMemory |
Entity–relationship graph with neighbors, paths, subgraphs | works |
Anything else falls back to a default ConversationMemory (buffer).
SharedMemorySpace(cross-agent shared store) and the compression helper exist inlargestack._memorybut are notcreate_memorystrategies — construct them directly (e.g.from largestack._memory.shared import SharedMemorySpace).
Conversation memory (buffer / sliding_window / token_limited)
Add and read messages. add_message/add_messages are async; get_messages
returns a defensive copy.
import asyncio
from largestack.memory import create_memory
async def main():
mem = create_memory("buffer")
await mem.add_message({"role": "user", "content": "Hello"})
await mem.add_message({"role": "assistant", "content": "Hi there!"})
print(mem.get_messages()) # [{'role': 'user', ...}, {'role': 'assistant', ...}]
print(len(mem), mem.token_count, mem.stats)
asyncio.run(main())
Eviction kicks in for the bounded strategies (system messages are preserved by
default via include_system=True):
sw = create_memory("sliding_window", max_messages=2)
# ...after adding m0..m3, get_messages() keeps only ['m2', 'm3']
Other helpers: get_by_role(role), prune_older_than(keep_last), clear().
Semantic memory
import asyncio
from largestack.memory import create_memory
async def main():
sem = create_memory("semantic")
await sem.add("Python was created by Guido van Rossum")
hits = await sem.search("Who created Python?", k=1)
print(hits[0]["content"], round(hits[0]["score"], 3))
asyncio.run(main())
The default backend uses a 128-dim bag-of-words hash vector, so it matches on
shared tokens, not meaning — paraphrases won't match. For genuine semantic recall,
construct SemanticMemory directly with a real embedder:
from largestack._memory.semantic import SemanticMemory
sem = SemanticMemory(embedder=my_embed_fn) # sync or async callable -> list[float]
Episodic memory
ep = create_memory("episodic")
await ep.add("User prefers dark mode", importance=8.0) # importance 1–10
top = await ep.retrieve("dark mode preference", k=1) # tri-score ranked
Procedural memory
pm = create_memory("procedural")
await pm.add_skill(
name="book_flight",
description="Search and book a flight between cities",
procedure="1. flight_search 2. filter by price 3. book lowest",
trigger="user wants to book travel",
)
matches = pm.search("how do I book a trip") # keyword search; [Skill, ...]
pm.record_usage("book_flight", success=True) # tracks success_rate
Observational memory
obs = create_memory("observational")
await obs.observe([{"role": "user", "content": "I always prefer tea over coffee."}])
print(obs.get_context()) # emoji-prioritized notes for LLM context
Graph memory
g = create_memory("graph")
await g.add_entity("Alice", "person")
await g.add_relation("Alice", "Acme", "works_at") # entities auto-created
print(await g.neighbors("Alice")) # ['Acme']
print(await g.find_paths("Alice", "Acme")) # [['Alice', 'Acme']]
See also: RAG for retrieval over documents.