How Semantica Manages State and Memory: A Deep Dive into AgentMemory's Three-Layer Architecture
Semantica uses a hierarchical, retrieval‑augmented memory system called AgentMemory that combines short-term memory, long-term vector storage, and knowledge‑graph integration to manage agent state across interactions.
Modern AI agents require sophisticated memory mechanisms to maintain context, learn from past interactions, and reason over accumulated knowledge. In the semantica-agi/semantica repository, the AgentMemory class in semantica/context/agent_memory.py implements exactly such a system. This article examines how Semantica manages state and memory through its three-layer architecture, with practical code examples from the source.
The Three-Layer Memory Architecture
AgentMemory organizes information across three specialized layers, each optimized for different access patterns and retention requirements.
Short-Term Memory: Fast, Recent Context
The short-term memory layer maintains recent items in an in-memory list for immediate retrieval. According to the source code at lines 11–13, this is implemented as:
self.short_term_memory: List[MemoryItem]
This layer supports fast keyword-based search via _search_short_term and token-based pruning through _prune_short_term_memory (lines 89–112). The short-term buffer enforces configurable count and token limits to prevent unbounded growth, automatically pruning older entries when thresholds are exceeded.
Long-Term Memory: Semantic Persistence
The long-term memory layer stores semantic embeddings in a pluggable vector store backend. As implemented in lines 98–100 and 61–66:
self.vector_store # configurable: in-memory, SQLite, Qdrant, Pinecone, etc.
The _store_memory_vector method persists embeddings, while the retrieve method performs vector-similarity search with optional keyword overlap fallback. This design allows Semantica to scale from prototype deployments using in-memory storage to production systems with managed vector databases.
Knowledge Graph Integration: Entity-Centric Reasoning
The knowledge-graph layer extracts and stores entities and relationships from memories, enabling structural queries. Lines 90–92 define:
self.knowledge_graph # graph store with add_nodes/add_edges API
The _update_knowledge_graph method (lines 770–789) populates the graph with extracted structure, supporting queries like "find all memories involving entity X" through methods such as find_by_entity().
Core Memory Operations
Storing Memories
The store() method (lines 58–67, 69–89) orchestrates the entire storage pipeline:
- Creates a
MemoryItemwith content and metadata - Appends to
short_term_memory - Optionally persists vector embedding in
vector_store - Pushes entities/relationships to
knowledge_graph - Updates statistics and applies retention policy
from semantica.context import AgentMemory
from semantica.vector_store import VectorStore
from semantica.kg import KnowledgeGraph
# Initialize components
vector_store = VectorStore(backend="inmemory", dimension=384)
knowledge_graph = KnowledgeGraph()
# Create the memory manager
memory = AgentMemory(vector_store=vector_store, knowledge_graph=knowledge_graph)
# Store a conversation turn with extracted structure
mem_id = memory.store(
"User asked about Python decorators",
metadata={"type": "conversation", "conversation_id": "conv_01"},
entities=[{"id": "python", "type": "language"}],
relationships=[{"source_id": "python", "target_id": "decorator", "type": "related_to"}],
)
Retrieving Memories
The retrieve() method (lines 24–31, 61–67) implements a cascading search strategy:
- First: Search
short_term_memoryfor recent matches - Second: Query
vector_storefor semantic similarity - Fallback: Use keyword overlap if vector search returns insufficient results
- Finally: Apply filters, rank by relevance score, and return top results
# Retrieve semantically relevant memories
results = memory.retrieve("Explain decorators in Python", max_results=3)
for r in results:
print(r["content"], r["score"])
# Get conversation history
conv_history = memory.get_conversation_history(conversation_id="conv_01")
Retention and Lifecycle Management
Semantica's memory system implements automatic lifecycle management to balance completeness with efficiency.
Retention Policies
The _apply_retention_policy method (lines 15–17) deletes items older than a configurable number of days from persistent storage. This prevents indefinite accumulation while respecting compliance requirements.
Short-Term Pruning
The _prune_short_term_memory method (lines 34–41) enforces hard limits on buffer size:
- Maximum item count
- Maximum token count
When exceeded, it removes oldest entries first, ensuring the short-term layer remains performant.
Introspection and Monitoring
AgentMemory provides operational visibility through multiple APIs:
| Method | Purpose | Location |
|---|---|---|
get_statistics() |
Aggregate counters (total items, per-type breakdowns) | lines 48–52 |
list() |
Enumerate memories with filtering | lines 62–68 |
get_by_conversation() |
Retrieve conversation-scoped history | related query APIs |
find_by_entity() |
Graph-traversal queries | entity-centric lookup |
These methods enable debugging, auditing, and dynamic memory management in production deployments.
Key Implementation Files
| File | Role |
|---|---|
semantica/context/agent_memory.py |
Central memory manager implementing all three layers |
semantica/vector_store/vector_store.py |
Abstract interface for vector store backends |
semantica/kg/temporal_model.py |
Knowledge graph structures for entity/relationship storage |
semantica/utils/progress_tracker.py |
Tracks embedding generation and indexing operations |
semantica/utils/logging.py |
Structured logging throughout the memory subsystem |
Summary
- Three-layer hierarchy:
AgentMemorycombines fast short-term buffer, scalable vector storage, and structured knowledge graph - Unified storage API: Single
store()call propagates data to all relevant layers - Cascading retrieval:
retrieve()searches short-term first, then semantic vectors, with keyword fallback - Automatic lifecycle: Configurable retention policies and pruning keep memory bounded
- Pluggable backends: Vector stores (in-memory, SQLite, Qdrant, Pinecone) and graph stores are interchangeable
- Operational visibility: Statistics, conversation history, and entity queries support production monitoring
Frequently Asked Questions
What vector store backends does Semantica support?
AgentMemory accepts any implementation of the VectorStore abstract interface defined in semantica/vector_store/vector_store.py. The repository includes support for in-memory, SQLite, Qdrant, and Pinecone backends. You initialize the desired backend and pass it to AgentMemory(vector_store=...).
How does Semantica decide what to store in the knowledge graph?
The _update_knowledge_graph method (lines 770–789) receives entities and relationships extracted from memory content during store() calls. These become nodes and edges in the graph. Extraction logic typically runs in upstream components; AgentMemory focuses on persistence and retrieval of this structured data.
Can I disable certain memory layers?
Yes. The AgentMemory constructor accepts optional vector_store and knowledge_graph parameters. Passing None disables the corresponding layer—operations depending on that layer will gracefully degrade or skip. Short-term memory always operates since it requires no external dependencies.
How do retention policies interact with the knowledge graph?
The _apply_retention_policy removes time-expired items from vector store and metadata storage. Knowledge graph cleanup depends on your graph store implementation—AgentMemory pushes updates to the graph but does not automatically prune stale entities. Implement custom logic if your use case requires graph garbage collection.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →