How to Perform Precedent Search in Semantica: A Complete Guide
Precedent search in Semantica is performed through AgentContext.find_precedents(), which routes to one of three backends—graph traversal, hybrid vector+graph search, or basic category filtering—depending on your configuration.
Semantica provides a unified API for retrieving past decisions relevant to new scenarios. This article explains how precedent search works under the hood, based on the actual implementation in the semantica-agi/semantica repository, and shows you practical code examples for every use case.
Understanding the Three Precedent Search Backends
Semantica implements precedent search across three interchangeable backends. Each offers different trade-offs between speed, accuracy, and implementation complexity.
ContextGraph: Pure Graph Traversal
The ContextGraph class in semantica/context/context_graph.py provides the foundational graph-based approach. Its find_precedents method traverses edges of type PRECEDENT_FOR or PRECEDES to locate related decisions.
Key implementation details:
- Edge detection is case-insensitive:
edge.edge_type.upper()matches both"PRECEDENT_FOR"and the legacy"PRECEDES"spelling (lines 13‑20) - Results are materialized as
Decisionobjects with populated metadata dictionaries - The method accepts a
limitparameter to control result set size
DecisionQuery: Hybrid Vector + Graph Search
The DecisionQuery class in semantica/context/decision_query.py offers the most sophisticated approach through find_precedents_hybrid. This method implements a cascading fallback strategy:
- Vector store hybrid search — semantic similarity via
HybridSearch.search - Enhanced KG graph search — knowledge graph similarity with semantic, structural, centrality, and textual features
- Basic graph scan — simple category-filtered node traversal
Default similarity weights are {"semantic": 0.4, "structural": 0.3, "text": 0.2, "category": 0.1} (lines 97‑102), fully configurable via the similarity_weights parameter.
AgentContext: The Unified Facade
AgentContext in semantica/context/agent_context.py serves as the public entry point. Its find_precedents method inspects self._decision_backend to route requests appropriately:
context_graph→ forwards toContextGraph.find_precedents_by_scenariograph_storewith hybrid enabled → callsDecisionQuery.find_precedents_hybridgraph_storewith hybrid disabled → falls back toDecisionQuery._find_precedents_basic
All paths normalize results to list[Decision] as defined in semantica/context/decision_models.py.
Basic Precedent Search with Default Configuration
Start with the simplest approach: let AgentContext handle backend selection automatically.
from semantica.context.agent_context import AgentContext
ctx = AgentContext() # Initialise with default config
scenario = "Refinance a mortgage loan"
precedents = ctx.find_precedents(
scenario=scenario,
category="mortgage",
limit=5
)
for p in precedents:
print(f"{p.decision_id}: {p.scenario} (score={p.metadata.get('score', 'N/A')})")
This code initializes the context façade, submits a natural language scenario, and retrieves up to 5 relevant prior decisions. The returned Decision objects expose decision_id, scenario, and a metadata dictionary containing scoring information.
Customizing Hybrid Search with Similarity Weights
For fine-grained control over how precedents are ranked, override the default similarity weights when hybrid search is active.
weights = {
"semantic": 0.5,
"structural": 0.2,
"text": 0.2,
"category": 0.1,
}
precedents = ctx.find_precedents(
scenario="Auto insurance claim for a total loss",
limit=3,
use_hybrid_search=True,
similarity_weights=weights
)
This configuration boosts semantic similarity to 50% weight—ideal when your scenario descriptions are rich and you want meaning to dominate over structural or categorical features. The use_hybrid_search=True flag ensures DecisionQuery.find_precedents_hybrid is invoked rather than basic graph traversal.
Direct Graph API Access for Advanced Use Cases
Bypass the façade to work directly with ContextGraph when you need precise control over traversal logic.
from semantica.context.context_graph import ContextGraph
graph = ContextGraph.load_from_store(...)
decision_id = "d12345"
precedents = graph.find_precedents(decision_id, limit=10)
for dec in precedents:
print(dec.scenario, dec.decision_id)
Note this interface accepts a decision_id rather than a natural language scenario. It walks PRECEDENT_FOR / PRECEDES edges where edge.target_id == decision_id, returning source decisions that informed or preceded the specified decision.
Debugging Vector Store Results
Inspect raw vector search output before KG enrichment for troubleshooting or custom tooling.
# Inside a custom tool or debugging session
query = "Supply chain disruption"
vector_results = ctx._decision_query._find_precedents_vector_store(
scenario=query,
category=None,
limit=5,
weights={"semantic": 0.4, "structural": 0.3, "text": 0.2, "category": 0.1}
)
for res in vector_results:
print(res.decision_id, res.metadata["similarity_score"])
This accesses the internal _find_precedents_vector_store helper directly, skipping the enhanced graph search and fallback logic that find_precedents_hybrid normally applies.
Key Implementation Files
| File | Purpose |
|---|---|
semantica/context/context_graph.py |
Core graph representation; ContextGraph.find_precedents follows PRECEDENT_FOR edges |
semantica/context/decision_query.py |
Hybrid search implementation with cascading fallbacks |
semantica/context/agent_context.py |
Public façade routing to appropriate backend |
semantica/context/decision_models.py |
Decision dataclass definition |
Summary
- Precedent search in Semantica is unified under
AgentContext.find_precedents()with three pluggable backends - Graph traversal via
ContextGraphfollowsPRECEDENT_FOR/PRECEDESedges for structure-aware retrieval - Hybrid search via
DecisionQuerycombines vector similarity with knowledge graph features, degrading gracefully on failure - Similarity weights are fully configurable: semantic, structural, text, and category components sum to relevance scores
- Result normalization ensures all paths return
list[Decision]with consistent metadata fields
Frequently Asked Questions
How do I choose between graph and hybrid precedent search?
Use graph search when your decisions have explicit precedent relationships already encoded as edges, or when you need deterministic, explainable traversal. Use hybrid search when scenarios are described in natural language and semantic similarity matters. Hybrid search excels when precedent relationships aren't explicitly recorded but emerge from content similarity.
What happens if the vector store is unavailable?
According to the source code in semantica/context/decision_query.py (lines 15‑31), find_precedents_hybrid implements graceful degradation: it catches vector store failures and automatically falls back to enhanced graph search, then to basic category-filtered graph traversal if needed. Your application continues functioning without manual intervention.
Can I search precedents by decision ID instead of scenario text?
Yes, but you must use the direct graph API. The AgentContext.find_precedents() façade accepts scenarios only. Call ContextGraph.find_precedents(decision_id, ...) directly after loading your graph via ContextGraph.load_from_store(). This interface is designed for cases where you already know a specific decision and want its antecedents.
Are prelude and precedent searches the same thing in Semantica?
No. Precedents are prior decisions that inform current choices—retrieved via the methods described here. Preludes are preparatory context or setup steps. The codebase uses distinct edge types and search methods for each concept. Precedent edges are labeled PRECEDENT_FOR or PRECEDES; search for these specifically when implementing decision audit trails or case-based reasoning workflows.
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 →