# How to Implement Persistent Agent Memory Using ContextGraph in Semantica

> Implement persistent agent memory in Semantica using ContextGraph and AgentMemory. Learn to save and load agent state with JSON for seamless continuity across restarts. Master ContextGraph for robust AI memory.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-08-16

---

**Persistent agent memory in Semantica is achieved by combining `AgentMemory` for conversational fragments with `ContextGraph` for entity relationships and decisions, using JSON serialization methods `save()`/`load()` and `save_to_file()`/`load_from_file()` to restore complete agent state across restarts.**

Semantica's architecture deliberately separates **short-term RAG memory** from **persistent knowledge storage**. This design lets agents retain learned entities, relationship patterns, and decision history even after process termination. The `ContextGraph` class in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) serves as the backbone for this persistence layer, working alongside `AgentMemory` to create a complete, reloadable cognitive state.

---

## Core Components of Persistent Memory

Three integrated classes handle persistence in Semantica:

| Component | Source File | Persistence Role |
|-----------|-------------|------------------|
| **AgentMemory** | [`semantica/context/agent_memory.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/agent_memory.py) | Stores conversational fragments, vector embeddings, and entity links with `save()`/`load()` methods |
| **ContextGraph** | [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) | Maintains entity/relationship graph and decision nodes with `save_to_file()`/`load_from_file()` methods |
| **AgentContext** | [`semantica/context/agent_context.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/agent_context.py) | High-level façade that wires memory and graph together; persistence flows through its composed components |

Both `AgentMemory` and `ContextGraph` use **JSON serialization** exclusively—no pickles for security. This makes persisted states version-controllable, portable across machines, and cloud-cacheable.

---

## Initializing ContextGraph for Persistent Memory

To enable persistence, instantiate `ContextGraph` with analytics capabilities and pass it to `AgentContext`:

```python
from semantica.context import AgentContext, ContextGraph
from semantica.vector_store import SimpleInMemoryStore

# Create the vector store backend

vector_store = SimpleInMemoryStore()

# Initialize ContextGraph with advanced analytics

kg = ContextGraph(advanced_analytics=True)  # Enables centrality, community detection

# Create the agent context with decision tracking

ctx = AgentContext(
    vector_store=vector_store,
    knowledge_graph=kg,
    decision_tracking=True,      # Required to use ContextGraph decision APIs

    retention_days=60,           # Automatic memory expiration

)

```

Setting `advanced_analytics=True` in `ContextGraph.__init__()` enables graph algorithms (degree centrality, community detection) that help the agent rank entity importance and identify knowledge clusters.

---

## Storing Memories with Entity Extraction

The `AgentContext.store()` method forwards to `AgentMemory.store()`, which performs three operations: buffering in short-term memory, indexing in the vector store, and updating the `ContextGraph` with extracted entities:

```python

# Store a conversational memory with linked entities

mem_id = ctx.store(
    content="User asked how to encrypt data with AES-256",
    metadata={"type": "conversation", "conversation_id": "conv-42"},
    entities=[
        {"id": "aes_256", "type": "algorithm", "text": "AES-256"},
        {"id": "encryption", "type": "concept", "text": "encryption"},
    ],
)

```

The internal `_update_knowledge_graph()` call in `AgentMemory` creates nodes for each entity and links them to the memory item. These entities become addressable in the persistent graph for future retrieval and decision-making.

---

## Recording Decisions in ContextGraph

When `decision_tracking=True`, `AgentContext` exposes `record_decision()` to create causal links between memories and agent actions:

```python
dec_id = ctx.record_decision(
    category="security_policy",
    scenario="data_at_rest",
    reasoning="User wants strong encryption",
    outcome="enable_aes_256",
    confidence=0.97,
    entities=["aes_256"],        # Links decision to existing graph node

)

```

This creates a **decision node** in `ContextGraph` connected to the same entities that appear in memory items. The resulting structure forms a *causal view* of why specific agent actions were taken, queryable via `trace_decision_causality()`.

---

## Persisting Agent State to Disk

To implement true persistence, serialize both components before shutdown:

```python

# Persist AgentMemory (includes items, buffer, vector-ID mappings, statistics)

ctx.memory.save("./persisted_memory")   # Creates agent_memory.json

# Persist ContextGraph (includes nodes, edges, sub-graphs, decision nodes)

ctx.knowledge_graph.save_to_file("./graph.json")

```

Both calls produce **self-contained JSON files**:

