Query-focused summarisation
Query-focused summarisation builds a summary around one specific question, pulling out only the parts of a document that answer it.
- 9 min read
- 3 reading levels
- Published
Read these first
On this page 5
One lesson, three depths. Pick the one that fits you today — you can switch any time.
Beginner — No maths. Plain English.
Query-focused summarisation builds a summary around one specific question, instead of trying to cover everything.
Picture missing a two-hour team meeting. You do not ask a colleague to replay the whole thing. You ask one question: "what did they decide about the budget?"
Your colleague does not repeat everything said. They scan their memory for the budget parts, and answer only that. Query-focused summarisation is a model doing the same filtering.
Why it exists
A regular summary tries to cover a document's most important points overall. That is fine when you want the whole picture.
Often you do not. You want one answer, buried somewhere in a long document, without reading the rest. A generic summary might not even mention it, since it was busy covering other topics.
Query-focused summarisation flips the goal. Instead of "what matters most in this document", it asks "what in this document matters for this question."
How it works
Document: 6 sentences, mixed topics
Query: "What did they decide about the budget?"
|
v
Score every sentence by how well it matches the query
|
v
Keep the sentences that scored highest
|
v
Summary = the budget-relevant sentences onlyThe scoring step usually relies on embeddings. An embedding turns a sentence into a list of numbers that captures its meaning. Sentences with a similar meaning end up with similar numbers. The query gets turned into numbers too, and whichever sentences land closest win.
Where you have already seen it
- Asking ChatGPT to "summarise only the pricing section" of a long document. You gave it a query.
- Search engines that show a highlighted answer snippet, not the whole page. The snippet is chosen for your specific search, not for the page in general.
- "Ask this PDF a question" tools. They pull the relevant passages before answering, rather than reading the whole document to you.
- Customer support search that jumps to the one paragraph answering your issue. Everything else in the article gets skipped.
Remember this
- Query-focused summarisation answers one specific question, not "what matters overall".
- It works by scoring how relevant each sentence is to the query, then keeping the best matches.
- The same document can produce completely different summaries for different queries.
What to learn next
- Embeddings — the technique behind measuring "how relevant" a sentence is.
- Multi-document summarisation — applying a similar idea across many documents at once.
- Keyword search vs semantic search — the retrieval idea this lesson leans on.
Developer — Code and libraries.
The core trick: turn every sentence, and the query, into a vector. Then rank sentences by how close their vector sits to the query's vector.
Setup
pip install transformers torchRanking sentences against a query
import torch
from transformers import AutoTokenizer, AutoModel
tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
def embed(texts):
tokens = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
with torch.no_grad():
output = model(**tokens)
# average every token's vector, ignoring padding, to get one vector per sentence
mask = tokens["attention_mask"].unsqueeze(-1)
summed = (output.last_hidden_state * mask).sum(1)
counts = mask.sum(1).clamp(min=1e-9)
return summed / counts
sentences = [
"The quarterly meeting covered three topics: hiring, budget and the new office.",
"Hiring is on track. We added six engineers and two designers this quarter.",
"The marketing team launched a new campaign for the festive season.",
"The budget is tight. Cloud costs rose eighteen percent due to higher traffic.",
"The new Bengaluru office will open in November, a month later than planned.",
"Everyone agreed the team lunch on Friday was a good idea.",
]
query = "What did they decide about the budget?"
sentence_vecs = embed(sentences)
query_vec = embed([query])[0]
scores = torch.nn.functional.cosine_similarity(sentence_vecs, query_vec.unsqueeze(0))
top_idx = torch.topk(scores, k=2).indices.tolist()
print("Query:", query)
print("\nQuery-focused summary:")
for i in sorted(top_idx):
print(f" ({scores[i]:.3f}) {sentences[i]}")Query: What did they decide about the budget? Query-focused summary: (0.482) The quarterly meeting covered three topics: hiring, budget and the new office. (0.390) The budget is tight. Cloud costs rose eighteen percent due to higher traffic.
Line by line
embed() does mean pooling. The model outputs one vector per token, not one vector per sentence. Averaging those vectors, while ignoring padding, gives a single sentence-level vector. This is a common, simple way to turn a token-level model into a sentence-level one.
cosine_similarity measures the angle between two vectors, ignoring their length. Two vectors pointing in a similar direction score close to 1. Two pointing in unrelated directions score close to 0.
torch.topk(scores, k=2) picks the two highest-scoring sentences. Raise k for a longer, safer summary. Lower it for a tighter one — the same trade-off covered in controlling summary length.
Why sentence 1 scored highest. It never states a budget decision. It only mentions the word "budget" once, in a list. But it still beat four sentences that share zero words with the query, because embeddings compare meaning, not exact words.
Common mistakes
Expecting an exact keyword match. Embeddings compare meaning, not vocabulary. A query about "cost overruns" can match a sentence that never uses the word "cost" at all. This is a feature, not a bug. It also means the top match will not always contain your search words.
Only extracting, never generating. This lesson's code is extractive: it picks existing sentences. Want a fluent, one-paragraph answer instead of a list of quotes? Feed the top sentences into an abstractive summariser as a second step. That is the same pattern used in hierarchical summarisation.
Forgetting to re-embed the query for every new question. The document's sentence embeddings can be computed once and reused. The query embedding changes every time the question changes, and must be recomputed each time.
Not truncating long sentences before embedding. truncation=True protects you here, but a model has a maximum input length. A sentence longer than that gets silently cut, and the cut-off part plays no role in its score.
Try it yourself
Change the query to "Is the new office ready yet?" and rerun. The top two sentences should shift entirely, even though the document itself did not change at all.
What to learn next
- Bi-encoders vs cross-encoders — a more accurate, more expensive way to score relevance than this lesson's approach.
- Sentence-transformers — the library this lesson's model family comes from, covered in full.
- Reranking the top 50 — refining a first-pass ranking like this one.
Researcher — Mathematics and papers.
The task as constrained selection
Given document sentences s_1, ..., s_n and query q, query-focused summarisation selects S, a subset of {s_1, ..., s_n}. The goal: maximise relevance to q under a length budget, optionally penalising redundancy within S. This is the MMR objective from extractive summarisation, with sim(s_i, D) replaced by sim(s_i, q).
The task originates in the DUC 2005-2007 evaluations. Systems answered a short natural-language "topic statement" using a small document set. It is a direct ancestor of the retrieval step in modern RAG (retrieval-augmented generation) pipelines.
Scoring relevance: from lexical to dense
Classical systems scored sim(s_i, q) with BM25 or TF-IDF cosine similarity — exact-term overlap, reweighted by term rarity. These fail on vocabulary mismatch. A query about "layoffs" will not match a sentence about "workforce reduction" under pure lexical scoring.
Dense retrieval replaces this with learned sentence embeddings. The developer block's mean-pooling encoder is a minimal version of the architecture behind sentence-transformers (Reimers & Gurevych, 2019). It is trained with a contrastive objective. Semantically similar sentences land near each other in vector space, regardless of shared vocabulary.
Bi-encoders vs cross-encoders
The developer block is a bi-encoder: document and query are embedded independently, then compared by a cheap vector operation. This lets the document's sentence embeddings be precomputed once and reused across many queries, at O(n) cost per new query.
A cross-encoder instead feeds (q, s_i) jointly through one model, letting the model attend across both texts at once. This is far more accurate, since the model can directly compare query and sentence, not only their separately-computed summaries. But it costs one full forward pass per candidate sentence. That does not scale to scoring a full document against every possible query in real time. Production systems typically retrieve with a bi-encoder, then rerank the top candidates with a cross-encoder. The full pattern is in bi-encoders vs cross-encoders.
Generation, given the retrieved evidence
Selection alone gives an extractive query-focused summary. For an abstractive one, retrieved sentences are concatenated and passed to a sequence-to-sequence model. The query is folded into the input string too. For example: "answer using only this context: " + retrieved + " question: " + q. This is architecturally identical to retrieval-augmented generation for question answering. Query-focused summarisation and RAG-based QA differ mainly in output form: a synthesised paragraph, versus a direct answer.
Evaluation
DUC-era systems were scored with ROUGE, against multiple human-written query-focused reference summaries. A good answer to an open query is rarely unique. Modern evaluation increasingly uses LLM-as-a-judge, covered in using an LLM to grade text. It scores relevance to the query, not only generic fluency.
Key references
- Dang, H. (2005). Overview of DUC 2005. Document Understanding Conference.
- Reimers, N. & Gurevych, I. (2019). Sentence-BERT. arXiv:1908.10084
- Lewis, P. et al. (2020). Retrieval-Augmented Generation. arXiv:2005.11401
Current state and open problems
Query-focused summarisation, as an academic task, has largely merged into the broader RAG literature. The retrieval step is now near-identical machinery, whether the final output is a summary paragraph or a direct answer.
The open problem is one of scope: what counts as "relevant" when a query is ambiguous. A query like "what happened with the budget" could reasonably want the decision, the reasoning, or both. No retrieval score alone distinguishes between these different reader intents.
What to learn next
- What is RAG? — the broader pattern this technique is a special case of.
- Bi-encoders vs cross-encoders — the accuracy-versus-speed trade-off in full depth.
- Building a retrieval test set for your own corpus — how to actually measure whether your retrieval step works.