Jude

March 7, 2026 · View on GitHub

A local AI study assistant for Jewish texts. Ask questions about Torah, Talmud, Halacha, Kabbalah, Midrash, and more. Runs fully offline.

How it works

Each question passes through a five-stage pipeline:

  1. Router — classifies the question by tier (halacha, narrative, debate, mystical) and depth, generates search queries. For halachic questions, a second fast classifier identifies the specific topic (Shabbat, Divorce, Kashrut, etc.) and maps it to its canonical source hierarchy.
  2. Retrieval — queries a ChromaDB vector database of 288,737 Sefaria passages. Halachic questions use dual retrieval: a primary pass fetches sources strictly from the topic's canonical hierarchy (Torah → Mishnah → Talmud → Rambam → Shulchan Arukh), then a secondary pass sweeps the broader corpus for contextual material.
  3. Filter — an LLM pass drops irrelevant sources
  4. Synthesis — streams a cited answer tuned to the question type. Primary sources are labeled and cited first in the canonical halachic order.
  5. Tools (optional, requires llama3.2+) — the synthesiser can call retrieve_more, lookup_ref, and find_parallel mid-generation to pull additional passages as needed.

Results are streamed live to the browser. Every source card links back to Sefaria.

Three modes: Q&A (default), Study (pre-loads a deep source pool for sustained exploration), Sources Only (skip synthesis, browse raw passages).

Hebrew input is detected automatically; search queries are translated to English before retrieval so the full corpus is always searchable.

Models run via Ollama by default. You can also point Jude at any OpenAI-compatible cloud provider (OpenAI, Groq, Together, etc.) using a .env file — see Configuration below.

Halachic topic routing

When a question is identified as halachic, Jude detects the specific topic and enforces a canonical source hierarchy for retrieval and citation:

TopicSederCanonical sources
ShabbatMoedExodus → Mishnah Shabbat → Shabbat → Mishneh Torah, Sabbath → Shulchan Arukh OC
EruvinMoedMishnah Eruvin → Eruvin → Mishneh Torah, Eruvin
PesachMoedExodus → Mishnah Pesachim → Pesachim → Mishneh Torah, Leavened and Unleavened Bread
Yom TovMoedMishnah Beitzah → Beitzah → Mishneh Torah, Rest on a Holiday
Rosh HashanahMoedMishnah Rosh Hashanah → Rosh Hashanah → Mishneh Torah, Shofar...
Yom KippurMoedLeviticus → Mishnah Yoma → Yoma → Mishneh Torah, Rest on the Tenth of Tishrei
SukkotMoedLeviticus → Mishnah Sukkah → Sukkah → Mishneh Torah, Shofar...
Purim / MegillahMoedMishnah Megillah → Megillah → Mishneh Torah, Scroll of Esther...
Fast DaysMoedMishnah Ta'anit → Ta'anit → Mishneh Torah, Fasts
MarriageNashimDeuteronomy → Mishnah Kiddushin → Kiddushin → Mishneh Torah, Marriage → SA Even HaEzer
DivorceNashimDeuteronomy → Mishnah Gittin → Gittin → Mishneh Torah, Divorce → SA Even HaEzer
NiddahTahorotLeviticus → Mishnah Niddah → Niddah → Mishneh Torah, Forbidden Intercourse
KashrutKodashimLeviticus → Mishnah Chullin → Chullin → Kitzur SA → SA Yoreh De'ah
PrayerZeraimMishnah Berakhot → Berakhot → Mishneh Torah, Prayer... → SA Orach Chayim
BlessingsZeraimMishnah Berakhot → Berakhot → Kitzur Shulchan Arukh
Torts & DamagesNezikinExodus → Mishnah Bava Kamma → Bava Kamma → Mishneh Torah, Laws of Wounding...
Loans & ContractsNezikinMishnah Bava Metzia → Bava Metzia → Mishneh Torah, Creditor and Debtor
Vows / NedarimNashimNumbers → Mishnah Nedarim → Nedarim → Mishneh Torah, Vows
Temple SacrificesKodashimLeviticus → Mishnah Zevachim → Zevachim → Mishneh Torah, Sacrificial Procedure

