用本地模型时需按 Python 版本和加速器手动安装对应的 llama-cpp-python 预编译 wheel,并非所有组合都可用;插入非 PDF 文档需额外安装 raglite[pandoc];本地 llama.cpp 模型首次使用会从 Hugging Face 下载 GGUF 权重。
raglite
superlinear-aiMPL-2.0活跃维护轻量级 Python RAG 工具包,用 DuckDB 或 PostgreSQL 就能搭起检索增强生成,省去部署向量数据库的麻烦。
🥤 RAGLite is a Python toolkit for Retrieval-Augmented Generation (RAG) with DuckDB or PostgreSQL
pip install ragliteREADME 未说明显存要求;支持 macOS 上的 Metal 加速,以及 Linux 和 Windows 上的 CUDA 加速;本地模型通过 llama-cpp-python 预编译二进制运行。
轻量级 Python RAG 工具包,用 DuckDB 或 PostgreSQL 做检索,避开 PyTorch 和 LangChain
轻量级 Python RAG 工具包,用 DuckDB 或 PostgreSQL 就能搭起检索增强生成,省去部署向量数据库的麻烦。
核心能力
- 用 LiteLLM 接入任意 LLM,支持本地 llama-cpp-python 模型
- 用 DuckDB 或 PostgreSQL 原生 FTS 与向量检索做混合搜索
- 用二元整数规划求解最优句子切分与语义分块
- 多向量分块嵌入,结合 late chunking 与上下文标题
- 内置 MCP 服务器,可选 Chainlit 聊天前端与 Ragas 评估
容易踩的坑
- v1.1.1最新正式版2026-05-18 · 2026-05-18 07:31 UTC
What's Changed
- feat: add metadata filtering by @SimonJasansky in https://github.com/superlinear-ai/raglite/pull/160
- feat: add document metadata expansion by @emilradix in https://github.com/superlinear-ai/raglite/pull/161
- feat: add self-query functionality by @Robbe-Superlinear in https://github.com/superlinear-ai/raglite/pull/163
- feat: change sentence splitter to sat-1l-sm and fix: context management. by @jirastorza in https://github.com/superlinear-ai/raglite/pull/164
- docs: update README.md with metadata filtering documentation by @jirastorza in https://github.com/superlinear-ai/raglite/pull/168
- chore: update mypy to ignore unused ignores by @emilradix in https://github.com/superlinear-ai/raglite/pull/169
- fix: cap max_workers in insert_documents by @Robbe-Superlinear in https://github.com/superlinear-ai/raglite/pull/167
- feat: add parallel tool execution by @jirastorza in https://github.com/superlinear-ai/raglite/pull/166
- feat: support deletion for PostgreSQL and DuckDB by @r-dh in https://github.com/superlinear-ai/raglite/pull/170
- fix: ignore warning that prevents tests from running by @r-dh in https://github.com/superlinear-ai/raglite/pull/173
- perf: optimise splitting of chunklets by @r-dh in https://github.com/superlinear-ai/raglite/pull/171
- perf: replace ILP solver with O(N) dynamic programming for sentence splitting by @r-dh in https://github.com/superlinear-ai/raglite/pull/176
- fix: relax user prompt in programmatic rag by @MattiaMolon in https://github.com/superlinear-ai/raglite/pull/177
- fix(insert): handle duplicate documents by @MattiaMolon in https://github.com/superlinear-ai/raglite/pull/174
- fix: resolve ruff 0.15.0 lint violations by @r-dh in https://github.com/superlinear-ai/raglite/pull/178
- feat: add Mistral Document AI for document parsing by @r-dh in https://github.com/superlinear-ai/raglite/pull/175
- feat: allow for multiple metadata filters on list fields by @MattiaMolon in https://github.com/superlinear-ai/raglite/pull/179
- feat: add agentic RAG with iterative sub-agent search by @MattiaMolon in https://github.com/superlinear-ai/raglite/pull/180
- fix: narrow Python support and remove Mistral extra by @StijnGoossens in https://github.com/superlinear-ai/raglite/pull/183
New Contributors
- @Robbe-Superlinear made their first contribution in https://github.com/superlinear-ai/raglite/pull/163
- @jirastorza made their first contribution in https://github.com/superlinear-ai/raglite/pull/164
- @r-dh made their first contribution in https://github.com/superlinear-ai/raglite/pull/170
- @StijnGoossens made their first contribution in https://github.com/superlinear-ai/raglite/pull/183
Full Changelog: https://github.com/superlinear-ai/raglite/compare/v1.0.0...v1.1.1
- v1.0.02025-06-11 · 2025-06-11 15:55 UTC
查看更新说明
🎉 RAGLite v1.0: DuckDB, Qwen3, parallel insertion, benchmarking, better retrieval quality
Release Highlights
- 🐤 support for DuckDB (#137)
- 🐻 support for Qwen3 (#124)
- ⚡️ parallel document insertion (#150)
- 🏁 benchmarking with
raglite bench(#150) - 🎯 better retrieval quality with improved multi-vector search, chunk quality, and chunk front matter (#123, #126, #132)
- 💎 new and improved query adapter algorithm (#146, #147, #149)
What's Changed
- fix: don't convert markdown to markdown by @joachim-Heirbrant-SL in https://github.com/superlinear-ai/raglite/pull/116
- fix: fix chunking of single-sentence chunks by @emilradix in https://github.com/superlinear-ai/raglite/pull/115
- fix: incorporate headings and prevent windowing chunks by @emilradix in https://github.com/superlinear-ai/raglite/pull/117
- fix: improve contextual chunk headings by @SimonJasansky in https://github.com/superlinear-ai/raglite/pull/118
- feat: add option to use single chunk embeddings by @emilradix in https://github.com/superlinear-ai/raglite/pull/119
- feat: add metadata at the document level by @emilradix in https://github.com/superlinear-ai/raglite/pull/122
- feat: add support for reasoning tool use and upgrade to Qwen3 by @lsorber in https://github.com/superlinear-ai/raglite/pull/124
- feat: add front matter to chunk content by @lsorber in https://github.com/superlinear-ai/raglite/pull/126
- feat: introduce chunklets to improve chunking by @lsorber in https://github.com/superlinear-ai/raglite/pull/123
- fix: remove mdformat by @emilradix in https://github.com/superlinear-ai/raglite/pull/128
- feat: rank chunks by the L∞ norm of their multi-vector similarity by @lsorber in https://github.com/superlinear-ai/raglite/pull/132
- feat: enable weighted reciprocal rank fusion by @emilradix in https://github.com/superlinear-ai/raglite/pull/136
- fix: fix off-by-one error in parsing of Markdown headings by @joachim-Heirbrant-SL in https://github.com/superlinear-ai/raglite/pull/133
- feat: improve config and API by @lsorber in https://github.com/superlinear-ai/raglite/pull/138
- feat: replace SQLite with DuckDB by @lsorber in https://github.com/superlinear-ai/raglite/pull/137
- ci: skip slow tests in CI by @lsorber in https://github.com/superlinear-ai/raglite/pull/139
- fix: adapt oversampling to chunk size by @lsorber in https://github.com/superlinear-ai/raglite/pull/140
- feat: make pandas an optional dependency by @lsorber in https://github.com/superlinear-ai/raglite/pull/141
- fix: upgrade rerankers and recommended Cohere model by @lsorber in https://github.com/superlinear-ai/raglite/pull/142
- fix: improve token assignment in late chunking by @lsorber in https://github.com/superlinear-ai/raglite/pull/144
- fix: run checkpoint after DuckDB inserts by @lsorber in https://github.com/superlinear-ai/raglite/pull/145
- feat: improve query adapter algorithm by @lsorber in https://github.com/superlinear-ai/raglite/pull/146
- feat: add ability to control the gap in query adapter by @lsorber in https://github.com/superlinear-ai/raglite/pull/147
- feat: optimally separate result sets in query adapter by @lsorber in https://github.com/superlinear-ai/raglite/pull/149
- feat: parallelize inserts and add benchmarking by @lsorber in https://github.com/superlinear-ai/raglite/pull/150
- docs: set Rerankers verbosity to 0 in README by @ThomasDelsart in https://github.com/superlinear-ai/raglite/pull/156
- fix: fix parsing of font sizes for pdfs with no headings by @ThomasDelsart in https://github.com/superlinear-ai/raglite/pull/155
New Contributors
- @SimonJasansky made their first contribution in https://github.com/superlinear-ai/raglite/pull/118
Full Changelog: https://github.com/superlinear-ai/raglite/compare/v0.7.0...v1.0.0
- v0.7.02025-03-17 · 2025-03-17 13:22 UTC
查看更新说明
What's Changed
- feat: make importing faster by @lsorber in https://github.com/superlinear-ai/raglite/pull/86
- fix: avoid conflicting chunk ids by @joachim-Heirbrant-SL in https://github.com/superlinear-ai/raglite/pull/93
- feat: add ability to directly insert Markdown content into the database by @ThomasDelsart in https://github.com/superlinear-ai/raglite/pull/96
- feat: make llama-cpp-python an optional dependency by @rchretien in https://github.com/superlinear-ai/raglite/pull/97
- feat: migrate from poetry-cookiecutter to substrate by @rchretien in https://github.com/superlinear-ai/raglite/pull/98
- chore: upgrade scaffolding by @lsorber in https://github.com/superlinear-ai/raglite/pull/105
- fix: revert pandoc extra name by @lsorber in https://github.com/superlinear-ai/raglite/pull/106
- docs: improve inline comments by @lsorber in https://github.com/superlinear-ai/raglite/pull/107
- fix: lazily raise module not found for optional deps by @lsorber in https://github.com/superlinear-ai/raglite/pull/109
- feat: compute optimal sentence boundaries by @lsorber in https://github.com/superlinear-ai/raglite/pull/110
- fix: fix CLI entrypoint regression by @lsorber in https://github.com/superlinear-ai/raglite/pull/111
- feat: replace post-processing with declarative optimization by @lsorber in https://github.com/superlinear-ai/raglite/pull/112
New Contributors
- @joachim-Heirbrant-SL made their first contribution in https://github.com/superlinear-ai/raglite/pull/93
- @ThomasDelsart made their first contribution in https://github.com/superlinear-ai/raglite/pull/96
- @rchretien made their first contribution in https://github.com/superlinear-ai/raglite/pull/97
Full Changelog: https://github.com/superlinear-ai/raglite/compare/v0.6.2...v0.7.0
- v0.6.22025-01-06 · 2025-01-06 22:27 UTC
查看更新说明
What's Changed
- fix: remove unnecessary stop sequence by @lsorber in https://github.com/superlinear-ai/raglite/pull/84
Full Changelog: https://github.com/superlinear-ai/raglite/compare/v0.6.1...v0.6.2
- v0.6.12025-01-06 · 2025-01-06 14:18 UTC
查看更新说明
What's Changed
- fix: conditionally enable
LlamaRAMCacheby @lsorber in https://github.com/superlinear-ai/raglite/pull/83 - fix(deps): exclude litellm versions that break get_model_info by @lsorber in https://github.com/superlinear-ai/raglite/pull/78
- fix: improve (re)insertion speed by @lsorber in https://github.com/superlinear-ai/raglite/pull/80
- fix: fix Markdown heading boundary probas by @lsorber in https://github.com/superlinear-ai/raglite/pull/81
Full Changelog: https://github.com/superlinear-ai/raglite/compare/v0.6.0...v0.6.1
- fix: conditionally enable
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
🥤 RAGLite
RAGLite is a Python toolkit for Retrieval-Augmented Generation (RAG) with DuckDB or PostgreSQL.
Features
Configurable
- 🧠 Choose any LLM provider with LiteLLM, including local llama-cpp-python models
- 💾 Choose either DuckDB or PostgreSQL as a keyword & vector search database
- 🥇 Choose any reranker with rerankers, including multilingual FlashRank as the default
Fast and permissive
- ❤️ Only lightweight and permissive open source dependencies (e.g., no PyTorch or LangChain)
- 🚀 Acceleration with Metal on macOS, and CUDA on Linux and Windows
Unhobbled
- 📖 PDF to Markdown conversion on top of pdftext and pypdfium2
- 🧬 Multi-vector chunk embedding with late chunking and contextual chunk headings
- ✏️ Optimal sentence splitting with wtpsplit-lite by solving a binary integer programming problem
- ✂️ Optimal semantic chunking by solving a binary integer programming problem
- 🔍 Hybrid search with the database's native keyword & vector search (FTS+VSS; tsvector+pgvector)
- 💭 Adaptive retrieval where the LLM decides whether to and what to retrieve based on the query
- 💰 Improved cost and latency with a prompt caching-aware message array structure
- 🍰 Improved output quality with Anthropic's long-context prompt format
- 🌀 Optimal closed-form linear query adapter by solving an orthogonal Procrustes problem
Extensible
- 🔌 A built-in Model Context Protocol (MCP) server that any MCP client like Claude desktop can connect with
- 💬 Optional customizable ChatGPT-like frontend for web, Slack, and Teams with Chainlit
- ✍️ Optional conversion of any input document to Markdown with Pandoc
- 🔎 Optional high-quality document processing with Mistral OCR for PDFs, images, DOCX, and PPTX with automatic image descriptions
- ✅ Optional evaluation of retrieval and generation performance with Ragas
Installing
[!TIP] 🚀 If you want to use local models, it is recommended to install an accelerated llama-cpp-python precompiled binary with:
# Configure which llama-cpp-python precompiled binary to install (⚠️ not every combination is available): LLAMA_CPP_PYTHON_VERSION=0.3.9 PYTHON_VERSION=310|311|312 ACCELERATOR=metal|cu121|cu122|cu123|cu124 PLATFORM=macosx_11_0_arm64|linux_x86_64|win_amd64 # Install llama-cpp-python: pip install "https://github.com/abetlen/llama-cpp-python/releases/download/v$LLAMA_CPP_PYTHON_VERSION-$ACCELERATOR/llama_cpp_python-$LLAMA_CPP_PYTHON_VERSION-cp$PYTHON_VERSION-cp$PYTHON_VERSION-$PLATFORM.whl"
Install RAGLite with:
pip install raglite
To add support for a customizable ChatGPT-like frontend, use the chainlit extra:
pip install raglite[chainlit]
To add support for filetypes other than PDF, use the pandoc extra:
pip install raglite[pandoc]
To add support for high-quality document processing with Mistral OCR, install mistralai:
pip install mistralai
To add support for evaluation, use the ragas extra:
pip install raglite[ragas]
Using
Overview
- Configuring RAGLite
- Inserting documents
- Retrieval-Augmented Generation (RAG)
- Computing and using an optimal query adapter
- Evaluation of retrieval and generation
- Running a Model Context Protocol (MCP) server
- Serving a customizable ChatGPT-like frontend
1. Configuring RAGLite
[!TIP] 🧠 RAGLite extends LiteLLM with support for llama.cpp models using llama-cpp-python. To select a llama.cpp model (e.g., from Unsloth's collection), use a model identifier of the form
"llama-cpp-python/<hugging_face_repo_id>/<filename>@<n_ctx>", wheren_ctxis an optional parameter that specifies the context size of the model.
[!TIP] 💾 You can create a PostgreSQL database in a few clicks at neon.tech.
First, configure RAGLite with your preferred DuckDB or PostgreSQL database and any LLM supported by LiteLLM:
from raglite import RAGLiteConfig
# Example 'remote' config with a PostgreSQL database and an OpenAI LLM:
my_config = RAGLiteConfig(
db_url="postgresql://my_username:my_password@my_host:5432/my_database",
llm="gpt-4o-mini", # Or any LLM supported by LiteLLM
embedder="text-embedding-3-large", # Or any embedder supported by LiteLLM
)
# Example 'local' config with a DuckDB database and a llama.cpp LLM:
my_config = RAGLiteConfig(
db_url="duckdb:///raglite.db",
llm="llama-cpp-python/unsloth/Qwen3-8B-GGUF/*Q4_K_M.gguf@8192",
embedder="llama-cpp-python/lm-kit/bge-m3-gguf/*F16.gguf@512", # More than 512 tokens degrades bge-m3's performance
)
You can also configure any reranker supported by rerankers:
from rerankers import Reranker
# Example remote API-based reranker:
my_config = RAGLiteConfig(
db_url="postgresql://my_username:my_password@my_host:5432/my_database"
reranker=Reranker("rerank-v3.5", model_type="cohere", api_key=COHERE_API_KEY, verbose=0) # Multilingual
)
# Example local cross-encoder reranker per language (this is the default):
my_config = RAGLiteConfig(
db_url="duckdb:///raglite.db",
reranker={
"en": Reranker("ms-marco-MiniLM-L-12-v2", model_type="flashrank", verbose=0), # English
"other": Reranker("ms-marco-MultiBERT-L-12", model_type="flashrank", verbose=0), # Other languages
}
)
Self-query is also supported, allowing the LLM to automatically generate and apply metadata filters to refine search results based on the user's input. To enable self-query, set self_query=True in your RAGLiteConfig:
my_config = RAGLiteConfig(
db_url="duckdb:///raglite.db",
llm="gpt-4o-mini",
embedder="text-embedding-3-large",
self_query=True, # Enable self-query
)
2. Inserting documents
[!TIP] ✍️ To insert documents other than PDF, install the
pandocextra withpip install raglite[pandoc].
[!TIP] 🔎 For higher-quality document processing with automatic image descriptions, install
mistralaiand configure it as follows:from raglite import RAGLiteConfig, MistralOCRConfig my_config = RAGLiteConfig( document_processor=MistralOCRConfig( include_image_descriptions=True, # Describe images, charts, and diagrams as text image_types=frozenset({"chart", "diagram", "photo", "table", "logo", "icon"}), # Custom image categories exclude_image_types=frozenset({"logo", "icon"}), # Filter out specific types from the output ), )The
image_typesparameter defines the categories that Mistral classifies each image into — you can use the defaults or provide your own domain-specific types. Useexclude_image_typesto filter out any classified types that are not useful for retrieval.
Next, insert some documents into the database. RAGLite will take care of the conversion to Markdown, optimal level 4 semantic chunking, and multi-vector embedding with late chunking:
# Insert documents given their file path
from pathlib import Path
from raglite import Document, insert_documents
documents = [
Document.from_path(Path("On the Measure of Intelligence.pdf")),
Document.from_path(Path("Special Relativity.pdf")),
]
insert_documents(documents, config=my_config)
# Insert documents given their text/plain or text/markdown content
content = """
# ON THE ELECTRODYNAMICS OF MOVING BODIES
## By A. EINSTEIN June 30, 1905
It is known that Maxwell...
"""
documents = [
Document.from_text(content, author="Einstein", topic="physics", year=1905)
]
insert_documents(documents, config=my_config)
[!TIP] 📝 Documents can include metadata by passing keyword arguments to
Document.from_text()orDocument.from_path(). This metadata can later be used for filtering during retrieval. For list values, metadata is stored as-is (e.g.domain=["open", "music"]).
You may also want to expand the document metadata before insertion:
from typing import Annotated, Literal
from pydantic import Field
from raglite import expand_document_metadata
# Expand the documents' metadata.
metadata_fields = {
"title": Annotated[str, Field(..., description="Document title.")],
"author": Annotated[str, Field(..., description="Primary author.")],
"topics": Annotated[list[Literal["A", "B", "C"]], Field(..., description="Key themes.")],
}
documents = list(expand_document_metadata(documents, metadata_fields, config=my_config))
# Insert documents given their text/plain or text/markdown content
insert_documents(documents, config=my_config)
3. Retrieval-Augmented Generation (RAG)
3.1 Adaptive RAG
Now you can run an adaptive RAG pipeline that consists of adding the user prompt to the message history and streaming the LLM response:
from raglite import rag
# Create a user message
messages = [] # Or start with an existing message history
messages.append({
"role": "user",
"content": "How is intelligence measured?"
})
# Adaptively decide whether to retrieve and then stream the response
chunk_spans = []
stream = rag(messages, on_retrieval=lambda x: chunk_spans.extend(x), config=my_config)
for update in stream:
print(update, end="")
# Access the documents referenced in the RAG context
documents = [chunk_span.document for chunk_span in chunk_spans]
The LLM will adaptively decide whether to retrieve information based on the complexity of the user prompt. If retrieval is necessary, the LLM generates the search query and RAGLite applies hybrid search and reranking to retrieve the most relevant chunk spans (each of which is a list of consecutive chunks). The retrieval results are sent to the on_retrieval callback and are appended to the message history as a tool output. Finally, the assistant response is streamed and appended to the message history.
3.2 Programmable RAG
If you need manual control over the RAG pipeline, you can run a basic but powerful pipeline that consists of retrieving the most relevant chunk spans with hybrid search and reranking, converting the user prompt to a RAG instruction and appending it to the message history, and finally generating the RAG response:
from raglite import add_context, rag, retrieve_context, vector_search
# Choose a search method
from dataclasses import replace
my_config = replace(my_config, search_method=vector_search) # Or `hybrid_search`, `search_and_rerank_chunks`, ...
# Retrieve relevant chunk spans with the configured search method
user_prompt = "How is intelligence measured?"
chunk_spans = retrieve_context(
query=user_prompt,
num_chunks=5,
metadata_filter={"author": "Einstein"}, # Optional: filter by metadata
config=my_config
)
# Append a RAG instruction based on the user prompt and context to the message history
messages = [] # Or start with an existing message history
messages.append(add_context(user_prompt=user_prompt, context=chunk_spans, config=my_config))
# Stream the RAG response and append it to the message history
stream = rag(messages, config=my_config)
for update in stream:
print(update, end="")
# Access the documents referenced in the RAG context
documents = [chunk_span.document for chunk_span in chunk_spans]
[!TIP] 🥇 Reranking can significantly improve the output quality of a RAG application. To add reranking to your application: first search for a larger set of 20 relevant chunks, then rerank them with a rerankers reranker, and finally keep the top 5 chunks.
RAGLite also offers more advanced control over the individual steps of a full RAG pipeline:
- Searching for relevant chunks with keyword, vector, or hybrid search
- Retrieving the chunks from the database
- Reranking the chunks and selecting the top 5 results
- Extending the chunks with their neighbors and grouping them into chunk spans
- Converting the user prompt to a RAG instruction and appending it to the message history
- Streaming an LLM response to the message history
- Accessing the cited documents from the chunk spans
A full RAG pipeline is straightforward to implement with RAGLite:
# Search for chunks
from raglite import hybrid_search, keyword_search, vector_search
user_prompt = "How is intelligence measured?"
chunk_ids_vector, _ = vector_search(user_prompt, num_results=20, config=my_config)
chunk_ids_keyword, _ = keyword_search(user_prompt, num_results=20, config=my_config)
chunk_ids_hybrid, _ = hybrid_search(
user_prompt, num_results=20, metadata_filter={"topic": "physics"}, config=my_config
) # Filter results to only include chunks from documents with topic="physics" (works with any search method)
# Multi-value filter in one field uses OR semantics:
chunk_ids_or, _ = hybrid_search(
user_prompt,
num_results=20,
metadata_filter={"domain": ["open", "music"]},
config=my_config,
) # Returns chunks where domain includes "open" OR "music".
# Retrieve chunks
from raglite import retrieve_chunks
chunks_hybrid = retrieve_chunks(chunk_ids_hybrid, config=my_config)
# Rerank chunks and keep the top 5 (optional, but recommended)
from raglite import rerank_chunks
chunks_reranked = rerank_chunks(user_prompt, chunks_hybrid, config=my_config)
chunks_reranked = chunks_reranked[:5]
# Extend chunks with their neighbors and group them into chunk spans
from raglite import retrieve_chunk_spans
chunk_spans = retrieve_chunk_spans(chunks_reranked, config=my_config)
# Append a RAG instruction based on the user prompt and context to the message history
from raglite import add_context
messages = [] # Or start with an existing message history
messages.append(add_context(user_prompt=user_prompt, context=chunk_spans, config=my_config))
# Stream the RAG response and append it to the message history
from raglite import rag
stream = rag(messages, config=my_config)
for update in stream:
print(update, end="")
# Access the documents referenced in the RAG context
documents = [chunk_span.document for chunk_span in chunk_spans]
4. Computing and using an optimal query adapter
RAGLite can compute and apply an optimal closed-form query adapter to the prompt embedding to improve the output quality of RAG. To benefit from this, first generate a set of evals with insert_evals and then compute and store the optimal query adapter with update_query_adapter:
# Improve RAG with an optimal query adapter
from raglite import insert_evals, update_query_adapter
insert_evals(num_evals=100, config=my_config)
update_query_adapter(config=my_config) # From here, every vector search will use the query adapter
5. Evaluation of retrieval and generation
If you installed the ragas extra, you can use RAGLite to answer the evals and then evaluate the quality of both the retrieval and generation steps of RAG using Ragas:
# Evaluate retrieval and generation
from raglite import answer_evals, evaluate, insert_evals
insert_evals(num_evals=100, config=my_config)
answered_evals_df = answer_evals(num_evals=10, config=my_config)
evaluation_df = evaluate(answered_evals_df, config=my_config)
6. Running a Model Context Protocol (MCP) server
RAGLite comes with an MCP server implemented with FastMCP that exposes a search_knowledge_base tool. To use the server:
- Install Claude desktop
- Install uv so that Claude desktop can start the server
- Configure Claude desktop to use
uvto start the MCP server with:
raglite \
--db-url duckdb:///raglite.db \
--llm llama-cpp-python/unsloth/Qwen3-4B-GGUF/*Q4_K_M.gguf@8192 \
--embedder llama-cpp-python/lm-kit/bge-m3-gguf/*F16.gguf@512 \
mcp install
To use an API-based LLM, make sure to include your credentials in a .env file or supply them inline:
export OPENAI_API_KEY=sk-...
raglite \
--llm gpt-4o-mini \
--embedder text-embedding-3-large \
mcp install
Now, when you start Claude desktop you should see a 🔨 icon at the bottom right of your prompt indicating that the Claude has successfully connected with the MCP server.
When relevant, Claude will suggest to use the search_knowledge_base tool that the MCP server provides. You can also explicitly ask Claude to search the knowledge base if you want to be certain that it does.
7. Serving a customizable ChatGPT-like frontend
If you installed the chainlit extra, you can serve a customizable ChatGPT-like frontend with:
raglite chainlit
The application is also deployable to web, Slack, and Teams.
You can specify the database URL, LLM, and embedder directly in the Chainlit frontend, or with the CLI as follows:
raglite \
--db-url duckdb:///raglite.db \
--llm llama-cpp-python/unsloth/Qwen3-4B-GGUF/*Q4_K_M.gguf@8192 \
--embedder llama-cpp-python/lm-kit/bge-m3-gguf/*F16.gguf@512 \
chainlit
To use an API-based LLM, make sure to include your credentials in a .env file or supply them inline:
OPENAI_API_KEY=sk-... raglite --llm gpt-4o-mini --embedder text-embedding-3-large chainlit
Contributing
-
Generate an SSH key and add the SSH key to your GitHub account.
-
Configure SSH to automatically load your SSH keys:
cat << EOF >> ~/.ssh/config Host * AddKeysToAgent yes IgnoreUnknown UseKeychain UseKeychain yes ForwardAgent yes EOF -
Install VS Code and VS Code's Dev Containers extension. Alternatively, install PyCharm.
-
Optional: install a Nerd Font such as FiraCode Nerd Font and configure VS Code or PyCharm to use it.
The following development environments are supported:
-
⭐️ GitHub Codespaces: click on Open in GitHub Codespaces to start developing in your browser.
-
⭐️ VS Code Dev Container (with container volume): click on Open in Dev Containers to clone this repository in a container volume and create a Dev Container with VS Code.
-
⭐️ uv: clone this repository and run the following from root of the repository:
# Create and install a virtual environment uv sync --python 3.10 --all-extras # Activate the virtual environment source .venv/bin/activate # Install the pre-commit hooks pre-commit install --install-hooks -
VS Code Dev Container: clone this repository, open it with VS Code, and run Ctrl/⌘ + ⇧ + P → Dev Containers: Reopen in Container.
-
PyCharm Dev Container: clone this repository, open it with PyCharm, create a Dev Container with Mount Sources, and configure an existing Python interpreter at
/opt/venv/bin/python.
- This project follows the Conventional Commits standard to automate Semantic Versioning and Keep A Changelog with Commitizen.
- Run
poefrom within the development environment to print a list of Poe the Poet tasks available to run on this project. - Run
uv add {package}from within the development environment to install a run time dependency and add it topyproject.toml. Add--devto install a development dependency. - Run
uv sync --upgradefrom within the development environment to upgrade all dependencies to the latest versions allowed bypyproject.toml. Add--only-devto upgrade the development dependencies only. - Run
cz bumpto bump the package's version, update theCHANGELOG.md, and create a git tag. Then push the changes and the git tag withgit push origin main --tags.