Generate a summary, then check what it kept and changed
natural language generation
abstractive summarization
evaluation
Learn how abstractive summarization differs from sentence selection and why shorter text still needs source review.
Rosa prepares the morning brief for a neighborhood archive. Two service notes have arrived, and each is longer than the one sentence her colleagues need. The shorter sentence still has to respect the source.
Abstractive summarization generates wording for a shorter account of a source. The output may reuse some source phrases, but it is not limited to selecting whole sentences. Lesson 54 used sentence selection. This lesson asks a local language model to write a new sentence, then checks the candidate against the original record.
TipWhat you will learn
This lesson shows how to:
keep source records, prompts, and outputs tied to durable IDs;
count the model’s input tokens before generation;
compare generated summaries with a first-sentence baseline;
separate compression from source support and useful coverage;
inspect names, numbers, and explicit limits without calling them proof; and
leave factual and editorial approval to a recorded human review.
Load the local model
The model files were downloaded before rendering at the revision recorded in data/nlg-models.csv. The code below uses huggingfaceR to load that local snapshot. Offline mode is set by R/use-nlg.R, so a missing model stops the lesson instead of starting a network download.
suppressPackageStartupMessages({library(dplyr)library(huggingfaceR)library(knitr)library(purrr)library(reticulate)library(stringr)library(tibble)library(tidyr)})source("R/use-nlg.R")summary_model <-load_nlg_pipeline("qwen_1_5b_instruct","text-generation")model_record <- summary_model$metadata |>select(model_id, revision, license, task_scope)kable( model_record,col.names =c("Model", "Revision", "License", "Use in this course"),caption ="Pinned local model used for the generated summaries",row.names =FALSE)
Pinned local model used for the generated summaries
The model card documents an instruction-tuned causal language model. That description and license do not establish that its summaries are accurate.
Keep the source beside the brief
These records are fictional teaching examples. They were written for this lesson and are not a random sample, a held-out benchmark, or evidence about archive services elsewhere.
Each brief states information that matters to the reader. SUM-01 needs the service, Tuesday schedule, and boundary on volunteer help. SUM-02 needs the event, photo-identification rule, and restricted-storage limit.
summary_sources <-tribble(~source_id, ~brief, ~source_text,"SUM-01",paste("One sentence for staff; retain the job-search service, Tuesday help","schedule, and boundary on volunteer help." ),paste("The Riverton library opens a new job-search room on Monday.","The room has 12 computers.","Volunteers offer free help on Tuesdays, but they do not complete","applications for visitors.","The pilot runs for six weeks." ),"SUM-02",paste("One sentence for visitors; retain the catalog workshop,","photo-identification rule, and restricted-storage limit." ),paste("The neighborhood archive will open Room 5 on 14 September for a","catalog workshop led by Maya Chen.","Registration is free, but visitors must bring photo identification.","The session does not include access to restricted storage." ))kable( summary_sources,col.names =c("Source ID", "Brief", "Source text"),caption ="Constructed source records and their summary briefs",row.names =FALSE)
Constructed source records and their summary briefs
Source ID
Brief
Source text
SUM-01
One sentence for staff; retain the job-search service, Tuesday help schedule, and boundary on volunteer help.
The Riverton library opens a new job-search room on Monday. The room has 12 computers. Volunteers offer free help on Tuesdays, but they do not complete applications for visitors. The pilot runs for six weeks.
SUM-02
One sentence for visitors; retain the catalog workshop, photo-identification rule, and restricted-storage limit.
The neighborhood archive will open Room 5 on 14 September for a catalog workshop led by Maya Chen. Registration is free, but visitors must bring photo identification. The session does not include access to restricted storage.
Declare required and optional facts
The checklist is fixed before generation. A missing required item sends a candidate back for revision. Optional clues remain useful during source review, but their omission alone does not violate the brief.
Required facts and optional review clues declared before generation
Source ID
Check
Predeclared information
Required by brief
SUM-01
F1
job-search service
TRUE
SUM-01
F2
Tuesday help
TRUE
SUM-01
F3
volunteers do not complete applications
TRUE
SUM-01
F4
12 computers
FALSE
SUM-01
F5
six-week pilot
FALSE
SUM-02
F6
catalog workshop
TRUE
SUM-02
F7
photo identification
TRUE
SUM-02
F8
no restricted-storage access
TRUE
SUM-02
F9
Room 5
FALSE
SUM-02
F10
14 September
FALSE
SUM-02
F11
Maya Chen
FALSE
SUM-02
F12
free registration
FALSE
Check the input budget before generation
A model token is a tokenizer unit, not necessarily a word. The prompt includes the instruction, brief, and source text, so all three count against the input budget. This demonstration uses a 256-token ceiling and refuses to truncate.
summary_system <-paste("Write one sentence for the stated brief.","Use only information in the source.","Do not add a cause, recommendation, or new event.")summary_inputs <- summary_sources |>mutate(user_prompt =paste0("BRIEF: ", brief,"\nSOURCE ID: ", source_id,"\nSOURCE: ", source_text ),model_prompt =map2_chr( summary_system, user_prompt, \(system, user) {nlg_chat_prompt( summary_model$tokenizer, system, user ) } ),input_tokens =map_int( model_prompt, \(prompt) nlg_token_count(summary_model$tokenizer, prompt) ) )kable( summary_inputs |>select(source_id, input_tokens),col.names =c("Source ID", "Complete prompt tokens"),caption ="Tokenizer counts before summarization",row.names =FALSE)
Tokenizer counts before summarization
Source ID
Complete prompt tokens
SUM-01
120
SUM-02
117
No text is cut to fit. A longer document would need a stated policy such as sectioning or hierarchical summarization before the model call.
Generate the candidate summaries
Greedy decoding chooses the highest-scoring next token at each step. The output limit is 72 new tokens. The call returns the generated text and token-level stopping information from the local model.
Generated summaries beside an extractive comparator
Source ID
Generated abstractive candidate
First-sentence teaching baseline
SUM-01
The Riverton library will continue to provide a job-search room with 12 computers, offer Tuesday volunteer help, and maintain a boundary on volunteer assistance during the pilot program’s six-week run.
The Riverton library opens a new job-search room on Monday.
SUM-02
Visitors are encouraged to attend the catalog workshop, participate in photo-identification, and adhere to the restricted-storage limit at the neighborhood archive’s opening on 14 September.
The neighborhood archive will open Room 5 on 14 September for a catalog workshop led by Maya Chen.
The first-sentence baseline is available before any model output is read. It is not a fair contest with a matched length budget; it shows the difference between selecting source wording and generating a new account.
Measure shortening without calling it truth
The next table counts whitespace-separated words. That rule is easy to inspect, but it is different from the model tokenizer used for the generation budget. A compression ratio below 1 means the candidate is shorter. It says nothing about whether the candidate kept the needed facts.
The generated sentence can be short because it chose the right content, because it omitted necessary content, or both. Length cannot separate those cases.
Inspect facts chosen before generation
Rosa writes a checklist before reading the output. The regular expressions below flag visible strings related to that checklist. A missing flag points to an omission worth reading. A present flag cannot prove that the name, number, or negative statement has the right role or scope.
Only missing required facts trigger automatic revision
Source ID
Missing required facts
Missing optional clues
Next action
SUM-01
1
0
revise
SUM-02
1
3
revise
This check is intentionally incomplete. It cannot detect a changed relation, a number attached to the wrong thing, an unsupported cause, or a fluent generalization. Those require reading the source and candidate together. In this render, the first candidate changes the boundary on volunteer help. The second uses negative wording while changing the relationship to restricted storage. The surface table catches part of the problem, and source comparison catches the rest. Likewise, n-gram overlap metrics such as ROUGE measure reference overlap under a specified normalization rule. They do not measure the share of claims supported by the source.
Record the review boundary
Execution can establish that a model ran, stayed inside the configured budgets, and returned text. It cannot grant factual or editorial approval.
summary_review <-tibble(review =c("local model execution","prompt input within 256 tokens","output stopped at EOS or token cap","required-fact surface screen","human source-support review","human usefulness and prose review" ),status =c(sprintf("completed: %d candidates",sum(nzchar(summary_results$generated_summary)) ),sprintf("within budget: %d/%d candidates",sum(summary_inputs$input_tokens <=256L),nrow(summary_inputs) ),sprintf("recorded: %d/%d candidates",sum(summary_results$ended_by_eos | summary_results$hit_token_cap),nrow(summary_results) ),sprintf("held: %d/%d candidates missing required facts",sum(summary_actions$missing_required >0L),nrow(summary_actions) ),"pending","pending" ))kable( summary_review,col.names =c("Review gate", "Status"),caption ="Automatic execution checks remain separate from human review",row.names =FALSE)
Automatic execution checks remain separate from human review
Review gate
Status
local model execution
completed: 2 candidates
prompt input within 256 tokens
within budget: 2/2 candidates
output stopped at EOS or token cap
recorded: 2/2 candidates
required-fact surface screen
held: 2/2 candidates missing required facts
human source-support review
pending
human usefulness and prose review
pending
A publishable summary needs a reader to trace each claim to the source, decide whether the brief’s essential information survived, and reject unsupported additions. A fluent one-sentence result is only a candidate.