Asterix agents have a sophisticated memory system that allows them to remember, learn, and persist their knowledge across sessions. The memory system consists of memory blocks, archival storage, and conversation history.
- Overview
- Memory Blocks
- Built-in Memory Tools
- Automatic Memory Management
- Direct Memory Access
- Archival Memory
- Conversation Search
The Asterix memory system has three layers:
- Memory Blocks - Short-term, editable memory that agents can read and write
- Archival Memory - Long-term storage in Qdrant with semantic search
- Conversation History - Complete record of all interactions
┌─────────────────┐
│ Memory Blocks │ ← Short-term, editable (task, notes, etc.)
└─────────────────┘
↓ (when full)
┌─────────────────┐
│ Archival Memory │ ← Long-term, searchable (Qdrant)
└─────────────────┘
+
┌─────────────────┐
│ Conversation │ ← Full interaction history
│ History │
└─────────────────┘
Memory blocks are editable sections of the agent's short-term memory. Each block has:
- Name - Identifier (e.g., "task", "notes", "user_prefs")
- Size - Maximum tokens before eviction
- Priority - Lower priority blocks are evicted first
- Description - Purpose of the block
from asterix import Agent, BlockConfig
agent = Agent(
blocks={
"task": BlockConfig(
size=2000, # Max tokens before eviction
priority=1, # Lower = evicted first
description="Current task context"
),
"user_prefs": BlockConfig(
size=500,
priority=5, # High priority = rarely evicted
description="User preferences and settings"
),
"notes": BlockConfig(
size=1000,
priority=2,
description="Important notes and reminders"
)
},
model="openai/gpt-4o-mini"
)- Task blocks - Use for current work context (priority: 1-2)
- User preferences - Keep user settings (priority: 4-5)
- Notes - Temporary information (priority: 2-3)
- Context - Relevant background info (priority: 2-3)
Agents have 5 built-in tools for managing their memory:
Add content to a memory block.
# Agent automatically calls this when needed
agent.chat("Remember that I prefer Python over JavaScript")
# The agent uses: core_memory_append(block="user_prefs", content="User prefers Python over JavaScript")Replace content in a memory block.
# Agent automatically calls this when needed
agent.chat("Actually, I prefer TypeScript now")
# The agent uses: core_memory_replace(
# block="user_prefs",
# old_content="User prefers Python",
# new_content="User prefers TypeScript"
# )Store information in Qdrant for long-term retrieval.
# Agent stores important information for later
# archival_memory_insert(content="Project X uses PostgreSQL database with 10M records")Search archived memories semantically.
# Agent searches when it needs to recall something
# archival_memory_search(query="database details", k=5)Search conversation history.
# Agent searches past conversations
# conversation_search(query="API key", k=3)Note: These tools are called automatically by the agent. You don't need to invoke them manually.
When a memory block exceeds its token limit, Asterix automatically:
- Summarizes the content using the LLM
- Archives the full content in Qdrant
- Replaces the block with the summary
- Makes it searchable via
archival_memory_search
# Block "task" has 2000 token limit
# Current content: 1950 tokens
# Agent tries to append 200 tokens → Exceeds limit!
# Asterix automatically:
# 1. Summarizes the 1950 token content → 500 tokens
# 2. Archives original 1950 tokens in Qdrant
# 3. Replaces block with 500 token summary
# 4. Appends new 200 tokens
# Result: Block now has 700 tokensYou can configure how memory is managed:
from asterix import Agent, MemoryConfig
agent = Agent(
...,
memory_config=MemoryConfig(
eviction_strategy="summarize_and_archive", # Default
context_window_threshold=0.85 # Trigger at 85% full
)
)Available strategies:
summarize_and_archive- Summarize and store in Qdrant (default)archive_only- Store in Qdrant without summarizingdiscard- Remove oldest content (not recommended)
You can manually access and update memory blocks:
# Get all memory blocks
memory = agent.get_memory()
print(memory["task"])
print(memory["notes"])
# Access specific block
task_content = memory.get("task", "")# Update a memory block directly
agent.update_memory("task", "New task: Build user authentication system")
# Clear a memory block
agent.update_memory("notes", "")# Manually search archived memories
tool_result = agent._tool_registry.execute_tool(
"archival_memory_search",
query="user preferences",
k=5
)
print(tool_result)Archival memory uses Qdrant for long-term, semantic storage.
Set up Qdrant in your .env:
QDRANT_URL=https://your-cluster.cloud.qdrant.io:6333
QDRANT_API_KEY=your-qdrant-api-key- Storage - Content is embedded using OpenAI embeddings
- Indexing - Vectors stored in Qdrant collection
- Retrieval - Semantic search finds relevant memories
- Context - Retrieved memories are added to agent context
Unlike keyword search, semantic search understands meaning:
# Stored: "User prefers Python for data analysis"
# Search: "programming language preference"
# ✅ Finds the memory (semantically similar)
# Search: "favorite food"
# ❌ Doesn't find it (not semantically related)Search through the agent's conversation history:
# Agent automatically searches when needed
# conversation_search(query="API key location", k=3)
# Returns the 3 most relevant conversation turns- Recall previous instructions
- Find mentioned file paths
- Remember user preferences from earlier in conversation
- Locate specific information discussed before
┌──────────────────────────────────────┐
│ Agent Context │
├──────────────────────────────────────┤
│ Memory Blocks (Short-term) │
│ ┌────────┐ ┌────────┐ ┌──────────┐ │
│ │ task │ │ notes │ │user_prefs││ │
│ └────────┘ └────────┘ └──────────┘ │
│ ↓ │
│ When block is full: summarize │
│ ↓ │
│ ┌────────────────────────────────┐ │
│ │ Archival Memory (Qdrant) │ │
│ │ - Semantic search │ │
│ │ - Long-term storage │ │
│ └────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ Conversation History │ │
│ │ - Full interaction record │ │
│ │ - Keyword search │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────┘
- Small blocks (500-1000 tokens) - Frequently changing info
- Medium blocks (1000-2000 tokens) - Current work context
- Large blocks (2000-3000 tokens) - Comprehensive background
- Priority 5 - Critical info (user preferences, requirements)
- Priority 3-4 - Important context
- Priority 1-2 - Temporary working memory
| Memory Type | Use For | Lifespan |
|---|---|---|
| Blocks | Current task, active context | Until evicted |
| Archival | Long-term facts, important info | Persistent |
| Conversation | Recent interactions | Session |
- Tool System - Memory tools documentation
- Storage Backends - Persisting memory across sessions
- Configuration - Memory configuration options