Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RAG Article Navigator

A retrieval-augmented generation system that lets you semantically search and ask questions across a corpus of news articles — with FAISS for vector search, LangChain for orchestration, and a Streamlit UI.

Built with an emphasis on making the answers trustworthy, not just fluent: every response comes with source citations, a transparent confidence score, and a guardrail that refuses to answer when nothing in the corpus is actually relevant.

Features

  • Semantic search over a corpus of news articles using FAISS
  • RAG question answering grounded in retrieved excerpts, orchestrated with LangChain
  • Prompt guardrails — if retrieval similarity is too low, the system says so instead of letting the model improvise from weak context
  • Transparent confidence scoring — every answer is labeled High / Medium / Low / Insufficient Evidence based on retrieval strength and agreement across sources
  • Runs with zero API keys in mock mode (deterministic hashed embeddings + placeholder generation), so the whole pipeline — retrieval, guardrails, scoring — is testable and demoable without credentials

Architecture

Streamlit UI (src/app)
        │
        ▼
answer_question() (src/rag/chain.py)
        │
        ├──▶ VectorIndex.search() ──▶ FAISS (src/rag/index.py)
        │                                   │
        │                          embeddings (src/rag/embeddings.py)
        │
        ├──▶ check_retrieval_guardrail() ──▶ refuse if similarity too low
        │
        ├──▶ score_confidence() ──▶ High / Medium / Low / Insufficient
        │
        └──▶ LangChain prompt + ChatOpenAI (or mock) ──▶ grounded answer

Project layout

rag-article-navigator/
├── data/
│   └── articles/            # sample news corpus (JSON, one file per article)
├── src/
│   ├── config.py             # env-driven settings
│   ├── rag/
│   │   ├── documents.py       # article loading + chunking
│   │   ├── embeddings.py       # real (OpenAI) + mock embedding backends
│   │   ├── index.py            # FAISS vector index + retriever
│   │   ├── guardrails.py       # retrieval guardrail + confidence scoring
│   │   └── chain.py            # LangChain-orchestrated RAG answer chain
│   └── app/
│       └── streamlit_app.py    # Streamlit UI
├── tests/
├── requirements.txt
├── .env.example
└── README.md

Getting started

1. Install

git clone https://github.com/<your-username>/rag-article-navigator.git
cd rag-article-navigator
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

2. Configure environment

cp .env.example .env
# Optionally set OPENAI_API_KEY for real embeddings + generation.

The app runs in mock mode automatically with no API key: retrieval, guardrails, and confidence scoring all run for real against deterministic hashed embeddings, while generated answers are placeholder text. This makes the whole pipeline runnable and testable with zero credentials.

3. Run the app

streamlit run src/app/streamlit_app.py

Open the local URL Streamlit prints (usually http://localhost:8501). Use the Ask a question tab for grounded Q&A with citations and a confidence score, or the Semantic search tab to browse raw retrieval results.

4. Run tests

pytest -v

How the guardrails work

Every query goes through retrieval first. If the best-matching passage falls below MIN_SIMILARITY_FOR_ANSWER (default 0.35), the system refuses to answer and explains why, rather than asking the model to generate a plausible-sounding response from irrelevant context — the most common way RAG systems quietly hallucinate.

If retrieval clears that bar, a confidence score is still attached to the answer: a weighted blend of the top match's similarity and the average similarity across all retrieved passages, mapped to a high / medium / low / insufficient_evidence label. This means an answer can be allowed but still flagged as low-confidence, giving the product surface (and the user) an honest signal about how much to trust it.

Adding your own articles

Drop additional JSON files into data/articles/, following the shape:

{
  "id": "art-006",
  "title": "Article headline",
  "source": "Publication name",
  "published": "YYYY-MM-DD",
  "text": "Full article body as plain text."
}

The index rebuilds from the corpus on app startup, so no separate ingestion step is required for a corpus this size.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages