An end-to-end chatbot that assists:
- Applicants coming to study in Iran
- Students in Iran seeking to study abroad
It combines a Nuxt 3 frontend, a Node.js/Express backend, and a Python FastAPI RAG service powered by lightweight Sentence Transformers to retrieve curated, verified country-specific guidance. The system prioritizes grounded answers using RAG to minimize hallucinations.
front/— Nuxt 3 single-page app with a chat UI and i18n-friendly layoutbackend/— Express API gateway that:- Uses OpenAI or Gemini to generate responses
- Optionally enables RAG mode to fetch relevant chunks from the RAG API
- Persists chat history in MongoDB
RAG/— FastAPI service that:- Builds embeddings with Sentence Transformers (
LaBSEby default) - Stores chunked text and embeddings in MongoDB
- Exposes
/sendand/receiveendpoints secured by a token header
- Builds embeddings with Sentence Transformers (
Screenshots
- Node.js 18+ and npm
- Python 3.10+
- MongoDB (local or Atlas connection string)
- OpenAI API key (required for query expansion in RAG and for backend OpenAI mode) or Gemini API key (if using Gemini in backend)
All three components use .env files. Do not commit secrets. See the provided .envexample files in front/ and RAG/ for guidance.
# API base URL of the backend
VITE_API_URL=http://localhost:5100
# UI language and direction
VITE_APP_LANGUAGE=en
VITE_APP_DIRECTION=ltr
# Conversation direction used by backend logic: "send" (going abroad) or "receive" (coming to Iran)
VITE_DIRECTION=send
# A stable user id to load/save chat history
VITE_USER_ID=local-dev-user# Server
PORT=5100
NODE_ENV=development
# Persistence
MONGODB_URI=mongodb://localhost:27017/elmino
# LLM provider for response generation
# AI_PROVIDER=OPENAI or GEMINI
AI_PROVIDER=OPENAI
OPENAI_API_KEY=sk-...
# If using Gemini instead of OpenAI
# GEMINI_API_KEY=...
# Response strategy: RAG uses RAG API, PROMPT bypasses RAG
MODE=RAG
# RAG API integration
QUERY_API_URL=http://localhost:8001
RAG_API_TOKEN=dev-tokenNotes
- The backend exposes:
POST /chatbot— send a message{ message, direction, userId }POST /chatbot/history— fetch last messages{ direction, userId }DELETE /chatbot— delete all history{ direction, userId }
- In RAG mode, the backend calls the RAG API at
QUERY_API_URLwith headerX-Token: RAG_API_TOKEN.
MONGODB_URI=mongodb://localhost:27017/elmino_rag
API_PORT=8001
API_HOST=127.0.0.1
API_TOKEN=dev-token
# Used for query expansion prompts inside the RAG service
OPENAI_API_KEY=sk-...Important
- Ensure
API_TOKENhere matchesRAG_API_TOKENinbackend/.env. - For Docker, set
API_PORT=3010if you use the includedRAG/docker-compose.ymlmapping3010:3010.
Open three terminals or run sequentially.
cd RAG
python -m venv .venv
. .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .envexample .env # fill values
python rag_api.py # serves on API_HOST:API_PORT (default 0.0.0.0:8000; set 8001 in .env)Endpoints (with X-Token: API_TOKEN):
POST /send/queryandPOST /receive/queryGET /send/healthandGET /receive/healthPOST /send/reloadandPOST /receive/reload— rebuild chunks/embeddings
Request body for /query:
{
"query": "visa requirements for Germany",
"reload": false,
"memory": "recent chat context text"
}cd backend
npm install
cp .envexample .env # create if not present and fill values
npm run dev # or: npm startThe backend reads PORT from .env. The frontend example uses http://localhost:5100.
cd front
npm install
cp .envexample .env # fill values or adjust VITE_API_URL
npm run dev # default: http://localhost:3000Open the app in your browser and start chatting. The UI language and text direction are controlled by VITE_APP_LANGUAGE and VITE_APP_DIRECTION. The chat mode (send or receive) is controlled by VITE_DIRECTION.
Docker files are provided for the backend and RAG services.
cd backend
docker build -t chatbot .
docker network create persiastudy || true
docker compose up -dThis maps 3012:3012 by default (see backend/docker-compose.yml). If you rely on Docker for backend in dev, set VITE_API_URL=http://localhost:3012 in the frontend.
cd RAG
docker build -t chatbotrag .
docker network create persiastudy || true
docker compose up -dThe compose maps 3010:3010. Ensure API_PORT=3010 inside RAG/.env so the FastAPI service listens on the mapped port.
- Backend prompt templates:
backend/data/prompt-base/ - Backend RAG base prompt handles send/receive modes:
backend/data/RAG-base/ - RAG datasets (curated text):
RAG/data/Send/,RAG/data/Receive/ - Query expansion prompts:
RAG/data/Prompts/
To refresh RAG chunks/embeddings after changing data, call:
curl -X POST \
-H "X-Token: $API_TOKEN" \
http://localhost:8001/send/reloadDebug artifacts are written by the RAG service for inspection:
RAG/debug_similarity_scores.txtRAG/processors/*may writedebug_chunks.txtduring chunking
The RAG service currently loads sentence-transformers/LaBSE in RAG/rag_utils.py. You may switch to a lighter model (e.g., all-MiniLM-L6-v2) by editing the model load line and reloading the service.
- CORS: the backend enables CORS for common dev ports (3000/5173/3007). Ensure your frontend uses one of those origins or adjust the CORS config in
backend/server.js. - Ports: keep
front VITE_API_URLaligned withbackend PORT. Keepbackend QUERY_API_URLaligned withRAG API_PORT. - MongoDB connectivity: both backend and RAG use
MONGODB_URI. Verify credentials and IP allowlists when using Atlas.
Backend
npm run dev # nodemon
npm start # node server.js
npm test # mocha tests/*Frontend
npm run dev
npm run build
npm run previewRAG
python rag_api.py
