Conversational assistant that answers technical questions using indexed official documentation as its only source of knowledge (local-first, no API keys required).
DocuRAG indexes official technical documentation and lets you chat with it. Instead of searching through pages of docs, you ask a question in natural language and get an answer with sources shown separately in the UI.
- RAG direct: single-collection retrieval (optionally scoped by
technology) + answer generation. - Smart agent: multi-technology routing via
smart_search, then synthesizes a single answer (this is the React UI "Agent" mode). - AG2 (experimental / legacy UI): AutoGen agent runner kept for experimentation (used by the Streamlit UI).
- Python 3.10+
- Ollama installed and running
- Node.js 18+ with npm (for the React UI)
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS / Linux
pip install -r requirements.txtollama pull granite3.2:latest
ollama pull nomic-embed-text:latestpython scripts/ingest.py fastapi
python scripts/ingest.py pythonThis scrapes the official documentation, chunks it, embeds it, and stores vectors in data/chroma_db/ (git-ignored).
uvicorn src.api.app:app --reload --port 8000Verify: open http://localhost:8000/docs.
cd frontend
npm install
npm run devOpen http://localhost:5173.
- Sources are rendered in the UI (not injected into the answer text).
- The primary action toggles Send/Stop. Stop cancels the in-flight request (AbortController).
- Chat sessions can be renamed and deleted (client-side only).
- The UI shows
RAGvsAgentmode:RAG: usesPOST /api/v1/chatwithmode="rag"and optionaltechnology.Agent: usesmode="agent"and runssmart_searchfor deterministic multi-tech routing.
streamlit run src/ui/streamlit_app.pyOpen http://localhost:8501.
Primary endpoints (used by the React UI):
POST /api/v1/chat- body:
{ "message": "...", "technology": "fastapi|python|null", "mode": "rag|agent" } - returns:
{ "answer": "...", "sources": [{ "url": "...", "section": "...", "technology": "..." }], "latency_ms": 123 }
- body:
GET /api/v1/technologies(indexed technologies + chunk counts)
Additional endpoints (sources/ingestion management):
GET /api/v1/sourcesPOST /api/v1/sourcesDELETE /api/v1/sources/{technology}/{url_id}POST /api/v1/ingest
DocuRAG/
config/
config.yaml
sources.yaml
ag2_config.yaml
src/
api/
app.py # FastAPI wrapper for the React UI
agents/
smart_retriever.py # smart_search multi-tech routing
assistant_agent.py # AG2 runner (experimental)
generation/
chain.py # RAG chain + technology-scoped retrieval
ingestion/
scraper.py # scraping + cleanup (e.g. removes header anchor artifacts like "¶")
pipeline.py # chunking/embedding/upsert + stats
sources_manager.py # runtime sources management
ui/
streamlit_app.py # legacy UI
frontend/ # React UI (Vite)
src/
package.json
scripts/
ingest.py
test_rag.py
inspect_chunks.py
- Scrape pages from configured official docs URLs.
- Remove navigation noise and header anchor artifacts.
- Chunk the cleaned text.
- Embed chunks (Ollama embeddings) and upsert into ChromaDB.
- The retriever uses MMR to balance relevance and diversity.
- The answer is generated only from retrieved context.
- Sources are returned as structured metadata and displayed in the UI.
- JavaScript-rendered docs: sites that require JS execution are not supported (BeautifulSoup parses static HTML).
- First response latency: local LLM cold-start can take time; subsequent responses are faster.
- PDF / book ingestion in the UI
- More ingestion sources and better crawling controls
- Evaluation harness (quality checks)


