local-semantic-rag
A local-first Retrieval-Augmented Generation (RAG) library for Python.
Build semantic search and RAG applications using local embeddings, vector stores, and local LLMs โ without sending your documents to external APIs.
Features
- ๐ Semantic Search โ Search documents using vector embeddings.
- ๐ง RAG Pipeline โ Retrieve relevant context and generate grounded answers.
- ๐ Multiple Document Formats โ TXT, PDF, Markdown, HTML, DOCX, CSV, XML, JSON, JSONL, and Excel.
- โ๏ธ Flexible Chunking โ Fixed-size, sentence-based, and recursive chunking.
- ๐ข Local Embeddings โ Powered by Sentence Transformers.
- ๐๏ธ Vector Stores โ In-memory and optional FAISS support.
- ๐ Reranking โ Optional cross-encoder reranking.
- ๐ค Local LLMs โ Ollama and Hugging Face Transformers.
- ๐ Evaluation โ Precision@K, Recall@K, MRR, and Hit Rate.
- ๐งฉ Extensible โ Replace or implement any core component.
- ๐ Privacy First โ Documents remain on your machine unless you explicitly use a remote service.
- ๐ Library First โ Designed to be imported into your Python applications.
- ๐ป CLI Included โ Index, search, and ask questions directly from the terminal.
Architecture
Documents
โ
โผ
Document Loaders
โ
โผ
Chunking
โ
โผ
Embeddings
โ
โผ
Vector Store
โ
โผ
Retriever
โ
โโโ Metadata Filtering
โ
โโโ Optional Reranking
โ
โผ
RAG Pipeline
โ
โผ
Local LLM
โ
โผ
Answer + Sources
Installation
Core Package
pip install local-semantic-rag
All Optional Dependencies
pip install local-semantic-rag[all]
Individual Extras
pip install local-semantic-rag[pdf]
pip install local-semantic-rag[docx]
pip install local-semantic-rag[html]
pip install local-semantic-rag[markdown]
pip install local-semantic-rag[faiss]
pip install local-semantic-rag[excel]
pip install local-semantic-rag[transformers]
pip install local-semantic-rag[ollama]
Quick Start
1. Create a Knowledge Base
from local_semantic_rag import (
Document,
KnowledgeBase,
SentenceTransformerEmbedding,
)
kb = KnowledgeBase(
embedding_model=SentenceTransformerEmbedding()
)
2. Add Documents
kb.add_documents([
Document(
id="doc1",
content="Laravel is a PHP framework."
),
Document(
id="doc2",
content="Django is a Python framework."
),
])
3. Search
results = kb.search("PHP framework", top_k=5)
for result in results:
print(result.document.content)
print(f"Score: {result.score:.4f}")
4. Save the Index
kb.save("./my_index")
5. Load and Search Later
kb = KnowledgeBase.load("./my_index")
results = kb.search("PHP framework")
for result in results:
print(result.document.content)
RAG with Ollama
local-semantic-rag can use Ollama for completely local RAG generation.
Install Ollama Support
pip install local-semantic-rag[ollama]
Install Ollama and pull a model:
ollama pull llama3.2
Create a RAG Pipeline
from local_semantic_rag import (
KnowledgeBase,
RAGPipeline,
OllamaLLM,
)
kb = KnowledgeBase.load("./my_index")
llm = OllamaLLM(
model="llama3.2"
)
rag = RAGPipeline(
retriever=kb,
llm=llm,
)
response = rag.ask("What is Laravel?")
print(response.answer)
for source in response.sources:
print(
f"- {source.document.id} "
f"(score: {source.score:.4f})"
)
Command Line Interface
local-semantic-rag also provides a simple CLI.
Index Documents
local-semantic-rag index ./documents --output ./my_index
Semantic Search
local-semantic-rag search ./my_index "PHP framework"
Ask a Question
local-semantic-rag ask ./my_index "What is Laravel?" --llm llama3.2
Supported Document Formats
local-semantic-rag supports loading documents from multiple formats:
| Format | Support |
|---|---|
| TXT | โ |
| โ | |
| Markdown | โ |
| HTML | โ |
| DOCX | โ |
| CSV | โ |
| XML | โ |
| JSON | โ |
| JSONL | โ |
| Excel | โ |
Embeddings
The default embedding model is:
all-MiniLM-L6-v2
It provides:
- 384-dimensional embeddings
- Small model size
- Fast local inference
- Good general-purpose semantic search
Custom Embedding Model
from local_semantic_rag import SentenceTransformerEmbedding
embedder = SentenceTransformerEmbedding(
model_name="all-MiniLM-L12-v2",
device="cpu",
)
GPU can be enabled with:
embedder = SentenceTransformerEmbedding(
model_name="all-MiniLM-L12-v2",
device="cuda",
)
Models are lazy-loaded and downloaded only when first used.
Vector Stores
In-Memory
Good for development, testing, and small datasets.
from local_semantic_rag import InMemoryVectorStore
store = InMemoryVectorStore()
FAISS
For larger datasets and high-performance similarity search:
pip install local-semantic-rag[faiss]
from local_semantic_rag import FAISSVectorStore
store = FAISSVectorStore(
dimension=384
)
Semantic Search
You can use the high-level API:
results = kb.search(
"PHP web framework",
top_k=5,
)
Or use the lower-level Retriever:
from local_semantic_rag import (
Retriever,
InMemoryVectorStore,
SentenceTransformerEmbedding,
)
embedder = SentenceTransformerEmbedding()
store = InMemoryVectorStore()
retriever = Retriever(
embedding_model=embedder,
vector_store=store,
top_k=5,
)
results = retriever.search("PHP framework")
Metadata Filtering
Search can be combined with metadata filters:
results = retriever.search(
"API documentation",
filters={
"category": "documentation"
},
)
Supported operators include:
=
!=
in
not in
contains
startswith
endswith
Example:
filters = {
"language": {
"op": "in",
"value": ["en", "es"],
},
"category": {
"op": "!=",
"value": "draft",
},
}
Reranking
For higher retrieval precision, you can use a cross-encoder reranker:
from local_semantic_rag import CrossEncoderReranker
reranker = CrossEncoderReranker(
model_name="cross-encoder/ms-marco-MiniLM-L-6-v2"
)
Then attach it to the retriever:
retriever = Retriever(
embedding_model=embedder,
vector_store=store,
top_k=10,
reranker=reranker,
)
Custom RAG Prompts
You can customize the prompt used by the RAG pipeline:
from local_semantic_rag import PromptTemplate
template = PromptTemplate(
template="Context:\n{context}\n\nQuestion: {question}",
system=(
"You are an expert assistant. "
"Answer accurately using the provided context."
),
fallback="I don't have enough context to answer this.",
)
Use it with the RAG pipeline:
rag = RAGPipeline(
retriever=kb,
llm=llm,
prompt_template=template,
)
Available placeholders:
{context}
{question}
{system}
Evaluation
local-semantic-rag provides retrieval evaluation metrics:
- Precision@K
- Recall@K
- MRR
- Hit Rate@K
Example:
from local_semantic_rag.evaluation import evaluate_retrieval
test_cases = [
{
"query": "PHP framework",
"expected_ids": [
"laravel_doc"
],
},
{
"query": "Python framework",
"expected_ids": [
"django_doc"
],
},
]
metrics = evaluate_retrieval(
retriever=retriever,
test_cases=test_cases,
k=5,
)
print(metrics)
Example output:
{
"precision": 0.8,
"recall": 0.7,
"mrr": 0.85,
"hit_rate": 0.9
}
Extensibility
local-semantic-rag is built around abstract interfaces, making it easy to replace individual components.
| Component | Extension |
|---|---|
| Document Loader | DocumentLoader |
| Chunker | Chunker |
| Embedding | EmbeddingModel |
| Vector Store | VectorStore |
| Reranker | Reranker |
| LLM | LLM |
For example, create a custom embedding implementation:
from local_semantic_rag import EmbeddingModel
from local_semantic_rag.types import Embedding
from typing import List
class MyCustomEmbedder(EmbeddingModel):
def __init__(self):
self._dim = 768
def embed_documents(
self,
texts: List[str],
) -> List[Embedding]:
return [
[0.0] * self._dim
for _ in texts
]
def embed_query(
self,
text: str,
) -> Embedding:
return [0.0] * self._dim
@property
def dimension(self) -> int:
return self._dim
Use it with the knowledge base:
kb = KnowledgeBase(
embedding_model=MyCustomEmbedder()
)
Project Structure
local-semantic-rag/
โ
โโโ local_semantic_rag/
โ โโโ __init__.py
โ โโโ documents/
โ โโโ chunking/
โ โโโ embeddings/
โ โโโ vectorstores/
โ โโโ retrieval/
โ โโโ llm/
โ โโโ evaluation/
โ โโโ pipeline/
โ โโโ cli.py
โ
โโโ docs/
โ โโโ index.md
โ โโโ getting-started.md
โ โโโ architecture.md
โ โโโ embeddings.md
โ โโโ semantic-search.md
โ โโโ rag.md
โ โโโ vector-stores.md
โ โโโ llm-providers.md
โ โโโ evaluation.md
โ โโโ extending.md
โ
โโโ tests/
โ
โโโ pyproject.toml
โโโ README.md
โโโ LICENSE
โโโ CONTRIBUTING.md
Design Principles
Modular
Use only the components you need and replace implementations when required.
Extensible
Core components are defined using abstract base classes.
Library-First
The framework is designed to be imported into Python applications rather than being limited to CLI usage.
Local-First
Embeddings, vector search, and LLM generation can all run locally.
Type-Safe
The project uses Python type hints throughout the core APIs.
Performance
local-semantic-rag includes several performance-focused design decisions:
- Lazy loading of embedding and LLM models.
- Batch document embedding.
- Vectorized similarity search.
- Optional FAISS acceleration.
- Configurable retrieval limits.
- Optional reranking.
- Lightweight core dependencies.
Security & Privacy
local-semantic-rag follows a local-first approach.
- Documents can remain entirely on your machine.
- No external API is required for the core RAG workflow.
- Local embeddings can be generated without cloud services.
- Local LLMs can be used through Ollama or Transformers.
- File validation helps prevent invalid or malicious input.
If you choose to integrate a remote embedding, vector database, or LLM provider, data handling will depend on that provider.
Documentation
Detailed documentation is available in the docs/ directory.
- Getting Started
- Architecture
- Embeddings
- Semantic Search
- RAG Pipeline
- Vector Stores
- LLM Providers
- Evaluation
- Extending the Framework
Development
Clone the repository:
git clone https://github.com/awais69735/local-semantic-rag.git
cd local-semantic-rag
Create a virtual environment:
python -m venv .venv
Activate it on Linux/macOS:
source .venv/bin/activate
Activate it on Windows:
.venv\Scripts\activate
Install the package in editable mode:
pip install -e .
Install development dependencies if available:
pip install -e ".[dev]"
Run tests:
pytest
Contributing
Contributions are welcome.
- Fork the repository.
- Create a feature branch.
- Implement your changes.
- Add or update tests.
- Run the test suite.
- Submit a pull request.
See CONTRIBUTING.md for contribution guidelines.
Roadmap
Potential future improvements include:
- Streaming LLM responses.
- Additional vector database integrations.
- Advanced RAG evaluation metrics.
- Hybrid keyword + semantic search.
- Improved document preprocessing.
- More reranking models.
- Async APIs.
- Additional local LLM backends.
- Better chunking strategies.
- Production-oriented observability and tracing.
License
This project is licensed under the terms specified in LICENSE.
Acknowledgements
local-semantic-rag builds on the Python open-source ecosystem, including:
- Sentence Transformers
- Hugging Face Transformers
- FAISS
- Ollama
- Pydantic
Status
๐ง Active Development
local-semantic-rag is designed as a lightweight foundation for building private, local-first semantic search and RAG applications in Python.
โญ If you find this project useful, consider starring the repository and contributing improvements.
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 local_semantic_rag-1.0.0.tar.gz.
File metadata
- Download URL: local_semantic_rag-1.0.0.tar.gz
- Upload date:
- Size: 38.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbfdf5dcd8dbab68586682e289b539bdce9388417a2324e3132f7c2e33a5e225
|
|
| MD5 |
f82627ac67a9332c7b2714585d861365
|
|
| BLAKE2b-256 |
09b9b8d27862b43f5dc6e75a743de041a0cdd235da68058046e016f2d621cdf9
|
File details
Details for the file local_semantic_rag-1.0.0-py3-none-any.whl.
File metadata
- Download URL: local_semantic_rag-1.0.0-py3-none-any.whl
- Upload date:
- Size: 54.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
976b2c4495033e0f3fc5c28d80f99c29dfc7477f27b534ad77fdbc6fd986243c
|
|
| MD5 |
4f9216557866dd2f6cddb96eac1b35e7
|
|
| BLAKE2b-256 |
81fa0f5bf43e81054a6607750f8db57ca16f413c2a9957d2c1b3d84fb01cffbf
|