How Semantica Transforms Unstructured Data into Knowledge Graphs: A Complete Technical Guide
Semantica converts raw text into structured knowledge graphs through a four-stage pipeline combining semantic extraction, coreference resolution, event detection, and graph construction.
The semantica-agi/semantica open-source project provides a modular, production-ready system for transforming free-form documents into queryable graph structures. This article examines the exact mechanisms—source file by source file—that enable this conversion.
The Core Pipeline Architecture
Semantica's transformation process operates as a layered pipeline where each stage refines unstructured input into increasingly structured representations. The pipeline is orchestrated through the Micro-Control-Plane (MCP) and exposed via tool functions in semantica_mcp/mcp/tools/extraction.py.
The four stages execute sequentially:
- Named Entity Recognition (NER) identifies atomic entities
- Coreference Resolution collapses multiple mentions
- Relation & Event Extraction discovers connections and temporal structures
- Graph Construction materializes nodes, edges, and provenance
Stage 1: Semantic Extraction
The extraction.py module contains three primary entry points that define the extraction surface.
Entity Extraction
The handle_extract_entities function (lines 23-44) executes Named-Entity Recognition to produce labeled spans:
from semantica_mcp.mcp.server import SemanticaMCP
mcp = SemanticaMCP()
entities = mcp.run_tool("extract_entities", {
"text": "Apple Inc. announced quarterly earnings in Cupertino."
})
# Returns: [{text: "Apple Inc.", type: "ORG", offset: 0}, ...]
Each entity carries provenance metadata: extraction method, confidence score, and source text offsets.
Relation and Triplet Extraction
The handle_extract_relations function (lines 50-78) performs two-phase extraction:
- First, re-runs NER to ensure entity coverage
- Then feeds entities to
RelationExtractor(source → target pairs) andTripletExtractor(subject-predicate-object structures)
Relations capture typed connections between entities, while triplets provide semantic (RDF-style) statements suitable for ontology alignment.
Full Extraction Stack
The handle_extract_all function (lines 87-136) executes the complete pipeline:
text = """
Alice bought a new laptop from Acme Corp. She loves its performance,
but the battery life is disappointing. Bob, her colleague, recommended a different model.
"""
payload = mcp.run_tool("extract_all", {"text": text})
This invokes NER → CoreferenceResolver → RelationExtractor → EventDetector (optional) → TripletExtractor, returning a unified payload with all extract types.
Stage 2: Coreference Resolution and Event Detection
Two optional but critical components normalize extracted content before graph construction.
Coreference Resolution
The CoreferenceResolver (implemented in semantica/semantic_extract/coreference.py) collapses pronoun chains and repeated mentions. In the example above, "She" and "its" are resolved to "Alice" and "laptop" respectively, ensuring a single node represents each real-world entity.
Event Detection
The EventDetector identifies temporal structures—actions with triggers, participants, and time expressions. Events become first-class nodes in the graph with specialized linking to their arguments.
Stage 3: Graph Construction
The semantica/context/context_graph.py module materializes extracted structures into a property graph model.
Node Creation
Every unique entity becomes a node storing:
- Canonical label (post-coreference)
- Semantic type (PERSON, ORGANIZATION, CONCEPT, etc.)
- Provenance metadata (extraction source, confidence, original spans)
Edge Construction
Relations generate typed edges:
- Binary relations:
source → targetwith relation type label - Triplet edges:
subject → objectlabeled by predicate - Event linkages: event nodes connected to participant entities
Building from Extraction Payload
# payload from handle_extract_all
graph = mcp.context_graph_from_payload(payload)
print("Nodes:", list(graph.nodes(data=True)))
print("Edges:", list(graph.edges(data=True)))
The resulting ContextGraph supports in-memory operations, traversal queries, and export to persistent stores.
Stage 4: Persistence and Storage
Semantica abstracts graph storage through adapters in semantica/vector_store/*, enabling multiple backend strategies:
| Backend | Use Case |
|---|---|
In-memory (ContextGraph) |
Rapid prototyping, small-scale analysis |
| Neo4j | Production graph queries, Cypher support |
| Amazon Neptune | AWS-native, RDF/SPARQL compatibility |
| Vector stores with embeddings | Semantic similarity search on graph nodes |
Persisting to Neo4j
from semantica.context.graph_backends import Neo4jBackend
neo = Neo4jBackend(
uri="bolt://localhost:7687",
auth=("neo4j", "password")
)
neo.save_graph(graph)
Provenance Tracking and Auditability
Every graph element carries provenance metadata managed through semantica/visualization/visualization_provenance.py. This records:
- Which extraction activity produced the node/edge
- Confidence scores and alternative interpretations
- Source text references
This audit trail enables:
- Visualization of extraction uncertainty
- "Right to be forgotten" operations (remove all data derived from specific text spans)
- Debugging and pipeline improvement (identify low-confidence extraction patterns)
Custom Extension Points
The modular architecture supports component replacement without pipeline restructuring:
# Adding domain-specific edges post-extraction
graph.add_node("Acme Corp", type="organization", source="domain_kb")
graph.add_edge(
"Alice",
"Acme Corp",
relation="employee_of",
provenance={"method": "hr_database_lookup"}
)
Swappable components include:
- NER engine (spaCy, transformers, custom models)
- Relation extractor (rule-based, supervised, or LLM-powered)
- Graph backend (any adapter implementing the storage interface)
Summary
- Semantica's extraction pipeline in
semantica_mcp/mcp/tools/extraction.pyprovides three tool functions (handle_extract_entities,handle_extract_relations,handle_extract_all) with progressive depth of analysis. - Coreference resolution and event detection normalize and enrich extracts before graph construction.
- The
ContextGraphclass insemantica/context/context_graph.pymaterializes nodes and edges with full provenance tracking. - Storage adapters in
semantica/vector_store/*enable persistence to memory, Neo4j, Neptune, or embedded vector stores. - Provenance records in
semantica/visualization/visualization_provenance.pyensure the knowledge graph remains auditable and compliant.
Frequently Asked Questions
What file formats can Semantica ingest?
Semantica processes raw text strings as primary input. The MCP tool interface accepts JSON payloads with text fields; preprocessing for PDF, HTML, or DOCX must occur upstream. The extraction engine operates on cleaned UTF-8 text regardless of original format.
How does Semantica handle ambiguous entity mentions?
The CoreferenceResolver (called within handle_extract_all) applies mention clustering to link pronouns and variants to canonical entities. Post-resolution, the graph contains one node per real-world referent. Confidence scores from the resolver are preserved in edge metadata for downstream filtering.
Can I use a custom NER model with Semantica?
Yes. The SemanticaMCP class accepts configurable extractors at initialization. Replace the default NER by passing a custom extractor implementing the EntityExtractor interface to mcp.register_extractor("entities", custom_ner). The pipeline structure in handle_extract_all remains unchanged.
What is the performance characteristic for large documents?
Processing scales with extraction depth. Entity-only extraction (lines 23-44) runs in linear time. Full pipeline with coreference and event detection (lines 87-136) requires quadratic complexity in the worst case due to pairwise relation scoring. For production workloads, chunk documents at paragraph or section boundaries and merge graphs at entity identity boundaries.
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 →