vectorlite
A tiny, dependency-free in-memory vector store for prototyping RAG and semantic search — no numpy, no FAISS, no Pinecone.
Part of the ragkit suite. Install with
pip install ragkit-vectorlite, thenimport vectorlite.
Every prototype seems to start by re-implementing cosine similarity and a little vector store from scratch. vectorlite is that little store, done once, correctly. It's pure standard library (Python 3.8+), so you can drop it into a notebook or a script and start querying embeddings in seconds.
Install
pip install ragkit-vectorlite
Local development (from vectorlite/):
pip install -e .
Quick Start
from vectorlite import VectorStore
# metric defaults to "cosine"; dim is inferred from the first vector
store = VectorStore(metric="cosine")
store.add("doc1", [0.1, 0.2, 0.9], metadata={"topic": "space"}, document="Rockets and orbits.")
store.add("doc2", [0.9, 0.1, 0.0], metadata={"topic": "cooking"}, document="How to sear a steak.")
store.add("doc3", [0.15, 0.25, 0.85], metadata={"topic": "space"}, document="Satellites and telescopes.")
results = store.query([0.12, 0.2, 0.88], top_k=2)
for r in results:
print(r.id, round(r.score, 4), r.document)
Each result is a SearchResult dataclass:
SearchResult(id, score, vector, metadata, document)
Results are always sorted best-first.
Metrics
Pass metric= when constructing the store:
| Metric | Meaning | Ranking |
|---|---|---|
"cosine" |
Cosine similarity in [-1, 1] (default) |
Higher is better |
"dot" |
Raw dot product | Higher is better |
"euclidean" |
L2 distance | Closer is better (ranked internally by negative distance) |
For euclidean, "higher score means closer" — the store handles the sign for you, so results still come back best-first. The score on each result reflects the negative distance in that mode.
The standalone functions are available too, operating on plain lists of floats:
from vectorlite import cosine_similarity, dot, euclidean_distance
cosine_similarity([1, 0], [1, 0]) # 1.0
cosine_similarity([1, 0], [0, 1]) # 0.0 (orthogonal)
cosine_similarity([0, 0], [1, 1]) # 0.0 (zero vector handled gracefully)
Mismatched dimensions raise ValueError.
Metadata filtering
Pass a filter callable to restrict candidates before scoring. It receives each item's metadata dict and returns True to keep it:
space_only = store.query(
[0.12, 0.2, 0.88],
top_k=5,
filter=lambda md: md is not None and md.get("topic") == "space",
)
Only items whose metadata passes the filter are scored and ranked.
MMR: diversity-aware results
Plain top-k similarity can return several near-duplicates of the same best match. Maximal Marginal Relevance (MMR) re-ranks results to balance relevance to your query against diversity among the results themselves.
results = store.query_mmr(
query_vector,
top_k=3,
fetch_k=20, # pull this many by raw similarity first
lambda_mult=0.5, # 1.0 = pure relevance, 0.0 = pure diversity
)
How it works: vectorlite fetches fetch_k candidates by similarity, then greedily builds the result set. At each step it picks the candidate maximizing
lambda_mult * relevance(query, candidate)
- (1 - lambda_mult) * max_similarity(candidate, already_selected)
So if you've already selected item A, a near-duplicate A' gets penalized for being too similar to A, and a different-but-still-relevant item B can win instead. Lower lambda_mult favors diversity; lambda_mult=1.0 reduces to ordinary relevance ranking. Diversity is always measured with cosine similarity between candidate vectors.
Save and load
The whole store — items, metric, and dim — serializes to plain JSON:
store.save("mystore.json")
from vectorlite import VectorStore
store = VectorStore.load("mystore.json")
Other operations
len(store) # number of items
"doc1" in store # membership test
store.get("doc1") # SearchResult (score 0.0) or None
store.delete("doc1") # True if it existed, else False
store.ids() # list of all ids
store.add_many([
{"id": "x", "vector": [0.1, 0.2, 0.3], "metadata": {"k": "v"}},
("y", [0.4, 0.5, 0.6]), # (id, vector)
("z", [0.7, 0.8, 0.9], {"k": "v"}, "a doc"), # (id, vector, metadata, document)
])
Adding an existing id overwrites the previous item.
Prototype scale — and swapping in FAISS later
vectorlite does a brute-force O(n) scan on every query. That is genuinely fine for prototyping and small apps — think up to ~10k–100k vectors, where a full scan still returns in well under a second. There's no index, no approximate search, and no on-disk memory mapping.
When your corpus grows past that, or you need sub-millisecond latency at scale, graduate to a real vector database or ANN library — FAISS, Chroma, Qdrant, or Pinecone. The API here (add, query, metadata filtering, MMR) intentionally mirrors those tools, so porting your prototype is mostly a matter of swapping the store — your surrounding code stays the same.
License
MIT
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 ragkit_vectorlite-0.1.0.tar.gz.
File metadata
- Download URL: ragkit_vectorlite-0.1.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e0defd803bfec9f5cbcf1bd0c7cf75086c2f611512d928a85bd6cff90dfea3b
|
|
| MD5 |
b0e523eb03d6f54bf2caa5aacb408b8d
|
|
| BLAKE2b-256 |
60ee1718fdaf550bb83c88a10b1beb26c0dc8746f9bb80531715ef418a808918
|
Provenance
The following attestation bundles were made for ragkit_vectorlite-0.1.0.tar.gz:
Publisher:
publish.yml on Meet2147/pythonLibraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ragkit_vectorlite-0.1.0.tar.gz -
Subject digest:
4e0defd803bfec9f5cbcf1bd0c7cf75086c2f611512d928a85bd6cff90dfea3b - Sigstore transparency entry: 2245055820
- Sigstore integration time:
-
Permalink:
Meet2147/pythonLibraries@6fde7a37ee929e2e8cfd85031d173ee2d3bb73a2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Meet2147
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6fde7a37ee929e2e8cfd85031d173ee2d3bb73a2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ragkit_vectorlite-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ragkit_vectorlite-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
107029901ebc9d990ac59b0381dd9bf7a013fef2c2e0379ae4b45fd53bf4a8a5
|
|
| MD5 |
dc63bf5fb5a0423a003e8adc880ede8f
|
|
| BLAKE2b-256 |
ccba978ad1ab03b43840f1a279044458a94ab37668503e5db457c142a8d7f4e5
|
Provenance
The following attestation bundles were made for ragkit_vectorlite-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Meet2147/pythonLibraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ragkit_vectorlite-0.1.0-py3-none-any.whl -
Subject digest:
107029901ebc9d990ac59b0381dd9bf7a013fef2c2e0379ae4b45fd53bf4a8a5 - Sigstore transparency entry: 2245056067
- Sigstore integration time:
-
Permalink:
Meet2147/pythonLibraries@6fde7a37ee929e2e8cfd85031d173ee2d3bb73a2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Meet2147
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6fde7a37ee929e2e8cfd85031d173ee2d3bb73a2 -
Trigger Event:
workflow_dispatch
-
Statement type: