A small but real Retrieval-Augmented Generation pipeline:
- Split local markdown into chunks, tagging each with its source file
- Embed them locally with
sentence-transformers(no embedding API needed) - Store + retrieve with a FAISS vector store that persists to disk
- Answer with Claude, grounded only in the retrieved context, and cite the sources
Built with LangChain. A clean starting point for grounding an LLM in your own docs.
pip install -r requirements.txt
export ANTHROPIC_API_KEY=sk-...
python rag.py "What does MotionKit deliver?"The first run downloads the embedding model (~90 MB) and builds the index; later
runs reuse the saved index under .index/.
python rag.py --rebuild -k 5 "Compare MotionKit and Tinkf"--rebuild rebuilds the index from scratch; -k sets how many chunks to retrieve.
docs ──split──> chunks ──embed──> FAISS index (saved to .index/)
│
question ──embed──> similarity search ┘ ──> top-k context ──> Claude ──> answer + sources
Swap the files in sample_docs/ for your own to ground answers in any corpus.
ruff check rag.py test_rag.py
pytest -qThe pure helpers (chunking + source tagging, citation formatting) are unit-tested
without needing embeddings, the LLM, or a network call — the heavy deps are
imported lazily inside the functions that use them. CI runs lint + those tests on
every push (.github/workflows/ci.yml).
- Add reranking on top of the FAISS recall step
- Return character offsets / quotes alongside each cited source
- Evaluate retrieval quality with a small labelled question set