A small modular RAG service: ingest PDFs into Qdrant, retrieve/answer over them with Ollama, exposed via a FastAPI API and a dark-mode Streamlit chat UI. LangChain runs are traceable through LangSmith.
app/
config.py # central settings from .env
observability.py # LangSmith tracing setup
main.py # FastAPI app + startup
api/
routes.py # /ingest and /extract endpoints
schemas.py # request/response models
services/
rag.py # ingestion + retrieval + answer generation
streamlit_app.py # dark-mode chat interface
.streamlit/config.toml
ingest.py / extract.py / llm-judge.py # original CLI scripts (still usable)
- Start Qdrant:
docker compose up -d - Start the API:
uv run uvicorn app.main:app --reload- Docs at http://localhost:8000/docs
- Start the chat UI:
uv run streamlit run streamlit_app.py
POST /ingest— multipart upload of a PDF (file, optionalcleanflag).POST /extract— JSON{ "query": str, "k": int, "generate": bool }. Withgenerate: trueit returns a grounded answer plus source chunks.
Add to .env to capture LangChain traces:
LANGSMITH_TRACING=true
LANGSMITH_ENDPOINT=https://api.smith.langchain.com
LANGSMITH_API_KEY=<your LangSmith key>
LANGSMITH_PROJECT=rag-tut
Startup logs whether tracing is active.