Memory

SQLite-backed persistent storage for long-term memory. Save, search, and manage key-value entries with optional tags. Zero external dependencies.

Quick Start

from acorn import Module
from acorn.services.memory import Memory

class Agent(Module):
    """Agent with long-term memory."""
    max_steps = 10
    tools = [Memory(path="./agent_memory.db")]
    final_output = Output

The LLM gets four tools: memory__save, memory__search, memory__delete, and memory__list_all.

Configuration

Parameter Type Default Description
path str "./memory.db" Path to the SQLite database file

Database Path

Store memories in a file:

memory = Memory(path="./memories/agent.db")

Use an in-memory database for testing:

memory = Memory(path=":memory:")

Tools Provided

memory__save

Save or update a memory entry by key. If the key exists, it’s updated. If not, a new entry is created.

# LLM calls:
memory__save(key="user_preference", content="User prefers dark mode", tags=["ui", "settings"])

Parameters:

  • key (str): Unique identifier for the memory
  • content (str): The content to store
  • tags (list[str], optional): Tags for categorization

Returns: Confirmation message

Search memories by keyword. Matches against key, content, and tags.

# LLM calls:
memory__search(query="dark mode", limit=5)

Parameters:

  • query (str): Search query
  • limit (int, default=5): Maximum number of results

Returns: JSON array of matching entries with key, content, and tags fields

memory__delete

Delete a memory entry by key.

# LLM calls:
memory__delete(key="user_preference")

Parameters:

  • key (str): The key of the memory to delete

Returns: Confirmation message or “Memory not found” if key doesn’t exist

memory__list_all

List all stored memories, ordered by most recently updated.

# LLM calls:
memory__list_all(limit=20)

Parameters:

  • limit (int, default=20): Maximum number of entries to return

Returns: JSON array of all entries with key, content, and tags fields

Memory Entry Format

Each memory entry has:

{
  "key": "unique_identifier",
  "content": "The stored content",
  "tags": ["tag1", "tag2"]
}
  • key: Unique identifier (string). Acts as primary key.
  • content: Text content to store (string).
  • tags: Optional list of strings for categorization (array, can be empty).

Entries also have internal timestamps (created_at, updated_at) used for sorting, but these are not exposed to the LLM.

Common Patterns

Pattern 1: User Preferences

Store and retrieve user preferences across sessions:

from acorn.services.memory import Memory

class PersonalAssistant(Module):
    """Assistant that remembers user preferences."""
    max_steps = 10
    tools = [Memory(path="./user_prefs.db")]
    final_output = Response

# LLM stores preference:
# memory__save(key="timezone", content="America/New_York", tags=["settings"])

# Later, LLM searches:
# memory__search(query="timezone")
# Returns: [{"key": "timezone", "content": "America/New_York", "tags": ["settings"]}]

See examples/personal_assistant.py for a complete implementation.

Pattern 2: Fact Database

Build a knowledge base the agent can query:

memory = Memory(path="./facts.db")

class FactChecker(Module):
    """Agent that verifies facts against stored knowledge."""
    max_steps = 8
    tools = [memory, search_web]
    final_output = FactCheckResult

# LLM stores facts:
# memory__save(key="earth_radius", content="6,371 kilometers", tags=["science", "geography"])
# memory__save(key="python_created", content="1991 by Guido van Rossum", tags=["technology", "history"])

# Later, LLM checks a claim:
# memory__search(query="python created")
# Returns stored fact for verification

Pattern 3: Session Memory

Track conversation context and decisions made during a session:

memory = Memory(path="./session.db")

class ProjectManager(Module):
    """Agent that tracks project decisions."""
    max_steps = 15
    tools = [memory, list_tasks, update_status]
    final_output = ProjectUpdate

# LLM records decisions:
# memory__save(key="decision_2024_01_15_api", content="Decided to use REST API instead of GraphQL", tags=["decisions", "architecture"])

# LLM lists all decisions:
# memory__list_all(limit=50)

When to Use

Good use cases:

  • User preferences and settings that persist across sessions
  • Building a knowledge base the agent can reference
  • Recording decisions, facts, or context for future reference
  • Storing structured data the agent needs to retrieve later

Not recommended:

  • Temporary state within a single module execution (use module attributes instead)
  • Large binary data (Memory stores text; use file storage for binary data)
  • High-frequency updates (Memory uses SQLite; consider Redis for caching)

Best Practices

Use descriptive keys: Make keys self-documenting for easier search and debugging.

# Good
memory__save(key="user_timezone_preference", content="America/New_York")

# Less clear
memory__save(key="tz", content="America/New_York")

Tag entries for categorization: Tags enable filtered searches and logical grouping.

memory__save(
    key="project_deadline",
    content="March 15, 2024",
    tags=["project", "deadline", "important"]
)

# Later search by tag
memory__search(query="deadline")

Use search before save: Check if a key exists before overwriting to avoid losing data.

# LLM workflow:
# 1. memory__search(query="user_name")
# 2. If found, use existing; if not, memory__save(key="user_name", content="Alice")

Limit search results: Use the limit parameter to control how much context is returned.

# Get top 3 most relevant results
memory__search(query="project", limit=3)

Clean up stale data: Use memory__delete to remove outdated entries.

# Remove completed tasks
memory__delete(key="task_123_completed")

Benefits

Persistence: Data survives across module executions and system restarts.

Zero dependencies: Pure SQLite, no external database required.

Keyword search: Built-in search across keys, content, and tags.

Flexible schema: Store any text content with optional tags for organization.

Automatic timestamps: Entries track creation and update times for sorting.

ACID guarantees: SQLite provides transaction safety and data integrity.


This site uses Just the Docs, a documentation theme for Jekyll.