Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AriaAI — RAG-Powered Customer Service Backend

A Django REST backend for an AI customer-service desk. It combines a retrieval-augmented (RAG) chatbot that answers from your own uploaded documents, a full grievance/ticketing workflow with email notifications, and real-time chat over WebSockets — all behind JWT-authenticated APIs.

Built as a backend internship project (Sept 2025) to explore how an LLM can be grounded in private company knowledge instead of answering from generic model memory.


What problem it solves

A plain LLM chatbot hallucinates and can't answer questions about your policies, products, or procedures. AriaAI fixes that by:

  1. Letting staff upload company documents, which are chunked and embedded into a searchable vector store.
  2. On each user question, retrieving the most relevant chunks and feeding them to the model as context — so answers are grounded in real documentation.
  3. Escalating anything the bot can't resolve into a tracked grievance that moves through a human assign → resolve → rate workflow with emails at every step.

Key Features

Area What it does
RAG chatbot Answers grounded in uploaded docs via the Claude API (claude-opus-4-8) over locally-embedded context
Document ingestion Sentence-aware chunking, batched embeddings, vector storage
Semantic search Cosine-similarity search across all processed documents
Grievance system Create → assign → resolve → rate, with HTML email at each stage
Real-time chat WebSocket consumer (Django Channels) with JWT auth
Auth & ownership JWT (SimpleJWT); users only ever see their own sessions/docs/tickets; staff see all grievances
Admin Django admin over every model

How it works

Document ingestion (building the knowledge base)

POST /api/documents/upload_and_process/
        │
        ▼
RAGProcessor.process_document()
        ├─ _chunk_text()        sentence-aware ~1000-char chunks, 200-char overlap
        ├─ _create_embeddings() local deterministic hashing embedding (no API call)
        └─ persist DocumentChunk rows (content + embedding stored as JSON)

Answering a question (the RAG loop)

User ─▶ POST /api/chat/sessions/{id}/send_message/   (or the WebSocket)
            │
            ▼
     ChatbotEngine.process_chat_message()
            │
            ├─▶ RAGProcessor.get_relevant_context(query)
            │       ├─ embed the query (local hashing embedding)
            │       ├─ cosine similarity vs every stored chunk vector
            │       └─ pack top matches into a ~2000-token context budget
            │
            └─▶ Claude (claude-opus-4-8)  ◀─ system prompt + retrieved context + user message
                    │
                    ▼
            assistant reply ─▶ saved as a ChatMessage
                               (with token count + context metadata)

Retrieval is a straightforward in-Python cosine-similarity scan over chunk vectors stored as JSON — simple and dependency-light, ideal for a demo-scale corpus. Embeddings are computed locally (a deterministic hashing embedding), so the whole pipeline runs with only a Claude API key and no second vendor. (See Scaling notes for the production path.)


Tech Stack

  • Framework: Django 5.2 + Django REST Framework
  • Auth: JWT via djangorestframework-simplejwt
  • AI/ML: Anthropic Claude API (claude-opus-4-8) for chat; local hashing embedding for retrieval (no embeddings vendor required)
  • Real-time: Django Channels (in-memory channel layer; Redis-ready)
  • Database: SQLite by default (swappable for PostgreSQL/MySQL)
  • Email: SMTP (console backend used automatically when no credentials are set)

Project Structure

ariaai/
├── config/                 # Django project (settings, URLs, ASGI/WSGI)
│   ├── settings.py         # env-driven config, JWT/CORS/Channels setup
│   ├── urls.py             # API root + admin + JWT token routes
│   └── asgi.py             # HTTP + WebSocket (ProtocolTypeRouter)
├── chat/                   # The single application
│   ├── models.py           # UserProfile, ChatSession, ChatMessage,
│   │                       #   Document, DocumentChunk, Grievance
│   ├── views.py            # DRF viewsets + auth + chatbot/health endpoints
│   ├── serializers.py      # Request/response schemas
│   ├── rag_utils.py        # RAGProcessor + ChatbotEngine (the core logic)
│   ├── email_utils.py      # Grievance/chatbot notification emails
│   ├── consumers.py        # WebSocket chat consumer
│   ├── middleware.py       # JWT authentication for WebSocket connections
│   ├── routing.py          # WebSocket URL routing
│   ├── templates/emails/   # HTML email templates
│   └── tests.py            # Auth, grievance, RAG, and health-check tests
├── requirements.txt
└── .env.example

Data model at a glance

  • UserProfile — phone/address, one-to-one with Django's User.
  • ChatSession / ChatMessage — conversations and their turns (UUID keys; messages carry RAG metadata like tokens used and context length).
  • Document / DocumentChunk — uploaded source text and its embedded chunks.
  • Grievance — a support ticket with status, priority, assignee, resolution notes, and a 1–5 satisfaction rating.

Getting Started

Prerequisites

  • Python 3.10+
  • An Anthropic API key (required for the chatbot; document search/RAG works without it)

Setup

# 1. Clone
git clone https://github.com/jaisinha77777/ariaai.git
cd ariaai

# 2. Virtual environment
python -m venv venv
source venv/bin/activate          # Windows: venv\Scripts\activate

# 3. Dependencies
pip install -r requirements.txt

# 4. Environment variables
cp .env.example .env              # then edit .env (see below)

# 5. Database
python manage.py migrate

# 6. Admin user
python manage.py createsuperuser

# 7. Run
python manage.py runserver

Visit http://localhost:8000/ for the API index, or /admin/ for the admin.

