# Lutheran Confessional Q&A (RAG + Grok 4.3) A chat-based web application that answers theological questions grounded in Holy Scripture and the Lutheran Confessions (Book of Concord / Tunnustuskirjat). Answers are generated by **Grok 4.3** using retrieval-augmented generation (RAG) over a local vector database. The grounding corpus includes: - Full content scraped from https://www.tunnustuskirjat.fi/ (Finnish Confessions) - The complete public-domain KJV Bible - Content from the official Finnish site (tunnustuskirjat.fi) - Public domain KJV Bible text ## Features - Modern chat interface (multi-turn questions stay on the main screen) - Every answer is explicitly grounded — the model only sees retrieved passages - Sources are shown for transparency - Works in English or Finnish depending on the ingested material ## Quick Start ```bash cd /tmp/lutheran-qa-app python -m venv .venv source .venv/bin/activate pip install -r requirements.txt # 1. Ingest the grounding data (one-time, can take 5–15 minutes the first time) python scripts/ingest.py # 2. Configure Grok 4.3 cp .env.example .env # Edit .env and add your XAI_API_KEY # 3. Run the app # IMPORTANT: Use `python -m uvicorn` (not bare `uvicorn`) after activating. # This ensures the correct Python from your .venv is used (avoids PATH issues # with Xcode Python, pyenv, etc. and the reloader subprocess). python -m uvicorn app.main:app --reload ``` Then open http://127.0.0.1:8000 ### Verify your venv before running After `source .venv/bin/activate`, run: ```bash which python python -c "import fastapi, pydantic_core; print('venv imports OK')" ``` `which python` must print a path containing `lutheran-qa-app/.venv/bin/python`. If imports fail or `which` points elsewhere, recreate the venv: ```bash rm -rf .venv python -m venv .venv source .venv/bin/activate pip install -r requirements.txt python -m uvicorn app.main:app --reload ``` ## Getting an xAI API Key (for Grok 4.3) 1. Go to the xAI console (https://console.x.ai or the developer portal). 2. Create an API key. 3. Export it as `XAI_API_KEY` (or put it in `.env`). The client uses the OpenAI-compatible endpoint at `https://api.x.ai/v1` with model `grok-4.3`. ## How Grounding Works - `scripts/ingest.py` downloads the requested materials (content from tunnustuskirjat.fi + full public-domain KJV Bible), cleans them, chunks them (dynamically sized based on the embedding model's max_seq_length), embeds them with a multilingual model (BAAI/bge-m3), and stores everything in a local ChromaDB database (`data/chroma`). - At query time the app performs semantic (vector) search to retrieve the top ~8 most relevant passages. - Grok 4.3 receives the user question + the retrieved passages (formatted with source + citation) and is instructed to answer **only** from that material, with proper citations and Law/Gospel clarity. - The exact retrieved chunks are shown in the UI (expandable) so you can see precisely what grounded the answer. - No data leaves your machine except the prompt sent to the xAI API. **Important:** After code changes to the ingester (or on first setup), always re-run: ```bash source .venv/bin/activate python scripts/ingest.py ``` You can re-run it anytime to refresh the index. ### Current index composition (after a successful ingest) - ~2160+ KJV Bible chapter chunks (strong scripture grounding) - Full extracted sections from the Finnish confessions site (Augsburgin tunnustus, Yksimielisyyden kirja, Iso/Vähä Katekismus, etc.) - ~80-90 chunks from the requested tunnustuskirjat.fi portal pages (Finnish context + history of the confessions) ## Previous (keyword-only) behavior The original simple keyword matcher over 4 curated entries has been replaced by the full RAG + LLM system. The curated_db.json is no longer used for grounding. ## Development Notes - Vector store lives in `data/chroma` (gitignored by default — you must run ingest locally). - The chat UI renders LLM-generated answers with expandable accordions showing the exact retrieved passages used for grounding. - Temperature is kept low (0.3) for faithfulness.