- **`AgentMemory.save()`** in [`semantica/context/agent_memory.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/agent_memory.py) writes: items dictionary, short-term deque, vector-ID map, and runtime statistics
- **`ContextGraph.save_to_file()`** in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) writes: nodes, edges, linked sub-graphs, and analytics cache

---

## Restoring Persistent Memory After Restart

The reload sequence recreates the identical cognitive state:

```python
from semantica.context import AgentContext, ContextGraph
from semantica.vector_store import SimpleInMemoryStore

# Reinitialize with the same vector store backend

vector_store = SimpleInMemoryStore()

# Restore the ContextGraph first

kg = ContextGraph()
kg.load_from_file("./graph.json")   # Rebuilds entity/decision graph

# Create AgentContext with restored graph

ctx = AgentContext(
    vector_store=vector_store,
    knowledge_graph=kg,
    decision_tracking=True,
)

# Restore AgentMemory (must happen after AgentContext creation)

ctx.memory.load("./persisted_memory")   # Restores all memories and mappings

# Agent now retains full prior state: conversations, entities, and decisions

```

**Critical restoration order**: `ContextGraph` must be loaded before `AgentContext` construction, but `AgentMemory.load()` must occur after `AgentContext` exists since `AgentContext` creates and holds the `AgentMemory` instance.

---

## Querying Persisted Knowledge Graph Data

Once restored, combine semantic retrieval with graph analytics:

```python

# Hybrid RAG + graph context retrieval

results = ctx.retrieve(
    "What encryption method should I use?",
    max_results=5,
    min_score=0.2,
    type="conversation",
)

# Rank results by entity centrality in the knowledge graph

for r in results:
    for entity in r.get("entities", []):
        centrality = ctx.knowledge_graph.get_node_centrality(entity["id"])
        print(f"{entity['text']}: degree={centrality['degree']}")

```

The `get_node_centrality()` method—available when `advanced_analytics=True`—returns degree, betweenness, and eigenvector centrality scores that help the agent prioritize more "important" entities in reasoning.

---

## Tracing Decision Causality

Leverage `ContextGraph` to explain why specific decisions were made:

```python

# Trace the causal chain for a recorded decision

causal_chain = ctx.knowledge_graph.trace_decision_causality(dec_id)

for hop in causal_chain:
    print(f"Node: {hop['node_id']}, Reason: {hop['reason']}")

```

This traversal follows edges from decision nodes through supporting entities and prerequisite memories, enabling explainable agent behavior audits.

---

## Summary

- **Persistent agent memory** requires both `AgentMemory` (conversational data) and `ContextGraph` (entity/decision graph) working together
- **JSON serialization** via `save()`/`load()` and `save_to_file()`/`load_from_file()` provides secure, portable, version-controllable persistence
- **Entity linking** during `store()` operations creates the bridge between raw memory and structured graph knowledge
- **Decision tracking** with `record_decision()` builds causal, explainable agent action histories
- **Restoration order matters**: load `ContextGraph` before `AgentContext`, then `AgentMemory` after

---

## Frequently Asked Questions

### What file formats does Semantica use for persistent memory?

Semantica uses **JSON exclusively** for all persistence. Both `AgentMemory.save()` and `ContextGraph.save_to_file()` produce JSON outputs. This design avoids pickle serialization for security (preventing arbitrary code execution) and enables human inspection, version control, and cross-platform portability.

### Can I use a different vector store with persisted ContextGraph?

Yes. The vector store and `ContextGraph` are **loosely coupled**. You can persist `AgentMemory` and `ContextGraph` independently, then restore them with any vector store implementation that matches your original schema. However, `AgentMemory` maintains an internal `vector_id_map` that must remain consistent with your vector store's indexing—use the same backend type (e.g., `SimpleInMemoryStore`, Chroma, Pinecone) for reliable retrieval.

### How do I migrate persisted memory between Semantica versions?

Since persistence uses **self-contained JSON**, migrate by: (1) loading with the original version, (2) optionally reprocessing with `AgentContext` methods to update schemas, and (3) saving with the new version. The `ContextGraph` structure in [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) uses standard node/edge dictionaries that remain backward-compatible across minor versions.

### Does ContextGraph persistence include vector embeddings?

No—embeddings are **not stored in `ContextGraph`**. Vector embeddings reside in the configured `vector_store` (passed to `AgentContext`). Persist the vector store separately using its own mechanism (e.g., Chroma's `persist()` or Pinecone's native storage). `AgentMemory` saves only the *mapping* between memory items and vector IDs, not the embeddings themselves.