Deterministic, cited knowledge graphs from your documents.

Local-first, with byte-level provenance on every edge. Deterministic by default — the same corpus always yields a byte-identical graph you can audit and re-verify. Explore it in an interactive graph studio, derive new relations with link prediction & Datalog rules, and layer opt-in LLM extraction, grounded answer synthesis, and semantic search on top — always quarantined so model output never poses as ground truth.

Open the interactive demo → GitHub PyPI Changelog

pip install textgraph-kg

Every claim is cited

Each edge carries a re-verifiable [doc:byte-span] citation — re-hash it against the source and it still matches.

Deterministic pipeline

A pure layer stack — ingest → structure → encoder IE → resolution → claims → analytics → retrieval — that never calls a model. Same corpus, byte-identical graph, gated in CI.

The LLM augments, never grounds

Two opt-in touchpoints only: --llm-extract reads chunks and adds relations the deterministic pass missed; --llm summarizes finished communities. Both run before/after the core, stay GENERATED-tagged and byte-cited, and vanish when off.

Decisions & provenance

WHY/DECISION/ADR markers become a queryable causal chain; export a W3C PROV-O audit trail.

Conflicts, never silent

Contradictory single-truth claims are surfaced for review, resolved only on an explicit, non-destructive policy.

Bring your own scale

Optional GQL, vision retrieval, access control, and Graph-of-Thoughts reasoning — each an opt-in module.

How a build runs

Every layer is a pure function of the one below it plus a pinned config hash — the property that makes the graph reproducible and incremental. The LLM appears at exactly two opt-in, quarantined touchpoints; turn them off and the build is byte-identical.

  1. L0 ingest — files become a canonical UTF-8 doc with a raw-byte offset map and hierarchical chunks.
  2. L1 structure — zero-model parse: sections, links, definitions, citations, rationale & requirements (STRUCTURAL).
  3. L2 / L3 encoder IE — deterministic entities + typed relations, coref-lite, negation/modality preserved (EXTRACTED).
  4. 🧠 LLM relation extraction (opt-in --llm-extract) — the LLM reads each chunk and returns {subject, predicate, object} triples; each endpoint merges onto an existing entity by name (no duplicate nodes) or mints a new one, and every edge is GENERATED-tagged and cited to the chunk's byte span. Prompt-cached, budget-capped, deterministic given a fixed model.
  5. 🔗 Co-occurrence backbone (opt-in --co-occurrence) — links entities co-mentioned in a chunk so a relation-sparse corpus still forms a connected, clustered graph (STRUCTURAL, cited).
  6. L5 resolution → L6 claims → L7 analytics → L8 retrieval — resolution, bi-temporal claims, PageRank/communities/layout, and the dual-node retrieval graph. Because extraction runs before this, LLM entities are ranked, clustered and positioned like any other.

textgraph build ./case-files --llm-extract --co-occurrence -o case-out && textgraph console case-out