Policy RAG web application for answering questions from an internal policy corpus with evidence-backed citations.
- Multi-format ingestion (
.md,.txt,.html,.pdf) - Deterministic chunking with overlap
- Local embeddings (HuggingFace sentence-transformers)
- Local vector database (Chroma)
- FastAPI endpoints:
GET /web chat UIPOST /chatanswer with citations and snippetsGET /healthservice/index health
- Evaluation runner with latency metrics (p50/p95)
- CI pipeline via GitHub Actions
policy-rag-assistant/
app.py
requirements.txt
render.yaml
corpus/
evaluation/
docs/
design.md
src/
config.py
ingest.py
rag.py
schemas.py
eval.py
templates/
index.html
- Python 3.11+
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envThe project uses a fixed random seed via RANDOM_SEED in .env (default: 42) for deterministic chunking/eval behavior.
Required:
OPENROUTER_API_KEY
Common defaults are already provided in .env.example:
OPENROUTER_MODELOPENROUTER_BASE_URLEMBEDDING_MODELVECTOR_DB_DIRCORPUS_DIRTOP_K,CHUNK_SIZE,CHUNK_OVERLAP
python -m src.ingest --rebuildExpected output:
- Number of indexed documents
- Number of indexed chunks
uvicorn app:app --reloadOpen:
http://localhost:8000/for chat UIhttp://localhost:8000/healthfor health JSON
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"question":"What is the patch deadline for critical vulnerabilities?"}'Response contains:
questionanswercitations[]withdoc_id,title,source,snippetmetawithlatency_ms,model,top_k, andrefusal
Question set and scoring templates are in evaluation/.
Run eval:
python -m src.eval --base-url http://localhost:8000 --limit 22 --out evaluation/eval_run_22q_final.jsonThis reports:
- Answered count
- Latency p50 and p95
- Per-question outputs for groundedness/citation scoring
Latest artifacts:
evaluation/eval_run_22q_final.jsonevaluation/EVAL_REPORT_LATEST.mdevaluation/SUCCESS_METRICS.md
GitHub Actions workflow: .github/workflows/ci.yml
On push/PR it:
- Installs dependencies
- Runs import/build check (
import app)
Render blueprint is included in render.yaml.
Steps:
- Connect repo to Render.
- Set
OPENROUTER_API_KEYin Render environment variables. - Deploy using
render.yaml.
After deployment, verify the following:
GET /healthreturns{"status":"ok", ...}.GET /loads the chat UI.POST /chatreturnsquestion,answer,citations[], andmeta.
Example:
curl -X POST https://<your-render-url>/chat \
-H "Content-Type: application/json" \
-d '{"question":"What is the patch deadline for critical vulnerabilities?"}'See docs/design.md for decisions on:
- embedding model
- chunking strategy
- retrieval top-k
- prompt/guardrail structure
- vector store choice
- This assistant is intentionally corpus-bounded for safer policy Q&A.
- For best accuracy, rebuild index after corpus changes.
- Repository contains setup/run instructions and
.env.example. - Corpus and ingestion/indexing pipeline are present and reproducible.
- Endpoints implemented and working:
/,/chat,/health. - Evaluation artifacts committed:
evaluation/EVAL_QUESTIONS.mdevaluation/eval_run_22q_final.jsonevaluation/EVAL_REPORT_LATEST.md
- CI workflow present in
.github/workflows/ci.yml. - Render deployment config present in
render.yaml. - Design rationale documented in
docs/design.md. - Share repository access with GitHub account
quantic-grader.