sportonic.mp4
An AI-powered full-stack web app that lets you ask natural language questions about a podcast and get grounded answers with exact timestamps and direct quotes — no vector database, no heavy ML models.
Currently powered by the Lex Fridman × Elon Musk podcast (YouTube ID:
Rni7Fz7208c)
- 💬 Natural language Q&A — ask anything about the podcast
- 🕐 Timestamped answers with a direct YouTube link to the exact moment
- 💬 Direct quote — exact phrase from the transcript, max 15 words
- 📖 Auto-generated chapters — 8 major topic shifts detected by Gemini
- 🔍 BM25-style keyword retrieval — fast token-based chunk scoring, no embeddings needed
- 🚫 Out-of-scope refusal — refuses gracefully if the topic wasn't discussed
- 🌙 Dark mode UI
podcast-intelligence/
├── frontend/ # React app (Vite)
│ ├── src/
│ ├── public/
│ └── package.json
├── backend/ # FastAPI app (Python)
│ ├── main.py
│ ├── requirements.txt
│ ├── chunks.json # auto-generated on first run
│ └── vercel.json
├── .gitignore
└── README.md
| Layer | Technology |
|---|---|
| Frontend | React, Vite |
| Backend | FastAPI, Python |
| AI Model | Google Gemini 2.5 Flash |
| Retrieval | Keyword token scoring (no vector DB) |
| Transcript | youtube-transcript-api |
| Chunking | Sliding window (12 segments, 3 overlap) |
- Python 3.10+
- Node.js 18+
- A Google Gemini API key
cd backend
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Mac/Linux
pip install -r requirements.txtCreate a .env file in backend/:
GEMINI_API_KEY=your_api_key_hereRun the server:
uvicorn main:app --reloadThe API will be available at http://localhost:8000.
On first run the backend automatically fetches the YouTube transcript, chunks it, and saves it to chunks.json. Subsequent runs load from disk instantly.
cd frontend
npm install
npm run devThe app will be available at http://localhost:5173.
| Method | Endpoint | Description |
|---|---|---|
POST |
/ask |
Ask a question about the podcast |
GET |
/chapters |
Get AI-generated chapter list |
GET |
/health |
Health check + chunk count |
curl -X POST http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{"question": "What did Elon say about the future of video?"}'{
"refused": false,
"answer": "Elon believes most interaction will be real-time video with AI in the future...",
"timestamp": "00:04:11",
"start_seconds": 251,
"quote": "most interaction is going to be real-time video with AI",
"video_url": "https://www.youtube.com/watch?v=Rni7Fz7208c&t=251s",
"sources": [...]
}{
"refused": true,
"answer": "This topic was not discussed in this podcast.",
"sources": []
}- On startup, the backend downloads the YouTube transcript using
youtube-transcript-api, chunks it into overlapping windows of 12 segments with 3-segment overlap, and saves the result tochunks.json. - On subsequent restarts the chunks are loaded from disk — no re-download needed.
- On a
/askrequest, the question is tokenized and scored against all chunks using keyword term frequency. Stopwords and topic-aware synonym expansion improve precision. - The top-6 scoring chunks are passed as context to Gemini 2.5 Flash, which generates a grounded answer in structured JSON — answer, timestamp, and a direct quote.
- The response includes a direct YouTube link pointing to the exact second in the video.
- If no relevant chunks are found, or if Gemini cannot find the answer in the provided context, the API refuses gracefully.
| Variable | Required | Description |
|---|---|---|
GEMINI_API_KEY |
✅ Yes | Google Gemini API key |
Never commit .env to the repository.
Create a .env.example file for contributors:
GEMINI_API_KEY=your_api_key_herechunks.jsonis auto-generated on first run and committed to the repo so Vercel and other deployments don't need to call YouTube at build time.- Chapters are generated once per session and cached in memory.
- The retrieval is purely keyword-based — no embeddings, no vector DB, no heavy dependencies — making the backend lightweight and fast to deploy.
MIT