The problem: amnesic agents
Every AI agent starts each conversation from zero. It forgets what the user said yesterday, what decisions were made last week, and what context matters right now. This is not a limitation of the LLM — it is a limitation of the architecture.
The fix is persistent memory: a system that stores, retrieves, and reasons over past interactions so the agent can behave as if it has continuity of experience.
This tutorial walks you through adding persistent memory to an AI agent using Engramma in under 30 minutes.
What you will build
A Python AI agent that:
- Remembers facts from previous conversations
- Retrieves relevant context before responding
- Builds causal links between related memories
- Consolidates knowledge over time
Prerequisites
- Python 3.9+
- An Engramma API key (free tier works for this tutorial)
- An LLM API key (OpenAI, Anthropic, or any provider)
Step 1: Install dependencies
pip install engramma-cloud openai
Step 2: Initialize the memory client
import os
from engramma_cloud import EngrammaClient
memory = EngrammaClient(api_key=os.environ["ENGRAMMA_API_KEY"])
Step 3: Store memories after each interaction
After the agent processes a user message, extract key facts and store them:
def store_interaction(user_message: str, agent_response: str, metadata: dict = None):
"""Store the interaction as a memory pattern."""
memory.store(
text=f"User said: {user_message}\nAgent responded: {agent_response}",
metadata=metadata or {"type": "interaction"},
importance=0.7
)
Not every interaction needs to be stored. A production agent should filter for meaningful content:
def should_store(message: str) -> bool:
"""Only store messages that contain factual or preference information."""
trivial_patterns = ["hello", "thanks", "ok", "bye"]
return not any(message.lower().strip() == p for p in trivial_patterns)
Step 4: Retrieve context before responding
Before the agent generates a response, query memory for relevant context:
def get_relevant_context(query: str, top_k: int = 5) -> str:
"""Retrieve memories relevant to the current query."""
results = memory.retrieve(
query=query,
top_k=top_k,
min_confidence=0.5
)
if not results:
return ""
context_parts = []
for r in results:
context_parts.append(f"[{r.confidence:.0%} relevant] {r.text}")
return "\n".join(context_parts)
Step 5: Wire it into the agent loop
from openai import OpenAI
llm = OpenAI()
SYSTEM_PROMPT = """You are a helpful assistant with persistent memory.
You remember previous conversations and use that context to give better answers.
When you reference a past interaction, mention it naturally."""
def agent_respond(user_message: str) -> str:
# 1. Retrieve relevant memories
context = get_relevant_context(user_message)
# 2. Build the prompt with context
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
if context:
messages.append({
"role": "system",
"content": f"Relevant memories from past interactions:\n{context}"
})
messages.append({"role": "user", "content": user_message})
# 3. Generate response
response = llm.chat.completions.create(
model="gpt-4o",
messages=messages
)
agent_response = response.choices[0].message.content
# 4. Store the interaction
if should_store(user_message):
store_interaction(user_message, agent_response)
return agent_response
Step 6: Add causal linking
When the agent detects that a new fact relates to an existing one, create a causal link:
def link_related_memories(new_pattern_id: str, query: str):
"""Find and link causally related memories."""
related = memory.recall(
query=query,
causal_weight=0.8,
limit=3
)
for r in related:
if r.pattern_id != new_pattern_id:
memory.text.link(
source_id=new_pattern_id,
target_id=r.pattern_id,
relation="related_to"
)
Step 7: Periodic consolidation
Over time, memories accumulate. Schedule consolidation to merge duplicates and prune low-value patterns:
def consolidate_memories():
"""Run weekly to keep memory clean and efficient."""
preview = memory.engine.consolidation.preview()
print(f"Merge candidates: {preview.merge_candidates}")
print(f"Prune candidates: {preview.prune_candidates}")
if preview.merge_candidates > 0:
result = memory.engine.consolidation.merge()
print(f"Merged: {result.merged}, Pruned: {result.pruned}")
Complete example
Putting it all together in a runnable script:
import os
from engramma_cloud import EngrammaClient
from openai import OpenAI
memory = EngrammaClient(api_key=os.environ["ENGRAMMA_API_KEY"])
llm = OpenAI()
SYSTEM_PROMPT = """You are a helpful assistant with persistent memory.
You remember previous conversations and use that context naturally."""
def agent_respond(user_message: str) -> str:
context = memory.retrieve(query=user_message, top_k=5, min_confidence=0.5)
context_str = "\n".join(f"- {r.text}" for r in context) if context else ""
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
if context_str:
messages.append({"role": "system", "content": f"Memories:\n{context_str}"})
messages.append({"role": "user", "content": user_message})
response = llm.chat.completions.create(model="gpt-4o", messages=messages)
answer = response.choices[0].message.content
memory.store(
text=f"User: {user_message}\nAssistant: {answer}",
metadata={"type": "conversation"}
)
return answer
# Interactive loop
if __name__ == "__main__":
print("Agent with memory (type 'quit' to exit)")
while True:
msg = input("\nYou: ")
if msg.lower() == "quit":
break
print(f"\nAgent: {agent_respond(msg)}")
What happens over time
After a few sessions, the agent:
- Remembers the user's name, preferences, and ongoing projects
- References past decisions naturally ("Last week you mentioned...")
- Builds a knowledge graph of related facts via causal links
- Automatically prunes outdated or low-value memories
This is not RAG — it is genuine persistent memory with cognitive retrieval.
Next steps
- Add importance scoring based on message content (questions about deadlines get higher importance)
- Implement forget for sensitive data the user wants removed
- Use recall instead of retrieve for causal queries ("Why did we decide X?")
- Set up a cron job for weekly consolidation
See the Python SDK docs for the full API reference.
Tags
Share