rshashank11/outlook
0
NewsGPT
A FastAPI-based hybrid RAG chatbot for searching and answering questions from indexed news archives.
   
NewsGPT answers questions grounded exclusively in retrieved news content — it never draws on model memory. It supports two sources out of the box:
Table of Contents
How It Works
User question
│
▼
Planner — rewrites the question into a source-aware search query
│
▼
Retriever — dense embedding + BM25 sparse vectors → Pinecone hybrid search
│
▼
Context judge — checks whether retrieved chunks are sufficient
│
▼
Answer — generates a grounded response with inline citations- The planner turns the user's question into a source-aware search query.
- The retriever embeds the query for semantic (dense) search.
- The BM25 encoder converts the query into sparse keyword values.
- Pinecone runs hybrid search combining dense and sparse vectors.
- The context judge decides whether retrieved chunks are sufficient.
- The answer step writes a source-grounded response with citations.
Architecture
The editable source diagram is at docs/newsgpt-architecture.drawio.
Prerequisites
- Python 3.11+
- `uv` (recommended) or pip
- Docker & Docker Compose (for containerised runs and ingestion)
- A Pinecone account with indexes created for each source
- An OpenAI API key or an Azure OpenAI deployment
Quick Start
1. Clone and install
git clone https://github.com/your-org/news-rag.git
cd news-rag
uv sync2. Configure environment
cp .env.example .env
# Edit .env and fill in the required values (see Configuration below)3. Start the API
uv run uvicorn main:app --reload --host 0.0.0.0 --port 8000Docker Compose
docker compose up appConfiguration
Copy .env.example to .env and fill in real values. Never commit `.env`.
Required
Source-specific
OpenAI
Azure OpenAI (alternative to direct OpenAI)
Retrieval (optional)
Ingestion
Sakal
# 1. Convert XML dumps to JSON
python convert_sakal_xml_to_json.py
# 2. Chunk, embed, and upload to Pinecone
docker compose --profile ingest run ingest-sakalBar & Bench
# Ingest story dumps into Postgres + Pinecone
docker compose --profile ingest run ingest-barandbench
# Backfill published_at metadata for existing Pinecone chunks (if needed)
python backfill_barandbench_pinecone_published_at.pyTests
uv run python -m unittest discover -s testsProject Structure
news-rag/
├── app/
│ ├── agents/ # LangGraph agent definitions
│ ├── config.py # Settings (pydantic-settings)
│ ├── embeddings.py # Embedding helpers
│ ├── retrieval.py # Hybrid retrieval logic
│ ├── sparse.py # BM25 sparse encoder
│ └── vectorstore.py # Pinecone client wrapper
├── docs/ # Architecture diagrams
├── tests/ # Unit tests
├── main.py # FastAPI application entry point
├── ingest_sakal.py # Sakal ingestion script
├── ingest_barandbench.py# Bar & Bench ingestion script
├── .env.example # Environment variable template
├── docker-compose.yml
└── pyproject.toml