How Semantica's AgentContext Combines Vector Search and Graph Traversal for Hybrid Retrieval
The AgentContext class unifies dense vector similarity search with knowledge graph traversal through a ContextRetriever that blends cosine-based nearest-neighbor results with graph-expanded entities using a configurable hybrid_alpha weighting coefficient.
The semantica-agi/semantica repository implements a sophisticated hybrid retrieval system that allows AI agents to leverage both semantic embedding spaces and structured graph relationships. By combining these two complementary approaches, Semantica enables agents to retrieve context that matches vector similarity while also capturing relational knowledge through graph hops.
Architecture of the Hybrid Retrieval System
The hybrid retrieval capability rests on three composable components that work together inside AgentContext.
Core Components
-
VectorStore: Stores dense embeddings of raw text, decisions, and artifacts. Provides fast semantic similarity via cosine-based nearest-neighbor search.
-
Knowledge Graph (
ContextGraph): Stores entities, relationships, and bi-temporal facts. Enables graph-native lookups including BFS/DFS traversal, centrality analysis, and path-finding. -
ContextRetriever: Orchestrates the hybrid pipeline. This component queries the vector store, optionally expands results by traversing the graph up to
max_expansion_hops, and normalizes scores from both sources according to thehybrid_alphaparameter.
In semantica/context/agent_context.py (lines 90-105), the constructor initializes these components:
def __init__(self, vector_store, knowledge_graph=None, **retriever_config):
self._vector_store = vector_store
self._knowledge_graph = knowledge_graph
if knowledge_graph:
self._retriever = ContextRetriever(**retriever_config)
The Hybrid Retrieval Workflow
The retrieval process follows a structured pipeline that fuses vector and graph signals into a unified relevance score.
Initialization and Configuration
When instantiating AgentContext, the retriever configuration determines how vector and graph results blend. According to semantica/context/agent_context.py (lines 98-110), the system accepts:
use_graph_expansion(defaultTrue): Controls whether graph hops are performedmax_expansion_hops(default2): The depth of BFS expansionhybrid_alpha(default0.5): The blend factor where0favors pure vector scores and1favors pure graph signals
Vector Search Phase
The retrieval begins with semantic similarity search. As documented in semantica/context/context_retriever.py (lines 11-15), the ContextRetriever.retrieve method first calls the vector store's search method to obtain the top-k nearest neighbors based on cosine similarity.
Graph Expansion Phase
If use_graph_expansion is enabled, the retriever invokes graph utilities including PathFinder, CentralityCalculator, and other KG analytics tools to explore related entities up to the configured hop limit (self.max_expansion_hops). This expansion captures structurally relevant nodes that may not match the vector query semantically but are relationally significant.
Score Normalization and Blending
Both vector and graph results undergo normalization to a 0-1 range. The final relevance score is computed using the formula found in semantica/context/context_retriever.py (lines 31-34):
final_score = hybrid_alpha * graph_score + (1 - hybrid_alpha) * vector_score
The HybridSimilarityCalculator class (instantiated in context_retriever.py lines 58-60) handles this weighted combination, allowing developers to tune whether semantic similarity or graph structure dominates the ranking.
Decision-Aware Embedding Pipeline
When decision_tracking is enabled, the system enriches vector embeddings with graph-derived features before storage. In semantica/context/context_retriever.py (lines 74-80), the DecisionEmbeddingPipeline incorporates node2vec embeddings, centrality metrics, and community tags into the vector representation. This allows subsequent retrieval to benefit from both semantic and structural signals even during the initial vector search phase.
Practical Implementation
Here is a complete implementation demonstrating hybrid retrieval configuration:
from semantica.context import AgentContext, ContextGraph
from semantica.vector_store import VectorStore
# Initialize components
vs = VectorStore(backend="faiss", dimension=1536)
kg = ContextGraph(advanced_analytics=True)
# Configure hybrid retrieval
ctx = AgentContext(
vector_store=vs,
knowledge_graph=kg,
graph_expansion=True,
max_expansion_hops=3,
hybrid_alpha=0.6, # 60% graph influence, 40% vector
decision_tracking=True,
)
# Store content (vectorized and graphed)
mem_id = ctx.store(
"Alice approved the Acme renewal in Q1 2024",
conversation_id="conv_001",
extract_entities=True,
extract_relationships=True,
)
# Hybrid retrieval
results = ctx.retrieve("Who approved the Acme contract?", max_results=5)
for r in results:
print(f"[{r.score:.2f}] {r.content}")
print(f" ↳ Related entities: {[e['id'] for e in r.related_entities]}")
The ctx.retrieve call (implemented in semantica/context/agent_context.py lines 78-86) forwards to self._retriever.retrieve, returning RetrievedContext objects containing merged content, blended relevance scores, and related graph entities.
Summary
- AgentContext serves as the high-level façade that composes
VectorStore,ContextGraph, andContextRetrievercomponents. - Hybrid retrieval works by executing vector similarity search first, then expanding results via graph traversal up to
max_expansion_hops. - Score blending uses the formula
hybrid_alpha * graph_score + (1 - hybrid_alpha) * vector_scoreto weigh semantic versus structural relevance. - Decision-aware embeddings enrich vectors with graph features (centrality, communities) when
decision_trackingis enabled. - Configuration occurs at initialization through parameters like
hybrid_alpha,use_graph_expansion, andmax_expansion_hopsinagent_context.py.
Frequently Asked Questions
How does the hybrid_alpha parameter affect search results?
The hybrid_alpha parameter controls the weighting between vector similarity and graph structure in the final ranking. Set to 0.5 by default, values closer to 1.0 prioritize graph relationships and traversal depth, while values closer to 0.0 favor pure semantic similarity from the vector store. This allows tuning for domain-specific needs where either relational structure or semantic meaning is more predictive of relevance.
What graph algorithms does Semantica use during the expansion phase?
During graph expansion, the ContextRetriever instantiates several algorithm classes including PathFinder for BFS/DFS traversal and CentralityCalculator for network analysis (see context_retriever.py lines 62-68). These utilities enable exploration of entity relationships, calculation of node importance, and detection of community structures that inform the retrieval scoring.
Can I use AgentContext with only vector search and no graph component?
Yes. The knowledge_graph parameter is optional in the AgentContext constructor. If no graph is provided, the system operates in vector-only mode without invoking the ContextRetriever's graph expansion logic. However, enabling the graph requires setting graph_expansion=True and providing a ContextGraph instance to unlock hybrid retrieval capabilities.
Where does the actual retrieval method forward the query?
The AgentContext.retrieve method (lines 78-86 in agent_context.py) forwards the query to self._retriever.retrieve, which implements the hybrid pipeline in semantica/context/context_retriever.py. This design keeps the high-level API clean while delegating the complex orchestration of vector and graph operations to the specialized retriever component.
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 →