Each topic also carries a related_books list — topic-adjacent tractates used for the secondary retrieval pass (e.g. Shabbat → Eruvin + Beitzah; Divorce → Ketubot + Yevamot). This ensures secondary sources come from halachically relevant tractates rather than a generic corpus sweep.

The topic badge (e.g. 📚 Shabbat · Seder Moed) is shown in the answer header. Source cards are grouped into Primary Sources (gold border, ⚖ badge) and Secondary Sources.

Setup

1. Prerequisites

  • Python 3.11+
  • Ollama installed and running
  • The sefaria_rag_markdown/ corpus and chroma_db/ index (see below)

Pull the required models:

ollama pull llama3.2
ollama pull nomic-embed-text

llama3.2 handles all pipeline roles — routing, filtering, summarisation, and tool-calling synthesis. No separate model is needed.

2. Install dependencies

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

3. Download the data

The corpus and vector index are hosted on Hugging Face (too large for GitHub):

pip install huggingface_hub
python - <<'EOF'
from huggingface_hub import snapshot_download
snapshot_download(
    repo_id="RockyCo/jude-judaic-data",
    repo_type="dataset",
    local_dir=".",
)
EOF

This downloads sefaria_rag_markdown/ (~1.2 GB) and chroma_db/ (~2.0 GB) into the project root.

Or rebuild the index yourself from the corpus only:

python -m backend.indexer

4. Start the server

Option A — server + terminal UI together (recommended):

python run.py

This starts the FastAPI server in the background and opens the terminal UI in the same window. Server logs are written to server.log. Press Ctrl+C in the terminal UI to stop everything.

Option B — server only (web UI):

python run.py --web-only
# or the classic:
uvicorn backend.main:app --reload --port 8000

Open http://localhost:8000.

Option C — terminal UI against an already-running server:

python tui.py
# or with a custom host/port:
python tui.py --host localhost --port 8000

run.py flags

FlagDefaultDescription
--port8000Port for server and TUI
--host127.0.0.1Bind host for the server
--web-onlyoffStart server only, no terminal UI
--tui-onlyoffSkip starting server (connect to existing)
--reloadoffPass --reload to uvicorn (dev mode)

Configuration

Dynamic Cloud Fallback

Jude is designed and tuned to use a highly reliable fallback cascade for synthesis. If a primary API key hits a rate limit or times out, the backend seamlessly routes the request to the next available provider in the chain without dropping the user's query.

Copy .env.example to .env and fill in your credentials to enable cloud models:

cp .env.example .env
# .env
GEMINI_API_KEY=AIzaSy...     # Priority 1: Google Gemini (fastest, high quality)
LLMOD_API_KEY=sk-...         # Priority 2: LLMod RPRTHPB-gpt-5-mini
# If both fail or are missing, Priority 3: Ollama (Local) takes over

Note: The Gemini free tier has a strict 5 queries per minute rate limit. This fallback system allows Jude to handle sudden concurrency spikes by silently spilling over to LLMod and then to local execution.

Priority Cascade

  1. Gemini 2.5 Flash / gpt-4o scale (if GEMINI_API_KEY is present)
  2. LLMod RPRTHPB-gpt-5-mini (if LLMOD_API_KEY is present)
  3. Local Ollama llama3.2 (Default absolute fallback / Offline mode)

Per-role overriding

While synthesis uses the fallback chain to prevent timeouts, you can lock specific functional roles (like routing or filtering) to ALWAYS use the local Ollama instance explicitly, saving cloud tokens on easy JSON tasks:

# .env — typical hybrid routing
ROUTER_PROVIDER=ollama      # "ollama" | "cloud"
FILTER_PROVIDER=ollama
SUMMARY_PROVIDER=ollama
# Synthesis/Tools will still use the dynamic Gemini -> LLMod -> Ollama cascade

You can also completely override the cascade by supplying a direct OpenAI-compatible endpoint and key for any role:

