Memory for Agents

If you’re building intelligent agents, you need to give them memory which is their ability to learn about the user they are interacting with. Memory comes in 3 shapes:

  1. Session Storage: Session storage saves sessions in a database and enables Agents to have multi-turn conversations. Session storage also holds the session state, which is persisted across runs because it is saved to the database after each run. Session storage is a form of short-term memory called “Storage” in Agno.

  2. User Memories: The Agent can also store insights and facts about the user it learns over time. This helps the agents personalize its response to the user it is interacting with. Think of this as adding “ChatGPT like memory” to your agent. This is called “Memory” in Agno.

  3. Session Summaries: The Agent can store a condensed representations of the session, useful when chat histories gets too long. This is called “Summary” in Agno.

Memory helps Agents:

  • Manage session history and state (session storage).
  • Personalize responses to users (user memories).
  • Maintain long-session context (session summaries).

Managing User Memory

When we speak about Memory, the commonly agreed upon understanding of Memory is the ability to store insights and facts about the user the Agent is interacting with. In short, build a persona of the user, learn about their preferences and use that to personalize the Agent’s response.

Agentic Memory

Agno Agents natively support Agentic Memory Management and recommend it as the best way to give Agents memory.

With Agentic Memory, The Agent itself creates, updates and deletes memories from user conversations.

Set enable_agentic_memory=True to enable Agentic Memory.

agentic_memory.py
from agno.agent.agent import Agent
from agno.memory.v2.db.sqlite import SqliteMemoryDb
from agno.memory.v2.memory import Memory
from agno.models.openai import OpenAIChat
from rich.pretty import pprint

memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
# No need to set the model, it gets set to the model of the agent
memory = Memory(db=memory_db, delete_memories=True, clear_memories=True)

# Reset the memory for this example
memory.clear()

# User ID for the memory
john_doe_id = "john_doe@example.com"
agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    memory=memory,
    enable_agentic_memory=True,
)

# Send a message to the agent that would require the memory to be used
agent.print_response(
    "My name is John Doe and I like to hike in the mountains on weekends.",
    stream=True,
    user_id=john_doe_id,
)

# Send a message to the agent that checks the memory is working
agent.print_response("What are my hobbies?", stream=True, user_id=john_doe_id)

# Print the memories for the user
memories = memory.get_user_memories(user_id=john_doe_id)
print("Memories about John Doe:")
pprint(memories)

# Send a message to the agent that removes all memories for the user
agent.print_response(
    "Remove all existing memories of me.",
    stream=True,
    user_id=john_doe_id,
)
memories = memory.get_user_memories(user_id=john_doe_id)
print("Memories about John Doe:")
pprint(memories)

Create Memories after each run

Set enable_user_memories=True to trigger the MemoryManager after each run. We recommend using Agentic Memory but this option is there is you need it.

create_memories_after_each_run.py
from agno.agent.agent import Agent
from agno.memory.v2.db.sqlite import SqliteMemoryDb
from agno.memory.v2.memory import Memory
from agno.models.openai import OpenAIChat
from rich.pretty import pprint

memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
# No need to set the model, it gets set to the model of the agent
memory = Memory(db=memory_db, delete_memories=True, clear_memories=True)

# Reset the memory for this example
memory.clear()

# User ID for the memory
john_doe_id = "john_doe@example.com"
agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    memory=memory,
    enable_user_memories=True,
)

# Send a message to the agent that would require the memory to be used
agent.print_response(
    "My name is John Doe and I like to hike in the mountains on weekends.",
    stream=True,
    user_id=john_doe_id,
)

# Send a message to the agent that checks the memory is working
agent.print_response("What are my hobbies?", stream=True, user_id=john_doe_id)

# Print the memories for the user
memories = memory.get_user_memories(user_id=john_doe_id)
print("Memories about John Doe:")
pprint(memories)

# Send a message to the agent that removes all memories for the user
agent.print_response(
    "Remove all existing memories of me.",
    stream=True,
    user_id=john_doe_id,
)
memories = memory.get_user_memories(user_id=john_doe_id)
print("Memories about John Doe:")
pprint(memories)

Memory Architecture

The Memory class in Agno lets you manage all aspects of user memory. Let’s start with some examples of using Memory outside of Agents. We will:

  • Add, update and delete memories
  • Store memories in a database
  • Create memories from conversations
  • Search over memories
from agno.memory.v2.memory import Memory
from agno.memory.v2.db.sqlite import SqliteMemoryDb

# Create a memory instance with persistent storage
memory_db = SqliteMemoryDb(table_name="memory", db_file="memory.db")
memory = Memory(db=memory_db)

Adding a new memory

from agno.memory.v2.memory import Memory
from agno.memory.v2.schema import UserMemory

