RAG-powered knowledge base assistant. Upload your documents, ask anything — get accurate, source-cited answers in real time.
| Layer | Technology |
|---|---|
| Frontend | React 18 · TypeScript · Vite · UnoCSS |
| Backend | FastAPI · Python 3.11 |
| RAG | LangChain · ChromaDB |
| LLM | Anthropic Claude API |
| Streaming | Server-Sent Events (SSE) |
- 📄 Upload PDF / Markdown / TXT documents
- 🔍 Hybrid retrieval — vector search + BM25, fused via RRF
- ⚖️ Two-stage rerank — recall Top-20, rerank to Top-5
- 💬 Streaming answers with source citations
- 🚫 Hallucination-resistant — refuses to answer outside context
- Python 3.11+
- Node.js 18+
- Anthropic API key
cd backend
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Add your ANTHROPIC_API_KEY to .env
uvicorn main:app --reload --port 8000cd frontend
npm install
npm run dev # http://localhost:5173# Copy and fill in your API key first
cp .env.example .env
docker compose up --buildServices:
- Frontend →
http://localhost:5173 - Backend →
http://localhost:8000
docker-compose.yml mounts ./data for ChromaDB persistence.
Base URL: http://localhost:8000/api
POST /documents/upload
Content-Type: multipart/form-data
file: <PDF | TXT | MD>
{ "doc_id": "abc123", "chunk_count": 24, "status": "ok" }GET /documents
[{ "doc_id": "abc123", "filename": "handbook.pdf", "chunk_count": 24, "created_at": "2026-02-22T10:00:00Z" }]DELETE /documents/{doc_id}
POST /chat/stream
Content-Type: application/json
{ "query": "string", "doc_ids": ["abc123"], "history": [] }
SSE response stream:
data: {"type": "token", "content": "Based on..."}
data: {"type": "sources", "sources": [{"text": "...", "score": 0.91, "source": "handbook.pdf"}]}
data: {"type": "done", "usage": {"input_tokens": 480, "output_tokens": 212}}
GET /health
{ "status": "ok", "doc_count": 3, "vector_count": 72 }recall/
├── backend/
│ ├── main.py
│ ├── routers/
│ │ ├── chat.py
│ │ └── documents.py
│ ├── services/
│ │ ├── rag_service.py
│ │ ├── embedding.py
│ │ └── llm_service.py
│ ├── models/schemas.py
│ └── requirements.txt
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ ├── stores/
│ │ └── hooks/
│ ├── vite.config.ts
│ └── uno.config.ts
├── docker-compose.yml
└── .env.example
# .env.example
ANTHROPIC_API_KEY=sk-ant-...
CHROMA_PERSIST_DIR=./data/chroma
CHUNK_SIZE=512
CHUNK_OVERLAP=50
RETRIEVAL_TOP_K=20
RERANK_TOP_N=5- Fork the repo
- Create a feature branch —
git checkout -b feat/your-feature - Commit with conventional commits —
feat:/fix:/docs: - Open a pull request
MIT