How to Build Knowledge Graphs from Multiple Data Sources Using Semantica
To build knowledge graphs from multiple data sources using Semantica, instantiate the GraphBuilder class with merge_entities=True and resolve_conflicts=True, then pass a list of heterogeneous sources—raw text, JSON dictionaries, or file paths—to the build() method, which normalizes inputs, extracts entities, resolves duplicates, and detects conflicts automatically.
The semantica-agi/semantica repository provides a comprehensive framework for knowledge graph construction. Its central component, the GraphBuilder class located in semantica/kg/graph_builder.py, orchestrates the ingestion of heterogeneous data formats into a unified, queryable knowledge graph. This guide demonstrates how to leverage the builder's pipeline to integrate PDFs, web data, ontologies, and raw text into a coherent temporal graph structure.
Understanding the GraphBuilder Pipeline Architecture
The GraphBuilder implements a seven-stage pipeline for knowledge graph construction. Each stage handles specific concerns, from input normalization to persistent storage, allowing developers to process diverse data sources through a single interface.
When you invoke the build() method, the component automatically detects source types and applies the appropriate extraction and transformation logic. The pipeline supports optional entity resolution, conflict detection, and temporal versioning, making it suitable for production-grade knowledge management systems.
Normalizing Heterogeneous Input Sources
Before extraction begins, GraphBuilder._normalize_graph standardizes all inputs into a canonical dictionary structure containing entities, relationships, and optional metadata fields. This normalization accepts single sources, lists of sources, or dictionaries with pre-extracted graph fragments.
According to the implementation in semantica/visualization/kg_visualizer.py, the builder handles raw text strings, pre-extracted entity dictionaries, relationship mappings, and file references (JSON, CSV) seamlessly. This ensures that whether you ingest a PDF paragraph or a structured API response, the data conforms to the internal graph schema before processing continues.
Extracting Entities and Relationships from Raw Text
For unstructured text inputs, the builder triggers local extraction pipelines via _extract_from_text in semantica/kg/graph_builder.py. You control extraction behavior through boolean flags and method selectors:
extract: Enable named entity recognition (NER)extract_relations: Extract binary relationships between entitiesextract_triplets: Extract subject-predicate-object tripletsner_method: Choose between"ml"(local ML model),"pattern", or"llm"backendsrelation_methodandtriplet_method: Configure respective extraction backends
When ner_method="ml", the builder utilizes semantica/semantic_extract/ner_extractor.py for local processing without requiring external API keys.
Entity Resolution and Conflict Handling
Two critical features ensure graph integrity when merging multiple sources: entity resolution and conflict detection.
Entity Resolution: Setting merge_entities=True instantiates an EntityResolver (defaults to fuzzy matching) from semantica/kgraph/entity_resolver.py. This component deduplicates entities across sources, and _remap_relationship_endpoints updates relationship source/target IDs to reference the canonical entity identifiers.
Conflict Detection: With resolve_conflicts=True, the builder invokes ConflictDetector from semantica/conflicts/conflict_detector.py to identify contradictory facts. The system flags inconsistencies between sources, enabling automated or manual resolution strategies.
Implementing Temporal Knowledge Graphs
Semantica supports time-bound graph semantics through explicit temporal methods. After building the initial graph, you can augment it with temporal edges or create historical snapshots:
add_temporal_edge: Creates time-valid relationships between entities withvalid_fromandvalid_untiltimestampscreate_temporal_snapshot: Generates a point-in-time view of the graph, useful for historical analysis or audit trails
These methods, implemented in semantica/kg/graph_builder.py, allow you to model entity states and relationship evolution over time.
Complete Implementation Example
The following implementation demonstrates ingesting PDF text, pre-extracted JSON, and ontology fragments into a unified knowledge graph:
# 1️⃣ Initialise the builder – enable merging and conflict handling
from semantica.kg import GraphBuilder
builder = GraphBuilder(merge_entities=True, resolve_conflicts=True)
# 2️⃣ Prepare heterogeneous sources
pdf_text = "The Lattice‑A2 radar covers low‑altitude threats."
web_json = {
"entities": [{"id": "radar_1", "name": "Lattice‑A2", "type": "system"}],
"relationships": []
}
ontology_file = {"entities": [], "relationships": []} # could be loaded via ingest_ontology
sources = [
{"text": pdf_text}, # raw text – will be extracted
web_json, # pre‑extracted dict
ontology_file # already‑structured graph fragment
]
# 3️⃣ Build the KG (the builder will extract from text, resolve duplicates,
# and run conflict detection automatically)
kg = builder.build(
sources,
extract=True, # run NER on raw strings
extract_relations=False,
extract_triplets=True,
ner_method="ml", # local ML model (no API key needed)
)
print("Entities:", len(kg["entities"]))
print("Relationships:", len(kg["relationships"]))
To add temporal context to specific relationships:
# 4️⃣ Adding a temporal edge manually
from datetime import datetime, timezone
builder.add_temporal_edge(
kg,
source="radar_1",
target="mission_42",
relationship="SUPPORTS",
valid_from=datetime(2025, 1, 1, tzinfo=timezone.utc),
valid_until=None,
)
For historical analysis, generate temporal snapshots:
# 5️⃣ Creating a snapshot for a specific date
snapshot = builder.create_temporal_snapshot(
kg,
timestamp="2025-06-01T00:00:00Z",
snapshot_name="mid‑2025"
)
print("Snapshot contains", len(snapshot["entities"]), "entities")
Summary
- Instantiate
GraphBuilderfromsemantica/kg/graph_builder.pywithmerge_entities=Trueandresolve_conflicts=Trueto enable entity deduplication and contradiction detection. - Normalize inputs through
_normalize_graph, which converts raw text, JSON, CSV, and dictionaries into a canonical graph structure. - Extract entities using local ML models by setting
extract=Trueandner_method="ml", eliminating external API dependencies. - Resolve conflicts automatically using the
ConflictDetectorclass whenresolve_conflicts=Trueis enabled. - Add temporal dimensions with
add_temporal_edgeandcreate_temporal_snapshotto model time-bound relationships and historical graph states. - Track progress throughout the pipeline using the internal
ProgressTrackerand logging mechanisms.
Frequently Asked Questions
What data formats does Semantica's GraphBuilder support?
The GraphBuilder accepts raw text strings, Python dictionaries containing entities and relationships keys, and file paths to JSON or CSV documents. The _normalize_graph method in semantica/visualization/kg_visualizer.py handles format detection and conversion to the internal canonical structure, enabling seamless integration of PDF-extracted text, API responses, and ontology files within a single build() call.
How does entity resolution work when merging multiple sources?
When merge_entities=True is passed to the constructor, the builder instantiates an EntityResolver that applies fuzzy matching algorithms to identify duplicate entities across sources. After resolution, the _remap_relationship_endpoints method updates all relationship source and target IDs to reference the canonical entity identifiers, ensuring graph consistency even when different sources use varying names or identifiers for the same real-world entity.
Can I build knowledge graphs without using external LLM APIs?
Yes. Set ner_method="ml", relation_method="pattern", or triplet_method="pattern" to use local extraction backends. The semantica/semantic_extract/ner_extractor.py module provides a local ML-based NER implementation that requires no API keys, while pattern-based methods in semantica/semantic_extract/relation_extractor.py and semantica/semantic_extract/triplet_extractor.py apply rule-based extraction for offline processing.
How do I handle temporal data and graph versioning?
Use the add_temporal_edge method to create relationships with explicit valid_from and valid_until timestamps. For historical analysis, call create_temporal_snapshot with an ISO timestamp to generate a point-in-time view of the graph. These methods, implemented in semantica/kg/graph_builder.py, enable time-travel queries and audit trails by filtering entities and relationships based on temporal validity periods.
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 →