Skip to content

Shared Memory Architecture - Separate Storage Design

Overview

This document describes the architecture where each agent uses its own database for sessions, metrics, eval, and knowledge collections, but memories are stored in a shared auth_db database to enable memory sharing across all agents and applications.

Architecture Design

Database Structure

auth_db/
├── users (collection)           # User information
└── user_memories (collection)   # SHARED user memories for all agents/apps

{prefix}_agno_agent/             # Agent-specific database
├── {agent_name}_sessions        # Agent-specific sessions
├── {agent_name}_metrics         # Agent-specific metrics
├── {agent_name}_eval            # Agent-specific eval
└── {agent_name}_kb              # Agent-specific knowledge

Key Principle

  • Agent Storage: Each agent uses its own database ({prefix}_agno_agent) for:
  • Sessions
  • Metrics
  • Eval
  • Knowledge

  • Memory Storage: All agents share the same database (auth_db) for:

  • User memories (user_memories collection)

Implementation

How It Works

  1. Agent Creation: Each agent gets its own storage for sessions/metrics/eval/knowledge
  2. MemoryManager: MemoryManager uses shared storage (auth_db) instead of agent storage
  3. Result: Memories are shared across agents, but everything else is isolated

Code Example

from bast_ai_agno.bp.agno_agents import AgnoAgentFactory

factory = AgnoAgentFactory(catname="testcat")

# Create agent with shared memory storage (default behavior)
agent1 = factory.create_openai_chat_agent(
    name="support_agent",
    # db=None means agent gets its own storage for sessions/metrics/etc
    # MemoryManager automatically uses shared auth_db storage
    config_raw={
        "enable_user_memories": True
    }
)

agent2 = factory.create_openai_chat_agent(
    name="sales_agent",
    # Same setup - agent gets its own storage, but memories in auth_db
    config_raw={
        "enable_user_memories": True
    }
)

# Agent 1 stores memory in auth_db.user_memories
agent1.print_response("My name is John", user_id="user123")

# Agent 2 retrieves memory from auth_db.user_memories
agent2.print_response("What's my name?", user_id="user123")
# Agent 2 knows: "John" (from shared memory)

# Both agents have their own sessions/metrics in their own databases
# But they share memories in auth_db

Configuration Options

Option 1: Shared Memory Storage (Default)

agent = factory.create_openai_chat_agent(
    name="my_agent",
    use_shared_memory_storage=True,  # Default
    shared_memory_db_name='auth_db'  # Default
)

Result: - Agent storage: {prefix}_agno_agent (agent-specific) - Memory storage: auth_db (shared)

Option 2: Agent-Specific Memory Storage

agent = factory.create_openai_chat_agent(
    name="my_agent",
    use_shared_memory_storage=False  # Use agent's own storage for memories too
)

Result: - Agent storage: {prefix}_agno_agent (agent-specific) - Memory storage: {prefix}_agno_agent (agent-specific, NOT shared)

Internal Implementation

AgnoAgentFactory._prepare_agent_fields()

The factory method separates storage:

  1. Agent Storage: Created via get_agent_storage(name) - agent-specific
  2. Memory Storage: Created via get_shared_user_memory_storage() - shared in auth_db
  3. MemoryManager: Uses memory storage (auth_db)
  4. Agent: Uses agent storage (agent-specific)
# Agent's main storage - agent-specific
agent_db = self._storage_resources.get_agent_storage(name)

# Memory storage - shared in auth_db
memory_db = self._storage_resources.get_shared_user_memory_storage(
    db_name='auth_db',
    memory_collection='user_memories'
)

# MemoryManager uses shared storage
memory_obj = self._memory_resources.build_memory(
    memory_manager, mem_cfg, model=model_obj, db=memory_db  # auth_db
)

# Agent uses agent-specific storage
agent = Agent(
    db=agent_db,  # {prefix}_agno_agent
    memory_manager=memory_obj  # Uses auth_db
)

Benefits

  1. Isolated Agent Data: Each agent's sessions, metrics, eval, and knowledge are isolated
  2. Shared Memories: User memories are shared across all agents and apps
  3. Clean Separation: Clear separation between agent-specific and shared data
  4. Scalability: Each agent can scale independently
  5. Data Management: Easy to manage agent-specific data vs shared user data

Database Collections

auth_db Database

auth_db/
├── users                    # User information (existing)
└── user_memories           # Shared user memories (NEW)
    ├── user_id: "user123"
    ├── user_id: "user456"
    └── ...

{prefix}_agno_agent Database

{prefix}_agno_agent/
├── support_agent_sessions   # support_agent specific
├── support_agent_metrics    # support_agent specific
├── support_agent_eval       # support_agent specific
├── support_agent_kb         # support_agent specific
├── sales_agent_sessions     # sales_agent specific
├── sales_agent_metrics       # sales_agent specific
├── sales_agent_eval         # sales_agent specific
└── sales_agent_kb           # sales_agent specific

Usage Examples

Example 1: Multiple Agents with Shared Memories

factory = AgnoAgentFactory(catname="testcat")

# Create multiple agents
support = factory.create_openai_chat_agent(
    name="support",
    config_raw={"enable_user_memories": True}
)

sales = factory.create_openai_chat_agent(
    name="sales",
    config_raw={"enable_user_memories": True}
)

# Support agent stores memory
support.print_response("I prefer email", user_id="user123")

# Sales agent retrieves memory
sales.print_response("How should I contact you?", user_id="user123")
# Sales knows: "email" (from shared memory in auth_db)

# But each agent has its own sessions/metrics
# support -> {prefix}_agno_agent.support_sessions
# sales -> {prefix}_agno_agent.sales_sessions

Example 2: MemoryRetriever with Shared Storage

from bast_ai_agno.svc.memory_retriever import MemoryRetriever

# MemoryRetriever uses shared storage by default
retriever = MemoryRetriever(
    catname="testcat",
    use_shared_storage=True,  # Default
    db_name='auth_db'         # Default
)

# Retrieve memories from auth_db
memories = retriever.get_user_memories(user_id="user123")

Migration Notes

For Existing Agents

If you have existing agents that use shared storage for everything:

  1. Before: Agent uses shared storage for all collections
  2. After: Agent uses agent-specific storage, but MemoryManager uses shared storage
# Before (everything shared)
shared_storage = resources.get_shared_user_memory_storage()
agent = Agent(db=shared_storage, ...)

# After (agent-specific + shared memories)
agent = factory.create_openai_chat_agent(
    name="my_agent",
    use_shared_memory_storage=True  # Only memories are shared
)

Summary

  • ✅ Each agent uses its own database for sessions, metrics, eval, knowledge
  • ✅ All agents share auth_db for user memories
  • ✅ Clean separation between agent-specific and shared data
  • ✅ Default behavior: use_shared_memory_storage=True
  • ✅ Can be disabled: use_shared_memory_storage=False for agent-specific memories