A production-oriented Retrieval-Augmented Generation (RAG) system built using LangChain and Clean Architecture.
Unlike my previous RAG implementation—which was built entirely from scratch without any framework—this project explores how to build a maintainable and extensible RAG using LangChain while keeping framework-specific code isolated from the core domain.
- Clean Architecture
- Framework-agnostic domain layer
- Modular ingestion pipeline
- Local-first stack
- Production-oriented design
- Easy experimentation with retrieval techniques
PDF
│
PDF Loader
│
Document Processors
│
Recursive Chunker
│
Ollama Embeddings
│
PostgreSQL + pgvector
│
──────────── Retrieval ────────────
Question
│
PGVector Retriever
│
Cross-Encoder Reranker
│
Relevant Context
│
Prompt Builder
│
Llama 3.1 (Ollama)
│
Answer
rag/
│
├── app/
│ ├── api/
│ ├── application/
│ ├── config/
│ ├── domain/
│ └── infrastructure/
│
├── evaluation/
├── tests/
├── main.py
└── pyproject.toml
- Ollama
- Llama 3.1 8B
- nomic-embed-text
- PostgreSQL
- pgvector
- LangChain
- Dense Retrieval
- Cross-Encoder Reranking
- DeepEval
- RAGAS
- PDF ingestion
- Recursive text chunking
- Custom document processing pipeline
- Ollama embeddings
- PostgreSQL + pgvector storage
- Dense semantic retrieval
- Cross-encoder reranking
- Modular retrieval and generation services
- Clean Architecture
- Hybrid retrieval (Dense + BM25)
- Metadata filtering
- Context compression
- Query rewriting
- Multi-query retrieval
- Reciprocal Rank Fusion (RRF)
- LangGraph workflows
- Streaming responses
- Source citations
- FastAPI API
- LangSmith tracing
- Comprehensive evaluation benchmarks
- Keep business logic independent of LangChain.
- Depend on interfaces instead of implementations.
- Isolate infrastructure components.
- Make every component replaceable.
- Prefer composition over inheritance.
This repository is the LangChain counterpart to my previous project, where every RAG component—including embeddings, vector search, prompt orchestration, and retrieval—was implemented manually without using LangChain.