CoolFace
Apppublic

monradach/parag-on

sourceHugging Faceupdated 1mo agoView on Hugging Face
0likes
App README

PARAG-On

A local retrieval-augmented generation (RAG) prototype for making sense of longitudinal, narrative programmatic-assessment data in medical education. Built for a hands-on workshop: the configurable knobs are the point.

Everything runs on the user's machine. Assessment text is never sent to an external service.

\---

What it does

Given a corpus of narrative assessment records (reflective essays, WBA comments, supervisor feedback) tagged by learner, timepoint, rotation, and competency, PARAG-On lets an educator ask a question in plain language and get an evidence-grounded answer — a longitudinal summary, a concern scan, or a trajectory account — with the exact retrieved evidence shown alongside.

The UI presents the pipeline as a clickable workflow diagram — Data → Embedding Model → Retrieval Results → Prompt → Generation — where clicking a component opens its settings (or, for Data, read-only EDA insights) below the diagram, and clicking it again collapses them.

The default data source is data/feedback.xlsx (sheets: feedback, student_info, evaluator_info). The workbook has no explicit dates, so timepoints are derived from each student's contiguous subject blocks in feedback-ID order. Point PARAGON_DATA at another .xlsx workbook with the same sheets, or at a JSON array of AssessmentRecord objects.

The pipeline

records ─▶ chunk ─▶ embed ─▶ index        (build, cached)
question ─▶ filter ─▶ retrieve top-k ─▶ frame prompt ─▶ generate ─▶ answer

Each stage is controlled by a knob on RAGConfig:

StageKnobWhat changing it demonstrates
Indexingchunk\_strategyprecision vs. context (per\comment / per\timepoint / per\_learner)
Indexingembedding\_backendretrieval quality and token windows (minilm / bge-m3 / gte-base / bge-base / hashing)
Retrievaltop\_krecall vs. noise
Retrievalrerankersimilarity vs. true relevance (none / bge-reranker-v2-m3 / ms-marco-minilm)
Retrievalexpand\_to\_timepointparent-document retrieval: precise matching, contextual evidence
Retrievalfilter\_learner\_id, filter\_rotation, filter\_assessment\_type, filter\_competencyscoping the search
Generationtask\_framingsame evidence, different output (neutral / flag\concerns / track\trajectory)
Generationtemperaturedeterminism vs. variety

Module map

FileResponsibility
parag\_on/schema.pyAssessmentRecord — the data contract
parag\_on/excel\_loader.pyfeedback.xlsx workbook → AssessmentRecords
parag\_on/config.pyRAGConfig — every knob
parag\_on/ingest.pychunking strategies
parag\_on/embeddings.pylocal embedders (MiniLM / BGE-M3 / GTE / BGE + hashing fallback)
parag\_on/rerank.pycross-encoder rerankers (BGE-reranker-v2-m3, MS-MARCO MiniLM)
parag\_on/vectorstore.pytransparent numpy store + metadata filtering
parag\_on/llm.pyOllama / OpenAI-compatible clients + extractive fallback
parag\_on/rag.pyorchestration + the three task framings
app.pyStreamlit UI (workflow diagram + panels)
data/feedback.xlsxdefault feedback corpus (feedback / student\info / evaluator\info sheets)
data/sample\_assessments.jsonJSON demo corpus (usable via PARAGON_DATA)
tests/test\_pipeline.pyoffline smoke tests

Setup (three tiers)

Tier 0 — runs anywhere, no downloads. Lexical retrieval, no generation. Good for verifying the install and for understanding retrieval in isolation.

bash
pip install numpy pandas openpyxl altair requests streamlit
streamlit run app.py   # pick "hashing" in the Embedding Model panel
                       # (the app also falls back to it automatically if
                       #  sentence-transformers is not installed)

Tier 1 — real semantic retrieval. Adds the MiniLM embedder.

bash
pip install -r requirements.txt   # pulls sentence-transformers + torch
# set embedding backend = "minilm" (default)

Tier 2 — full local RAG with generation. Adds Ollama.

bash
# install Ollama from https://ollama.com, then:
ollama pull llama3.1
streamlit run app.py

The app auto-detects Ollama and lists its installed models in the Generation panel; if it is not running the app shows retrieved evidence without a generated summary.

The Generation panel also offers hosted models out of the box — ministral-3b-2512, ministral-8b-2512 and codestral-2508, all on Mistral's OpenAI-compatible endpoint. One secret (PARAGON\_MISTRAL\_KEY) covers all three. Additional models (e.g. a Gemini one) come from PARAGON\_LLM\_MODELS + PARAGON\_LLM\_BASE\_URL + PARAGON\_LLM\_API\_KEY.

Environment variables

VariablePurpose
PARAGON\_DATAdata source path (default data/feedback.xlsx; .xlsx or .json)
PARAGON\_LLM\_MODELScomma-separated hosted model names to offer in the UI
PARAGON\_LLM\_BASE\_URLOpenAI-compatible endpoint; a bare host gets /v1 appended, provider paths like /openai/v1 pass through
PARAGON\_LLM\_API\_KEYserver-side key for the hosted endpoint (generic fallback)
PARAGON\_MISTRAL\_KEYserver-side key used when any of the Mistral example models is selected
PARAGON\_OLLAMA\_HOSTOllama host (default http://localhost:11434; in Docker use http://host.docker.internal:11434)

Try this (demo / activity prompts)

With the default workbook, pick a class group in the Retrieval Results panel (e.g. 22XXX), optionally narrow by subject, and ask: "Are there any concerns about these learners across the year?"

  • task\_framing = neutral\_summary reads reassuringly — ratings are acceptable.
  • task\_framing = flag\_concerns surfaces the interpersonal pattern building across Blocks 1–3 that the numbers alone hide.
  • Switch chunk\_strategy to per\_learner and watch retrieval lose the ability to filter by competency or assessment type.
  • Switch embedding\_backend to hashing and watch semantic recall drop.

Tests

bash
python -m tests.test\_pipeline

A note on responsible use

Outputs are decision support. The prompts require the model to ground claims in dated evidence, cite sources, and flag thin evidence, but generated text can still mislead. Keep a human educator in the loop for every judgement.