entroptics-llm
Read the context as the directions it resolves, and the selection follows from the data.
A language model's context is assembled from several sources at once: a retrieval-augmented prompt, an agent scratchpad, a long conversation. The decisions made about it — how many retrieved items to keep, which of them to trust, whether an answer stayed on its evidence — are conventionally made with one number per item against one summary of the whole.
This reads the context as the K directions it resolves above its own noise floor, using the
entroptics instrument, and makes each of those
decisions from that span. K is counted from the data: nothing is trained, no threshold is set,
and no constant is fitted per corpus.
The result
How many to keep, when relevance has several facets. A query whose relevance spreads across R independent facets, both sides running the same parameter-free lock over the same screen:
| facets R | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| cosine F1 | 1.000 | 1.000 | 1.000 | 0.806 | 0.000 | 0.000 |
| entroptics F1 | 1.000 | 1.000 | 1.000 | 1.000 | 1.000 | 1.000 |
| edge | +0.000 | +0.000 | +0.000 | +0.194 | +1.000 | +1.000 |
Entroptics holds F1 at 1.000 at every facet count. One scalar carries one facet's worth of evidence; an R-mode subspace holds all of them.
Which item is foreign. Real attacks from deepset/prompt-injections planted in wikitext-103
articles, against a centroid and against a k-nearest-neighbour detector:
| sources | entroptics | centroid | k-NN | vs centroid | vs k-NN |
|---|---|---|---|---|---|
| 1 | 0.990 | 0.983 | 0.983 | +0.007 [+0.003, +0.012] | +0.007 [+0.003, +0.011] |
| 2 | 0.970 | 0.901 | 0.960 | +0.069 [+0.052, +0.088] | +0.010 [+0.004, +0.017] |
| 3 | 0.941 | 0.811 | 0.940 | +0.131 [+0.105, +0.157] | +0.001 [−0.007, +0.010] |
| 5 | 0.907 | 0.733 | 0.927 | +0.174 [+0.147, +0.201] | −0.020 [−0.031, −0.010] |
The margin over a centroid grows from +0.007 to +0.174 as sources multiply. On the question an operator asks — which item do I open first — entroptics leads at every source count: 0.787 / 0.467 / 0.287 / 0.160 against the centroid's 0.740 / 0.253 / 0.140 / 0.053, three times the hit rate at five sources from a pool of 192 items.
Whether a continuation belongs. Held-out on-topic sentences against sentences from a different article:
| sources | entroptics | centroid | vs centroid |
|---|---|---|---|
| 1 | 0.955 | 0.954 | +0.001 [−0.002, +0.004] |
| 2 | 0.931 | 0.893 | +0.038 [+0.031, +0.046] |
| 3 | 0.922 | 0.838 | +0.084 [+0.074, +0.095] |
| 5 | 0.872 | 0.717 | +0.155 [+0.141, +0.169] |
The same curve from an independent task: the centroid falls 0.954 → 0.717 as the context spreads while entroptics holds 0.955 → 0.872.
python -m research.benchmarks.bench_facets # runs on CPU in seconds, no corpus
python -m research.benchmarks.bench_injection
python -m research.benchmarks.bench_drift
research/PAPER.md has the construction, the real-corpus results on BEIR and HotpotQA, and
every number with what it was measured on.
Use it
from entroptics_llm import coherent_basis, in_subspace_fraction, most_anomalous, coherence
V, K = coherent_basis(context_embeddings) # the K directions the context resolves
suspect = most_anomalous(context_embeddings) # the item furthest outside them
score = coherence(answer_embedding, context_embeddings) # is this still on its sources?
K is read from the data — the count of singular values standing above the derived noise
floor — so nothing is chosen. context_embeddings are the ones your pipeline already computed
for retrieval; no additional model call is made.
These are scores and rankings, not verdicts. most_anomalous localises the item worth
inspecting. "Is there an anomaly in this one set" is ill-posed without a reference
distribution, so a caller wanting a yes/no supplies its own null.
Install
pip install entroptics-llm
Runtime dependencies are numpy and entroptics,
nothing else. No encoder, no torch, no corpus: the vectors are yours, and the package never
downloads anything.
Working on it, or reproducing the tables:
pip install -e ".[dev]" # + pytest
pytest -q # the whole suite, no model, no downloads
pip install -e ".[bench]" # + encoders and datasets, for research/benchmarks/
Layout
research/
PAPER.md the write-up, and every number with what it was measured on.
benchmarks/
bench_injection locating a real injection, against source count.
bench_drift on-topic decision, against source count.
bench_facets the budget's win condition: relevance across R facets.
bench_beir the budget on real BEIR corpora, where relevance is unimodal.
bench_hotpot_e2e end to end with a language model answering.
src/entroptics_llm/
engine.py the one seam onto `entroptics`. Nothing else imports it.
subspace.py coherent basis, in-subspace fraction, anomaly, coherence.
lock.py gap_split / top_break — where a salience spectrum stops.
cut.py the retrieval budget: a query-relative screen, and the lock on cosine.
tests/ the suite, including the structural guards that read prose
Where it ties, and why
On unimodal relevance it ties, which is the same prediction. At one coherent mode the read reduces to the statistic it is measured against. Four real BEIR corpora over 2,421 queries: every interval contains zero. And HotpotQA end-to-end with a language model, handed cosine's top-m where m is the count the cut derived for that question: +0.000 (Qwen2.5-1.5B) and −0.001 (Qwen2.5-7B) — the selection is indistinguishable. Only 12.2% of the 3,265 pooled BEIR queries are multi-modal at the point the cut sees them, so a tie is what the law requires there.
Size the budget to the task. On HotpotQA the derived count spends 36% of a fixed top-5's tokens; it keeps 2.1 paragraphs and 66 of 150 questions kept exactly one, where the answer needs two. Against that fixed top-5 that is −0.133 F1 at 7B, all of it the count rather than the ranking. Where a task needs several passages, put a floor on the count.
Coherence reads topic, not factual correctness. A wrong-but-on-topic answer reads as coherent — on those same 150 questions it separated right answers from wrong ones by 0.008. Use it for off-source and lost-thread monitoring, not as a fact checker.
Built on entroptics
Every spectral read reaches entroptics through one module,
engine.py; nothing else imports the library and a test
enforces it. The resolved-mode count that sets K is the library's own read — the singular
values standing above a noise floor derived from the data rather than assumed. See
research/PAPER.md for the citation and the construction.
License
Dual-licensed: AGPL-3.0-only or commercial. See LICENSE and NOTICE;
commercial and white-label terms in COMMERCIAL_LICENSE.md.
Contributing: CONTRIBUTING.md and CLA.md.
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 entroptics_llm-0.1.0.tar.gz.
File metadata
- Download URL: entroptics_llm-0.1.0.tar.gz
- Upload date:
- Size: 51.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
549dc8d3b5fb9e1674f11f4875af7835390ad1e78a4a5d78cbb8c8cc6d549328
|
|
| MD5 |
bd241fdddd847f7ad120fdac39a00b0e
|
|
| BLAKE2b-256 |
1d3131651bf52dbd1e2a908dc6c9562622e2854672e4084564c35e920c8e5161
|
Provenance
The following attestation bundles were made for entroptics_llm-0.1.0.tar.gz:
Publisher:
publish.yml on Agience/entroptics-llm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
entroptics_llm-0.1.0.tar.gz -
Subject digest:
549dc8d3b5fb9e1674f11f4875af7835390ad1e78a4a5d78cbb8c8cc6d549328 - Sigstore transparency entry: 2719680811
- Sigstore integration time:
-
Permalink:
Agience/entroptics-llm@f6144b0ca0e6331a16c9c8ba820d5e4e2f2f94a7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Agience
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f6144b0ca0e6331a16c9c8ba820d5e4e2f2f94a7 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file entroptics_llm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: entroptics_llm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dba5bee0a5b7bba1f80e4fb948bb76dc21f6c7fc36a4450d918bea6b2f5085b9
|
|
| MD5 |
35456879e79a7888c3ed22065e07b186
|
|
| BLAKE2b-256 |
80c211c51a12686081019d19d570dfcba73829b5457f85d0167b91a77a27506f
|
Provenance
The following attestation bundles were made for entroptics_llm-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Agience/entroptics-llm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
entroptics_llm-0.1.0-py3-none-any.whl -
Subject digest:
dba5bee0a5b7bba1f80e4fb948bb76dc21f6c7fc36a4450d918bea6b2f5085b9 - Sigstore transparency entry: 2719681447
- Sigstore integration time:
-
Permalink:
Agience/entroptics-llm@f6144b0ca0e6331a16c9c8ba820d5e4e2f2f94a7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Agience
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f6144b0ca0e6331a16c9c8ba820d5e4e2f2f94a7 -
Trigger Event:
workflow_dispatch
-
Statement type: