ma-rag / README.md
DannyTeo
Drop Fly.io deploy path; document HF Spaces as Option 2
8e2022e
|
Raw
History Blame Contribute Delete
6.66 kB
metadata
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:

  1. Install dependencies into .venv/
  2. Drop sample documents into data/source/ if empty
  3. Build the Chroma index lazily on the first /api/ingest call (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 β€” required
  • GROQ_MODEL β€” default openai/gpt-oss-120b
  • EMBEDDING_MODEL β€” default sentence-transformers/all-mpnet-base-v2
  • SOURCE_DATA_DIR, CHROMA_DB_PATH β€” override storage locations
  • CHUNK_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

  • 100dvh layout (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 data/source/ (30 s) before answering. Subsequent deploys are just a regular 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.