GRAPH · OSS · kgr

A knowledge graph that learns its own ontology.

Drop in text, news feeds, or SQL. kgr extracts entities and relations, evolves the schema to fit them, and lands everything in a live Kinetica property graph — then answers questions in plain English over what it built.

What it does

The schema is induced, not declared.

For each paragraph, kgr asks an LLM not just what the entities and relations are, but what types they belong to. New entity types, relation types, and attributes append themselves to a registry and materialize as real columns — on the fly. Rows upsert by identity, so the same entity across many documents collapses into one node.

  1. 01
    HASH
    Content-hash dedup at the document level — re-ingest forever, only new info lands.
  2. 02
    EXTRACT
    An LLM returns entity types, relation types, entities, and relations as JSON.
  3. 03
    FOLD
    A curated alias map collapses synonyms so the vocabulary stays tight.
  4. 04
    EVOLVE
    New types become new ontology rows, then ALTER TABLE columns.
  5. 05
    UPSERT
    PK upserts merge entities; the property graph is re-applied live.
Schema-on-write

Induced by an LLM

The ontology emerges from the data and evolves with it — new types become new ontology rows and new columns, instead of being modeled in advance.

Idempotent

Incremental forever

Document-level content-hash dedup plus row-level PK upserts. Poll feeds indefinitely; only genuinely new information is written.

Native graph

Queryable on landing

Extraction feeds straight into a live Kinetica property graph — Cypher and graph analytics, with the meta-graph derivable cheaply from labels.

WHAT LANDS — Four objects in schema kgr: documents (hash ledger), ontology (type registry), nodes and edges (with typed columns) — plus the kgr.kg property graph, kept live with add_table_monitor.
Quickstart

Install, init, ingest. Three commands.

kgr is a Python CLI. Set up the virtualenv, point it at your Kinetica instance, and start feeding it documents — from files, a directory tree, a URL, or an RSS feed.

bash · one-time setup
install
# core install
.venv/bin/pip install -e .
# add the web driver (RSS, articles)
.venv/bin/pip install -e ".[web]"
# point kgr at your instance
cp .env.example .env
# set KINETICA_DB_SKILL_PASS in .env

# create schema + property graph
# (idempotent — safe to re-run)
.venv/bin/kgr init
bash · ingest
ingest
# a single file
kgr ingest examples/ft_article.txt

# walk a whole directory tree
kgr ingest path/to/dir/

# a web article (needs the [web] extra)
kgr ingest-url 'https://www.bbc.com/news/...'

# an RSS feed, newest N items
kgr ingest-feed https://feeds.bbci.co.uk/news/business/rss.xml --limit 5
Ask in English

Ask a question. Get schema-grounded Cypher.

kgr ask grounds your question against the live meta-graph, has the LLM write one read-only Cypher query over the graph, runs it, and answers in prose. Because every label and relation is validated against the schema first, the model can't reference types that don't exist in your corpus.

bash · graph-RAG
kgr ask
kgr ask "What has Microsoft patched,
        released, or investigated?"

kgr ask "Which vulnerabilities affect
        the most products? Give counts." --show-cypher

# three steps under the hood:
# 1 · GROUND   derive the live meta-graph
# 2 · GENERATE one read-only Cypher query
# 3 · RUN      execute, answer in prose
generated · read-only
multi_hop.gql
-- "Which organizations make products
--  affected by known vulnerabilities?"

GRAPH "kgr"."kg"
MATCH (o:Organization)-[:MAKES]->(p:Product)
      <-[:AFFECTS]-(v:Vulnerability)
RETURN DISTINCT
  o."name_original" AS organization,
  p."name_original" AS product,
  v."name_original" AS vulnerability
LIMIT 100;
RE-PROMPTED ON FAILURE — If the generated query isn't read-only, kgr re-prompts the model once with the specific problem. The arrow flips mid-pattern (org → product ← vulnerability) — generated from the question, grounded in the schema.
Continuous

Point it at a feed. The graph keeps growing.

A polling daemon watches RSS sources and ingests new items as they publish. Content-hash dedup means re-polling the same feed forever only writes genuinely new information — and because the graph sits on add_table_monitor, what it writes is queryable the moment it lands.

bash · daemon
watch-feeds
# poll threat-intel feeds, evolve the graph continuously
kgr watch-feeds --help

# every paragraph is also appended to corpus.txt with a
# timestamp + source URI + sha8 — an immutable replay log
At scale

A live Bitcoin money-flow graph, growing in real time.

The same pipeline that builds a knowledge graph from news builds a transaction graph from a chain — trace multi-hop money flow across the whole network without a rebuild.

25M
Nodes

Addresses and transactions across the chain.

589M
Edges

Money-movement links, multi-hop traceable.

live
As blocks land

New blocks append in real time — no rebuild window.

Query it visually → Graph ExplorerOpen the graph kgr builds in a browser — ontology, query helper, and live render in one tab.

Build your first graph from text.

Frequently asked questions

What does "the schema is induced, not declared" mean?
For each paragraph, kgr asks an LLM not just what the entities and relations are, but what types they belong to. New entity types, relation types, and attributes append themselves to a registry and materialize as real columns via ALTER TABLE — so the ontology emerges from your data and evolves with it, instead of being modeled in advance.
Can I re-ingest the same documents or poll a feed forever?
Yes — kgr is idempotent. Document-level content-hash dedup plus row-level primary-key upserts mean only genuinely new information is ever written. You can re-run an ingest or point the watch-feeds daemon at an RSS source indefinitely, and the same entity across many documents collapses into one node.
How does <code>kgr ask</code> answer a question?
It grounds your question against the live meta-graph, has the LLM write one read-only Cypher query over the graph, runs it, and answers in prose. Because every label and relation is validated against the schema first, the model can't reference types that don't exist in your corpus — and if the generated query isn't read-only, kgr re-prompts the model once with the specific problem.
What does kgr create in my Kinetica instance?
Four objects in the kgr schema — documents (the hash ledger), ontology (the type registry), and nodes and edges (with typed columns) — plus the kgr.kg property graph, which is kept live with add_table_monitor so what kgr writes is queryable the moment it lands.
Is kgr only for text and news feeds?
No. The same pipeline that builds a knowledge graph from documents builds a transaction graph from a blockchain — for example a live Bitcoin money-flow graph of roughly 25M nodes and 589M edges that grows in real time as new blocks land, traceable multi-hop with no rebuild window.
What do I need to run it?
kgr is an open-source Python CLI (on GitHub). Set up the virtualenv, add the [web] extra for RSS and articles, point it at your instance via .env, run kgr init, then ingest files, directory trees, URLs, or feeds.

To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions. Cookie Policy