Skip to main content

Memory Management

Erdo’s memory system provides persistent storage and intelligent retrieval of information across agent executions. This enables agents to build up knowledge over time, remember context from previous interactions, and share insights across different workflows.

Core Concepts

Memory Structure

Memories in Erdo are structured documents that can store various types of information:
# Memory structure
memory_entry = {
    "content": "Core insights from Q3 sales analysis",
    "description": "Quarterly sales performance review with key findings",
    "type": "business_insight",
    "searchable_texts": [
        "Q3 revenue increased 15% year-over-year",
        "Customer acquisition cost decreased",
        "Premium tier shows highest growth potential"
    ],
    "tags": ["sales", "quarterly", "analysis", "growth"],
    "extra": {
        "quarter": "Q3",
        "year": 2024,
        "metrics": {
            "revenue_growth": 0.15,
            "cac_reduction": 0.12,
            "premium_growth": 0.23
        },
        "confidence_score": 0.94
    }
}

Memory Types

Erdo supports different memory types for various use cases:

Business Insights

  • Analysis results - Key findings - Performance metrics - Strategic recommendations

Technical Knowledge

  • Code patterns - System configurations - Error solutions - Best practices

User Preferences

  • Workflow preferences - Output formats - Custom settings - Historical choices

Process Documentation

  • Workflow steps - Decision trees - Standard procedures - Troubleshooting guides

Memory Storage Actions

Store Memory

Store new information for future retrieval:
# Basic memory storage
store_step = Step(
    agent=analyzer_agent,
    key="store_insights",
    actiontype=memory.store(memory=
        memory={
            "content": "{{analysis_results}}",
            "description": "Analysis of customer churn patterns",
            "type": "data_insight",
            "searchable_texts": [
                "{{key_findings}}",
                "customer churn analysis",
                "retention strategies"
            ],
            "tags": ["churn", "customers", "retention", "analysis"],
            "extra": {
                "dataset": "{{dataset_name}}",
                "model_accuracy": "{{model_performance}}",
                "recommendations": "{{action_items}}"
            }
        }
    )
)

Update Memory

Modify existing memories with new information:
# Update existing memory
update_step = Step(
    agent=updater_agent,
    key="update_knowledge",
    actiontype=memory.update(
        memory_id="{{memory_id}}",
        updates={
            "content": "{{updated_content}}",
            "tags": ["{{existing_tags}}", "updated", "validated"],
            "extra": {
                "last_validated": "{{current_date}}",
                "validation_score": "{{confidence_level}}"
            }
        }
    )
)

Delete Memory

Remove outdated or incorrect information:
# Delete obsolete memory
delete_step = Step(
    agent=cleanup_agent,
    key="cleanup_memory",
    actiontype=memory.delete(
        memory_id="{{obsolete_memory_id}}",
        reason="Information superseded by newer analysis"
    )
)

Memory Retrieval Actions

Search Memory

Find relevant memories using semantic search:
# Search for relevant memories
search_step = Step(
    agent=research_agent,
    key="find_context",
    actiontype=memory.search(
        query="customer retention strategies for SaaS companies",
        limit=5,
        tags=["retention", "saas", "strategies"],
        memory_types=["business_insight", "best_practice"],
        min_confidence=0.7
    )
)

Search from Queries

Search memories using multiple related queries:
# Multi-query search
multi_search_step = Step(
    agent=research_agent,
    key="comprehensive_search",
    actiontype=memory.search_from_queries(
        queries=[
            "revenue optimization techniques",
            "pricing strategy analysis",
            "customer lifetime value improvement"
        ],
        limit=10,
        combine_results=True,
        deduplicate=True
    )
)

Process Integration Queries

Handle complex queries that span multiple data sources:
# Integration-aware search
integration_search_step = Step(
    agent=data_agent,
    key="cross_system_search",
    actiontype=memory.process_integration_queries(
        queries=[
            "CRM data analysis patterns",
            "Sales pipeline optimization"
        ],
        integration_types=["salesforce", "hubspot"],
        include_metadata=True,
        filter_by_recency="30d"
    )
)

Advanced Memory Patterns

Contextual Memory Chains

Build context across multiple agent executions:
# Store execution context
context_agent = Agent(
    name="context_manager",
    description="Manages execution context and memory"
)

# Store initial context
store_context = Step(
    agent=context_agent,
    key="store_context",
    actiontype=memory.store(memory=
        memory={
            "content": "Starting analysis of {{project_name}}",
            "type": "execution_context",
            "searchable_texts": [
                "project initialization",
                "{{project_name}} analysis started"
            ],
            "tags": ["context", "start", "{{project_name}}"],
            "extra": {
                "execution_id": "{{execution_id}}",
                "start_time": "{{timestamp}}",
                "parameters": "{{input_parameters}}"
            }
        }
    )
)

