ContextWeave is a private knowledge base and chat system. You upload documents, the system indexes them, and users can ask questions about the indexed content.
- Upload PDF, Word, TXT, and other common files.
- Resume interrupted multipart uploads.
- Search with both keywords and meaning-based vectors.
- Rerank the best candidates with a Cross-Encoder.
- Restore the surrounding parent text when a small child chunk matches.
- Keep citations in chat answers and chat history.
- Enforce user, organization, and public-document permissions in both search paths.
The default FULL path is:
document -> child chunks -> BM25 + HNSW -> RRF -> Cross-Encoder
-> parent context -> Dynamic Top-K -> answer with citations
Current defaults:
- BM25 weight:
0.25 - HNSW weight:
1.0 - Recall window: up to
100candidates per branch - Cross-Encoder window:
20candidates - Parent chunk:
2048characters - Child chunk:
512characters with100characters of overlap
These settings are the best point found in the local experiments below. They are still configurable and should be rechecked on a larger production-like dataset.
Requirements: Windows 11, WSL2, Docker, Java 17, Maven, Node.js 18.20+, and pnpm 8.7+.
- Copy
.env.exampleto.envand fill in local database, service, and model keys. Never commit.env. - Start the local services:
powershell -ExecutionPolicy Bypass -File .\scripts\start-local.ps1- Open the chat page:
http://localhost:9527/#/chat - Stop the services when finished:
powershell -ExecutionPolicy Bypass -File .\scripts\stop-local.ps1For Java changes, compile without restarting the whole stack:
mvn -q -DskipTests compile| Service | Job |
|---|---|
| Spring Boot | API, permissions, search, chat |
| Vue 3 | Web interface |
| MySQL | Users, files, and durable chat history |
| Redis | Sessions, short-lived chat state, upload resume state |
| Elasticsearch | BM25 and HNSW search |
| Kafka | Background document processing |
| MinIO | Source files and upload parts |
The benchmark uses 48 fixed queries from a small SciFact/NFCorpus subset. It is useful for comparing changes, but it is not a full BEIR leaderboard or a production guarantee.
| Method | Recall@5 | Recall@10 | MRR@10 | NDCG@10 |
|---|---|---|---|---|
| BM25 | 0.4910 | 0.5111 | 0.7339 | 0.6313 |
| HNSW KNN | 0.5326 | 0.5799 | 0.8201 | 0.7264 |
| HNSW KNN + rerank | 0.5368 | 0.5889 | 0.8492 | 0.7509 |
| Equal hybrid + rerank | 0.5325 | 0.5700 | 0.8408 | 0.7365 |
Tuned hybrid + rerank (0.25:1.0) |
0.5441 | 0.5965 | 0.8492 | 0.7569 |
Equal-weight fusion gave BM25 too much influence. It changed the first 20 candidates sent to the reranker and pushed out useful semantic matches. A BM25:KNN weight of 0.25:1.0 fixed that on this benchmark.
For parent-child chunks, the 2048-character parent was the best balance tested. It reached Recall@5 0.5641, selected 7.04 results on average, and used fewer selected results than the 1024-character parent. The 4096 test timed out during an embedding request and was not counted.
Detailed, query-free reports are in benchmarks/retrieval/reports.
CONTEXTWEAVE_RETRIEVAL_RRF_BM25_WEIGHT=0.25
CONTEXTWEAVE_RETRIEVAL_RRF_KNN_WEIGHT=1.0
CONTEXTWEAVE_RERANK_MAX_CANDIDATES=20
CONTEXTWEAVE_RERANK_TOP_N=10
FILE_PARSING_PARENT_CHUNK_SIZE=2048mvn test
python -m unittest discover benchmarks\retrieval -p 'test_*.py'Frontend type checking:
Set-Location frontend
pnpm typecheckApache License 2.0. See LICENSE.