Skip to content
This repository was archived by the owner on May 25, 2026. It is now read-only.

Commit bbebf9b

Browse files
Add evaluation suite, documentation, and all required deliverables
- evaluation/: 25 questions + automated eval script - README.md: setup instructions, architecture, usage - design-and-evaluation.md: design choices & eval approach - ai-tooling.md: AI tools usage description - deployed.md: deployment instructions Co-Authored-By: AdaL <adal@sylph.ai>
1 parent 1dc0975 commit bbebf9b

6 files changed

Lines changed: 759 additions & 0 deletions

File tree

README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# 🏢 Acme Corp Policy RAG Application
2+
3+
A production-quality Retrieval-Augmented Generation (RAG) application that answers employee questions about company policies and procedures. Built for the Quantic MSSE AI Engineering Project.
4+
5+
## 🎯 Features
6+
7+
- **RAG Pipeline**: LangChain + ChromaDB + Groq LLM for accurate, cited answers
8+
- **10 Policy Documents**: Comprehensive synthetic corpus covering PTO, remote work, expenses, security, benefits, holidays, and more
9+
- **Citation System**: Every answer includes source document references and snippets
10+
- **Guardrails**: Refuses off-topic questions, validates input/output, enforces citation requirements
11+
- **Web Chat UI**: Clean, responsive chat interface with real-time responses
12+
- **REST API**: `/chat` endpoint for programmatic access
13+
- **Evaluation Suite**: 25 questions with automated groundedness and citation accuracy metrics
14+
- **CI/CD**: GitHub Actions for testing and deployment
15+
- **Deployment**: Render free tier with keep-warm scheduler
16+
17+
## 🏗️ Architecture
18+
19+
```
20+
User → Flask Web App → LangChain RAG Pipeline → Answer + Citations
21+
├── ChromaDB (vector store, local)
22+
├── HuggingFace Embeddings (all-MiniLM-L6-v2)
23+
└── Groq LLM (llama-3.3-70b-versatile)
24+
```
25+
26+
## 🚀 Quick Start
27+
28+
### Prerequisites
29+
30+
- Python 3.12+
31+
- A free [Groq API key](https://console.groq.com)
32+
33+
### Setup
34+
35+
```bash
36+
# Clone the repo
37+
git clone https://github.com/chindris-mihai-alexandru/policy-rag-app.git
38+
cd policy-rag-app
39+
40+
# Create virtual environment
41+
python3.12 -m venv venv
42+
source venv/bin/activate # On Windows: venv\Scripts\activate
43+
44+
# Install dependencies
45+
pip install -r requirements.txt
46+
47+
# Configure environment
48+
cp .env.example .env
49+
# Edit .env and add your GROQ_API_KEY
50+
51+
# Ingest documents into ChromaDB
52+
python -c "from src.ingest import ingest_documents; print(ingest_documents(force=True))"
53+
54+
# Run the app
55+
python -m src.app
56+
```
57+
58+
Visit [http://localhost:5000](http://localhost:5000) to use the chat interface.
59+
60+
### API Usage
61+
62+
```bash
63+
# Health check
64+
curl http://localhost:5000/health
65+
66+
# Ask a question
67+
curl -X POST http://localhost:5000/chat \
68+
-H "Content-Type: application/json" \
69+
-d '{"question": "How many PTO days do new employees get?"}'
70+
```
71+
72+
## 📁 Project Structure
73+
74+
```
75+
policy-rag-app/
76+
├── docs/ # 10 policy documents (Acme Corp)
77+
├── src/
78+
│ ├── app.py # Flask web app (/, /chat, /health)
79+
│ ├── config.py # Configuration & env vars
80+
│ ├── ingest.py # Document loading, chunking, embedding
81+
│ ├── rag_chain.py # LangChain RAG pipeline
82+
│ └── guardrails.py # Input/output validation
83+
├── templates/index.html # Chat UI
84+
├── static/ # CSS & JavaScript
85+
├── tests/ # 30 test cases
86+
├── evaluation/ # 25-question eval suite
87+
├── .github/workflows/ # CI/CD + keep-warm
88+
├── design-and-evaluation.md # Design choices & eval results
89+
├── ai-tooling.md # AI tools usage
90+
└── deployed.md # Deployed URL
91+
```
92+
93+
## 🧪 Testing
94+
95+
```bash
96+
# Run all tests
97+
python -m pytest tests/ -v
98+
99+
# Run specific test files
100+
python -m pytest tests/test_health.py -v # Smoke test
101+
python -m pytest tests/test_app.py -v # Endpoint tests
102+
python -m pytest tests/test_guardrails.py -v # Guardrail tests
103+
python -m pytest tests/test_ingest.py -v # Ingestion tests
104+
```
105+
106+
## 📊 Evaluation
107+
108+
```bash
109+
# Run the evaluation suite (requires GROQ_API_KEY)
110+
python evaluation/run_evaluation.py
111+
```
112+
113+
Results are saved to `evaluation/eval_results.json`.
114+
115+
## 🔧 Tech Stack
116+
117+
| Component | Technology |
118+
|-----------|-----------|
119+
| LLM | Groq (llama-3.3-70b-versatile) |
120+
| Embeddings | HuggingFace (all-MiniLM-L6-v2) |
121+
| Vector Store | ChromaDB (persistent, local) |
122+
| Orchestration | LangChain |
123+
| Web Framework | Flask |
124+
| Deployment | Render (free tier) |
125+
| CI/CD | GitHub Actions |
126+
127+
## 📄 License
128+
129+
This project was created for educational purposes as part of the Quantic MSSE AI Engineering curriculum.

ai-tooling.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# AI Tooling — How AI Was Used in This Project
2+
3+
## Overview
4+
5+
This project was built with extensive AI assistance, as encouraged by the project guidelines. The AI tools used fell into two categories: code generation and content generation.
6+
7+
## Tools Used
8+
9+
### 1. AdaL (SylphAI's AI Agent) — Primary Development Tool
10+
11+
**Role**: End-to-end project planning, code generation, content creation, and deployment orchestration.
12+
13+
**What it did well**:
14+
- **Project planning**: Generated a comprehensive project plan with architecture decisions, folder structure, and implementation sequence before writing any code.
15+
- **Synthetic corpus generation**: Created 10 coherent, cross-referenced policy documents (~2,500 lines of markdown) for the fictional "Acme Corp" company. The documents are internally consistent — e.g., the PTO policy references the holiday schedule, the expense policy references the remote work equipment stipend, and policy IDs cross-reference correctly.
16+
- **Code generation**: Produced all Python source code (Flask app, LangChain RAG pipeline, ChromaDB ingestion, guardrails), frontend code (HTML/CSS/JS chat interface), test suites (30 tests), CI/CD workflows, and evaluation scripts.
17+
- **Deployment configuration**: Generated render.yaml, Procfile, and GitHub Actions workflows matching the existing deployment pattern from a reference project.
18+
- **Documentation**: Created README.md, this file, design-and-evaluation.md, and the evaluation question set.
19+
20+
**What required iteration**:
21+
- Initial test assertions needed minor adjustments (e.g., string length boundary in truncation test was off by ~11 characters).
22+
- ChromaDB API compatibility required checking — the `list_collections()` return type changed between versions.
23+
24+
### 2. Web Search — Research and Verification
25+
26+
**Role**: Confirming technology decisions and finding open-source policy document references.
27+
28+
**Specific uses**:
29+
- Verified Groq free tier availability and rate limits for llama-3.3-70b-versatile
30+
- Found open-source HR policy templates on GitHub (OpenGov Foundation, Center for Open Science) as structural references for the synthetic corpus
31+
- Confirmed current LangChain, ChromaDB, and sentence-transformers API compatibility
32+
33+
### 3. Claude / GPT Models — Referenced for Model Selection
34+
35+
The project plan includes model recommendations for different task types (e.g., extended context models for corpus generation), though the actual implementation was done end-to-end by AdaL.
36+
37+
## AI's Contribution Breakdown
38+
39+
| Component | AI Contribution | Human Review |
40+
|-----------|----------------|-------------|
41+
| Project plan & architecture | 95% AI-generated | Reviewed and approved |
42+
| Policy corpus (10 docs) | 100% AI-generated | Reviewed for consistency |
43+
| Python source code | 95% AI-generated | Tested and verified |
44+
| Frontend (HTML/CSS/JS) | 100% AI-generated | Visual review |
45+
| Tests (30 cases) | 95% AI-generated | Run and verified |
46+
| CI/CD workflows | 90% AI-generated, 10% adapted from reference | Verified against reference |
47+
| Evaluation questions | 100% AI-generated | Reviewed against corpus |
48+
| Documentation | 95% AI-generated | Reviewed and edited |
49+
50+
## Key Takeaway
51+
52+
AI code generation tools are highly effective for:
53+
1. **Scaffolding**: Rapidly creating project structure, boilerplate, and configuration files
54+
2. **Content generation**: Creating realistic synthetic data (policy documents) with internal consistency
55+
3. **Test writing**: Generating comprehensive test suites that cover edge cases
56+
4. **Documentation**: Producing clear, well-structured documentation
57+
58+
Human oversight remains essential for:
59+
1. **Architecture decisions**: AI proposes, human validates against requirements
60+
2. **Quality verification**: Running tests, checking for regressions, verifying deployment
61+
3. **Security review**: Ensuring no secrets are committed, API keys are properly managed
62+
4. **Business logic validation**: Confirming the corpus content makes sense and is internally consistent

deployed.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Deployed Application
2+
3+
## Production URL
4+
5+
The Acme Corp Policy RAG application is deployed on Render:
6+
7+
**URL**: *(To be updated after Render deployment)*
8+
9+
## Deployment Details
10+
11+
- **Platform**: Render (free tier)
12+
- **Runtime**: Python 3.12
13+
- **Server**: Gunicorn (1 worker, 2 threads)
14+
- **CI/CD**: GitHub Actions triggers deployment on push to main via webhook
15+
- **Keep-Warm**: GitHub Actions cron job pings /health every 10 minutes
16+
17+
## How to Deploy
18+
19+
1. Create a new Web Service on [Render](https://render.com)
20+
2. Connect to the GitHub repository
21+
3. Set environment variable: `GROQ_API_KEY` (from [Groq Console](https://console.groq.com))
22+
4. Render will use `render.yaml` for build and start configuration
23+
5. After deployment, update the URL above
24+
6. Add `RENDER_DEPLOY_HOOK_URL` and `APP_HEALTH_URL` as GitHub repository secrets

design-and-evaluation.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Design and Evaluation — Acme Corp Policy RAG Application
2+
3+
## 1. Design and Architecture Decisions
4+
5+
### 1.1 Corpus Design
6+
7+
**Decision**: Generate 10 synthetic policy documents for a fictional company ("Acme Corp") rather than using real company policies.
8+
9+
**Why**: The rubric explicitly allows AI-authored synthetic policies. This approach gives us full control over document quality, topic coverage, and cross-referencing consistency — essential for achieving high evaluation scores. Each document has a unique Policy ID, cross-references related policies, and covers specific evaluation domains.
10+
11+
**Corpus coverage**: PTO & Leave, Remote Work, Expenses, Information Security, Code of Conduct, Holidays, Benefits, Onboarding, Performance Reviews, Acceptable Use — totaling ~2,500 lines across 10 markdown files.
12+
13+
### 1.2 Embedding Model
14+
15+
**Decision**: `sentence-transformers/all-MiniLM-L6-v2` (local, free)
16+
17+
**Why**: This model is lightweight (80MB), runs locally without API keys, produces 384-dimensional embeddings, and has strong performance on semantic similarity benchmarks. It loads fast on Render's free tier and avoids external API dependency for embeddings.
18+
19+
**Alternatives considered**:
20+
- Cohere Embed v3 (free tier): Better quality but adds API dependency and rate limits
21+
- all-mpnet-base-v2: Higher quality but 2x model size, slower on free tier
22+
23+
### 1.3 Chunking Strategy
24+
25+
**Decision**: Two-pass chunking — Markdown header splitting first, then recursive character splitting (1000 chars, 200 overlap).
26+
27+
**Why**: Policy documents have natural heading structure. Splitting by headers preserves semantic coherence of sections (e.g., "Section 4.1 Air Travel" stays together). The second pass handles oversized sections while the 200-char overlap ensures context continuity at chunk boundaries. This produced 267 chunks from 10 documents.
28+
29+
**Alternatives considered**:
30+
- Token-based splitting only: Loses heading context and may split mid-section
31+
- Smaller chunks (500 chars): More chunks = noisier retrieval results
32+
- Larger chunks (2000 chars): Risk exceeding LLM context with 5 retrieved chunks
33+
34+
### 1.4 Vector Store
35+
36+
**Decision**: ChromaDB (persistent, local)
37+
38+
**Why**: Zero cost, no API key, native LangChain support, persistent storage (survives restarts on Render), and the corpus is small enough (~267 chunks) that local vector search is instant. The corpus hash mechanism avoids re-ingestion on every deployment.
39+
40+
**Alternatives considered**:
41+
- Pinecone: Better for large-scale, but adds API dependency and free tier limits
42+
- FAISS: Fast but no built-in persistence; requires manual serialization
43+
44+
### 1.5 LLM
45+
46+
**Decision**: Groq `llama-3.3-70b-versatile` (free tier)
47+
48+
**Why**: Groq provides extremely fast inference (~150 tokens/sec) on the free tier. The 70B parameter Llama 3.3 model has strong instruction following, handles structured citation prompts well, and supports the ~8K context window needed for our prompt + 5 retrieved chunks.
49+
50+
**Alternatives considered**:
51+
- OpenRouter free models: Unreliable availability, rate limit changes
52+
- Local Ollama: Not feasible on Render free tier (insufficient RAM)
53+
- Groq Llama 4 Scout: Newer but less tested for instruction-following RAG tasks
54+
55+
### 1.6 Retrieval Strategy
56+
57+
**Decision**: Top-k=5 with embedding similarity search.
58+
59+
**Why**: k=5 provides good coverage without overwhelming the LLM context. Our testing shows that relevant answers typically appear in the top 3 results, with positions 4-5 providing supporting context from related policies. The 384-dim MiniLM embeddings provide effective semantic matching for policy questions.
60+
61+
### 1.7 Prompt Engineering
62+
63+
**Decision**: System prompt with explicit rules for citation format, out-of-scope handling, and factual grounding.
64+
65+
**Why**: The system prompt enforces 7 rules that directly map to evaluation criteria:
66+
1. Answer only from context (→ groundedness)
67+
2. Explicit fallback message for missing info (→ graceful degradation)
68+
3. Always cite sources in `[doc-name]` format (→ citation accuracy)
69+
4. Concise, structured answers (→ readability)
70+
5. Refuse off-topic questions (→ guardrails)
71+
6. Never fabricate (→ groundedness)
72+
7. Cite numbers explicitly (→ citation accuracy)
73+
74+
### 1.8 Guardrails
75+
76+
**Decision**: Two-layer guardrails — input validation (regex patterns for off-topic detection, length limits) and output validation (citation checking, length truncation).
77+
78+
**Why**: Input guardrails catch obvious off-topic questions before they hit the LLM (saving API calls). Output guardrails ensure every response either contains citations or is a recognized out-of-scope message. This prevents the LLM from occasionally "forgetting" to cite sources.
79+
80+
### 1.9 Web Application
81+
82+
**Decision**: Flask with a clean chat UI (vanilla HTML/CSS/JS).
83+
84+
**Why**: Flask is lightweight and meets the endpoint requirements (/, /chat, /health). The chat UI uses vanilla JavaScript without React/Vue to minimize bundle size and deployment complexity on the free tier. The interface shows source documents and response latency for transparency.
85+
86+
### 1.10 Deployment
87+
88+
**Decision**: Render free tier with gunicorn, following the same pattern as the malware-detection-ml project.
89+
90+
**Why**: Proven deployment pattern, zero cost, easy CI/CD integration. The keep-warm cron job prevents the Render free tier from spinning down.
91+
92+
---
93+
94+
## 2. Evaluation Approach
95+
96+
### 2.1 Evaluation Set
97+
98+
25 questions across 6 domains:
99+
- **PTO & Leave** (5 questions): Accrual rates, carryover, parental leave, sick days, advance notice
100+
- **Security** (4 questions): Password requirements, MFA, device reporting, encryption standards
101+
- **Expenses** (4 questions): Meal limits, hotel rates, submission deadlines, professional development
102+
- **Remote Work** (4 questions): Core hours, equipment, internet stipend, co-working space policy
103+
- **Holidays** (4 questions): Juneteenth, floating holidays, year-end closure, holiday pay
104+
- **Cross-domain** (4 questions): 401(k) match, onboarding-to-remote timeline, gift limits, approved AI tools
105+
106+
Each question has an expected answer and expected source document for automated evaluation.
107+
108+
### 2.2 Metrics
109+
110+
| Metric | Definition | Method |
111+
|--------|-----------|--------|
112+
| **Groundedness** | % of answers whose content is factually supported by retrieved context | LLM-as-judge (Groq llama-3.3-70b) evaluates each answer against its retrieved context chunks |
113+
| **Citation Accuracy** | % of answers that correctly cite the expected source document | Automated regex check for `[expected-source]` in the answer |
114+
| **Latency p50** | Median end-to-end response time | Timed from question submission to answer return |
115+
| **Latency p95** | 95th percentile response time | Sorted latency array, index at 95% |
116+
117+
### 2.3 Evaluation Results
118+
119+
*(To be populated after running `python evaluation/run_evaluation.py`)*
120+
121+
| Metric | Target | Actual |
122+
|--------|--------|--------|
123+
| Groundedness | ≥ 90% | TBD |
124+
| Citation Accuracy | ≥ 85% | TBD |
125+
| Latency p50 | < 3s | TBD |
126+
| Latency p95 | < 8s | TBD |
127+
128+
### Per-Domain Breakdown
129+
130+
| Domain | Questions | Groundedness | Citation Accuracy |
131+
|--------|-----------|-------------|------------------|
132+
| PTO & Leave | 5 | TBD | TBD |
133+
| Security | 4 | TBD | TBD |
134+
| Expenses | 4 | TBD | TBD |
135+
| Remote Work | 4 | TBD | TBD |
136+
| Holidays | 4 | TBD | TBD |
137+
| Cross-domain | 4 | TBD | TBD |
138+
139+
---
140+
141+
## 3. Technology Stack Summary
142+
143+
| Component | Choice | Rationale |
144+
|-----------|--------|-----------|
145+
| LLM | Groq llama-3.3-70b-versatile | Free, fast, strong instruction following |
146+
| Embeddings | all-MiniLM-L6-v2 | Free, local, lightweight, good quality |
147+
| Vector Store | ChromaDB | Free, persistent, LangChain native |
148+
| Orchestration | LangChain | Required by spec; handles retrieval chain |
149+
| Web Framework | Flask | Lightweight, meets endpoint requirements |
150+
| Chunking | Markdown headers + recursive (1000/200) | Preserves document structure |
151+
| Retrieval | Top-k=5 similarity | Good coverage-to-noise balance |
152+
| Deployment | Render free tier + gunicorn | Proven pattern, zero cost |
153+
| CI/CD | GitHub Actions | Build + test + deploy on push |

0 commit comments

Comments
 (0)