# Force the router to use Groq specifically:
ROUTER_API_KEY=gsk_...
ROUTER_BASE_URL=https://api.groq.com/openai/v1
ROUTER_MODEL=llama-3.3-70b-versatile

Model configuration guide

Each pipeline step has different requirements:

RoleTaskQuality needLocal (llama3.2)Cloud options
ROUTER_MODELClassify tier, depth, search queries (JSON ~150 tok)Medium2–7 sgpt-4o-mini (~0.5 s), Groq llama3 (~0.3 s)
FILTER_MODELScore each source keep/drop (JSON ~200 tok)Medium, fail-open4–5 sgpt-4o-mini, Groq llama3
SUMMARY_MODELCompress chat history (2-4 sentences)Low1–2 sany
SYNTH_MODELFull cited structured answer (500–2000 tok)High30–90 sgpt-4o (~20 s), claude-3-5-sonnet, gpt-4o-mini
TOOLS_MODELTool selection + full answer (needs function calling)High30–90 ssame as SYNTH

Recommended configurations:

ProfileRouter / Filter / SummarySynthesisTotal latencyCost
Full localOllama llama3.2Ollama llama3.230–90 sFree
Hybrid balanced (default)Ollama llama3.2gpt-4o-mini cloud20–50 sLow (~$0.001/query)
Hybrid qualityOllama llama3.2gpt-4o cloud15–40 sMedium
Groq acceleratedGroq llama-3.3-70bgpt-4o cloud5–20 sMedium
Full cloudgpt-4o-mini cloudgpt-4o cloud40–120 sHigh

The default .env.example ships with the Hybrid balanced profile: Ollama for fast tasks, cloud model for synthesis quality.

User login

Jude supports lightweight name-based user sessions. On first visit a login modal asks for a name. The name is stored in localStorage and sent with every request so each user sees only their own chat history. There is no password or server-side authentication — it is purely a convenience for shared local deployments.

To switch users, click your name in the top-right corner of the interface.

Disk space

ItemSizeNotes
llama3.2 (Ollama)2.0 GBRouter, filter, summarisation, tool-calling synthesis
nomic-embed-text (Ollama)274 MBEmbeddings — always required
chroma_db/2.0 GBVector index — required at runtime
sefaria_rag_markdown/1.2 GBSource corpus — required for Hebrew text on source cards and re-indexing
Total~5.5 GB+(cloud synthesis model, no local storage needed)

Terminal UI

The terminal UI connects to the same /api/chat SSE endpoint as the browser and supports the same three modes (Q&A, Study, Sources Only).

Your name: Alice

Mode: qa  ·  Type /help for commands

You: What is the biblical source for lighting Shabbat candles?
  Retrieving sources…
  Filtering sources…

Jude: The primary biblical basis for Shabbat candle lighting derives from…

  Shabbat 25b        The Sages derived the obligation…
  Mishnah Shabbat 2  These are the wicks…

You: /mode study
Mode set to 'study'. New chat started.

You: /quit
Goodbye.

Available commands:

CommandAction
/newStart a fresh chat
/mode qaSwitch to Q&A mode
/mode studySwitch to Study mode
/mode sourcesSwitch to Sources-only mode
/helpShow command reference
/quitExit

Project structure

backend/
  main.py          # FastAPI server, SSE streaming
  llm.py           # LLM provider abstraction (Ollama + OpenAI-compatible)
  router.py        # Question routing, halachic topic classification
  retriever.py     # ChromaDB vector search, dual retrieval, reranking
  filter.py        # Post-retrieval relevance filter
  synthesiser.py   # Answer generation (streaming + tool-calling)
  tools.py         # Agentic tool definitions and dispatch
  chat_store.py    # Chat history (JSON) + session caches
  guard.py         # Prompt injection defense
  indexer.py       # One-time index builder
frontend/
  index.html       # Single-file web UI
tui.py             # Terminal UI client
run.py             # Launcher: starts server + terminal UI together
chroma_db/         # Vector index (required at runtime)
sefaria_rag_markdown/  # Source corpus (required for Hebrew text + re-indexing)