Persistent semantic memory for AI agents — Python SDK
from engram import Engram, EngramConfig
memory = Engram(EngramConfig(db_path="./memory.db"))
# Store
memory.remember("user_123", "User prefers TypeScript and dark mode", "user")
# Recall semantically — finds the right memory without exact keyword match
results = memory.recall("user_123", "what are the user's preferences?", limit=5)
# [MemoryEntry(content='User prefers TypeScript and dark mode', similarity=0.82, ...)]pip install cartisien-engrampip install "cartisien-engram[langchain]"# Install Ollama: https://ollama.ai
ollama pull nomic-embed-textWithout Ollama, keyword search is used automatically.
from engram import Engram, EngramConfig
memory = Engram(EngramConfig(
db_path="./agent.db",
embedding_url="http://localhost:11434", # Ollama default
))
# In your agent loop
def handle_message(session_id: str, user_input: str) -> str:
# 1. Recall relevant context
context = memory.recall(session_id, user_input, limit=5)
context_str = "\n".join(f"[{e.role}]: {e.content}" for e in context)
# 2. Build prompt + call your LLM
response = llm.chat(f"Context:\n{context_str}\n\nUser: {user_input}")
# 3. Store both sides
memory.remember(session_id, user_input, "user")
memory.remember(session_id, response, "assistant")
return responseDrop-in replacement for ConversationBufferMemory:
from engram.langchain import EngramMemory
from langchain.chains import ConversationChain
from langchain.llms import OpenAI
memory = EngramMemory(
session_id="user_abc",
db_path="./memory.db",
recall_limit=10
)
chain = ConversationChain(llm=OpenAI(), memory=memory)
chain.predict(input="My name is Jeff and I'm building GovScout")
# Start a new session — memory persists
chain.predict(input="What am I building?") # Remembers "GovScout"config = EngramConfig(
db_path="./memory.db", # SQLite path (default: ":memory:")
max_context_length=4000, # Max chars per entry
embedding_url="http://localhost:11434", # Ollama base URL
embedding_model="nomic-embed-text", # Embedding model
semantic_search=True, # Enable semantic search
)
memory = Engram(config)entry = memory.remember("session_1", "User loves Thai food", "user")
# MemoryEntry(id=..., content=..., role='user', timestamp=...)Semantic search when Ollama available, keyword fallback otherwise.
results = memory.recall("session_1", "food preferences", limit=5)
# [MemoryEntry(..., similarity=0.84)]Chronological conversation history.
chat = memory.history("session_1", limit=20)memory.forget("session_1") # clear all
memory.forget("session_1", id="abc123") # delete one
memory.forget("session_1", before=datetime.now()) # delete oldstats = memory.stats("session_1")
# {"total": 42, "by_role": {"user": 21, "assistant": 21}, "with_embeddings": 42}with Engram(EngramConfig(db_path="./memory.db")) as memory:
memory.remember("s1", "test", "user")| Package | Language | Purpose |
|---|---|---|
cartisien-engram |
Python | This package |
@cartisien/engram |
TypeScript/Node | TS SDK |
@cartisien/engram-mcp |
TypeScript | MCP server |
@cartisien/extensa |
TypeScript | Vector infrastructure (soon) |
@cartisien/cogito |
TypeScript | Agent identity (soon) |
MIT © Cartisien Interactive