Spaces:
Runtime error
title: Ma Rag
emoji: π€
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 8000
pinned: false
license: mit
short_description: Multi-agent RAG chat over Dell product / policy / tech docs
LangGraph Multi-Agent RAG β Mobile Web App
A mobile-responsive chat app that turns a LangGraph collaborative multi-agent
pipeline (planner β product / policy / tech / general specialists with RAG +
DuckDuckGo β synthesizer) into a production-style web application. The
bundled knowledge base is a set of Dell laptop product / policy / tech
support documents, but the ingestion pipeline is generic β swap the files
in data/source/ to retarget the app to any domain.
- Backend: FastAPI + LangGraph + LangChain + Chroma + Groq LLM
- Frontend: Mobile-first responsive HTML + Tailwind (CDN) + vanilla JS
- Features:
- Planner picks one or more specialist agents for a single question
- Per-domain RAG collections (
product,policy,tech,general) - DuckDuckGo search tool for fresh external info
- Final synthesizer merges specialist answers
- Collapsible Planner Trace and Specialist Outputs in the UI
- File upload endpoint to extend the knowledge base at runtime
- Single-container deploy (Docker) with Hugging Face Spaces / Cloud Run /
Render / Railway recipes in
DEPLOY.md
Project layout
.
βββ backend/
β βββ app/
β β βββ config.py # env + paths
β β βββ llm.py # LLM, embeddings, Chroma singletons
β β βββ tools.py # RAG tools + DuckDuckGo tool
β β βββ graph.py # LangGraph: planner β agents β synthesizer
β β βββ ingest.py # classify + chunk + index documents
β β βββ main.py # FastAPI app + routes + static frontend
β βββ requirements.txt
βββ frontend/
β βββ index.html # mobile-first chat UI
β βββ app.js # chat logic, upload, health
β βββ styles.css
βββ data/
β βββ source/ # drop your .txt/.md/.pdf/.docx here
β βββ chroma/ # persistent vector store (gitignored)
βββ scripts/
β βββ push-to-hf.sh # deploy to a Hugging Face Space
βββ Dockerfile
βββ docker-compose.yml
βββ DEPLOY.md # per-platform deploy recipes
βββ .env.example
βββ run.sh
Quick start
cp .env.example .env
# edit .env: set GROQ_API_KEY=...
./run.sh
# then open http://localhost:8000
On first run it will:
- Install dependencies into
.venv/ - Drop sample documents into
data/source/if empty - Build the Chroma index lazily on the first
/api/ingestcall (or auto on upload)
To trigger the initial ingest, open the app, click Settings β Re-index existing docs, or call:
curl -X POST http://localhost:8000/api/ingest
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | / |
Serves the mobile chat UI |
| GET | /api/health |
Backend + API-key status |
| POST | /api/chat |
{ "message": "..." } β final answer + trace + per-agent logs |
| POST | /api/ingest |
Rebuild Chroma collections from data/source/ |
| POST | /api/upload |
multipart/form-data files[] β saves + re-indexes |
Chat response shape
{
"response": "synthesized final answer (markdown)",
"selected_agents": ["product_agent", "policy_agent"],
"agent_labels": { "product_agent": "Product Agent", "...": "..." },
"agent_outputs": { "product_agent": "...", "policy_agent": "..." },
"debug_log": "Planner selected: ...\nProduct Agent contributed.\n..."
}
Configuration
All settings live in .env (see .env.example). Key ones:
GROQ_API_KEYβ requiredGROQ_MODELβ defaultopenai/gpt-oss-120bEMBEDDING_MODELβ defaultsentence-transformers/all-mpnet-base-v2SOURCE_DATA_DIR,CHROMA_DB_PATHβ override storage locationsCHUNK_SIZE,CHUNK_OVERLAPβ splitter tuning
How document classification works
Files are routed into a specialist collection by filename keyword:
| Keywords in filename | Collection |
|---|---|
product, catalog, inventory, price |
product_collection |
policy, return, shipping, warranty, faq |
policy_collection |
tech, repair, support, troubleshoot |
tech_collection |
| anything else | general_collection |
Name your uploaded files accordingly to keep specialists sharp.
Mobile responsiveness notes
100dvhlayout (no iOS URL-bar jump)- Safe-area padding on the input footer
- Tap-sized buttons and single-column chat stream
- Textarea auto-grows and submits on Enter (Shift+Enter = newline)
- Collapsible trace / specialist panes so the screen stays clean on small devices
Deployment
For production deploys (Docker, Hugging Face Spaces, Cloud Run, Render, Railway, or a plain VPS), see DEPLOY.md. TL;DR for any Docker host:
cp .env.example .env # set GROQ_API_KEY=gsk_...
docker compose up -d --build
curl -X POST http://localhost:8000/api/ingest
Hugging Face Spaces
This repo is Spaces-ready β the YAML frontmatter at the top of this README configures it as a Docker Space on port 8000. A helper script handles the one-off push:
# 1. Create an empty Docker Space at https://huggingface.co/new-space
# 2. In the Space's Settings β Variables and secrets, add:
# Secret: GROQ_API_KEY = gsk_...
# 3. Push the code:
HF_USER=your_hf_username \
HF_SPACE=your_space_name \
HF_TOKEN=hf_your_write_token \
./scripts/push-to-hf.sh
The first build takes 5β8 minutes (it pre-downloads the embedding model into
the image). After it's "Running", the first request triggers auto-ingest of
the documents in 30 s) before answering. Subsequent deploys
are just a regular data/source/ (git push hf HEAD:main.
Extending
The code mirrors the notebook structure so the extensions suggested there
(memory, confidence scoring, weighted voting, guardrails, more tools) slot in
cleanly β add new tools to tools.py, new nodes/edges in graph.py.