Token-efficient document ingestion and RAG connector
Project description
knomi
knomi is a token-efficient document ingestion CLI and RAG connector for local AI agents: it indexes your documents (PDF, Markdown, DOCX, HTML, plain text) into a vector database and serves them as a retrieval source for Claude, OpenWebUI, Ollama and other agents.
Project Status
Published on PyPI (pip install knomi);
releases are tag-driven — see docs/WORKFLOWS.md.
Features
- Recursive document ingestion — scans a folder for PDFs, Markdown, plain text, DOCX, and HTML files.
- Token-efficient chunking — expresses
chunk_size/chunk_overlapin tokens (viatiktoken), not characters, across three strategies:token,structure,sentence. - Deduplication — stores a SHA-256 hash per source file and skips re-embedding unchanged documents.
- Pluggable embeddings —
openai,local(sentence-transformers),cohere, orollama. - Pluggable vector stores —
qdrant(default),chroma, orpgvector; all share the same abstract interface. - Named profiles — bundle store, embedding, and chunking settings in
knomi.jsonand switch between them with--profile. - RAG serve mode — exposes the indexed vector store as an HTTP API for Claude, OpenWebUI, Ollama, and other agents.
- Single-command infrastructure —
docker compose upbrings up Qdrant and an optional ingest worker.
Installation
knomi is a Python package published on PyPI. The npm and Homebrew options are thin wrappers that install and delegate to that same package — they require Python ≥ 3.12 on the machine.
# PyPI (recommended)
pip install knomi # or: uv tool install knomi / pipx install knomi
# npm — wrapper; runs `pip/pipx/uv install knomi` on postinstall (needs Python ≥ 3.12)
npm install -g knomi
# Homebrew — formula builds an isolated virtualenv (needs Python ≥ 3.12)
brew tap franjofranjic27/knomi
brew install knomi
Optional backends ship as extras and are imported lazily — install only what you use:
pip install "knomi[chroma]" # ChromaDB store
pip install "knomi[pgvector]" # Postgres/pgvector store
pip install "knomi[cohere]" # Cohere embeddings
pip install "knomi[ollama]" # Ollama embeddings
pip install "knomi[all]" # everything at once
Quick start
Option A — Docker + Qdrant (recommended)
# 1. Clone the repo (for compose.yml) and start Qdrant
git clone https://github.com/franjofranjic27/knomi.git
cd knomi
docker compose up qdrant -d
# 2. Install knomi and ingest your documents
pip install knomi
knomi ingest ./docs --backend qdrant --db-url http://localhost:6333 --collection my-kb
Option B — zero infrastructure (ChromaDB)
pip install "knomi[chroma]"
knomi ingest ./docs --backend chroma --db-url ./.knomi/chroma --collection my-kb
CLI usage
The global --profile / -p option selects a profile from knomi.json (see
Profiles & configuration) and applies to every subcommand.
ingest — index documents into the vector store
# Ingest a folder using the default (or selected) profile
knomi ingest ./docs
# Pick a profile and override the chunking strategy
knomi ingest ./docs --profile cloud --strategy structure
# Custom chunk size, overlap, and collection
knomi ingest ./docs --chunk-size 512 --chunk-overlap 64 --collection my-kb
# Choose store + embedding backends explicitly
knomi ingest ./docs --backend qdrant --db-url http://qdrant:6333 \
--embedding-backend openai --embedding-model text-embedding-3-small --embedding-dim 1536
profiles — list the profiles defined in knomi.json
knomi profiles
# Shows each profile's store, embedding, and chunking backends; marks the default.
status — inspect a collection
knomi status
# Prints point count and indexed-vector count for the resolved collection.
delete — remove a document from a collection
knomi delete <sha256-doc-id>
# Removes every vector whose doc_id matches the given SHA-256.
serve — expose RAG as an HTTP API for agents
knomi serve --port 8080
# Starts an HTTP server (GET /health, POST /query) that agents can query.
eval — measure retrieval quality against a gold set
Turn "did I pick the right embedding model / chunking strategy?" from a guess
into a measurement. A gold set (JSON or JSONL) lists questions and the source
documents that should be retrieved; knomi eval reports Recall@k, nDCG@k,
Hit@k and MRR for the selected profile against an already-indexed collection.
# Gold set (JSONL — one question per line, document-level relevance):
# {"question": "What is self-attention?", "relevant_sources": ["Transformer.pdf"]}
knomi --profile local eval gold.jsonl --collection uni-sg --top-k 10
knomi --profile local eval gold.jsonl --json report.json # machine-readable dump
Because each profile is a full config (embedding × chunking × store), evaluating
is an A/B test — run the same gold set under -p local vs -p cloud and compare
the numbers. See eval.example.jsonl for a template. relevant_sources are
matched leniently (basename / substring), so you only need the file name.
Reranking (optional second stage)
Vector search is fast but scores query and document independently. A cross-encoder reranker re-scores the top candidates jointly, which is often (but not always!) more accurate. It is opt-in per profile:
"reranking": {
"enabled": true,
"backend": "local",
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
"top_n": 20
}
The store returns top_n candidates, the reranker re-scores them down to your
top_k. Backends: local (HuggingFace CrossEncoder, no API key) or cohere.
Toggle it ad hoc for A/B testing:
knomi -p local eval gold.jsonl --collection uni-sg # baseline
knomi -p local eval gold.jsonl --collection uni-sg --rerank # with reranking
Reranking is not a guaranteed win — a reranker trained on a different domain, or a small gold set, can regress. Measure it with
knomi evalbefore enabling it.
Profiles & configuration
Configuration precedence
Settings resolve from four layers, highest priority first:
- CLI flags — e.g.
--backend,--strategy,--collection. - Environment variables — prefixed with
KNOMI_, nested groups joined by__(e.g.KNOMI_STORE__COLLECTION,KNOMI_EMBEDDING__BACKEND). - The selected
knomi.jsonprofile — chosen via--profile,KNOMI_PROFILE, or the file'sdefault_profile. - Built-in defaults.
knomi.json
A profile bundles the three nested config groups (store, embedding, chunking). knomi
searches for knomi.json in the current working directory first, then in
~/.config/knomi/ ($XDG_CONFIG_HOME/knomi/ if set). Copy
knomi.example.json to get started.
{
"default_profile": "local",
"profiles": {
"local": {
"store": { "backend": "chroma", "path": "./.knomi/chroma", "collection": "knomi" },
"embedding": { "backend": "local", "model": "sentence-transformers/all-MiniLM-L6-v2", "dim": 384 },
"chunking": { "strategy": "structure", "chunk_size": 512, "chunk_overlap": 64 }
},
"cloud": {
"store": { "backend": "qdrant", "url": "https://your-cluster.qdrant.io:6333", "collection": "knomi" },
"embedding": { "backend": "openai", "model": "text-embedding-3-small", "dim": 1536, "workers": 4 },
"chunking": { "strategy": "token", "chunk_size": 512, "chunk_overlap": 64 }
}
}
}
Select a profile per invocation:
knomi --profile cloud ingest ./docs # or: KNOMI_PROFILE=cloud knomi ingest ./docs
Secrets
Secrets are never stored in knomi.json. They are read from the environment and merged
into the resolved config based on the selected backend:
| Env var | Used by |
|---|---|
OPENAI_API_KEY |
embedding.backend = openai |
COHERE_API_KEY |
embedding.backend = cohere |
QDRANT_API_KEY |
store.backend = qdrant (Qdrant Cloud) |
KNOMI_PG_DSN |
store.backend = pgvector |
Backends & strategies
| Group | Config key | Values | Notes |
|---|---|---|---|
| Store | store.backend |
qdrant (default), chroma, pgvector |
chroma/pgvector need the matching extra |
| Embedding | embedding.backend |
openai (default), local, cohere, ollama |
cohere/ollama need the matching extra |
| Chunking | chunking.strategy |
token (default), structure, sentence |
all express sizes in tokens |
Selected fields
| Config key | Env var | Default | Description |
|---|---|---|---|
source_dir |
KNOMI_SOURCE_DIR |
. |
Folder to scan for documents |
store.backend |
KNOMI_STORE__BACKEND |
qdrant |
Vector store backend |
store.url |
KNOMI_STORE__URL |
http://localhost:6333 |
Qdrant server URL |
store.path |
KNOMI_STORE__PATH |
None |
On-disk path for local backends |
store.collection |
KNOMI_STORE__COLLECTION |
knomi |
Collection / table name |
embedding.backend |
KNOMI_EMBEDDING__BACKEND |
openai |
Embedding backend |
embedding.model |
KNOMI_EMBEDDING__MODEL |
text-embedding-3-small |
Model name or ID |
embedding.dim |
KNOMI_EMBEDDING__DIM |
1536 |
Output vector dimension |
chunking.strategy |
KNOMI_CHUNKING__STRATEGY |
token |
Chunking strategy |
chunking.chunk_size |
KNOMI_CHUNKING__CHUNK_SIZE |
512 |
Max chunk size in tokens |
chunking.chunk_overlap |
KNOMI_CHUNKING__CHUNK_OVERLAP |
64 |
Token overlap between chunks |
serve_port |
KNOMI_SERVE_PORT |
8080 |
Port for the RAG HTTP server |
top_k |
KNOMI_TOP_K |
5 |
Chunks returned per query |
Tech Stack
| Technology | Version | Purpose |
|---|---|---|
| Python | ≥ 3.12 | Language (uv-managed) |
| Typer | — | CLI framework |
| tiktoken | — | Token-based chunking |
| sentence-transformers | — | Local embeddings |
| Qdrant / ChromaDB | — | Vector stores |
| pytest / ruff / mypy | — | Tests, lint, types |
Documentation
| Document | Description |
|---|---|
| Docs site | Rendered documentation (GitHub Pages) |
| docs/ARCHITECTURE.md | System design, pipeline, interfaces |
| docs/adr/ | Architecture decision records |
| docs/COMMIT_CONVENTION.md | Commit message format and rules |
| docs/TESTING.md | How to run and write tests |
| docs/WORKFLOWS.md | GitHub Actions CI/CD workflows |
| docs/troubleshooting.md | Common problems and fixes |
| CONTRIBUTING.md | Contributor setup and workflow |
Repo-wide conventions (README/badge standard, PR and issue templates) live in franjofranjic27/.github.
License
Project details
Release history Release notifications | RSS feed
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 knomi-0.1.0.tar.gz.
File metadata
- Download URL: knomi-0.1.0.tar.gz
- Upload date:
- Size: 304.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d92b010e1fa7b5cb7d5fd5d9db21d67bf9ec192a66e4659348e688f8692900ac
|
|
| MD5 |
568073d160092a3b8d40490d2aec6737
|
|
| BLAKE2b-256 |
bc88cbc8d4f1d76478176d42ab9219998c4ec59a81aa3758e479cf914f6e6c8d
|
Provenance
The following attestation bundles were made for knomi-0.1.0.tar.gz:
Publisher:
release-knomi.yaml on franjofranjic27/knomi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knomi-0.1.0.tar.gz -
Subject digest:
d92b010e1fa7b5cb7d5fd5d9db21d67bf9ec192a66e4659348e688f8692900ac - Sigstore transparency entry: 2155301468
- Sigstore integration time:
-
Permalink:
franjofranjic27/knomi@16af6fcc954e86fea8e62685d3351d17a2c62016 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/franjofranjic27
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-knomi.yaml@16af6fcc954e86fea8e62685d3351d17a2c62016 -
Trigger Event:
push
-
Statement type:
File details
Details for the file knomi-0.1.0-py3-none-any.whl.
File metadata
- Download URL: knomi-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2472ab27c99a4278df4a29df878ac00f840a2f712479644515bad176962e1a0
|
|
| MD5 |
94523904d82cc8c78d4afcb0b92d9d1a
|
|
| BLAKE2b-256 |
4798246a7279408a9ea78479a31f9c595aae3b489f79a9d3032a9ca44339386a
|
Provenance
The following attestation bundles were made for knomi-0.1.0-py3-none-any.whl:
Publisher:
release-knomi.yaml on franjofranjic27/knomi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knomi-0.1.0-py3-none-any.whl -
Subject digest:
b2472ab27c99a4278df4a29df878ac00f840a2f712479644515bad176962e1a0 - Sigstore transparency entry: 2155301516
- Sigstore integration time:
-
Permalink:
franjofranjic27/knomi@16af6fcc954e86fea8e62685d3351d17a2c62016 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/franjofranjic27
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-knomi.yaml@16af6fcc954e86fea8e62685d3351d17a2c62016 -
Trigger Event:
push
-
Statement type: