Metadata-Version: 2.5
Name: vectrixdb
Version: 2.2.0
Summary: Where vectors come alive - A lightweight, visual-first vector database with embedded ML models
Project-URL: Homepage, https://github.com/knowusuboaky/VectrixDB
Project-URL: Documentation, https://knowusuboaky.github.io/VectrixDB/
Project-URL: Repository, https://github.com/knowusuboaky/VectrixDB
Project-URL: Changelog, https://github.com/knowusuboaky/VectrixDB/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/knowusuboaky/VectrixDB/issues
Author-email: Kwadwo Daddy Nyame Owusu - Boakye <kwadwo.owusuboakye@outlook.com>
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: ai,approximate-nearest-neighbors,embeddings,hnsw,machine-learning,similarity-search,vector-database
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Database
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: numpy>=1.24.0
Requires-Dist: onnxruntime<2,>=1.15.0
Requires-Dist: rich>=13.0.0
Requires-Dist: typer>=0.9.0
Requires-Dist: usearch>=2.0.0
Provides-Extra: all
Requires-Dist: azure-cosmos>=4.5.0; extra == 'all'
Requires-Dist: azure-identity>=1.15.0; extra == 'all'
Requires-Dist: azure-search-documents>=11.4.0; extra == 'all'
Requires-Dist: boto3>=1.28.0; extra == 'all'
Requires-Dist: databricks-sql-connector>=3.0.0; extra == 'all'
Requires-Dist: fastapi>=0.109.0; extra == 'all'
Requires-Dist: fastembed>=0.2.0; extra == 'all'
Requires-Dist: feedparser>=6.0.10; extra == 'all'
Requires-Dist: httpx>=0.24.0; extra == 'all'
Requires-Dist: mcp>=2.0.0; extra == 'all'
Requires-Dist: olefile>=0.46; extra == 'all'
Requires-Dist: openai>=1.0.0; extra == 'all'
Requires-Dist: openpyxl>=3.1.0; extra == 'all'
Requires-Dist: opensearch-py>=2.0.0; extra == 'all'
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'all'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'all'
Requires-Dist: pydantic>=2.0.0; extra == 'all'
Requires-Dist: pyjwt[crypto]>=2.8.0; extra == 'all'
Requires-Dist: pypdf>=4.0.0; extra == 'all'
Requires-Dist: pypdfium2>=4.20.0; extra == 'all'
Requires-Dist: python-docx>=1.0.0; extra == 'all'
Requires-Dist: qrcode>=7.4; extra == 'all'
Requires-Dist: requests-aws4auth>=1.2.0; extra == 'all'
Requires-Dist: scikit-learn>=1.3.0; extra == 'all'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'all'
Requires-Dist: truststore>=0.9; (python_version >= '3.10') and extra == 'all'
Requires-Dist: umap-learn>=0.5.0; extra == 'all'
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'all'
Requires-Dist: xlrd>=2.0.1; extra == 'all'
Provides-Extra: api
Requires-Dist: fastapi>=0.109.0; extra == 'api'
Requires-Dist: pydantic>=2.0.0; extra == 'api'
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'api'
Provides-Extra: asr
Requires-Dist: faster-whisper>=1.0.0; extra == 'asr'
Provides-Extra: asr-aws
Requires-Dist: boto3>=1.28.0; extra == 'asr-aws'
Provides-Extra: asr-azure
Provides-Extra: aws
Requires-Dist: boto3>=1.28.0; extra == 'aws'
Requires-Dist: opensearch-py>=2.0.0; extra == 'aws'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'aws'
Requires-Dist: requests-aws4auth>=1.2.0; extra == 'aws'
Provides-Extra: azure
Requires-Dist: azure-cosmos>=4.5.0; extra == 'azure'
Requires-Dist: azure-identity>=1.15.0; extra == 'azure'
Requires-Dist: azure-search-documents>=11.4.0; extra == 'azure'
Requires-Dist: openai>=1.0.0; extra == 'azure'
Provides-Extra: client
Requires-Dist: httpx>=0.24.0; extra == 'client'
Requires-Dist: truststore>=0.9; (python_version >= '3.10') and extra == 'client'
Provides-Extra: databricks
Requires-Dist: databricks-sql-connector>=3.0.0; extra == 'databricks'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'databricks'
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: hypothesis>=6.90.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pillow>=10.0.0; extra == 'dev'
Requires-Dist: pre-commit>=3.5.0; extra == 'dev'
Requires-Dist: psutil>=5.9.0; extra == 'dev'
Requires-Dist: pymupdf>=1.24.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest-github-actions-annotate-failures>=0.3.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: rank-bm25>=0.2.2; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: tomli>=2.0.0; (python_version < '3.11') and extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
Requires-Dist: mkdocs<2,>=1.5.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
Provides-Extra: documents
Requires-Dist: olefile>=0.46; extra == 'documents'
Requires-Dist: openpyxl>=3.1.0; extra == 'documents'
Requires-Dist: pypdf>=4.0.0; extra == 'documents'
Requires-Dist: pypdfium2>=4.20.0; extra == 'documents'
Requires-Dist: python-docx>=1.0.0; extra == 'documents'
Requires-Dist: xlrd>=2.0.1; extra == 'documents'
Provides-Extra: embeddings
Requires-Dist: fastembed>=0.2.0; extra == 'embeddings'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'embeddings'
Provides-Extra: extract
Requires-Dist: faster-whisper>=1.0.0; extra == 'extract'
Requires-Dist: imageio-ffmpeg>=0.4.9; extra == 'extract'
Requires-Dist: olefile>=0.46; extra == 'extract'
Requires-Dist: openpyxl>=3.1.0; extra == 'extract'
Requires-Dist: pillow>=10.0.0; extra == 'extract'
Requires-Dist: pypdf>=4.0.0; extra == 'extract'
Requires-Dist: pypdfium2>=4.20.0; extra == 'extract'
Requires-Dist: python-docx>=1.0.0; extra == 'extract'
Requires-Dist: rapidocr-onnxruntime>=1.3.0; extra == 'extract'
Requires-Dist: xlrd>=2.0.1; extra == 'extract'
Provides-Extra: fastembed
Requires-Dist: fastembed>=0.2.0; extra == 'fastembed'
Provides-Extra: feeds
Requires-Dist: feedparser>=6.0.10; extra == 'feeds'
Provides-Extra: ffmpeg
Requires-Dist: imageio-ffmpeg>=0.4.9; extra == 'ffmpeg'
Provides-Extra: hf
Requires-Dist: sentence-transformers>=2.2.0; extra == 'hf'
Provides-Extra: jobs-azure
Requires-Dist: azure-identity>=1.15.0; extra == 'jobs-azure'
Requires-Dist: azure-storage-blob>=12.19.0; extra == 'jobs-azure'
Requires-Dist: azure-storage-queue>=12.9.0; extra == 'jobs-azure'
Provides-Extra: masking
Requires-Dist: presidio-analyzer>=2.2.0; extra == 'masking'
Requires-Dist: spacy>=3.7.0; extra == 'masking'
Provides-Extra: mcp
Requires-Dist: httpx>=0.24.0; extra == 'mcp'
Requires-Dist: mcp>=2.0.0; extra == 'mcp'
Provides-Extra: nlp
Requires-Dist: spacy>=3.7.0; extra == 'nlp'
Provides-Extra: ocr
Requires-Dist: pillow>=10.0.0; extra == 'ocr'
Requires-Dist: pypdf>=4.0.0; extra == 'ocr'
Requires-Dist: pypdfium2>=4.20.0; extra == 'ocr'
Requires-Dist: rapidocr-onnxruntime>=1.3.0; extra == 'ocr'
Provides-Extra: ocr-aws
Requires-Dist: boto3>=1.28.0; extra == 'ocr-aws'
Provides-Extra: ocr-azure
Requires-Dist: azure-ai-documentintelligence>=1.0.0; extra == 'ocr-azure'
Provides-Extra: postgres
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'postgres'
Provides-Extra: setup-models
Requires-Dist: optimum[onnxruntime]>=1.12.0; extra == 'setup-models'
Requires-Dist: torch>=2.0.0; extra == 'setup-models'
Requires-Dist: transformers>=4.30.0; extra == 'setup-models'
Provides-Extra: signin
Requires-Dist: pyjwt[crypto]>=2.8.0; extra == 'signin'
Requires-Dist: qrcode>=7.4; extra == 'signin'
Provides-Extra: test
Requires-Dist: azure-cosmos>=4.5.0; extra == 'test'
Requires-Dist: azure-identity>=1.15.0; extra == 'test'
Requires-Dist: azure-search-documents>=11.4.0; extra == 'test'
Requires-Dist: black>=23.0.0; extra == 'test'
Requires-Dist: fastapi>=0.109.0; extra == 'test'
Requires-Dist: feedparser>=6.0.10; extra == 'test'
Requires-Dist: httpx>=0.24.0; extra == 'test'
Requires-Dist: hypothesis>=6.90.0; extra == 'test'
Requires-Dist: mcp>=2.0.0; extra == 'test'
Requires-Dist: mypy>=1.0.0; extra == 'test'
Requires-Dist: olefile>=0.46; extra == 'test'
Requires-Dist: openai>=1.0.0; extra == 'test'
Requires-Dist: openpyxl>=3.1.0; extra == 'test'
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'test'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == 'test'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'test'
Requires-Dist: pillow>=10.0.0; extra == 'test'
Requires-Dist: pre-commit>=3.5.0; extra == 'test'
Requires-Dist: psutil>=5.9.0; extra == 'test'
Requires-Dist: pydantic>=2.0.0; extra == 'test'
Requires-Dist: pyjwt[crypto]>=2.8.0; extra == 'test'
Requires-Dist: pymupdf>=1.24.0; extra == 'test'
Requires-Dist: pypdf>=4.0.0; extra == 'test'
Requires-Dist: pypdfium2>=4.20.0; extra == 'test'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
Requires-Dist: pytest-github-actions-annotate-failures>=0.3.0; extra == 'test'
Requires-Dist: pytest>=7.0.0; extra == 'test'
Requires-Dist: python-docx>=1.0.0; extra == 'test'
Requires-Dist: qrcode>=7.4; extra == 'test'
Requires-Dist: rank-bm25>=0.2.2; extra == 'test'
Requires-Dist: ruff>=0.1.0; extra == 'test'
Requires-Dist: tomli>=2.0.0; (python_version < '3.11') and extra == 'test'
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'test'
Requires-Dist: xlrd>=2.0.1; extra == 'test'
Provides-Extra: tracing
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'tracing'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == 'tracing'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'tracing'
Provides-Extra: video
Requires-Dist: faster-whisper>=1.0.0; extra == 'video'
Requires-Dist: imageio-ffmpeg>=0.4.9; extra == 'video'
Provides-Extra: viz
Requires-Dist: scikit-learn>=1.3.0; extra == 'viz'
Requires-Dist: umap-learn>=0.5.0; extra == 'viz'
Provides-Extra: youtube
Requires-Dist: yt-dlp>=2024.1.0; extra == 'youtube'
Description-Content-Type: text/markdown

<div align="center">

# VectrixDB

**The vector database that works with no network and no accounts.**

Embedded ONNX models, GraphRAG, and eight storage backends.
Nothing to sign up for, no API key, no service to run.

[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Python Versions](https://img.shields.io/pypi/pyversions/vectrixdb.svg)](https://pypi.org/project/vectrixdb/)
[![VectrixDB Version](https://img.shields.io/pypi/v/vectrixdb.svg)](https://pypi.org/project/vectrixdb/)
[![Downloads](https://pepy.tech/badge/vectrixdb)](https://pepy.tech/project/vectrixdb)
[![Issues](https://img.shields.io/github/issues/knowusuboaky/VectrixDB)](https://github.com/knowusuboaky/VectrixDB/issues)

[Changelog](https://github.com/knowusuboaky/VectrixDB/blob/main/CHANGELOG.md) &middot;
[Contributing](https://github.com/knowusuboaky/VectrixDB/blob/main/CONTRIBUTING.md) &middot;
[Security](https://github.com/knowusuboaky/VectrixDB/blob/main/SECURITY.md) &middot;
[Handle errors](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/handle-errors.md)

</div>

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/dashboard/tour-search.gif" alt="The VectrixDB dashboard: a question typed in, and its results, each led by its relevance and what found it" width="860">
  <br><sub>A question goes in, and every result says how well it matched and what found it: meaning, keywords, or both.</sub>
</p>

---

## Install

```bash
pip install vectrixdb
```

Five dependencies. That is the whole library: vector search, with the embedding
model inside the package. No web server, no cloud SDKs, no account.

## Quick start

```python
from vectrixdb import Vectrix

db = Vectrix("my_docs")
db.add(["Python is great", "JavaScript powers the web", "Rust is fast"])

results = db.search("programming")
print(results.top.text)
```

There is no configuration step. The embedding model ships with the package, so
the first search works offline on a machine that has never seen an API key.

It persists under `./vectrixdb_data` unless told otherwise; give a path to
choose where:

```python
db = Vectrix("my_docs", path="./data")
```

The default backend is SQLite in WAL mode, so committed writes survive an abrupt
shutdown and several threads can read and write at once.

## The server and its dashboard

`pip install "vectrixdb[api]"` and `vectrixdb serve` give the same collections
a REST API and a dashboard: health and text, search with a relevance on every
result, the evaluation runs that pick a setup, and with `vectrixdb[signin]`
people who sign in as themselves, roles, masking, and a record of who read
what. [Use the dashboard](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/dashboard.md) walks every page.

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/dashboard/evaluate.png" alt="The Evaluate page with a sample run: three picks, found in the top 10 against search time, and every setup ranked" width="860">
  <br><sub>The run in this picture is sample data, drawn to show the page, not a measurement. <code>vectrixdb evaluate</code> on your own questions gives real numbers.</sub>
</p>

## Run it in containers

Each release publishes signed images of the server and the extraction service,
for Intel and ARM. `docker/compose.yaml` runs the two on one machine, with
Jaeger beside them to see each search and upload as a trace, and
`docker/kubernetes` runs them on a cluster.
[Run it in containers](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/containers.md) has the steps, and how to
check a signature before anything runs.

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/containers/compose.gif" alt="Compose starting the server, the extraction service and Jaeger, then a scan read by the extraction service and a search that finds its words" width="860">
</p>

## From the command line, four languages, or an assistant

The same server answers the `vectrixdb` command, clients in Python,
TypeScript, Go and Rust, and an assistant over MCP. Every client keeps the same
safety rules: no key over plain HTTP, no redirects, certificates always checked.

| | Install | Guide |
|---|---|---|
| Command line | `pip install "vectrixdb[client]"` | [Use the command line on a server](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/command-line-server.md) |
| Python | `pip install "vectrixdb[client]"` | [Use it from Python, TypeScript, Go or Rust](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/clients.md) |
| TypeScript | `npm install vectrixdb` | [npm](https://www.npmjs.com/package/vectrixdb) |
| Go | `go get github.com/knowusuboaky/VectrixDB/sdk/go/v2` | [pkg.go.dev](https://pkg.go.dev/github.com/knowusuboaky/VectrixDB/sdk/go/v2) |
| Rust | `cargo add vectrixdb` | [crates.io](https://crates.io/crates/vectrixdb) |
| MCP | `pip install "vectrixdb[mcp]"` | [Use your collections from an assistant over MCP](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-server.md) |

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/terminal/clients.gif" alt="One server and one document: the same search run from the Python, TypeScript, Go and Rust clients answers with the same citations" width="860">
</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/terminal/cli.gif" alt="The vectrixdb command pointed at a server: a folder ingested, a search with each result's citation, whoami naming the key, and a plain-HTTP address it refuses to send the key to" width="860">
</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/dashboard/tour-mcp.gif" alt="An assistant connects over MCP, lists the collections and searches: real calls to a sample server and the answers that came back" width="860">
</p>

A company can ship its own command or client on these
([Ship your own client or command](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/wrap-it.md)) and serve all of
it from its own registry ([Run it inside your company's registry](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/inside-your-registry.md)).

## Documentation

Grouped by what you came for: learning it, doing one thing, looking something
up, or understanding why it works that way. They render at
[knowusuboaky.github.io/VectrixDB](https://knowusuboaky.github.io/VectrixDB/).
Their examples are executed by the test suite, apart from the few that need an
optional package or a cloud account, so the code on them cannot quietly rot.

**Tutorial**

- [Getting started](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/tutorial/getting-started.md), from an empty directory
  to a working search in one sitting
- [Add it with your coding agent](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/coding-agents.md), a prompt to
  paste into any coding agent, and
  [llms.txt](https://knowusuboaky.github.io/VectrixDB/llms.txt), the docs index
  agents read

**Start**

- [Install what you need](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/install.md), which extra adds what
- [Run without a network](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/offline.md)
- [Tips and tricks](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/tips.md), the things that are easy to miss
- [Handle errors](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/handle-errors.md)

**Ingest**

- [Ingest documents](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/ingest-documents.md)
- [Chunking](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/chunking.md), the strategies, parent sections and
  rechunking
- [Extraction quality and blocked pages](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/extraction-quality.md)
- [Videos, podcasts and recordings](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/recordings.md), cited by the
  second
- [Embedding models](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/embedding-models.md), which ship in the wheel
  and which download
- [Extract, keep, index](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/extract-keep-index.md)
- [Ingest when a file lands](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/ingest-on-event.md)
- [Keep a collection in step with feeds and pages](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/sources.md)
- [Run an extraction service](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/extraction-service.md)

**Search and evaluate**

- [Search options](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/search-options.md), every argument and what a
  result carries
- [Trace an answer to its source](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/lineage.md)
- [Work with the knowledge graph](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/knowledge-graph.md)
- [Measure retrieval](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/measure-retrieval.md)
- [Evaluate every setup](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/evaluate-setups.md)

**Assistants and agents**

- [Use it from an assistant over MCP](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-server.md)
- [Connect your client](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-connect.md), VS Code, Cursor, a desktop
  assistant, a command line
- [Company sign-in for MCP](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-sign-in.md)
- [Keys for a team](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-keys.md)
- [Tools reference](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-tools.md), every tool, prompt and resource
- [On your own machine](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-local.md), the one-person server
- [Keep conversation memory](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/conversation-memory.md)

**Secure**

- [Sign people in](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/sign-in.md)
- [Keys and roles](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/keys-and-roles.md), scoped and expiring keys
- [Collection policies](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/collection-policies.md)
- [Restrict what a search can see](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/entitlements.md)
- [Masking](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/masking.md), names and ids replaced before indexing
- [Audit trail](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/audit-trail.md)

**Run in production**

- [Run the REST API](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/rest-api.md)
- [Deploy the server](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/deploy.md)
- [Run it in containers](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/containers.md), signed images for one
  machine or Kubernetes
- [Put it behind a gateway](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/behind-a-gateway.md), APIM, API Gateway
  or any proxy
- [Size the server for load](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/sizing.md)
- [Scale out](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/scale.md)
- [Check and doctor](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/troubleshoot.md)
- [Trace searches and ingestion](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/tracing.md), opt-in OpenTelemetry
  spans that never carry query or document text
- [Choose a storage backend](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/storage-backends.md)
- [Back up, move and restore](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/export-import.md)
- [Put your company's name on it](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/branding.md)
- [Use the dashboard](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/dashboard.md), every page, with pictures

**Build on it**

- [Use it from Python, TypeScript, Go or Rust](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/clients.md), the
  four clients and their one set of calls
- [Use the command line on a server](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/command-line-server.md),
  with a key file or your company sign-in
- [Ship your own client or command on it](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/wrap-it.md), a
  company's wrapper with its settings filled in, published in its own registry
- [Run it inside your company's registry](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/inside-your-registry.md),
  packages, images and models through JFrog Artifactory, and the company's
  own tool as the way in
- [Use it from async code](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/async.md)
- [Build an app on it](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/build-an-app.md), in any language, on
  somebody else's server
- [LangChain, LlamaIndex, plugins, CLI](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/integrations.md)

**Reference**

- [Easy API](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/easy.md), the `Vectrix` surface
- [Python client](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/client.md), `connect()` and the server's calls
- [Async](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/aio.md)
- [Sources](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/sources.md), [Ingest](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/ingest.md),
  [Extract](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/extract.md),
  [Chunk models](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/chunk-models.md),
  [Extraction quality](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/quality.md)
- [Evaluation](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/evaluation.md),
  [Policy](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/policy.md), [Masking](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/masking.md),
  [Conversation memory](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/memory.md),
  [Tracing](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/tracing.md)
- [Exceptions](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/exceptions.md), the full hierarchy
- [Filters](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/filters.md), every operator and what it does to
  absent fields, nulls and lists
- [Command line](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/cli.md), every command and option
- [Settings](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/settings.md), every environment variable the
  server reads
- [REST API](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/rest-api.md), every route and who may call it
- [Errors](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/errors.md), every refusal a route can send and every
  exception the library raises, read off the code
- [OpenAPI document](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/reference/openapi.json), the same route table for a
  gateway to import

**Explanation**

- [Why VectrixDB](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/why-vectrixdb.md)
- [What it does not do](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/limits.md), the limits in one place
- [Benchmarks](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/benchmarks.md)
- [Search modes](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/search-modes.md)
- [Score and relevance](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/relevance.md)
- [HNSW and its limits](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/hnsw.md)
- [Threads and processes](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/concurrency.md)
- [Memory per vector](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/memory.md)
- [Writing past RAM](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/explanation/larger-than-ram.md)

## Errors

Everything VectrixDB raises derives from `VectrixError`, so one `except` covers
the library:

```python
from vectrixdb import VectrixError

try:
    results = db.search("programming")
except VectrixError as exc:
    log.warning("search unavailable: %s", exc)
```

A document that does not exist comes back as an empty result, not an
exception: `get()` takes one id or many and always returns a list, so a miss
is `[]`. A backend you cannot reach raises. Those stay distinguishable, so an
empty result always means "nothing matched" rather than "something broke".
See [Handle errors](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/handle-errors.md) for the full hierarchy.

---

## The dashboard is optional

> [!NOTE]
> **You do not need any of this to use VectrixDB.** The library is complete on
> its own, and `pip install vectrixdb` deliberately does not install a web
> server. The dashboard and REST API live behind an extra:
>
> ```bash
> pip install vectrixdb[api]
> vectrixdb serve
> ```
>
> Then open <http://127.0.0.1:7337/dashboard/>. If you only ever call VectrixDB
> from Python, skip this section entirely.

### What is on it

Nine pages, one server, no build step. Every number on them is read from the
running database and the page says so when it cannot read one. Each page is
shown with pictures in [Use the dashboard](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/dashboard.md).

- **Overview.** Collections, vectors, size on disk and search latency, and a
  *needs attention* list: a collection past 20% deleted vectors, a collection
  whose model is not on this machine. On a fresh server it is a first-run page
  with a working demo loader.
- **Collections.** Cards with a state pill, mode, language, model, tags and
  the current build id, filterable by state and mode. A collection opens with
  tabs: Overview, Points, Policy, Builds, Quality and Settings. A collection
  that carries an entitlement policy shows its rules and fingerprint and
  nothing that moves with its contents, because this API resolves no
  principals; each tab says so and shows the Python that does.
- **Search.** Hybrid by default, then dense, keyword and rerank, with the
  server time and round trip, per-result score parts where the mode reports
  them, and a graph tab for collections with entities. The previous page
  offered Rerank and Late interaction modes that the server ignored, so both
  ran plain dense search; Rerank is real now and Late interaction is gone
  until there is a text route for it.
- **Evaluate.** Golden questions run against every setup, ranked by how
  often the right answer is in the top ten and how long it took.
- **Ingest.** Files or pasted text into a collection as chunks, or into the
  document index, with metadata on every chunk. A plain splitter, on purpose:
  loaders, the four chunkers, parent sections, deduplication, the quality score
  and the metadata contract live in `add_document()`.
- **Audit.** The decision and ingestion records from a JSONL sink: with
  sign-in, to an admin; without it, only with `VECTRIXDB_API_KEY`; and never
  with the principal snapshot, the result ids or the undisclosable count.
- **Access.** For admins: the people and their roles, the keys and when each
  was last used, sign-ins against refusals.
- **Console.** A request builder with presets that shows the curl for what it
  sent.
- **Learn.** The tutorials and the copy-paste guide.

<p align="center">
  <img src="https://raw.githubusercontent.com/knowusuboaky/VectrixDB/main/docs/images/dashboard/tour-ingest.gif" alt="The Ingest page: a PDF added, and the server saying what it read: its pages, its chunks and their citations" width="860">
  <br><sub>A PDF goes in, the server reads it, and says what it found: two pages, two chunks, and the citation each one carries.</sub>
</p>

The badge in the sidebar reports what the server reports: *Open, no key set*
on a local server, *Read only* or *Authenticated* on one with a key. The
previous page said *Read Only* on every server and refused to load the demo
without a key the server did not have.

---

## Install what you need

The core install stays small on purpose. Everything past vector search is an
extra, so you never pay for a subsystem you do not use.

```bash
pip install vectrixdb              # the library, five dependencies

pip install vectrixdb[api]         # REST API server and dashboard
pip install vectrixdb[aws]         # OpenSearch, Aurora PostgreSQL
pip install vectrixdb[azure]       # Cosmos DB
pip install vectrixdb[databricks]  # Lakebase, Delta Lake
pip install vectrixdb[postgres]    # PostgreSQL
pip install vectrixdb[hf]          # HuggingFace sentence-transformers
pip install vectrixdb[fastembed]   # FastEmbed
pip install vectrixdb[viz]         # UMAP visualisation
pip install vectrixdb[mcp]         # MCP server for agent memory
pip install vectrixdb[nlp]         # spaCy, for better GraphRAG extraction

pip install vectrixdb[all]         # every backend and model extra above,
                                   # mcp included; not nlp, which is separate
```

From source, or a specific version:

```bash
pip install git+https://github.com/knowusuboaky/VectrixDB.git
pip install git+https://github.com/knowusuboaky/VectrixDB.git@v2.2.0
```

[uv](https://docs.astral.sh/uv/) works everywhere pip does here, including the
extras: `uv add vectrixdb`, or `uv pip install "vectrixdb[api]"`. The package
is a standard PEP 517 build with no pip-specific steps, so nothing about the
install path is special.

## Benchmarks

Same vectors, same machine, one thread, each library at its defaults. Reproduce with `python scripts/benchmark_compare.py --size 10000 --queries 200`; the [benchmarks page](https://knowusuboaky.github.io/VectrixDB/explanation/benchmarks/) has the chart, the BEIR retrieval-quality numbers and the caveats in full.

| Engine | ingest 10,000 | recall@10 | p50 | p95 | QPS |
| --- | ---: | ---: | ---: | ---: | ---: |
| VectrixDB | 1.7 s | 0.998 | 0.88 ms | 1.16 ms | 1,091 |
| Chroma | 2.2 s | 1.000 | 1.90 ms | 2.34 ms | 510 |
| LanceDB | 4.0 s | 0.802 | 7.24 ms | 8.83 ms | 135 |
| Qdrant (local mode) | 32.6 s | 1.000 | 16.87 ms | 21.36 ms | 57 |

Measured on 19 September 2026 on an Intel x86-64 CPU with 8 threads, Windows 11, Python 3.13. Milliseconds are the machine's; the order and the gaps are what carry over.

Two things the table hides. Qdrant's local mode is exhaustive search, not the server's HNSW, so its recall is 1.0 by construction; and LanceDB's default index is IVF_PQ, which trades recall for memory and can be tuned up. Embedding dominates real ingest for every engine and is not in this table.

### How it compares, honestly

| | VectrixDB | Chroma | LanceDB | Qdrant |
| --- | --- | --- | --- | --- |
| Embedding model in the package, offline | yes | no, downloads on first use | no | no |
| Hybrid search with BM25 | yes | Chroma Cloud only | yes, its own full-text index | yes, sparse vectors fused by RRF; the BM25 model is a download |
| Cross-encoder reranker bundled | yes | no | no | no |
| Late interaction (ColBERT) | yes, model in the package | no | yes, multivector columns; bring the model | yes, multivectors with MaxSim; bring the model |
| Knowledge graph and GraphRAG | yes | no | no | no |
| Conversation memory with token budgets | yes | no | no | no |
| Metadata filters | yes | yes | yes | yes |
| Columnar storage, Arrow, versioned tables | no | no | yes | no |
| Runs as a server for many clients | one team, one process: sign-in, roles, an access log | yes | cloud | yes |
| Sharding and replication | no | no | cloud | yes |
| GPU embedding | bundled models run on the CPU; via your own model | via your own model | via your own model | via your own model |
| Billions of vectors | no | no | yes, on disk | yes, clustered |

Checked against chromadb 1.5.9, lancedb 0.38.0 and qdrant-client 1.19.0, each embedded in a Python process as the benchmark runs them: Chroma refuses a sparse index outside its cloud, and LanceDB and Qdrant's local mode both search multivectors. VectrixDB is the one to pick when the search has to live inside a Python process and work with nothing else running. It is the wrong pick for a fleet of machines, a GPU embedding pipeline, or a corpus that does not fit one box.

## What is in the box

| | |
|---|---|
| **Search modes** | Dense, hybrid, ultimate (reranked), graph (GraphRAG) |
| **Storage** | Memory, SQLite, Lakebase, Delta Lake, Cosmos DB, Azure AI Search, OpenSearch, Aurora PostgreSQL |
| **Models** | Bundled ONNX for offline use, or bring your own from HuggingFace |
| **Memory** | Conversation turns, pinned facts, recency and feedback weighting |
| **Extras** | Document index with chunking, REST API, dashboard, CLI, MCP server |
| **Typing** | Ships `py.typed`, so your type checker sees the annotations |

---

## Search Modes

VectrixDB offers 4 search modes, each building on the previous:

| Mode | Components | Best For |
|------|------------|----------|
| `dense` | Vector similarity | Fast semantic search |
| `hybrid` | Dense + Sparse + Reranker | Keyword + semantic matching |
| `ultimate` | Hybrid + ColBERT | Maximum accuracy |
| `graph` | Ultimate + Knowledge Graph | Complex reasoning (GraphRAG) |

```python
# Choose your mode
db = Vectrix("docs", mode="dense")     # Fastest
db = Vectrix("docs", mode="hybrid")    # Balanced
db = Vectrix("docs", mode="ultimate")  # Best quality
db = Vectrix("docs", mode="graph")     # GraphRAG
```

---

## Model Selection

Customize models for each component. Models load from 3 sources:

### 1. Bundled Models (Offline, No Downloads)

Pre-packaged ONNX models that work without internet. Three of them, 33 MiB each, plus the BM25 vocabulary: about 100 MiB unpacked. They compress to most of a 68.6 MiB wheel, against PyPI's 100 MiB limit, measured by `python scripts/check_wheel_size.py`. Sizes here are mebibytes, the same unit PyPI measures that limit in; a file manager counting in megabytes shows the wheel as 72 MB.

```python
db = Vectrix(
    "docs",
    mode="ultimate",
    dense_model="bge-small",           # 384 dim, 33MB, the default
    sparse_model="bm25",               # 1MB
    reranker_model="L12",              # 33MB
    late_interaction_model="colbert",  # 33MB
)
```

| Component | Alias | Model | Dimension | Size |
|-----------|-------|-------|-----------|------|
| Dense | `bge-small` (default) | BAAI/bge-small-en-v1.5 | 384 | 33MB |
| Sparse | `bm25` | BM25 vocabulary | - | 1MB |
| Reranker | `L12` | ms-marco-MiniLM-L-12-v2 | - | 33MB |
| ColBERT | `colbert` | answerai-colbert-small-v1 | 128 | 33MB |

`e5-small` (intfloat/e5-small-v2, the default before 2.2) is not in the wheel.
A collection built with it fetches it once, or moves to `bge-small` with
`reembed()`. Other languages need the multilingual models, about 230 MB, from
`vectrixdb download-models`; English needs nothing from it. See
[Run without a network](https://knowusuboaky.github.io/VectrixDB/how-to/offline/).

### 2. Larger models, fetched by hand

These are too big to bundle and are published on the releases page. Naming one
does **not** download it. First use raises `ModelNotFoundError`, a
`FileNotFoundError`, with the URL to fetch and the directory to unpack it into,
so nothing reaches the network without you deciding to:

```pycon
>>> db = Vectrix("docs", dense_model="bge-base")
>>> db.add(["..."])
ModelNotFoundError: Dense model not found: .../models/data/bge_base_en/model.onnx

This model must be downloaded from GitHub releases.
Download: https://github.com/knowusuboaky/VectrixDB/releases/latest
Unpack it into: .../models/data/bge_base_en
```

| Alias | Model | Dimension | Size |
|-------|-------|-----------|------|
| `bge-base` | BAAI/bge-base-en-v1.5 | 768 | 110MB |
| `bge-reranker` | BAAI/bge-reranker-base | - | 212MB |
| `colbert-v2` | colbert-ir/colbertv2.0 | 128 | 67MB |
| `splade` | SPLADE++ | - | 508MB |

Unpack into the directory the error names, or point `VECTRIXDB_MODELS_DIR` at
a directory that already holds them, which is how you would cache them on a
shared volume.

There is one form that does download: a model named `github:<release-tag>`
fetches that release's archive on first use. It is the only path in the
library that reaches the network on its own.

### 3. HuggingFace Models

Use any compatible model from HuggingFace (requires `pip install vectrixdb[hf]`):

```python
db = Vectrix(
    "docs",
    mode="hybrid",
    dense_model="BAAI/bge-large-en-v1.5",
    sparse_model="naver/splade-cocondenser-ensembledistil",
    reranker_model="cross-encoder/ms-marco-MiniLM-L-12-v2",
)
```

**Compatible models:**
- Dense: `BAAI/bge-large-en-v1.5`, `intfloat/e5-large-v2`, `sentence-transformers/all-mpnet-base-v2`
- Sparse: `naver/splade-cocondenser-ensembledistil`
- Reranker: `cross-encoder/ms-marco-MiniLM-L-12-v2`, `BAAI/bge-reranker-base`
- ColBERT: `jinaai/jina-colbert-v2`, `colbert-ir/colbertv2.0`

---

## Storage Backends

VectrixDB has 8 storage backends, plus one deprecated alias:

| Backend | Type | Persistence | Modes | Best For |
|---------|------|-------------|-------|----------|
| `memory` | In-Memory | No | All | Testing, small datasets |
| `sqlite` | File-based | Yes | All | Local development |
| `lakebase` | PostgreSQL + pgvector | Yes | All | Databricks Lakebase |
| `delta_lake` | Delta Lake | Yes | All | Databricks Unity Catalog |
| `cosmosdb` | Azure CosmosDB | Yes | All | Azure cloud |
| `postgresql` | *deprecated alias* | | | Warns and resolves to `aurora_postgresql`, which speaks pgvector over any PostgreSQL. Removed in 2.3 |
| `opensearch` | AWS OpenSearch | Yes | Dense, Hybrid | AWS managed search |
| `aurora_postgresql` | AWS Aurora + pgvector | Yes | All | AWS managed PostgreSQL |
| `azure_search` | Azure AI Search | Yes | Dense, Hybrid | Azure managed search, semantic ranker |

### Memory Storage (Default)

```python
from vectrixdb import VectrixDB, StorageConfig, StorageBackend

# In-memory (default, no persistence)
db = VectrixDB()

# Or explicitly
config = StorageConfig(backend=StorageBackend.MEMORY)
db = VectrixDB(storage_config=config)
```

### SQLite Storage (Local Persistence)

```python
from vectrixdb import VectrixDB

# SQLite with file path
db = VectrixDB(path="./my_vectors")

# Creates: ./my_vectors/_vectrixdb.db
```

### Lakebase Storage (Databricks)

```python
from vectrixdb import Vectrix, VectrixDB

# Connect to Lakebase (PostgreSQL + pgvector)
lakebase = VectrixDB.with_lakebase(
    host="your-lakebase-host.cloud.databricks.com",
    database="databricks_postgres",
    user="your-user",
    password="your-oauth-token",  # OAuth JWT from Lakebase Connect
    port=5432,
)

# Use with Vectrix
db = Vectrix(
    "products",
    mode="ultimate",
    storage_backend=lakebase,
)

db.add(texts=["Product A", "Product B"])
results = db.search("query")
```

### Delta Lake Storage (Databricks Unity Catalog)

```python
from vectrixdb import VectrixDB

# Connect to Delta Lake via Databricks SQL
delta = VectrixDB.with_delta_lake(
    workspace_url="https://your-workspace.cloud.databricks.com",
    token="dapi_your_token",
    catalog="main",
    schema="vectrixdb",
    warehouse_id="your_warehouse_id",
)

# Use with Vectrix
db = Vectrix("products", mode="hybrid", storage_backend=delta)
```

### CosmosDB Storage (Azure)

```python
from vectrixdb import VectrixDB, StorageConfig, StorageBackend

config = StorageConfig(
    backend=StorageBackend.COSMOSDB,
    cosmos_endpoint="https://your-account.documents.azure.com:443/",
    cosmos_key="your-primary-key",
    cosmos_database="vectrixdb",
)

db = VectrixDB(storage_config=config)
```

### Azure AI Search Storage (Azure)

Vector, BM25 and hybrid queries served by Azure AI Search, one index per collection, with Azure's semantic ranker as an option.

> **Note**: Azure AI Search supports `dense` and `hybrid` modes. Late interaction and the knowledge graph stay local.

```python
import os
from vectrixdb import Vectrix, VectrixDB

azure = VectrixDB.with_azure_search(
    endpoint="https://my-service.search.windows.net",
    key=os.environ["AZURE_SEARCH_KEY"],   # or key=None for DefaultAzureCredential
    semantic=False,                        # True adds Azure's semantic ranker (needs a tier that has it)
)

db = Vectrix("products", mode="hybrid", storage_backend=azure)
db.add(["Product A", "Product B"])
results = db.search("query")
```

Install with `pip install vectrixdb[azure]`. Ids are stored as given and keyed by a URL-safe encoding, so any string id works. Writes become searchable when the service has indexed them, normally within a second or two.

### OpenSearch Storage (AWS)

AWS OpenSearch Serverless with native k-NN vector search.

> **Note**: OpenSearch supports `dense` and `hybrid` modes only.

```python
from vectrixdb import VectrixDB

opensearch = VectrixDB.with_opensearch(
    endpoint="https://xxx.us-east-1.aoss.amazonaws.com",
    region="us-east-1",
)
```

### Aurora PostgreSQL Storage (AWS)

AWS Aurora PostgreSQL with pgvector. Supports all modes including `ultimate`.

```python
from vectrixdb import VectrixDB

aurora = VectrixDB.with_aurora_postgresql(
    host="cluster.xxx.us-east-1.rds.amazonaws.com",
    database="vectrixdb",
    user="admin",
    password="password",
)
```

### Adaptive Schema

Schema adapts based on selected mode:

| Mode | Columns Created |
|------|-----------------|
| `dense` | `id`, `dense_embedding`, `metadata`, `text_content`, `created_at`, `updated_at` |
| `hybrid` | + `sparse_embedding` |
| `ultimate` | + `late_interaction_embedding` |
| `graph` | Same as ultimate + graph tables |

---

## Document Index

Hierarchical document storage with automatic chunking:

```python
from vectrixdb import VectrixDB, chunk_text, chunk_with_context

# The document index lives on a database and shares its storage
client = VectrixDB("./data")
doc_index = client.documents

markdown_text = """# Guide

## Install

pip install vectrixdb

## Search

Call search with a query string.
"""

# Chunk text (simple)
chunks = chunk_text(
    "Your long document text here...",
    chunk_size=1000,
    chunk_overlap=200,
)

# Chunk markdown with context (preserves headings)
chunks = chunk_with_context(
    markdown_text,
    chunk_size=1200,
    chunk_overlap=200,
)
# Returns: [{"content": "...", "heading": "Section Title", "level": 2}, ...]

# Build tree from markdown
from vectrixdb import build_tree_from_markdown

tree = build_tree_from_markdown(markdown_text, doc_id="guide")
# build_tree_from_pdf(text, doc_id) does the same for text extracted from a PDF
```

### Document Index with Storage Backend

```python
from vectrixdb import VectrixDB

# Connect to storage
lakebase = VectrixDB.with_lakebase(...)

# The document index keeps its documents and nodes in the same storage
doc_index = lakebase.documents

doc_index.index_text("doc_001", "# My Document\n\nThe text.", title="My Document")

# Query documents
docs = doc_index.list_documents()
nodes = doc_index.get_document_nodes("doc_001")
```

---

## Metadata & Filtering

```python
from vectrixdb import Vectrix

db = Vectrix("phones")
db.add(
    texts=["iPhone 15", "Galaxy S24", "Pixel 8"],
    metadata=[
        {"brand": "Apple", "price": 999},
        {"brand": "Samsung", "price": 899},
        {"brand": "Google", "price": 699}
    ]
)

# Filter by metadata
results = db.search("smartphone", filter={"brand": "Apple"})

# Complex filters
results = db.search("phone", filter={
    "brand": {"$in": ["Apple", "Samsung"]},
    "price": {"$lt": 1000}
})
```

---

## Advanced API

For full control, use the `VectrixDB` class directly:

```python
from vectrixdb import VectrixDB, Collection

# Create database
db = VectrixDB(path="./my_db")

# Create collection with specific dimension
coll = db.create_collection("products", dimension=384)

# Add vectors directly
coll.add(
    ids=["p1", "p2"],
    vectors=[[0.1] * 384, [0.3] * 384],   # your own 384-dim vectors
    metadata=[{"name": "Product A"}, {"name": "Product B"}],
)

# Search with vectors
results = coll.search(query=[0.1] * 384, limit=10)

# List collections
collections = db.list_collections()

# Delete collection
db.delete_collection("products")
```

---

## Embedded Models API

Use embedding models directly:

```python
from vectrixdb import (
    DenseEmbedder,
    SparseEmbedder,
    RerankerEmbedder,
    LateInteractionEmbedder,
)

# Dense embeddings
dense = DenseEmbedder(model="bge-small")  # in the wheel; e5-small is fetched by download-models
vectors = dense.embed(["Hello world", "How are you?"])

# Sparse embeddings (BM25)
sparse = SparseEmbedder()
sparse_vectors = sparse.embed(["Hello world"])

# Reranker
reranker = RerankerEmbedder(model="L12")
scores = reranker.rerank("query", ["doc1", "doc2", "doc3"])

# Late interaction (ColBERT): one vector per token, scored by MaxSim
colbert = LateInteractionEmbedder(model="colbert")
token_embeddings = colbert.encode_documents(["Hello world"])
scores = colbert.score("greeting", ["Hello world", "Quarterly revenue"])
```

---

## REST API

Start the server:

```bash
export VECTRIXDB_API_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
vectrixdb serve --port 7337
```

Open the dashboard at `http://localhost:7337/dashboard`

### API Examples

```bash
# Create collection
curl -X POST http://localhost:7337/api/v1/collections \
  -H "Content-Type: application/json" \
  -H "api-key: $VECTRIXDB_API_KEY" \
  -d '{"name": "docs", "dimension": 384}'

# Add documents (auto-embedding)
curl -X POST http://localhost:7337/api/v1/collections/docs/text-upsert \
  -H "Content-Type: application/json" \
  -H "api-key: $VECTRIXDB_API_KEY" \
  -d '{"points": [{"id": "1", "text": "Hello world"}]}'

# Search
curl -X POST http://localhost:7337/api/v1/collections/docs/text-search \
  -H "Content-Type: application/json" \
  -H "api-key: $VECTRIXDB_API_KEY" \
  -d '{"query_text": "greeting", "limit": 10}'
```

---

## Conversation memory

A collection can hold an agent's memory rather than a corpus. Turns go in with
a session and a role, come back weighted by recency as well as similarity, and
can be graded so that what proved useful outranks what did not.

```python
from vectrixdb import Vectrix

db = Vectrix("memory", path="./memory_data")

db.remember("we decided to ship on Friday", session="u42", role="user")
db.remember("the release owner is Ama", session="u42", role="user")
db.remember("deploys are frozen in December", session="u42", pinned=True)

for hit in db.recall("when do we ship", session="u42", limit=3):
    print(hit.text)

# One block sized to a budget: pinned facts, then recent turns, then
# whatever else is relevant, with nothing silently cut.
block = db.context("what did we decide", session="u42", token_budget=800)
print(block.text)
```

`feedback(id, outcome)` grades a memory as `useful`, `dead_end` or
`corrected`, and the grade decays with a half-life so an old verdict stops
outweighing a recent one. `consolidate()` turns a session's old turns into
dated standalone facts with an LLM of your choosing and drops the turns.
`forget()` is the one call that loses information on purpose: by ids, by age
within a session, or only the facts a correction has already superseded.

Measured on LoCoMo and LongMemEval: evidence recall under a 1,500-token
budget is 0.623 across ten LoCoMo conversations and 0.721 on the first 150 of
the LongMemEval oracle split, against 0.620 and 0.721 for plain search over
the same turns. `scripts/memory_bench.py` runs both by one command, and
[Conversation memory](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/conversation-memory.md) explains what the
number measures and what it does not.

---

## MCP server

A plain install puts a second command on your path, so an assistant, or any MCP
client, can search a collection and keep memory in it:

```bash
pip install "vectrixdb[mcp]"
vectrixdb-mcp --name notes --path ./data
```

Six tools: `search`, `recall`, `remember`, `feedback`, `context` and `forget`.
Every one takes a `token_budget`, and every answer opens with a line saying
whether anything was cut, because a silently shortened list reads to a model
as a complete one:

```
[!] TRUNCATED: showing 3 of 9 results (~200-token budget). The answer may be
among the 6 cut. Raise token_budget or narrow the query.
```

The tool bodies are plain functions, so a host that already holds a `Vectrix`
can call them without the `mcp` package. Full details, including how to register
it with a client and the other transports, are in
[Use a collection from an assistant over MCP](https://github.com/knowusuboaky/VectrixDB/blob/main/docs/how-to/mcp-server.md).

---

## GraphRAG

Build knowledge graphs from documents:

```python
import os

from vectrixdb import Vectrix, create_openai_config

# Create with graph mode
db = Vectrix("docs", mode="graph")

# Or with custom LLM config
config = create_openai_config(
    model="gpt-4o-mini",
    llm_api_key=os.environ.get("OPENAI_API_KEY"),
)

db = Vectrix(
    "docs",
    mode="graph",
    graphrag_config=config,
)

# Add documents (extracts entities & relationships)
db.add(["Apple announced the iPhone 15 in September 2023."])

# Search with graph reasoning
results = db.search("What products did Apple release?")
```

---

## Project Structure

```
VectrixDB/
├── vectrixdb/
│   ├── core/           # Vector index, storage, search
│   │   ├── storage.py  # All storage backends
│   │   ├── collection.py
│   │   ├── database.py
│   │   ├── document_index.py
│   │   ├── graphrag/   # Knowledge graph
│   │   └── search/     # Search algorithms
│   ├── api/            # FastAPI server
│   ├── models/         # Embedded ONNX models
│   │   └── data/       # Bundled model files
│   ├── dashboard/      # Web UI
│   ├── easy.py         # Vectrix simple API
│   └── cli.py          # Command line
├── tests/
└── pyproject.toml
```

---

## Requirements

- Python 3.9 through 3.14
- No API keys, and no network, for the bundled models
- The larger models are fetched by hand; naming one does not download it

---

## Project

- [Changelog](https://github.com/knowusuboaky/VectrixDB/blob/main/CHANGELOG.md), what changed in each release and why
- [Contributing](https://github.com/knowusuboaky/VectrixDB/blob/main/CONTRIBUTING.md), setup, where tests live, what a good patch
  looks like
- [Roadmap](https://github.com/knowusuboaky/VectrixDB/blob/main/ROADMAP.md), what is planned, what is deliberately not, and how to
  argue for a change
- [Governance](https://github.com/knowusuboaky/VectrixDB/blob/main/GOVERNANCE.md), who decides what merges
- [Code of conduct](https://github.com/knowusuboaky/VectrixDB/blob/main/CODE_OF_CONDUCT.md)
- [Security policy](https://github.com/knowusuboaky/VectrixDB/blob/main/SECURITY.md), supported versions and how to report a
  vulnerability privately

---

## License

[Apache 2.0](https://github.com/knowusuboaky/VectrixDB/blob/main/LICENSE). The models VectrixDB carries or downloads keep their authors' licences, listed in [NOTICE](https://github.com/knowusuboaky/VectrixDB/blob/main/NOTICE). One of them, the knowledge graph's relation extraction model, is for non-commercial use only.

---

## Author

**Kwadwo Daddy Nyame Owusu - Boakye**

GitHub: [@knowusuboaky](https://github.com/knowusuboaky)
