semantica
Frameworksemantica-agi/semantica
Graph-native infrastructure for context and accountable AI systems with provenance.
Overview
Semantica is a self-hostable Python framework that ingests enterprise data into a queryable context/knowledge graph with deterministic reasoning, decision intelligence, and W3C PROV-O provenance. It supports RDF and property graphs, offers native Databricks/Snowflake connectors, and includes visualization, REST API, CLI, and MCP server for auditable AI agents.
README Preview
\n\n\n\n### Graph-Native Infrastructure for Context and Accountable AI Systems\n\n#### *The Open Source Palantir for AI Agents*\n\n> Ingest your enterprise data, extract what matters, build a Context Graph and knowledge graph (KG), and run graph analytics and causal reasoning over all of it, with full decision provenance baked in. Explainable, traceable, and trustworthy by design.\n\n**Decision Intelligence · Context Management · Deterministic Reasoning · Ontology Management · Knowledge Modeling · End-to-End Traceability**\n\n**Open Source · Self-Hostable · Auditable · Governed · Zero Vendor Lock-In**\n\n**Polyglot Graph Storage · RDF & LPG Support · W3C Standards · Interoperable**\n\n#### Built for High-Stakes, Regulated Domains\n\n[](https://github.com/semantica-agi/semantica) [](https://github.com/semantica-agi/semantica/network/members) [](https://github.com/semantica-agi/semantica/graphs/contributors) [](https://pypi.org/project/semantica/) [](https://pepy.tech/project/semantica) [](https://www.python.org/) [](https://opensource.org/licenses/MIT) [](https://github.com/semantica-agi/semantica/actions) [](https://deepwiki.com/semantica-agi/semantica)\n\n[](https://getsemantica.ai/) [](https://docs.getsemantica.ai/) [](https://discord.gg/sV34vps5hH) [](https://x.com/BuildSemantica) [](https://www.youtube.com/watch?v=QfnNZg4-dZA) [](CHANGELOG.md)\n\n```bash\npip install semantica\n```\n\n\n\n---\n\n\n\n\n\n\n\n*Knowledge Explorer · Context Graphs · Reasoning Engine · Decision Intelligence · Ontology Hub*\n\n**[▶ Watch the full platform walkthrough](https://www.youtube.com/watch?v=QfnNZg4-dZA)**\n\n\n\n---\n\nMost AI agents act without a trail. They store embeddings, not meaning: context that can't be explained, decisions that can't be audited. In lending, that gap is a compliance exposure, not an inconvenience: an underwrit
FAQ (5)
TroubleshootingHow do I fix the Explorer WebSocket 403 "connection rejected" error when running semantica-explorer on a custom port?
Set ALLOWED_ORIGINS (or EXPLORER_CORS_ORIGINS) to include the exact browser origin before starting the Explorer. By default, only http://localhost:5173 and http://127.0.0.1:5173 are allowed, and the same allowlist gates the /ws/graph-updates WebSocket handshake.
For port 8020, run:
ALLOWED_ORIGINS="http://127.0.0.1:8020,http://localhost:8020" \
semantica-explorer --graph any_graph.json --port 8020
Then open http://127.0.0.1:8020 and restart the server after changing the variable. This issue was observed in Semantica 0.6.7.
TroubleshootingHow do I fix "ImportError: gensim is required for Node2Vec" when running Semantica tests without the graph-embeddings extra?
Install the optional dependency, or skip the Node2Vec tests in slim-core environments.
For a full test environment:
pip install -e ".[dev,graph-embeddings]"This installs
gensim>=4.4.0. With it installed, all affected Node2Vec tests should pass.
If gensim is intentionally absent, add this guard at the top of each affected test module:
pytest.importorskip("gensim") # Node2Vec requires semantica[graph-embeddings]Apply it to the eight tests in:
-
tests/context/test_banking_context_graphs_e2e.py-
tests/context/test_context_explainability_regression.py-
tests/kg/test_enhanced_algorithms_e2e.py-
tests/kg/test_provenance_integration.py-
tests/test_030_realworld_comprehensive.py-
tests/vector_store/test_decision_embedding_pipeline.py
Do not move the gensim check from NodeEmbedder.__init__ into _train_word2vec(): the slim-core contract intentionally relies on the constructor raising so callers can disable Node2Vec gracefully. The tests requiring this behavior are test_node_embedder_gensim_missing_hint, test_agent_context_with_graph_builds_without_gensim, and test_graph_components_without_gensim_keep_everything_but_node2vec.
TroubleshootingHow do I fix pytest ImportError "gensim is required for Node2Vec" in tests/kg/test_node_embeddings.py on a clean dev install?
Install the optional dependency in your virtualenv:
pip install -e ".[graph-embeddings]"
or, for a released package:
pip install "semantica[graph-embeddings]"
Then rerun:
python -m pytest tests/kg/test_node_embeddings.py -q
For the repository test fix, do not add a module-level pytest.importorskip("gensim") because test_init_gensim_unavailable and test_init_invalid_method must run without gensim. Instead:
1. Register a marker in pyproject.toml:
[tool.pytest.ini_options]
markers = [
"no_gensim: test runs without the optional gensim dependency"
]
2. Add an autouse fixture that skips gensim-dependent tests unless the test is marked no_gensim:
import pytest
from semantica.kg.node_embeddings import GENSIM_AVAILABLE
@pytest.fixture(autouse=True)
def require_gensim(request):
if not GENSIM_AVAILABLE and "no_gensim" not in request.keywords:
pytest.skip("Install semantica[graph-embeddings] to run Node2Vec tests")
3. Mark test_init_gensim_unavailable and test_init_invalid_method with @pytest.mark.no_gensim.
Expected result without gensim: 2 passed, 31 skipped. With gensim installed: all 33 tests pass.
TroubleshootingWhy does Semantica CSVExporter export_relationships output empty source_id and target_id columns for Neo4j/FalkorDB/Neptune/AGE edges?
CSVExporter.export_relationships() only recognizes source/source_id and target/target_id as endpoint field names. Backend-shaped records use start_node_id/end_node_id (Neo4j, FalkorDB, Neptune, and renamed AGE edges) or start_id/end_id (raw AGE), so the normalizing path silently writes empty endpoint columns with no error or warning. Fixes/workarounds:
1. **Fix (patch)**: In semantica/export/csv_exporter.py (export_relationships), run records through canonical_endpoints from semantica/export/endpoint_names.py (which defines SOURCE_ENDPOINT_NAMES/TARGET_ENDPOINT_NAMES) at the start of the method — the same approach the Parquet and Arrow exporters already use. This maps all backend spellings into source_id/target_id while keeping source/target and source_id/target_id working as before.
2. **Workaround (no code change)**: Rename the fields before exporting:
record = {"id": "r1", "start_node_id": "alice", "end_node_id": "acme", "type": "WORKS_AT"}
record["source_id"], record["target_id"] = record.pop("start_node_id"), record.pop("end_node_id")
CSVExporter().export_relationships([record], "rel.csv")
3. **Alternative path**: export({"edges": [record]}) preserves the values but writes them under the original column names (start_node_id/end_node_id) without normalization. Parquet and Arrow exporters are not affected.
TroubleshootingWhy does GraphBuilder.build() return an empty graph when using FileObjects from FileIngestor?
FileObject instances are silently skipped because GraphBuilder._process_item() does not recognize them; it expects text strings or dictionaries such as {"text": ...}. As a workaround, convert each ingested FileObject before building the graph:
docs = FileIngestor().ingest_directory("./docs/", recursive=True)
kg = GraphBuilder(merge_entities=True, enable_temporal=True).build(
[{"text": d.text} for d in docs]
)
The permanent fix in PR #1951 makes build() extract text from FileObject.text directly and logs a warning naming unsupported source types instead of skipping them silently. Update to a release containing PR #1951, or apply that change if running from main.