# How to Build and Query Context Graphs for AI Agent Memory with Semantica

> Learn to build and query context graphs for AI agent memory using Semantica. Replace flat vector stores with advanced knowledge graphs and multi-hop Graph-RAG retrieval for better AI performance.

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

---

**Semantica's `ContextGraph` and `GraphBuilder` provide a structured knowledge graph system for AI agents that replaces flat vector stores with nodes, edges, and multi-hop Graph-RAG retrieval.**

The semantica-agi/semantica repository implements a complete pipeline for agent memory based on context graphs rather than simple embeddings. This article explains how to construct these graphs from raw text and query them using the Graph-RAG pattern implemented in `AgnoKnowledgeGraph`.

## Core Components for Context Graph Memory

Four primary classes work together to provide graph-based agent memory in Semantica:

| Component | Responsibility | Source Location |
|-----------|--------------|---------------|
| **`ContextGraph`** | In-memory graph storage with nodes, edges, and analytics (`get_neighbors()`, temporal/causal features) | [`semantica/context/context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/context/context_graph.py) (line 22) |
| **`GraphBuilder`** | Converts extracted entities and relations into graph structure; handles merging and conflict resolution | [`semantica/kg/graph_builder.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/kg/graph_builder.py) (line 30) |
| **`AgnoKnowledgeGraph`** | Agno-compatible wrapper providing `load()` and Graph-RAG `search()` — wires NER, relation extraction, and vector retrieval | [`integrations/agno/knowledge_graph.py`](https://github.com/semantica-agi/semantica/blob/main/integrations/agno/knowledge_graph.py) (line 90) |
| **`AgentContext`** | Thin vector-store wrapper for first-hop retrieval before graph expansion | Imported in [`knowledge_graph.py`](https://github.com/semantica-agi/semantica/blob/main/knowledge_graph.py) (lines 40-44) |

## Building a Context Graph from Raw Text

### Step 1: Initialize the Builder and Graph

Start by creating a `GraphBuilder` with your preferred configuration flags, then instantiate a `ContextGraph`:

```python
from semantica.kg import GraphBuilder
from semantica.context import ContextGraph

builder = GraphBuilder(merge_entities=True, resolve_conflicts=True)
graph = ContextGraph()

```

Setting `merge_entities=True` enables deduplication of entities across documents. The `resolve_conflicts=True` flag activates the conflict resolution strategy for contradictory relationship assertions.

### Step 2: Wire the Builder to Graph Storage

Connect the builder to your graph instance so constructed entities and edges populate storage:

```python
builder.graph_store = graph  # Internal wiring — see knowledge_graph.py lines 48-50

```

### Step 3: Ingest Documents with NER and Relation Extraction

The builder consumes source dictionaries containing text and optional pre-extracted entities. In practice, `AgnoKnowledgeGraph._ingest_text()` (lines 80-110) automates the extraction pipeline:

```python
from semantica.semantic_extract import NERExtractor, RelationExtractor

ner = NERExtractor()
rel = RelationExtractor()

documents = [
    {
        "text": "Acme Corp acquired Beta Ltd in 2022.",
        "entities": [],
        "relationships": [],
        "source": "press_release.txt"
    }
]

# The builder populates the graph with nodes and temporal edges

builder.build(documents)

```

The `_ingest_text()` method performs four operations: chunking text, running `NERExtractor` (`self._ner`) and `RelationExtractor` (`self._rel`), aggregating results, and calling `self._graph_builder.build()` at line 98.

### Step 4: Configure Persistence (Optional)

For production deployments, pass a Neo4j connection URI instead of using the default in-memory store:

```python
graph = ContextGraph(graph_store_uri="bolt://localhost:7687")

```

The graph backend is swappable — FalkorDB and other stores implementing the same interface work without code changes.

## Querying Context Graphs with Graph-RAG

The `AgnoKnowledgeGraph.search()` method implements multi-hop retrieval that augments vector search with structured graph context.

### The Graph-RAG Pipeline

| Stage | Implementation | Code Reference |
|-------|---------------|----------------|
| **Vector-first retrieval** | `AgentContext.retrieve()` fetches similar chunks | [`knowledge_graph.py`](https://github.com/semantica-agi/semantica/blob/main/knowledge_graph.py) lines 94-100 |
| **Entity extraction** | Retrieved items expose `entities` list for graph lookup | `_graph_context_for(entities)` lines 54-71 |
| **Context augmentation** | Neighbor summary appended under `[Graph context]` heading | Lines 106-108 |
| **Keyword fallback** | Scored search over cached `_docs` if vector retrieval fails | Lines 114-136 |

### Direct Graph Queries

For programmatic access to neighbor relationships, call `get_graph_context()` or `get_neighbors()` on any `ContextGraph` instance:

```python

# Get structured neighbor listing for a specific entity

print(graph.get_graph_context("Acme Corp"))

# Or query neighbors directly with hop control

neighbors = graph.get_neighbors("Acme Corp", hops=2)

```

Sample output:

```

Entity: Acme Corp
  --[acquired]--> Beta Ltd (type: organization)
  --[located_in]--> New York (type: location)

```

## Complete Working Example

This standalone script demonstrates building a context graph and querying it through the Graph-RAG interface:

```python
#!/usr/bin/env python
"""
Build and query a ContextGraph for AI agent memory (Semantica + Agno).
"""

from semantica.kg import GraphBuilder
from semantica.context import ContextGraph
from semantica.semantic_extract import NERExtractor, RelationExtractor
from semantica.vector_store import VectorStore
from semantica.context import AgentContext

# Initialize components

graph = ContextGraph()                               # In-memory graph

builder = GraphBuilder(merge_entities=True)          # Entity deduplication enabled

ner = NERExtractor()                                 # spaCy-based NER

rel = RelationExtractor()                            # Rule-based relation extraction

# Wire builder to graph storage

builder.graph_store = graph

# Prepare and ingest documents

documents = [
    "OpenAI launched GPT-4 in March 2023.",
    "Semantica provides a knowledge-graph pipeline for LLM-augmented agents."
]

for i, txt in enumerate(documents):
    builder.build([{"text": txt, "source": f"doc_{i}.txt"}])

# Set up vector store for first-hop retrieval

vector = VectorStore(backend="faiss")
agent_ctx = AgentContext(
    vector_store=vector,
    knowledge_graph=graph,
    decision_tracking=False
)

# Store raw texts for later retrieval

for txt in documents:
    agent_ctx.store(txt, conversation_id="example")

# Graph-RAG search implementation

def graph_rag(query: str, top_k: int = 3):
    """Two-step retrieval: vector search → graph neighbor expansion."""
    results = agent_ctx.retrieve(query, max_results=top_k)
    
    enriched = []
    for item in results:
        entities = item.get("entities", [])
        extra = "\n".join(
            f"- {e} → {', '.join(n['node_id'] for n in graph.get_neighbors(e, hops=1)[:2])}"
            for e in entities[:3]
        )
        content = item["content"]
        if extra:
            content += f"\n\n[Graph context]\n{extra}"
        enriched.append(content)
    return enriched

# Execute query

print("\n--- Query: 'What did OpenAI release?' ---")
for doc in graph_rag("What did OpenAI release?"):
    print("\n--- Result ---")
    print(doc)

```

## Advanced Graph Features

The `ContextGraph` implementation in [`context_graph.py`](https://github.com/semantica-agi/semantica/blob/main/context_graph.py) provides capabilities beyond basic storage:

- **Temporal reasoning** — Edges support timestamp fields for time-series queries
- **Causal analysis** — Relationship types include `causes`, `enables`, `prevents`
- **Community detection** — Built-in algorithms for clustering related entities
- **Multi-hop traversal** — `get_neighbors()` supports arbitrary hop counts with cycle detection

These features enable agents to answer questions requiring structured reasoning: "What acquisitions happened before 2023?" or "Which entities are in the same corporate network as Acme Corp?"

## Summary

- **`ContextGraph`** provides the core graph storage with analytics and temporal support
- **`GraphBuilder`** transforms extracted entities and relations into structured graphs
- **`AgnoKnowledgeGraph`** wraps the pipeline for Agno agent compatibility with Graph-RAG `search()`
- **Graph-RAG retrieval** combines vector similarity with multi-hop graph traversal for richer context
- **Persistence options** scale from in-memory prototypes to Neo4j/FalkorDB backends

## Frequently Asked Questions

### What is the difference between ContextGraph and a standard vector store?

A **vector store** retrieves documents by embedding similarity alone. **ContextGraph** preserves explicit entity relationships as edges, enabling multi-hop reasoning: if you ask "Who founded the company that acquired Beta Ltd?", the graph can traverse `founder_of` and `acquired` edges to return the answer. Vector stores cannot resolve such queries without explicit mention in retrieved text.

### How does entity merging work in GraphBuilder?

When `merge_entities=True`, the `GraphBuilder` maintains an internal entity resolution index. Identical or near-identical entity mentions (e.g., "Apple Inc." and "Apple") are canonicalized to a single node with aggregated sources. Conflicting attributes trigger the resolution strategy specified by `resolve_conflicts` — typically preferring the most recent or most frequently attested value.

### Can I use ContextGraph without the Agno framework?

Yes. The `ContextGraph` and `GraphBuilder` classes have no Agno dependencies. You can construct graphs directly via `add_nodes()` and `add_edges()`, query with `get_neighbors()`, and implement custom retrieval patterns. The `AgnoKnowledgeGraph` wrapper in [`integrations/agno/knowledge_graph.py`](https://github.com/semantica-agi/semantica/blob/main/integrations/agno/knowledge_graph.py) simply provides convenience methods for agents following the Agno `AgentKnowledge` protocol.

### What extraction models power the NER and relation extraction?

The `NERExtractor` in [`semantica/semantic_extract/ner_extractor.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/semantic_extract/ner_extractor.py) uses spaCy with a transformer-based model for domain-agnostic entity recognition. The `RelationExtractor` in [`relation_extractor.py`](https://github.com/semantica-agi/semantica/blob/main/relation_extractor.py) implements rule-based patterns augmented with dependency parse features. Both are replaceable — pass custom extractors to `GraphBuilder` or `AgnoKnowledgeGraph` constructor parameters.