memory = Memory()

# Create a user memory manually
memory_id = memory.add_user_memory(
    memory=UserMemory(
        memory="The user's name is Jane Doe",
        topics=["personal", "name"]
    ),
    user_id="jane_doe@example.com"
)

Updating a memory

from agno.memory.v2.memory import Memory
from agno.memory.v2.schema import UserMemory

memory = Memory()

# Replace a user memory
memory_id = memory.replace_user_memory(
    # The id of the memory to replace
    memory_id=previous_memory_id,
    # The new memory to replace it with
    memory=UserMemory(
        memory="The user's name is Verna Doe",
        topics=["personal", "name"]
    ),
    user_id="jane_doe@example.com"
)

Deleting a memory

from agno.memory.v2.memory import Memory

memory = Memory()

# Delete a user memory
memory.delete_user_memory(user_id="jane_doe@example.com", memory_id=memory_id)

Creating memories from user information

from agno.memory.v2 import Memory
from agno.memory.v2.db.sqlite import SqliteMemoryDb
from agno.models.google import Gemini

memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
memory = Memory(model=Gemini(id="gemini-2.0-flash-exp"), db=memory_db)

john_doe_id = "john_doe@example.com"

memory.create_user_memories(
    message="""
    I enjoy hiking in the mountains on weekends,
    reading science fiction novels before bed,
    cooking new recipes from different cultures,
    playing chess with friends,
    and attending live music concerts whenever possible.
    Photography has become a recent passion of mine, especially capturing landscapes and street scenes.
    I also like to meditate in the mornings and practice yoga to stay centered.
    """,
    user_id=john_doe_id,
)


memories = memory.get_user_memories(user_id=john_doe_id)
print("John Doe's memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory} - {m.topics}")

Creating memories from a conversation

from agno.memory.v2 import Memory
from agno.memory.v2.db.sqlite import SqliteMemoryDb
from agno.models.google import Gemini
from agno.models.message import Message

memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
memory = Memory(model=Gemini(id="gemini-2.0-flash-exp"), db=memory_db)


jane_doe_id = "jane_doe@example.com"
# Send a history of messages and add memories
memory.create_user_memories(
    messages=[
        Message(role="user", content="My name is Jane Doe"),
        Message(role="assistant", content="That is great!"),
        Message(role="user", content="I like to play chess"),
        Message(role="assistant", content="That is great!"),
    ],
    user_id=jane_doe_id,
)

memories = memory.get_user_memories(user_id=jane_doe_id)
print("Jane Doe's memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory} - {m.topics}")

Agno provides several retrieval methods to search and retrieve user memories:

Basic Retrieval Methods

You can retrieve memories using chronological methods such as last_n (most recent) or first_n (oldest first):

from agno.memory.v2 import Memory, UserMemory

memory = Memory()

john_doe_id = "john_doe@example.com"

memory.add_user_memory(
    memory=UserMemory(memory="The user enjoys hiking in the mountains on weekends"),
    user_id=john_doe_id,
)
memory.add_user_memory(
    memory=UserMemory(
        memory="The user enjoys reading science fiction novels before bed"
    ),
    user_id=john_doe_id,
)

# Get the most recent memory
memories = memory.search_user_memories(
    user_id=john_doe_id, limit=1, retrieval_method="last_n"
)
print("John Doe's last_n memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory}")

# Get the oldest memory
memories = memory.search_user_memories(
    user_id=john_doe_id, limit=1, retrieval_method="first_n"
)
print("John Doe's first_n memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory}")

Agentic search allows you to find memories based on meaning rather than exact keyword matches. This is particularly useful for retrieving contextually relevant information:

from agno.memory.v2.memory import Memory, UserMemory
from agno.models.google.gemini import Gemini

# Initialize memory with a model for agentic search
memory = Memory(model=Gemini(id="gemini-2.0-flash-exp"))

john_doe_id = "john_doe@example.com"

memory.add_user_memory(
    memory=UserMemory(memory="The user enjoys hiking in the mountains on weekends"),
    user_id=john_doe_id,
)
memory.add_user_memory(
    memory=UserMemory(
        memory="The user enjoys reading science fiction novels before bed"
    ),
    user_id=john_doe_id,
)

# Search for memories related to the query
memories = memory.search_user_memories(
    user_id=john_doe_id,
    query="What does the user like to do on weekends?",
    retrieval_method="agentic",
)
print("John Doe's found memories:")
for i, m in enumerate(memories):
    print(f"{i}: {m.memory}")

With agentic search, the model understands the intent behind your query and returns the most relevant memories, even if they don’t contain the exact keywords from your search.

Developer Resources

  • Find full examples in the Cookbook
  • View the class reference for the Memory class here