See why your vectors match.

Faithful, vector-only similarity & ranking attribution — for any embedder, any vector store. Think of it as SHAP for vector search: the missing explanation layer for similarity and ranking.

Apache-2.0core: Rustpython ≥ 3.8v0.2
python — zero setup, exact on the first call
import simlens

# Zero setup — an exact explanation on the very first call, no training required.
ex = simlens.Explainer(metric="cosine")
attr = ex.explain(query_vec, candidate_vec)

print(attr.as_sentence())
→ "Matched mainly on 'financial-regulation' (61%),
   '2024-filings' (22%)."
The problem

Vector search answers every question with a black box

Vector search powers your RAG pipeline, your recommendations, your semantic search, your anomaly detection. And every one of them answers a question with: this matches — score 0.83. Which concepts drove the match? Why did the wrong result rank first? Why was the right one buried at #7? The score won't say.

SimLens turns that score into an answer — the specific, named concepts that produced it, in plain language, and it proves the breakdown adds up. It reads only the vectors, so it drops into any stack without touching your model or your database.

Why teams reach for SimLens

Faithful by construction, not by storytelling

🎯 Answers the real questions

Not just why does A match? but why did A outrank B? — the margin, decomposed. The question search and recsys teams actually debug.

🧾 Faithful by construction

For dot & cosine, the explanation is the arithmetic: contributions provably sum to the score. Every result ships a completeness residual so you can see exactly how exact it is.

🔍 Three levels of zoom

Raw dimensions (exact) → learned monosemantic features → your own named concepts — one consistent, additive contract across all three.

🎛️ Steerable

“More like this, but less of that” — edit a query in concept space with ex.steer() and search again.

Drop-in & fast

Embedder-agnostic, database-agnostic, and backed by a compact Rust core for the per-query hot path. Zero-copy numpy FFI.

🔏 Auditable

Every explanation is stamped with a content hash of the artifacts that produced it — reproducible rationale for decisions that have to hold up.

Three levels of explanation

Zoom from exact math to named concepts

“Coordinate 412 contributed 80%” is faithful, but it doesn't mean anything to a human. SimLens trades a little exactness for a lot of readability as you zoom — and always reports the residual so you know the trade you made.

Level 1 · exact

Dimensions

The raw per-coordinate breakdown. Always available, always exact, zero setup — the ground truth the other levels are checked against.

residual = 0 (float precision)
Level 2 · learned

Features

A sparse autoencoder learns a dictionary of monosemantic directions — each feature lights up for a single, coherent concept, auto-labeled with measured confidence.

residual reported, every time
Level 3 · named

Concepts

Bring a handful of positive/negative examples per concept and SimLens fits concept directions (CAVs) to decompose scores along your vocabulary.

honestly partial, coverage shown
Beyond a single pair

What you can do

why did A outrank B? — margin attribution
ex.explain_margin(query, better=A, worse=B)
→ "Matched mainly on 'concept_4' (52%),
   'concept_2' (33%), 'concept_3' (−15%)."
minimal reason — ablation
abl = ex.ablate(query, candidate, threshold=0.5)
→ removing 1 feature: 0.582 → 0.399
  (dropped_below=True)
steer — more like this, less of that
new_query = ex.steer(query,
    {"sports": -1.0, "finance": +0.5})
autofit — one line from store to bundle
bundle = simlens.autofit(store)
# samples vectors, trains the dictionary,
# names features from payload fields + LLM
See the full capability table →
System extensions

Thin wrappers for the systems you already run

You bring the vectors, they bring the explanation. Business-logic-agnostic, configurable, and validated on real embedders.

📚 RAG

simlens.integrations.rag.RagExplainer — why retrieved / why ranked, with spurious-feature flags. Validated: deletion-AUC of top dims beats random (14.8 < 18.9).

🎬 Recommendations

simlens.integrations.recsys.RecsysExplainer — a faithful “because you liked…”, plus steering. Margin reconstructs the score gap exactly (residual 0.0).

🕸️ Knowledge graphs

simlens.integrations.kg.KnowledgeGraphExplainer — explain, propose, and type edges. Same-topic edge coherence 0.87 vs 0.25 random.

🧾 Audit

simlens.integrations.audit.AuditLog — signed, hashed decision records; signatures verify and re-explanation is deterministic.

Get started

One pip install away from your first “why”

shell
pip install simlens

# extras — stores, LLM naming, GPU training:
pip install "simlens[qdrant,openai,train]"