# Retrieve context in subsequent steps
retrieve_context = Step(
    agent=context_agent,
    key="get_context",
    actiontype=memory.search(
        query="execution context for {{project_name}}",
        tags=["context", "{{project_name}}"],
        limit=1,
        sort_by="created_at",
        order="desc"
    )
)

Knowledge Accumulation

Build up domain knowledge over time:
# Knowledge building workflow
knowledge_builder = Agent(
    name="knowledge_builder",
    description="Accumulates and organizes domain knowledge"
)

# Search for existing knowledge
find_existing = Step(
    agent=knowledge_builder,
    key="find_existing",
    actiontype=memory.search(
        query="{{domain_topic}}",
        tags=["knowledge", "{{domain}}"],
        limit=20
    )
)

# Analyze and consolidate
consolidate = Step(
    agent=knowledge_builder,
    key="consolidate",
    actiontype=llm.message(
        model="claude-sonnet-4",
        query="""
        Analyze the existing knowledge and new information:

        Existing Knowledge: {{steps.find_existing.content}}
        New Information: {{new_data}}

        Consolidate into updated knowledge base entry.
        """,
        response_format={
            "Type": "json_schema",
            "Schema": {
                "type": "object",
                "properties": {
                    "consolidated_knowledge": {"type": "string"},
                    "key_insights": {"type": "array"},
                    "confidence_score": {"type": "number"},
                    "sources": {"type": "array"}
                }
            }
        }
    ),
    depends_on=[find_existing]
)

# Store consolidated knowledge
store_knowledge = Step(
    agent=knowledge_builder,
    key="store_knowledge",
    actiontype=memory.store(memory=
        memory={
            "content": "{{steps.consolidate.consolidated_knowledge}}",
            "type": "domain_knowledge",
            "searchable_texts": ["{{steps.consolidate.key_insights}}"],
            "tags": ["knowledge", "{{domain}}", "consolidated"],
            "extra": {
                "confidence": "{{steps.consolidate.confidence_score}}",
                "sources": "{{steps.consolidate.sources}}",
                "last_updated": "{{timestamp}}"
            }
        }
    ),
    depends_on=[consolidate]
)

Memory Organization

Tagging Strategy

Use consistent tagging for effective memory organization:
# Hierarchical tagging
tags = [
    # Domain tags
    "finance", "marketing", "operations", "technology",

    # Content type tags
    "analysis", "insight", "procedure", "configuration",

    # Temporal tags
    "2024", "q3", "monthly", "daily",

    # Quality tags
    "validated", "preliminary", "high_confidence", "needs_review",

    # Source tags
    "automated", "manual", "imported", "generated"
]

# Example memory with strategic tagging
memory_entry = {
    "content": "Q3 marketing campaign performance analysis",
    "tags": [
        "marketing",           # Domain
        "analysis",           # Content type
        "2024", "q3",        # Temporal
        "validated",          # Quality
        "automated"           # Source
    ]
}

Memory Lifecycle Management

Implement memory lifecycle policies:
# Memory lifecycle agent
lifecycle_agent = Agent(
    name="memory_lifecycle",
    description="Manages memory lifecycle and cleanup"
)

# Archive old memories
archive_old = Step(
    agent=lifecycle_agent,
    key="archive_old",
    actiontype=memory.search(
        query="*",
        tags=["temporary"],
        created_before="30d",
        limit=100
    )
)

# Update status of old memories
update_archived = Step(
    agent=lifecycle_agent,
    key="update_archived",
    actiontype=memory.update(
        memory_ids="{{steps.archive_old.memory_ids}}",
        updates={
            "tags": ["archived", "historical"],
            "extra": {
                "archived_at": "{{timestamp}}",
                "archived_reason": "Age-based archival"
            }
        }
    ),
    depends_on=[archive_old]
)

Performance & Optimization

Efficient Search Patterns

Optimize memory searches for performance:
# Efficient search with filters
optimized_search = Step(
    agent=search_agent,
    key="efficient_search",
    actiontype=memory.search(
        query="{{search_term}}",

        # Use specific filters to reduce search space
        tags=["{{domain}}", "{{content_type}}"],
        memory_types=["{{specific_type}}"],

        # Limit results appropriately
        limit=10,

        # Use confidence thresholds
        min_confidence=0.6,

        # Sort by relevance
        sort_by="relevance",

        # Include only recent memories if needed
        created_after="7d"
    )
)

Batch Operations

Process multiple memories efficiently:
# Batch memory operations
batch_agent = Agent(
    name="batch_processor",
    description="Handles bulk memory operations"
)

# Batch store multiple related memories
batch_store = Step(
    agent=batch_agent,
    key="batch_store",
    actiontype=memory.batch_store(
        memories=[
            {
                "content": "Analysis result 1",
                "tags": ["batch", "analysis", "dataset_1"]
            },
            {
                "content": "Analysis result 2",
                "tags": ["batch", "analysis", "dataset_2"]
            }
        ]
    )
)

Integration with Agent Workflows

Memory-Aware Agents

Design agents that leverage memory effectively:
# Memory-enhanced agent
smart_agent = Agent(
    name="memory_enhanced_analyst",
    description="Analyst that learns from previous work",
    running_status="Analyzing data with historical context..."
)

# Step 1: Retrieve relevant context
get_context = Step(
    agent=smart_agent,
    key="get_context",
    actiontype=memory.search(
        query="{{analysis_topic}} previous analysis insights",
        tags=["analysis", "{{domain}}"],
        limit=5
    )
)

# Step 2: Perform analysis with context
analyze_with_context = Step(
    agent=smart_agent,
    key="analyze",
    actiontype=llm.message(
        model="claude-sonnet-4",
        query="""
        Perform analysis considering previous insights:

        Current Data: {{input_data}}
        Previous Insights: {{steps.get_context.content}}

        Provide new analysis building on previous knowledge.
        """,
        max_tokens=2000
    ),
    depends_on=[get_context]
)

# Step 3: Store new insights
store_insights = Step(
    agent=smart_agent,
    key="store_insights",
    actiontype=memory.store(memory=
        memory={
            "content": "{{steps.analyze.insights}}",
            "description": "Analysis of {{analysis_topic}} with historical context",
            "type": "enhanced_analysis",
            "searchable_texts": [
                "{{steps.analyze.key_findings}}",
                "{{analysis_topic}} analysis"
            ],
            "tags": ["analysis", "{{domain}}", "context_enhanced"],
            "extra": {
                "builds_on": "{{steps.get_context.memory_ids}}",
                "confidence": "{{steps.analyze.confidence}}",
                "methodology": "context_enhanced_analysis"
            }
        }
    ),
    depends_on=[analyze_with_context]
)

Memory Security & Privacy

Access Control

Implement proper access controls for sensitive memories:
# Secure memory storage
secure_store = Step(
    agent=secure_agent,
    key="store_secure",
    actiontype=memory.store(memory=
        memory={
            "content": "{{sensitive_analysis}}",
            "type": "confidential_insight",
            "tags": ["confidential", "restricted"],
            "extra": {
                "access_level": "organization_only",
                "classification": "internal",
                "retention_period": "2_years"
            }
        },
        access_control={
            "visibility": "organization",
            "requires_permission": True
        }
    )
)

Data Retention

Implement retention policies:
# Retention policy enforcement
retention_step = Step(
    agent=compliance_agent,
    key="enforce_retention",
    actiontype=memory.cleanup(
        retention_rules={
            "temporary": "30d",
            "analysis": "1y",
            "confidential": "2y",
            "archived": "7y"
        },
        dry_run=False
    )
)

Best Practices

Structured Content: Use consistent content structure across memory typesRich Metadata: Include comprehensive metadata for better searchabilitySemantic Searchability: Write searchable_texts that match how users will queryVersion Control: Track changes and updates to important memories
Specific Queries: Use specific rather than generic search termsTag Filtering: Leverage tags to narrow search scopeConfidence Thresholds: Set appropriate confidence levels for resultsResult Limiting: Use reasonable limits to improve performance
Consistent Tagging: Develop and follow consistent tagging conventionsType Classification: Use memory types to categorize different kinds of contentLifecycle Management: Implement policies for memory archival and cleanupAccess Controls: Apply appropriate security measures for sensitive content
Batch Operations: Use batch operations for multiple memory actionsTargeted Searches: Filter searches to reduce scope and improve speedCache Strategy: Consider caching frequently accessed memoriesCleanup Policies: Regular cleanup prevents memory bloat

Troubleshooting

Common Issues

Memory Not Found
Error: No memories found matching query
Check your search terms, tags, and filters. Consider broadening the search scope. Search Timeout
Error: Memory search timed out
Reduce search scope with more specific tags or filters, or increase timeout limits. Storage Failed
Error: Failed to store memory
Verify memory structure and check for required fields. Ensure proper access permissions.

Debugging Memory Operations

Enable detailed logging for memory operations:
# Debug memory search
debug_search = Step(
    agent=debug_agent,
    key="debug_search",
    actiontype=memory.search(
        query="{{search_term}}",
        debug=True,
        explain_relevance=True
    )
)
Monitor memory usage and performance:
# Memory system health check
health_check = Step(
    agent=monitor_agent,
    key="memory_health",
    actiontype=memory.system_health(
        check_storage=True,
        check_search_performance=True,
        check_retention_policies=True
    )
)