Mar 2026 – Mar 2026
AI · CSLast edited
Type-Aware Hybrid RAG for Factoid QA
Built a RAG system for short-answer factoid QA over UC Berkeley EECS pages. The pipeline crawls EECS subdomains into a JSONL corpus, generates candidate QA pairs with LLM assistance, and indexes chunks with enriched retrieval text (page title, URL host/path tokens, and content) to improve BM25 lexical matching.
At query time the system builds weighted query variants per question type (person, email, location, date/year, etc.), fuses BM25 scores, applies domain-specific reranking, and answers with an instruction-tuned LLM under strict short-answer formatting. A deterministic extractive fallback (regex + relation patterns + overlap scoring) takes over when the LLM is disabled.
Achieved token-level F1 of 76% on the validation set and 92% on the holdout-mini set with the LLM enabled. Inter-annotator agreement was 86.7% Exact Match and 92.4% token-level F1. Ablations isolate the LLM as the largest single contributor to end-to-end accuracy.
Affiliation
UC Berkeley
Partners
Report
- Manuscript
Keywords
- NLP
- RAG
- LLMs
- BM25
- BFS Crawl
- Query Expansion
- Slot Filling
- Python
- Slurm
Answering questions about Berkeley from Berkeley’s own website
The last project in UC Berkeley’s CS288 (Natural Language Processing) was to answer short factoid questions — who is the Director of External Relations, what is the graduate admissions email — using nothing but a crawl of the EECS website. My two teammates and I built the whole pipeline: a crawler that turns the site into a corpus, a type-aware BM25 retriever, an instruction-tuned LLM reader, and a deterministic extractor that takes over when the LLM is gone.

Scoring well on the questions you can see is not the hard part; you tune against them until the number goes up. The work is surviving the questions you can’t see: a hidden grader, running a different LLM, over pages your crawl never emphasised.
The trap in a single F1 number
The system is scored on exact match and token F1 against short gold answers. But a high F1 can come from three different places. Retrieval put the right page in front of the reader and the reader read it. Or the deterministic extractor pulled the answer straight out of the text without the LLM. Or, the dangerous one, the LLM already knew the answer from training and would have said it whatever the retriever returned. The first two generalise. The third collapses the moment the grader swaps in a different model.

So the pipeline is built to make those routes measurable. Beside the headline F1 it tracks URL recall@k (did the gold page reach the reader), answer-in-context (is the gold answer verbatim in the retrieved text), and fallback-only F1 (how far the system falls with the LLM switched off).
How it works

Turning a website into a corpus. A breadth-first crawler starts at the EECS homepage and walks the link graph, staying strictly inside the domain, normalising URLs so no page is crawled twice, and dropping everything that is not HTML. The result is 8,417 pages, the entire knowledge base the system is allowed to know anything from.

Making the URL part of the text. The highest-leverage retrieval choice is what a chunk is represented as. Every chunk gets its page title, URL host, and URL path tokens prepended before BM25 sees it. BM25 rewards exact token overlap, and a question about “the Director of External Relations” overlaps a path like /people/staff/external-relations-staff/ far more cleanly than it overlaps the prose. Counterintuitively, the less the page text is cleaned the better: aggressive cleaning strips the exact strings BM25 relies on.
Retrieving by answer type. Before retrieving, the system classifies what kind of answer the question wants — person, email, location, date, program, yes/no — and expands it into weighted query variants tuned to that type. Email questions over-weight @ and contact-page n-grams; person questions over-weight role and title tokens. Scores are fused, and a type-aware reranker rewards chunks whose URL path matches the cue. The default top-3 is deliberately small: enough to clear the recall bar, small enough to keep distractors out of the reader’s context.

Reading, and a fallback for when there’s no reader. The LLM sees the question plus the top chunks and returns only the answer, which is postprocessed for the strict grader: course codes canonicalised, degrees and dates normalised, “unknown” standardised. When the LLM is disabled, a deterministic extractor swaps in: regex and entity detectors for emails, phones, dates, and names over the same chunks. Weaker on the hard cases, but it keeps the system standing when the reader is taken away.
A soft prior, never a hard filter. After the first version underperformed on the hidden dev set, a question-prior module was added: find the most similar past question of the same type and use the URL it resolved to as a bias on reranking. Because it risks overfitting to the curated file, every ablation is reported with and without it, and the headline number is the prior-disabled one.
Results
Validation token-F1 is 0.758 with the prior disabled, against an inter-annotator ceiling of 0.924 measured on a blind subset.
The diagnostics localise the gap. URL recall@4 is 73 % and answer-in-context is 81 %, so for nearly a fifth of questions the right evidence never reaches the reader: retrieval, not reading, is the bottleneck. And the ablation that mattered for the hidden grader:
- Validation F1 drops 0.474 when the LLM is switched off (0.758 → 0.284).
- Holdout-mini F1 drops only 0.274 (0.924 → 0.650) under the same switch.
The validation set is full of disambiguation cases, several emails on one contact page, that only the LLM resolves, so the fallback collapses there. On the cleaner holdout the extractor gets close to parity, which is the robustness you want when a different LLM is grading. The uncomfortable 0.474 is the honest measure of how much the system still leans on its reader.
What I took away
Scoring well on the slice you can see is easy. Knowing why it scores well, and whether that reason still holds when the distribution moves, is where the engineering was.