Question answering
Answering a question from text comes in three flavors by where the answer lives and how it's produced. Extractive QA predicts a span of a passage; open-domain QA retrieves the passage first, then reads it; generative QA writes the answer freely. The retriever-reader pipeline is the direct ancestor of RAG.
Written and reviewed by Shreyash Prashu Last reviewed
What you'll learn
- Extractive QA — predicting an answer span (start and end)
- Open-domain QA — the retriever-reader pipeline, and its link to RAG
- Generative QA — free-text answers and the hallucination trade-off
- How QA evaluation (EM/F1) works, and where each flavor fits
Before you start
Question answering (QA) sounds like one task but is really three. They differ in where the answer comes from and how it’s produced: extract it from a given passage, retrieve the passage first and then extract, or generate it freely. These distinctions still structure how every modern QA system is built, including retrieval-augmented LLMs (systems that look up documents before a large language model writes its answer).
Extractive QA: predict a span
The classic benchmark, SQuAD (a large public set of questions, each paired with a passage that holds the answer), gives a question and a passage known to contain the answer. The answer is a contiguous span of that passage, meaning a run of consecutive words. The model scores every token (a word or word piece) twice: how likely it is to be the start of the answer, and how likely it is to be the end. The answer is the best valid span (start ≤ end):
passage = "the Eiffel Tower is in Paris France".split()
start = [0, 0, 0, 0, 0, 3, 0] # per-token START scores the model predicts
end = [0, 0, 0, 0, 0, 3, 1] # per-token END scores
best = (-1, None)
for i in range(len(passage)):
for j in range(i, min(i + 3, len(passage))): # spans up to length 3, with i <= j
if start[i] + end[j] > best[0]:
best = (start[i] + end[j], (i, j))
i, j = best[1]
print("Q: where is the Eiffel Tower?")
print(f"answer span: {' '.join(passage[i:j+1])!r} (score {best[0]})")
Q: where is the Eiffel Tower?
answer span: 'Paris' (score 6)
The model is really doing token classification (span labeling): score each position as start/end, then pick the highest-scoring legal span. This is the canonical task you fine-tune BERT for (take the pretrained BERT language model and train it a bit more on QA examples). Because the answer is copied verbatim from the passage, it can’t hallucinate, which means it can’t invent facts the text never stated. Its weakness is that the answer must be present as a literal span.
Open-domain QA: retrieve, then read
Extractive QA assumes you’re handed the right passage. Open-domain QA drops that: the question arrives alone (“Where is the Eiffel Tower?”), and the system must first find relevant text. The pipeline is retriever → reader. A retriever pulls candidate passages from a large corpus, using either BM25 (ranking by shared keywords) or dense embeddings (ranking by closeness in meaning). Then a reader (extractive QA) pulls the answer span from them. This two-stage pattern is the direct ancestor of RAG. Swap the extractive reader for a generative LLM and retriever-reader becomes retrieval-augmented generation.
Generative QA, and evaluation
Generative QA writes the answer in free text with a seq2seq model (a network that reads one text and writes another) or an LLM, rather than copying a span. It can synthesize across multiple passages and phrase the answer naturally. But being generation, it can hallucinate an answer that isn’t supported. Extractive QA is scored with Exact Match (is the predicted span exactly the gold answer?) and F1 (token overlap, for partial credit). Generative answers need fuzzier or model-based scoring because many phrasings are correct.
In one breath
- QA has three flavors: extractive (answer is a span of a given passage), open-domain (retrieve the passage first, then extract), and generative (write the answer freely).
- Extractive QA (SQuAD) predicts per-token start/end scores and returns the best legal span
(the demo:
Paris) — really token classification, the canonical BERT fine-tune; it can’t hallucinate but needs the answer present verbatim. - Open-domain QA is retriever → reader — find candidate passages (BM25/dense), then read the answer — the direct ancestor of RAG.
- Generative QA writes free-text answers (synthesize, paraphrase) but can hallucinate; evaluation uses Exact Match + F1 for spans, fuzzier scoring for generation.
- Modern QA = RAG (retrieve + generative reader); extractive span QA still wins when the answer must be provably grounded.
Quick check
Quick check
Next
The retriever-reader pattern here grows directly into RAG; span prediction is sequence labeling over the passage; and the generative reader is seq2seq. Conversational QA continues in dialogue systems.
Practice this in an interview
All questionsRAG retrieves relevant external documents at query time and gives them to an LLM as context before generation. A basic pipeline ingests and chunks documents, embeds the chunks into a searchable store, retrieves the best matches for a question, and asks the LLM to answer from that evidence.
RAG couples a retrieval step — fetching relevant documents from an external store — with a generative model so the LLM can answer questions about knowledge it was never trained on. It solves the stale-knowledge and hallucination problems without retraining. The pattern is preferred when the knowledge base changes frequently or contains proprietary data.
Nodes are the retrievable pieces of source content, carrying text, metadata, and relationships. A query engine retrieves relevant nodes and synthesizes an answer; wrapping it in QueryEngineTool lets an agent choose that RAG pipeline as a tool.
Evaluation splits into retrieval quality (did we fetch the right chunks?) and generation quality (did the model use them correctly?). Key metrics are context precision/recall for retrieval and faithfulness plus answer relevance for generation. Frameworks like RAGAS automate LLM-as-judge scoring; human annotation anchors the ground truth.