Local Knowledge Graph
Ask a local model a question, watch it reason step by step, and see the steps drawn as a graph where the edges are how similar the steps are to each other.
The run starts by breaking the question into angles worth checking, then works through them —
about eight steps, each with a named job rather than a quota to fill. Any arithmetic a step
relies on is handed over as an expression and evaluated exactly, in fractions, by
mpeqs. Those sums are shown above the graph: they are the
one part of a run the model did not decide, and you can check 20-13.5 = 6.5 at a glance in a
way you cannot check a paragraph of reasoning.
The graph draws in two colours, because it holds two kinds of claim. Blue links steps by how similar their embeddings are — an association, with no truth value, and the thing that makes indirect knowledge visible. Green is what an exact evaluator settled: a sum, or a conversion between two units, derived from exact ratios. A reader should never have to guess which is which.
Everything runs on your machine. Nothing is uploaded anywhere.
Three ways to answer
curl -sX POST localhost:5100/jobs -H 'content-type: application/json' \
-d '{"query":"...","mode":"settle"}'
| mode | what it does |
|---|---|
reason |
one run — steps, a graph, an answer |
explore |
the question is split into questions, each answered by a run of its own, then assembled |
settle |
explored, explored again, and finished only when two independent runs agree |
settle exists so that no single call decides. When the two runs disagree, three
checks vote through different lenses — same value, same conclusion, same action —
and the tally is shown rather than reduced to a verdict, because 2-1 and 3-0 are
different things.
A vote is still opinion, so both answers are then probed. The same sum with its numbers moved is graded against the exact evaluator and settles the matter outright; asking what a knower would also know is suggestive only, and labelled as such, because a model can be confidently and consistently wrong.
Headless, and as RDF
A run can be started without a browser, polled, and taken as RDF — the graph as text, for anything that would rather query it than look at it.
ID=$(curl -sX POST localhost:5100/jobs -H 'content-type: application/json' \
-d '{"query":"How many seconds are there in 23 weeks?"}' | jq -r .id)
curl -s localhost:5100/jobs/$ID # {"state":"running","steps":3,...}
curl -s localhost:5100/jobs/$ID/stream # N-Triples, live, one triple per line
curl -s localhost:5100/jobs/$ID/rdf # Turtle, once it has finished
curl -sX DELETE localhost:5100/jobs/$ID # stop it
Two formats for two purposes. N-Triples streams: each line is a complete document, so a consumer can parse what has arrived without waiting for the end. Turtle is prefixed and readable, and needs the whole document, so it is what a finished run serialises to.
The lkg:basis predicate carries the same distinction as the colours, so a consumer can take
only the part it can rely on:
<run/a1b2/link/Step1-Step2> lkg:similarity "0.8371"^^xsd:decimal ;
lkg:basis lkg:Embedding . # measured association
<run/a1b2/conversion/1> lkg:statement "23 week = 13910400 second" ;
lkg:from <unit/week> ;
lkg:to <unit/second> ;
lkg:basis lkg:Exact . # derived, reproducible
Run it
pip install mpe-lkg
mpe-lkg
Then open http://localhost:5100.
Which model matters more than anything else here. Measured on the same 40 generated
arithmetic questions, qwen3:4b-instruct-2507 answers 82.5% against llama3.2:3b's
40% — +42.5 points, 95% CI [+23.3, +61.7], replicated on a second battery — and does it in
fewer steps, not more. That is a larger gain than every prompt and design change in this
repository put together, so it is worth spending 2.5 GB on before spending an evening on
prompts:
ollama pull qwen3:4b-instruct-2507-q4_K_M
It needs a local model, which it reaches through Ollama. You do not
need to work that out from here — start it and it will tell you what it found, what is
missing, and the one command that fixes it. mpe-lkg doctor reports the same thing without
starting the server, and exits non-zero, so it works in a script.
Python 3.10 or newer. The wheel is py3-none-any, so nothing is compiled and the same
artefact serves Linux, macOS and Windows — all three tested on every push.
From a clone, or from Python
git clone https://github.com/punnerud/Local_Knowledge_Graph
cd Local_Knowledge_Graph
python3 -m venv .venv && .venv/bin/pip install -e .
.venv/bin/mpe-lkg
python app.py still works from a clone as it always has.
from mpe_lkg import create_app, health
print(health())
create_app().run(port=5100)
More
| Models and configuration | Choosing models, every environment variable, troubleshooting |
| Embeddings from inside a model | Reading a chosen layer instead of an embedding endpoint |
| How it works | The modules, the strongest-path search, why there is no ANN index |
| Development | Tests, and the gate that checks this documentation against measured data |
Licence
The mpedb License 1.0 — the same licence as mpedb and MPEqs, byte for byte.
Free of charge for every person and every organization, with one exception: a group whose revenue or valuation exceeds five billion dollars owes a one-time fee of seven US cents per device. Not an OSI-approved licence.
Published to PyPI as mpe-lkg — Morten Punnerud-Engelstad Local
Knowledge Graph.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mpe_lkg-0.7.0.tar.gz.
File metadata
- Download URL: mpe_lkg-0.7.0.tar.gz
- Upload date:
- Size: 759.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71eef35bb06e5381882fecf0504de6e1e04989b6ab025103975f8558b19b9ab8
|
|
| MD5 |
7fc1f3c885dbfcf060340f88fda0f358
|
|
| BLAKE2b-256 |
02646db1c8e908a2cbf91c20cfb6cc1acd7d21b38b87d3f90707e7babd86f2cb
|
File details
Details for the file mpe_lkg-0.7.0-py3-none-any.whl.
File metadata
- Download URL: mpe_lkg-0.7.0-py3-none-any.whl
- Upload date:
- Size: 268.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c23ee49d5dc36bdb1b5ef740be3ebadf2d5203ff666b61a7f723377875bf043
|
|
| MD5 |
16a1b7458886983b4c1ce66765b5d4b3
|
|
| BLAKE2b-256 |
776704937ac0a06a94d303f994bff7cf2e76ccb30c48aabf1c03ca4959df9f53
|