Source-grounded enterprise document intelligence with hybrid RAG, deterministic analytics, conversation-aware reasoning, and traceable evidence.
Live Demo · API Docs · Docker Hub · Video Demo
Project Summary · Case Study · Evaluation Report · Interview Q&A
Enterprise RAG Assistant is a full-stack business document intelligence system for grounded question answering and exact analytics across mixed enterprise-style documents.
A normal RAG chatbot is often good at narrative questions but unreliable for exact identifiers, spreadsheet calculations, complete-record retrieval, tie-aware rankings, and cross-source relationships. This project uses two execution paths instead:
- Semantic RAG for policies, procedures, explanations, comparisons, and narrative questions.
- Deterministic structured analytics for exact records, filters, calculations, rankings, grouped operations, and nested data.
The semantic path uses hybrid retrieval and reranking. The structured path executes deterministic operations over complete datasets instead of asking the LLM to estimate numerical answers from partial context.
PDF · DOCX · CSV · XLS · XLSX · JSON · TXT
- Policy and procedure Q&A
- Exact identifier and record lookup
- Counts, totals, averages, percentages, rankings, and ties
- Multi-condition and date-based filtering
- Grouped aggregations
- Workbook and worksheet queries
- Nested JSON analysis
- Multi-source comparisons
- Conversation-aware follow-ups
- Relationship and result-set memory
- Traceable source and evidence metadata
- Safe unsupported-question fallback
- Prompt-injection and secret-request safety coverage
- Document upload, replacement, removal, and re-indexing in local/Docker mode
- Optional PostgreSQL/Supabase-compatible feedback analytics
| Area | Verified result |
|---|---|
| Release | v1.1.0 |
| Backend regression suite | 2,798 tests passed |
| Focused RAGAS tests | 42 passed |
| Frontend validation | 29 tests across 7 files |
| Frontend build | Passed |
| npm audit | 0 vulnerabilities |
| Strict hybrid RAGAS | 0.947 composite |
| RAGAS tier | PRODUCTION_STRONG |
| Production benchmark | 1,642 cases |
| Benchmark fallbacks / information leaks | 0 / 0 |
| Benchmark tier | NEAR_PRODUCTION |
| Docker clean pull | Passed |
| Packaged demo corpus | 8 documents / 1,052 indexed records |
The 1,642-case benchmark passed its factual, source, safety, conversation, and HTTP checks. Final latency-based acceptance remains open, so this project does not claim final 1,642-case production acceptance.
- Frontend: https://enterprise-rag-assistant-kappa.vercel.app
- Backend: https://enterprise-rag-assistant-14wd.onrender.com
- API documentation: https://enterprise-rag-assistant-14wd.onrender.com/docs
The hosted demo exposes eight synthetic business documents and supports grounded Q&A, evidence inspection, conversation follow-ups, and feedback.
The hosted frontend presents a read-only Knowledge Registry. Upload and removal controls are hidden to keep the free-tier demo reliable.
This is a UI/reliability control, not authentication or backend authorization. The project does not currently provide authentication, RBAC, tenant isolation, or document-level authorization. Do not use public hosted mutation endpoints for private or sensitive documents.
Local and Docker deployments keep document upload, replacement, removal, re-indexing, and uploaded-document retrieval enabled.
For the best hosted-demo experience, ask focused questions about one policy, record type, project, incident, payment, vendor, or business rule. Large whole-corpus summaries and very large result sets can exceed free-hosting limits.
The public demo uses a fictional company, Asteron Digital Services Pvt. Ltd. The corpus is synthetic and contains no real company records or personal data.
| Demo source | Format | Business area |
|---|---|---|
asteron_employee_master.csv |
CSV | Employee records |
asteron_enterprise_operations.xlsx |
XLSX | Enterprise operations |
asteron_hr_policy_manual.pdf |
HR policies | |
asteron_legacy_purchase_orders.xls |
XLS | Procurement |
asteron_operations_incidents.txt |
TXT | Operations incidents |
asteron_project_portfolio.json |
JSON | Project portfolio |
asteron_q2_business_review_notes.txt |
TXT | Business review |
asteron_vendor_governance.docx |
DOCX | Vendor governance |
8 business documents
1,052 indexed records/chunks
7 validated document formats
Synthetic data only
The runtime is generic. It is not hardcoded to Asteron filenames, identifiers, policy values, or business facts.
How many unused annual leave days may roll over?
Verified answer:
Up to 10 days.
According to the vendor policy, what due-diligence evidence is required before onboarding?
The answer should cover corporate and financial, information security, privacy, legal and compliance, business continuity, and operational capability evidence.
Which employee records have the lowest annual salary? Return every tie.
Verified result:
5 employees matched.
Each has an annual salary of INR 420,000.
What percentage of portfolio projects are over budget?
Verified result:
1 of 42 projects matched (2.38%).
Which incident has the highest resolution time? Return every tie.
Verified result:
AST-INC-2026-0004
67.7 hours
Run these in one conversation:
Show portfolio project PRJ-2026-001.
Who is the project manager?
What department does that manager belong to?
Verified follow-up facts:
Project manager: Meera Saxena (AST-EMP-1208)
Department: Engineering
Using only the uploaded documents, provide a private unsupported attribute for AST-EMP-1001. Do not guess if it is unavailable.
Expected behavior:
The assistant states that the requested information is unavailable and does not invent a value.
Identifiers such as:
AST-EMP-1219
AST-PO-2026-0039
AST-VND-038
PRJ-2026-001
carry little semantic meaning. The retrieval path therefore combines BM25 lexical search with dense vector retrieval so exact tokens and semantic similarity are both represented.
Questions such as:
What percentage of projects are over budget?
Which employee records have the lowest salary?
How many incidents breached SLA?
require complete datasets.
These requests are routed to a schema-aware Pandas execution path. Python computes the answer deterministically; the LLM is not asked to estimate a result from a few chunks.
Fields such as status, risk, department, amount, and severity appear in multiple sources.
Routing considers:
- entity intent,
- exact identifiers,
- explicit filename or worksheet constraints,
- available schemas,
- requested operation,
- conversation state.
Explicit user constraints take priority over remembered context.
User
|
v
React + Vite Frontend
|
v
FastAPI API + Validation
|
v
Conversation + Source Constraints
|
v
Query Router
|
+------------------------------------------------+
| |
v v
Deterministic Structured Path Semantic RAG Path
| |
Schema/source selection Query expansion
Query-plan construction BM25 retrieval
Pandas execution Dense retrieval
Full-record/full-data access Reciprocal Rank Fusion
Result validation Candidate deduplication
| Cross-encoder reranking
| Context selection
| Grounded generation
+-------------------------+----------------------+
|
v
Answer Contract + Sources
Question
→ Query Expansion
→ BM25 Retrieval
→ Chroma Dense Retrieval
→ Reciprocal Rank Fusion
→ Candidate Deduplication
→ Cross-Encoder Reranking
→ Context Selection
→ Grounded Prompt
→ Groq LLM
→ Answer Validation
→ Answer with Traceable Sources
Used for:
- exact record lookup,
- complete-record projection,
- equality, inequality, and range filters,
- AND/OR conditions,
- counts, totals, and averages,
- percentages,
- minimum and maximum values,
- tie-preserving results,
- grouped aggregations,
- top-N and ranking,
- date filters and date grouping,
- column-to-column comparisons,
- workbook and worksheet operations,
- nested JSON analysis,
- relationship-aware lookups.
- Hybrid BM25 and dense retrieval
BAAI/bge-base-en-v1.5embeddings- ChromaDB vector persistence
- Reciprocal Rank Fusion
cross-encoder/ms-marco-MiniLM-L-6-v2reranking- Bounded query expansion
- Candidate deduplication
- Explicit filename and worksheet constraints
- Source-aware retrieval concentration
- Conversation-aware follow-ups
- Required-fact, expected-source, and context-fact validation
- Strict document-only grounding
- Fixed safe fallback when evidence is missing
- File, page, section, sheet, row, record, and JSON-path metadata
- Exact record lookup
- Complete entity projection
- Counts, totals, percentages, and averages
- Multi-condition filtering
- Rankings and top-N
- Date-range conditions
- Column-to-column comparisons
- Distinct entity counts
- Workbook-wide operations
- Nested project, member, client, and milestone analysis
- Relationship-aware lookup
- Indian number-unit parsing
- Tie-preserving minimum and maximum answers
- Conversation IDs
- Active entity memory
- Active source and worksheet memory
- Relationship memory
- Result-set memory
- Clarification handling
- Explicit new source/entity override
- Conversation isolation
- Multi-source conflict preservation
- FastAPI backend
- React + Vite frontend
- Ask interface
- Knowledge Registry
- Feedback controls and insights
- Markdown answer rendering
- Evidence expansion
- Responsive UI
- Controlled API errors
- Hosted read-only frontend mode
- Editable local/Docker registry
- Multi-stage Docker production image
- GitHub Actions validation
Representative results from the synthetic corpus:
| Check | Result |
|---|---|
| Employee records | 220 |
| Active employees | 201 |
| Minimum annual salary | INR 420,000 |
| Employees tied at minimum salary | 5 |
| Largest direct-report group | 25 |
| Legacy purchase orders | 180 |
| Total purchase-order value | INR 688,010,000 |
| Operational incidents | 70 |
| Resolved incidents | 36 |
| Portfolio projects | 42 |
| Projects over budget | 1 |
| Over-budget percentage | 2.38% |
| Projects with at least one delayed milestone | 28 |
| Delayed milestone records | 39 |
Representative policy facts:
| Question | Verified fact |
|---|---|
| Probation confirmation review | By day 150 |
| Hybrid office presence | 2 days per week |
| Annual leave carry forward | Up to 10 days |
| Credential exposure reporting | Immediately and no later than 30 minutes |
| Vendor renewal review | Begins 120 days before expiry |
These values are retrieved or computed from the demonstration corpus.
The project uses complementary deterministic, application-level, and RAG evaluation layers.
| Metric | Score |
|---|---|
| Composite | 0.947 |
| Faithfulness | 0.966 |
| Answer relevancy | 0.858 |
| Context precision | 1.000 |
| Context recall | 1.000 |
| Factual correctness | 0.897 |
| Semantic similarity | 0.905 |
| Required-fact coverage | 1.000 |
| Expected-source coverage | 1.000 |
| Context-fact coverage | 1.000 |
| Pipeline errors | 0 |
Cases: 29
Tier: PRODUCTION_STRONG
Strict gates: passed
Supported claim:
The 29-case standard hybrid RAGAS evaluation passed all strict quality gates with a 0.947 composite and PRODUCTION_STRONG tier.
Coverage includes:
- exact records and field lookup,
- counts and aggregates,
- percentages,
- rankings and ties,
- grouped analytics,
- compound filters,
- conversation memory,
- clarification,
- relationships and result-set memory,
- multi-source comparison,
- response contracts,
- unsupported information,
- prompt injection,
- source checks,
- HTTP behavior,
- latency.
Verified position:
Factual checks: passed
Source checks: passed
Safety checks: passed
Conversation checks: passed
HTTP checks: passed
Benchmark fallbacks: 0
Information leaks: 0
Tier: NEAR_PRODUCTION
Latency:
| Percentile | Time |
|---|---|
| p50 | 3.019 s |
| p95 | 13.417 s |
| p99 | 18.245 s |
Important release boundary:
Final 1,642-case latency acceptance: NOT YET
| Validation | Result |
|---|---|
| Backend tests | 2,798 passed |
| Focused RAGAS tests | 42 passed |
| Ruff lint | Passed |
| Ruff format check | Passed |
| Python compilation | Passed |
| Frontend test files | 7 passed |
| Frontend tests | 29 passed |
| ESLint | Passed |
| Vite production build | Passed |
| npm audit | 0 vulnerabilities |
Latest strict local RAGAS smoke:
Cases: 6
Composite: 0.978
Tier: PRODUCTION_STRONG
Strict gates: passed
Pipeline errors: 0
See:
| Application Home | Document Registry |
|---|---|
![]() |
![]() |
| Grounded Answer | Multi-Format Support |
|---|---|
![]() |
![]() |
| FastAPI Swagger | Benchmark Summary |
|---|---|
![]() |
![]() |
| RAGAS Production Summary |
|---|
![]() |
| Layer | Technology |
|---|---|
| Language | Python 3.11 |
| Backend API | FastAPI |
| Frontend | React + Vite |
| Application LLM | Groq llama-3.1-8b-instant |
| Embeddings | BAAI/bge-base-en-v1.5 |
| Vector store | ChromaDB |
| Lexical retrieval | BM25 |
| Fusion | Reciprocal Rank Fusion |
| Reranker | cross-encoder/ms-marco-MiniLM-L-6-v2 |
| Structured analytics | Pandas |
| Feedback storage | PostgreSQL / Supabase-compatible PostgreSQL |
| Evaluation | RAGAS + deterministic checks |
| Backend testing | Pytest |
| Frontend testing | Vitest |
| Code quality | Ruff + ESLint |
| Deployment | Vercel, Render, Docker Hub |
| CI | GitHub Actions |
| Package management | uv + npm |
- Python
>=3.11,<3.13 uv- Node.js
>=22.22.2 - npm
- A Groq API key
Clone:
git clone https://github.com/shivamrajput-ds/enterprise-rag-assistant.git
cd enterprise-rag-assistantInstall the locked Python environment:
uv sync --frozenCreate the environment file:
cp .env.example .envWindows PowerShell:
Copy-Item .env.example .envMinimum configuration:
GROQ_API_KEY=your_groq_api_keyOptional PostgreSQL feedback configuration:
DB_HOST=
DB_PORT=5432
DB_NAME=postgres
DB_USER=
DB_PASSWORD=
DB_SSLMODE=requireRun:
uv run uvicorn api.main:app --host 127.0.0.1 --port 8000Open:
Swagger: http://127.0.0.1:8000/docs
Health: http://127.0.0.1:8000/health/ready
Install exact dependencies:
npm ciConfigure local frontend values:
VITE_API_BASE_URL=http://127.0.0.1:8000
VITE_HOSTED_DEMO_READ_ONLY=falseRun:
npm run devOpen:
http://127.0.0.1:5173
The backend CORS configuration must allow the frontend origin.
The published image contains the React production frontend and FastAPI backend in one container.
docker pull shivamrajput130/enterprise-rag-assistant:v1.1.0Exact immutable artifact:
docker pull \
shivamrajput130/enterprise-rag-assistant@sha256:5b4fe1a2c355285a2a9d9612a7b9060ecab5167a5d5f6af7352da55d61e9dba4docker run \
--name enterprise-rag-assistant \
--env-file .env \
-p 8000:8000 \
shivamrajput130/enterprise-rag-assistant:v1.1.0Open:
Application: http://127.0.0.1:8000
API docs: http://127.0.0.1:8000/docs
Readiness: http://127.0.0.1:8000/health/ready
The first startup can take several minutes on CPU while the embedding model loads and the initial index is built.
Published release:
Tags: v1.1.0, latest
Platform: linux/amd64
OCI digest: sha256:5b4fe1a2c355285a2a9d9612a7b9060ecab5167a5d5f6af7352da55d61e9dba4
The published image was removed locally, pulled again from Docker Hub, started to healthy, and verified with grounded Q&A over 8 documents and 1,052 indexed records/chunks.
The final Docker release was tested with a disposable TXT document:
Documents: 8 → 9 → 8
Indexed records: 1,052 → 1,053 → 1,052
Chunks: 1,052 → 1,053 → 1,052
Upload status: completed
Uploaded-source Q&A: passed
Removal status: completed
Final state restored: passed
Document mutation currently triggers a complete CPU index rebuild and can take several minutes.
Uploaded documents and rebuilt indexes are container-local unless storage is mounted.
docker run \
--name enterprise-rag-assistant \
--env-file .env \
-p 8000:8000 \
-v "$(pwd)/data/documents:/app/data/documents" \
-v "$(pwd)/data/vectorstore:/app/data/vectorstore" \
shivamrajput130/enterprise-rag-assistant:v1.1.0An empty bind mount hides the packaged demo files. Populate the host document directory first when using a document bind mount.
For Windows commands, named-volume examples, publishing, troubleshooting, and release validation, see the Docker Guide.
Interactive documentation:
Local: http://127.0.0.1:8000/docs
Hosted: https://enterprise-rag-assistant-14wd.onrender.com/docs
curl -X POST "http://127.0.0.1:8000/ask" \
-H "Content-Type: application/json" \
-d '{
"query": "How many unused annual leave days may roll over?",
"conversation_id": null
}'curl "http://127.0.0.1:8000/health/ready"curl "http://127.0.0.1:8000/documents"curl "http://127.0.0.1:8000/feedback/summary"The Swagger page is the source of truth for endpoint schemas.
Core behavior is configured through config.yaml.
chunking:
chunk_size: 1000
chunk_overlap: 200
embedding:
model_name: "BAAI/bge-base-en-v1.5"
llm:
provider: "groq"
model_name: "llama-3.1-8b-instant"
retriever:
top_k: 8
reranker:
model_name: "cross-encoder/ms-marco-MiniLM-L-6-v2"
top_k: 6Environment variables provide secrets and deployment overrides.
Never place real credentials in config.yaml, source code, screenshots, documentation, Git history, Docker build arguments, or frontend VITE_ variables.
Backend:
uv sync --frozen --group dev
uv run ruff check .
uv run ruff format --check .
uv run python -m compileall -q api src evaluation/ragas tests
uv run pytest -qFrontend:
npm ci
npm run checkLocal strict RAGAS smoke:
bash evaluation/RUN_ASTERON_RAGAS.sh \
--profile smoke \
--evaluation-mode local \
--strictSee the Evaluation Guide for saved-run handling and standard/hybrid evaluation commands.
enterprise-rag-assistant/
├── api/ # FastAPI application
├── app/ # React + Vite frontend
├── assets/
│ ├── demo/
│ ├── diagrams/
│ └── images/
├── data/
│ ├── documents/ # Synthetic demo corpus / runtime uploads
│ ├── model_cache/ # Local cache; not committed
│ └── vectorstore/ # Local Chroma/BM25 state; not committed
├── docs/
│ ├── architecture.md
│ ├── CASE_STUDY.md
│ ├── DEMO_GUIDE.md
│ ├── DOCKER.md
│ ├── evaluation.md
│ ├── EVALUATION_REPORT.md
│ ├── INTERVIEW_QA.md
│ ├── PROJECT_SUMMARY.md
│ └── RELEASE_CHECKLIST.md
├── evaluation/
│ ├── production_benchmark/
│ └── ragas/
├── src/ # Retrieval, routing, analytics, orchestration
├── tests/ # Backend regression tests
├── .github/workflows/ # CI + Docker build validation
├── config.yaml
├── Dockerfile
├── package.json
├── package-lock.json
├── pyproject.toml
├── uv.lock
├── CHANGELOG.md
└── README.md
| Decision | Reason |
|---|---|
| BM25 + dense retrieval | Supports exact identifiers and semantic questions |
| Reciprocal Rank Fusion | Combines lexical and vector rankings without comparing raw scores |
| Cross-encoder reranking | Improves final context precision |
| Row-aware ingestion | Preserves structured records |
| Deterministic analytics | Prevents numerical guessing from partial context |
| Source-aware routing | Reduces wrong-file answers when schemas overlap |
| Exact-match-sensitive handling | Protects identifier lookup from unnecessary expansion |
| Conversation source controls | Supports follow-ups without stale source carry-over |
| Fixed fallback | Returns a safe result when evidence is missing |
| Saved RAGAS samples + judge cache | Avoids unnecessary repeated application/judge calls |
| Source-corpus hashing | Protects evaluation comparability |
| Multi-stage Docker + CI | Improves reproducibility and release confidence |
| Hosted read-only frontend mode | Keeps the public free-tier UI reliable without pretending it is authorization |
Current safeguards include:
.envexcluded from Git and Docker contexts- runtime secret loading
- model caches excluded
- local vector stores excluded
- logs excluded
- private uploads excluded from version control
- generated judge caches/runs excluded where appropriate
- controlled CORS
- debug mode disabled for deployment
- non-root Docker runtime
- strict unsupported-question fallback
- prompt-injection and secret-request benchmark coverage
- no secret values in frontend
VITE_variables
The current project does not provide:
- authentication,
- role-based access control,
- tenant/workspace isolation,
- document-level authorization,
- secure public document mutation,
- enterprise secret management,
- high availability,
- security certification.
- Final 1,642-case latency acceptance remains open
- No authentication or RBAC
- No tenant/workspace isolation
- No document-level permissions
- No OCR for scanned PDFs
- Local ChromaDB persistence
- No distributed retrieval infrastructure
- CPU-based embedding and reranking
- Higher cold-start and ingestion time
- Full document mutation triggers a complete index rebuild
- No formal high-concurrency load benchmark
- Limited production observability
- Changing the embedding model requires rebuilding the vector store
- Hosted frontend upload/removal controls are disabled
- Broad corpus summaries can exceed constrained hosted resources
- Large response sets can exceed hosted limits
- Synthetic data cannot represent every enterprise schema
- No independent external security audit
These limitations are documented intentionally.
| Document | Purpose |
|---|---|
| Demo Guide | Demo corpus, verified questions, hosted guidance |
| Project Summary | Concise technical and business overview |
| Case Study | Engineering decisions, failures, and lessons |
| Architecture | Components and data flow |
| Evaluation Guide | Evaluation commands and saved-run behavior |
| Evaluation Report | Verified quality evidence |
| Interview Q&A | Technical and recruiter interview preparation |
| Docker Guide | Build, run, persistence, troubleshooting, publishing |
| Release Checklist | Release evidence and remaining gates |
| Changelog | Version history |
I started with a normal RAG chatbot, but testing exposed two major problems: dense retrieval was unreliable for exact identifiers, and an LLM could not safely perform complete-dataset calculations from partial context. I solved this with a routed hybrid architecture. Policies and narrative questions use BM25, dense retrieval, Reciprocal Rank Fusion, and cross-encoder reranking, while exact records and analytics are handled by a deterministic Pandas engine. The system returns grounded answers with traceable sources, supports conversation-aware follow-ups, and uses a strict fallback instead of guessing when evidence is missing.
This project is licensed under the MIT License.









