Week 2 assignment support: RAG on your Week 1 endpoint
This guide walks you through the Week 2 assignment step by step using Claude Code or Cursor. You already shipped POST /ask in Week 1. Now you extend that same FastAPI service on Render with a vector store, POST /ingest (add documents after deploy), and RAG on POST /ask (retrieve before you generate).
You do not need to write code yourself. Your job is to give the AI the right instructions, verify retrieval before generation, and prove both endpoints on your live URL.
Critical
The Golden Rule (read this first)
Whenever anything goes wrong, copy the entire error message and paste it into Claude Code or Cursor with: "I got this error, please fix it and explain what happened in simple terms."
- That habit fixes most problems.
- You are never stuck. You just haven't pasted the error yet.
What you are building (in plain English)
- POST /ingest — you send documents (or text). The service chunks them, embeds them, and stores them in a vector database. Run this whenever your data changes. No redeploy needed.
- POST /ask — same endpoint as Week 1, but now it searches your documents first, then answers using only what it retrieved. It cites chunk IDs and refuses when the docs do not contain the answer.
- Vector store — Pinecone (cloud, easiest) or ChromaDB / pgvector (self-hosted). Cloud = less ops; self-hosted = more control.
- Done means both endpoints work on your public Render URL, with a README and golden-set eval scores.
Before you start: what you need
Week 1 service deployed
Your live Render URL with POST /ask working. Week 2 extends this repo — do not start from scratch.
Vector DB account (recommended: Pinecone)
Sign up at pinecone.io, create an index, copy API key + index name. Free tier is enough for the assignment.
Document corpus
Northwind sample docs from the syllabus, or your own capstone documents (PDF, CSV, web pages, plain text).
Same OpenAI key as Week 1
You need embeddings + generation. Lock one embedding model (e.g. `text-embedding-3-small`) — switching later means re-indexing.
Critical
Test retrieval BEFORE you wire the LLM
The #1 mistake in Week 2 is debugging generation when retrieval is wrong. Add a debug route or script that prints top-k chunks + scores for a question. Only upgrade /ask to RAG once the right passages come back.
Step 1: Open your Week 1 project
I am extending my Week 1 FastAPI /ask service for a Week 2 RAG assignment. Please read this repo and explain in plain English: 1. Where POST /ask is implemented 2. How structured output, tokens_used, and cost_usd are returned 3. Where I should add POST /ingest and vector-store logic 4. What env vars I will need for Pinecone (or ChromaDB) and OpenAI embeddings Do not write code yet — just map the project.
Step 2: Choose and wire your vector store
Recommended for speed: Pinecone (cloud). Alternative: ChromaDB embedded in the same Render service (simpler locally; persistence on Render needs thought). Document your choice in README.
Add vector store support to this FastAPI project using [Pinecone OR ChromaDB — pick one]. Requirements: - Config via environment variables (no secrets in code) - Use text-embedding-3-small for embeddings (same model at ingest and query time) - Add a small health/debug function I can call to confirm the store is reachable Explain what env vars I must set locally and on Render.
Step 3: Build POST /ingest
Build POST /ingest on this FastAPI app. Requirements: - Accept JSON with text + document_id (and optional metadata like source filename) - Chunk with RecursiveCharacterTextSplitter — chunk_size ~800, overlap ~100 (make these configurable) - Embed each chunk with text-embedding-3-small - Upsert into the vector store with metadata: document_id, chunk_index, source - Return JSON: document_id, chunks_indexed, status Include a curl example in comments. Handle empty input with a clear 400 error.
curl -s -X POST http://127.0.0.1:8000/ingest \
-H "Content-Type: application/json" \
-d '{"text": "Remote work: up to 3 days per week with manager approval.", "document_id": "handbook"}'Step 4: Test retrieval alone
Before changing POST /ask, add GET /debug/retrieve?q=... (or a small script) that: 1. Embeds the question 2. Returns top-5 chunks with similarity scores and document_id metadata 3. Does NOT call the LLM I will use this to verify retrieval before wiring generation.
Ingest the Northwind handbook (or one doc you know well). Ask a question you know the answer to. If the wrong chunks appear, fix chunking or embedding before Step 5.
Step 5: Upgrade POST /ask to RAG
Upgrade POST /ask to use retrieval-augmented generation: 1. Embed the question 2. Retrieve top-k chunks (start with k=5) 3. Build a grounding prompt: answer ONLY from context, cite document_id for each chunk used, refuse if context is insufficient 4. Call the existing Week 1 generation path 5. Preserve tokens_used and cost_usd in the response where possible 6. Include retrieved chunk IDs in the response JSON Show me the grounding prompt template you used.
Answer using ONLY the context below.
If the context does not contain the answer, say:
"I don't have enough information to answer that."
Cite the document_id of each chunk you used.
Context:
{retrieved_chunks}
Question: {question}Step 6: Ingest your full corpus
Help me ingest all documents in [sample_docs/ OR my corpus folder] via POST /ingest. For each file: read text, assign a stable document_id, call ingest, print chunk count. At the end, print total chunks in the vector store.
Step 7: Deploy to Render
Add new env vars to Render (Pinecone API key + index name, or Chroma path). Redeploy the same Web Service as Week 1.
- Push changes to GitHub.
- In Render → your Week 1 service → Environment: add vector DB secrets.
- Redeploy and wait for Live.
- Run ingest against the live URL, then ask a doc-grounded question.
# Ingest on live URL
curl -s -X POST https://YOUR-SERVICE.onrender.com/ingest \
-H "Content-Type: application/json" \
-d '{"text": "...", "document_id": "handbook"}'
# RAG ask
curl -s -X POST https://YOUR-SERVICE.onrender.com/ask \
-H "Content-Type: application/json" \
-d '{"question": "What is the remote work policy?"}'Step 8: Golden-set eval
Help me create a golden-set eval for my RAG service with at least 5 questions I know the answers to. For each question record: - question - expected answer (short) - retrieval hit? (right chunk in top-5) - faithfulness? (answer grounded in retrieved text) - correctness? (matches expected) - one question that SHOULD trigger refusal (answer not in docs) Format as a markdown table I can paste into README.
Stretch goals (pick 1+)
- Chunk size comparison — run two chunk sizes; document which wins on your golden set.
- Hybrid search — combine BM25 (or keyword) with vector similarity.
- Metadata filtering — filter by document_id or tag at retrieve time.
- Reranking — reorder top-k with a rerank model or API.
- Streamlit UI — simple UI for ingest + ask (API stays source of truth).
- Multi-document / batch ingest — upload multiple files in one request.
Step 9: Share it
Critical
Do NOT share your live URL publicly
Never post your Render URL on LinkedIn or any public page. Anyone with the link can call /ask and /ingest and burn your API credits.
- Maven / cohort WhatsApp: live URL, ingest + ask curls, one cited answer, golden-set scores, README link.
- LinkedIn: screenshots or screen recording only — no live URL.
Final checklist: are you actually done?
- Week 1 POST /ask still works (extended, not replaced blindly).
- POST /ingest chunks, embeds, and upserts with metadata.
- Retrieval tested alone — you can show top-k for a known question.
- POST /ask retrieves, cites chunk IDs, and refuses when docs lack the answer.
- Both endpoints work on live Render URL (not just localhost).
- Golden set ≥5 questions with retrieval + faithfulness + correctness in README.
- README explains architecture, how to ingest new docs, and what broke.
- At least one stretch goal attempted OR README explains why you deferred.
- Shared live URL + proof in Maven or WhatsApp only (not LinkedIn).
Troubleshooting
- Wrong chunks retrieved — fix chunk size/overlap before touching the prompt. Log what retrieval returns.
- Empty Pinecone index — confirm ingest ran on live URL after deploy, not only locally.
- Answers hallucinate despite good retrieval — strengthen grounding prompt; add explicit refusal instruction.
- Render deploy fails on new deps — paste build log into your coding agent; pin versions in requirements.txt.
- Embedding dimension mismatch — index dimension must match your embedding model.
Go deeper (optional)