Environment variables (.env)

# Django core
DJANGO_SECRET_KEY=your-random-secret-key      # generate a fresh one for any real deployment
DJANGO_DEBUG=True
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1

# Anthropic (Claude)
ANTHROPIC_API_KEY=your_anthropic_api_key_here
# ANTHROPIC_MODEL=claude-opus-4-8   # optional override

# Email — leave blank to print emails to the console instead of sending
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
DEFAULT_FROM_EMAIL=your-email@gmail.com

SITE_URL=http://localhost:8000

No secrets are committed: every credential is read from the environment, and email falls back to the console backend when SMTP isn't configured, so the app runs end-to-end without external services.

The default channel layer is in-memory, so WebSockets work out of the box for local development. Redis (channels-redis) is only needed to scale the channel layer across multiple processes in production.


API Reference

All /api/... routes except registration, login, and health require an Authorization: Bearer <access_token> header.

Authentication

Method Endpoint Description
POST /api/auth/register/ Register a user (optionally with a profile)
POST /api/auth/login/ Log in, returns access + refresh tokens
GET/PUT /api/auth/profile/ View / update the current user's profile
POST /api/token/ · /api/token/refresh/ Obtain / refresh a JWT

Chat

Method Endpoint Description
GET/POST /api/chat/sessions/ List or create chat sessions
GET/PUT/DELETE /api/chat/sessions/{id}/ Manage a session
POST /api/chat/sessions/{id}/send_message/ Send a message, get the bot's reply
GET/POST /api/chat/messages/ List or create messages
POST /api/chatbot/query/ One-shot chatbot query (no session)

Documents (RAG)

Method Endpoint Description
GET/POST /api/documents/ List or create documents
POST /api/documents/upload_and_process/ Upload text and embed it immediately
GET /api/documents/{id}/chunks/ Inspect a document's chunks
POST /api/documents/search/ Semantic search across documents

Grievances

Method Endpoint Description
GET/POST /api/grievances/ List or file a grievance
POST /api/grievances/{id}/assign/ Assign to staff (staff only)
POST /api/grievances/{id}/resolve/ Resolve with notes (staff only)
POST /api/grievances/{id}/rate/ Rate the resolution 1–5 (owner only)

System & Real-time

Method Endpoint Description
GET /api/health/ Health check (DB + Anthropic config status)
WS ws://localhost:8000/ws/chat/{session_id}/?token={JWT} Real-time chat stream

The WebSocket authenticates with the same JWT as the REST API (passed as the token query param). Send {"message": "..."} frames; the server replies with user_message and assistant_message events and persists both to the session.


Usage Examples

Register

curl -X POST http://localhost:8000/api/auth/register/ \
  -H "Content-Type: application/json" \
  -d '{"username":"testuser","email":"test@example.com",
       "password":"password123","confirm_password":"password123"}'

Upload a document for RAG

curl -X POST http://localhost:8000/api/documents/upload_and_process/ \
  -H "Authorization: Bearer YOUR_JWT" -H "Content-Type: application/json" \
  -d '{"title":"Remote Work Policy","content":"Employees may work remotely..."}'

Ask a grounded question

# Create a session
curl -X POST http://localhost:8000/api/chat/sessions/ \
  -H "Authorization: Bearer YOUR_JWT" -H "Content-Type: application/json" \
  -d '{"title":"Support Chat"}'

# Send a message (uses RAG over your uploaded docs)
curl -X POST http://localhost:8000/api/chat/sessions/<SESSION_ID>/send_message/ \
  -H "Authorization: Bearer YOUR_JWT" -H "Content-Type: application/json" \
  -d '{"message":"What is the company policy on remote work?"}'

File a grievance

curl -X POST http://localhost:8000/api/grievances/ \
  -H "Authorization: Bearer YOUR_JWT" -H "Content-Type: application/json" \
  -d '{"subject":"Issue with service","description":"Details...",
       "category":"service","priority":"medium","email":"user@example.com"}'

Configuration

Tunable in config/settings.py:

Setting Default Purpose
RAG_CHUNK_SIZE 1000 Target characters per document chunk
RAG_CHUNK_OVERLAP 200 Overlap between consecutive chunks
MAX_CHAT_HISTORY 50 Max messages retained per session

JWT lifetimes (SIMPLE_JWT): 60-minute access tokens, 1-day refresh tokens.


Testing

python manage.py test

The suite covers auth (registration/login/validation), grievance creation with mocked email, the RAG chunking / embedding / cosine-similarity helpers, and the health check. Embeddings are local and email is mocked, so no API key or network access is needed to run the tests.


Scaling notes

This project is intentionally demo-scale. To take it to production:

  • Embeddings: the local hashing embedding captures lexical overlap, not deep semantics. For production-quality retrieval, swap RAGProcessor._embed_text for a real embedder (Voyage AI — Anthropic's recommended partner — or a local sentence-transformer).
  • Vector search: replace the in-Python cosine scan with a real vector index (pgvector, FAISS, or a managed vector DB) — the current approach is O(n) per query over all chunks.
  • Background processing: move document embedding off the request path into a task queue (Celery/RQ); it's currently synchronous.
  • Channel layer: switch from the in-memory layer to channels-redis so WebSockets work across multiple processes/workers.
  • Database: swap SQLite for PostgreSQL.
  • Settings: DEBUG=False, a strong DJANGO_SECRET_KEY, scoped ALLOWED_HOSTS, HTTPS, and centralized logging/monitoring.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages