Projects

Quanta

A LangChain RAG system for source-grounded dermatology literature review — every claim traceable to a real passage, validated against MedQA, accepted at KSID × ISID APAC 2026.

TimelineSep 2024 – Dec 2025
ContextUM Cutaneous Lab (Dr. Lam Tsoi)
RoleSole engineer · first author
StackPython · LangChain · GPT-4 · ChromaDB · Streamlit

Overview

A retrieval-augmented system that lets clinicians ask grounded questions across long dermatology papers — and cites the exact passages that support every answer.

Dermatology research is fragmented across long, dense manuscripts, and the LLM tools clinicians reached for first (general-purpose chatbots) hallucinated citations and lost context across multi-page papers. Quanta is a Python application built around a layered LangChain retrieval pipeline — query expansion, hybrid semantic + BM25 search, MMR diversification, cross-encoder reranking, and parent-document context expansion — paired with a Streamlit interface for clinician use. Tested with 10+ clinicians across 55+ manuscripts; cut literature-review time by ~75%; produced a bioRxiv preprint (2025.08.14.670384v1) with abstract accepted at KSID × ISID APAC 2026 — Young Investigator Selection.

Stack

language
Python
retrieval & ml
LangChain Sentence-BERT (MPNet) ChromaDB GPT-4 (OpenAI API) BM25 Cross-encoder reranker ParentDocumentRetriever MultiQueryRetriever
front-end
Streamlit ConversationMemory
evaluation
MedQA (USMLE) retrieval-contains-answer diagnostic F1 · NDCG with significance testing
file ingestion
PDF TXT DOCX

The Problem

Dermatologists couldn't trust the AI tools they were reaching for first.

Clinical researchers in dermatology review large collections of long, dense manuscripts to stay current — but the obvious LLM-based shortcuts had two failure modes. General chatbots hallucinated citations (claiming a paper said something it didn't, or inventing references entirely). Naive vector-similarity retrieval returned passages that sounded topically related but weren't actually evidence for the user's question. For clinical use, "sounds right" isn't enough: every claim needs to point at a real passage, and the retrieval has to surface the actually relevant one, not just the topically similar one.

💡
How might we
build a retrieval system accurate enough for clinical literature review, with every answer traceable to a real passage in a real document?

Methodology

Layered retrieval with document-size-adaptive branching — small corpora and large ones get different retrievers because the optimal balance between precision and recall differs at scale.

Stage What it does & why
1. MultiQueryRetrieverGPT-4 expands the user's question into multiple sub-queries. Catches the case where the user's phrasing differs from how the answer is phrased in the document.
2. Document-size branchingSmall corpora (< 20 chunks) → ContextualCompressionRetriever. Large corpora (≥ 20 chunks) → EnsembleRetriever combining vector similarity with BM25. The branching threshold was picked from empirical chunk-count distribution across the actual corpus.
3. MMR diversificationReduces redundancy in the retrieved set — without it, top-k results often pull near-duplicate passages from the same section.
4. Cross-encoder rerankerDedicated reranking model. More accurate than cosine similarity alone; the most expensive step, so it operates on a small candidate set produced by the previous stages.
5. ParentDocumentRetrieverExpands the top-ranked chunks back into their parent context windows before passing to GPT-4 — so the LLM sees enough surrounding text to write a grounded answer.
6. GPT-4 generationAnswer + citation pass. The README explicitly separates retrieval from generation as a design principle.

Pipeline

Code organized so the retrieval system is testable independently of the front-end, and earlier experiments survive as an archive/ for reproducibility.

QuantaBot/ ├── scripts/ │ ├── run_app.py # Streamlit entry point │ └── run_medqa_eval.py # MedQA benchmark entry point ├── src/quantabot/ # importable package │ ├── core/ │ │ ├── rag.py # LangChain RAG system │ │ └── llm.py # OpenAI wrapper │ ├── loaders/ # PDF / TXT / DOCX │ ├── utils/ │ │ ├── document_processor.py │ │ ├── embedding_wrapper.py │ │ └── text_processing.py │ └── ui/streamlit_app.py ├── evaluations/ │ └── medqa/evaluator.py # USMLE / MedQA evaluator ├── data/ # MedQA dataset + medical textbooks ├── results/ # Eval JSON / CSV ├── docs/ # research roadmap, notes └── archive/ # TF-IDF vs SBERT, BEIR/NFCorpus, earlier iterations

The embedding model is configurable via env var (QUANTA_EMBEDDING_MODEL). Defaults to all-mpnet-base-v2; BAAI/bge-large-en-v1.5 is a tested alternative. Apache-2.0 licensed; 79 commits at time of writing.

Findings

Statistically significant gains over the vector-similarity baseline, ~97% memory reduction, and clinician-tested adoption inside the lab.

Statistical validation matters more than the headline numbers. Many RAG papers report that their system "performs better" without significance testing; Quanta's F1 and NDCG gains over a vector-similarity baseline were tested on a 55+ manuscript dermatology corpus and held up.

p = 0.0165
F1 vs. vector-similarity baseline
p = 0.004
NDCG vs. vector-similarity baseline
~97%
memory reduction vs. baseline

Clinical adoption: tested with 10+ clinicians across 55+ manuscripts; ~75% reduction in literature-review time per the user feedback. Now in working use inside Dr. Lam Tsoi's Cutaneous Lab.

Publication: Preprint on bioRxiv (2025.08.14.670384v1); abstract accepted at KSID × ISID APAC 2026 — Young Investigator Selection.

~75%
reduction in literature-review time
55+
manuscripts tested
10+
clinicians piloted the system

Limitations

  • Citation faithfulness isn't separately benchmarked. Quanta's evaluation tests whether the answer is correct; it doesn't yet have a benchmark for whether the cited passage actually supports the answer. That's the next evaluation pass.
  • Domain-bounded. Tested on dermatology manuscripts and MedQA. Generalization to other clinical domains is plausible but not yet validated.
  • Compute cost. The cross-encoder reranker is the most expensive stage and is configurable but not free. A production deployment would need either caching, smaller candidate sets, or model distillation.
  • LangChain ecosystem drift. Some components have been deprecated or replaced as LangChain has evolved; periodic rebases are required.

Lessons Learned

Separating retrieval from generation is the single decision that made the whole system debuggable.

Most early failures in RAG systems look the same from the outside — wrong answer, vague citation — and you can spend weeks tuning prompts when the real problem is that the retriever never surfaced the relevant chunk. Building the retrieval-contains-answer diagnostic was the unlock: I could see immediately whether the bottleneck was retrieval (improve search) or generation (improve prompts), and stop tuning one when the other was the actual cause.

What I'd do differently. Build the evaluation harness before the retrieval pipeline. Several weeks of early work tuning chunk sizes and embedding models would have been redirected if I'd had MedQA-style benchmarks running from day one. I'd also be more aggressive about archiving earlier experiments (TF-IDF, BEIR/NFCorpus) into a structured comparison from the start rather than retroactively.

← Prev: LinkedIn Scraper Next: Kyareureuk Party →