In this post, we'll briefly learn what text summarization is, how large language models approach it, and how to build practical summarization pipelines for different document types and length constraints in Python. The tutorial covers:
- What is Text Summarization?
- Types of Summarization
- Installation and Setup
- Basic Summarization with a System Prompt
- Controlling Summary Length and Style
- Bullet-Point and Structured Summaries
- Multi-Document Summarization
- Chunked Summarization for Long Documents
- Choosing the Right Summarization Approach
- Conclusion
Let's get started.
What is Text Summarization?
Text summarization is the task of automatically condensing a long piece of text into a shorter version that retains the most important information. It is one of the oldest and most practically useful NLP tasks — applied daily in news aggregation, meeting transcription, research paper review, customer support ticket triage, legal document analysis, and many other domains where reading everything in full is impractical.
LLMs bring a significant advantage over earlier summarization methods: because they understand language in context rather than scoring sentences statistically, they can synthesise information from multiple paragraphs, resolve pronouns, infer implicit connections, and produce summaries that read like natural prose written by a human — rather than a collection of mechanically extracted sentences stitched together.
Types of Summarization
There are two fundamental approaches to text summarization, and LLM-based systems can perform both. Extractive summarization selects and copies key sentences from the original document verbatim. Abstractive summarization generates new sentences that capture the meaning of the source, potentially using vocabulary and phrasing not present in the original text. LLMs default to abstractive summarization and are far better at it than any previous approach.
| Approach | Method | Output Style | Best For |
|---|---|---|---|
| Extractive | Selects key sentences verbatim | Exact quotes from source | Legal, compliance, audit trails |
| Abstractive | Generates new sentences | Fluent, rewritten prose | News, reports, general use |
| Structured | Organises into sections or bullets | Sections, bullets, headers | Meeting notes, research papers |
| Chunked (map-reduce) | Summarise chunks then combine | Coherent long-form summary | Books, transcripts, long docs |
Installation and Setup
All examples in this tutorial use Ollama with the
llama3.2
model running locally. Install Ollama from
ollama.com, pull the model, and
install the Python client. The same prompting patterns work unchanged with the
OpenAI, Anthropic, and Google Gemini APIs.
# Terminal — pull the model once
# ollama pull llama3.2
pip install ollama
import ollama
def summarise(
text: str,
system: str,
temperature: float = 0.3,
max_tokens: int = 400
) -> str:
"""Send text to the model with a summarisation system prompt."""
response = ollama.chat(
model="llama3.2",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": text}
],
options={"temperature": temperature, "num_predict": max_tokens}
)
return response["message"]["content"].strip()
The helper function
summarise()
accepts the raw text, a system prompt that defines the summarisation task, and
sampling parameters. All summarisation behaviour is controlled through the system
prompt — the same function handles every style demonstrated in this tutorial.
Basic Summarization with a System Prompt
The simplest summarisation prompt instructs the model to produce a concise, accurate summary of whatever text is provided. Explicitly stating the target length, the required tone, and any fields to preserve — such as key figures or dates — prevents the model from over-generalising and discarding important details.
import ollama
def summarise(text, system, temperature=0.3, max_tokens=400):
response = ollama.chat(
model="llama3.2",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": text}
],
options={"temperature": temperature, "num_predict": max_tokens}
)
return response["message"]["content"].strip()
system = (
"You are a professional summariser. "
"Summarise the given text in three to five sentences. "
"Preserve all key facts, figures, names, and dates. "
"Write in plain, neutral prose. Do not add information not in the text."
)
article = """
The European Space Agency (ESA) confirmed on Monday that its Hera mission
successfully entered orbit around the Didymos binary asteroid system, marking
a major milestone in planetary defence research. Launched in October 2024,
Hera is the first spacecraft to revisit an asteroid that has been intentionally
deflected — Dimorphos, which was struck by NASA's DART probe in 2022. The
spacecraft will spend the next 18 months mapping the crater left by DART,
measuring Dimorphos's internal structure, and assessing how much the asteroid's
orbit changed. ESA mission director Ian Carnelli described the arrival as
"textbook perfect" and said early telemetry showed all instruments operating
normally. The Hera data will be used to build deflection models that could
protect Earth from hazardous asteroids in the future. The mission cost
approximately €363 million and involves contributions from 17 ESA member states.
"""
summary = summarise(article, system)
print("Summary:")
print(summary)Output:
Summary:
ESA's Hera spacecraft has successfully entered orbit around the Didymos binary
asteroid system, becoming the first mission to revisit a deflected asteroid.
Launched in October 2024, Hera will spend 18 months studying the crater created
by NASA's DART impact on Dimorphos in 2022, measuring structural changes and
orbital shifts. Mission director Ian Carnelli called the arrival "textbook
perfect," with all instruments functioning normally. The €363 million mission,
supported by 17 ESA member states, aims to build deflection models that could
one day protect Earth from dangerous asteroids.
The summary preserves all key facts — the mission name, launch date, the DART connection, the cost, the 18-month timeline, and the mission director's quote — while reducing the source from roughly 120 words to 85. The instruction "do not add information not in the text" suppresses hallucination of plausible-sounding but unverified details.
Controlling Summary Length and Style
Different audiences and use cases require different summary lengths and tones. A product manager needs a two-line executive overview; a developer needs a technical synopsis; a general reader needs a jargon-free explanation. Below we send the same article through four distinct style presets and compare the outputs.
import ollama
def summarise(text, system, temperature=0.3, max_tokens=300):
response = ollama.chat(
model="llama3.2",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": text}
],
options={"temperature": temperature, "num_predict": max_tokens}
)
return response["message"]["content"].strip()
article = """
Researchers at MIT have developed a new battery technology that can charge to
80% capacity in under five minutes using a novel solid-state electrolyte design.
The prototype cells demonstrated an energy density of 400 Wh/kg — nearly double
that of conventional lithium-ion batteries — while maintaining stability over
1,500 charge cycles. Lead researcher Dr. Aiko Yamamoto said the team expects
to partner with automotive manufacturers within two years to scale production.
The breakthrough could significantly accelerate the adoption of electric vehicles
by eliminating the range anxiety associated with long charging times.
"""
styles = {
"One-Sentence (Executive)": (
"Summarise the text in exactly one sentence of no more than 25 words. "
"Focus on the single most important finding."
),
"Two-Paragraph (General Reader)": (
"Write a two-paragraph summary for a general audience with no technical "
"background. Avoid jargon. First paragraph: what happened. "
"Second paragraph: why it matters."
),
"Technical Synopsis": (
"Write a precise technical synopsis for an engineer. Include all "
"quantitative figures, materials mentioned, and methodological details. "
"Maximum four sentences."
),
"Social Media Caption": (
"Write a punchy, engaging social media caption summarising the news. "
"Maximum two sentences. Conversational tone. No hashtags."
),
}
for style_name, system_prompt in styles.items():
print(f"── {style_name} ──")
print(summarise(article, system_prompt))
print()
Output:
── One-Sentence (Executive) ──
MIT researchers have developed a solid-state battery that charges to 80% in
under five minutes with nearly double the energy density of lithium-ion cells.
── Two-Paragraph (General Reader) ──
Scientists at MIT have created a new type of battery that charges to 80% in
less than five minutes — far faster than any battery currently used in electric
cars. The prototype also holds almost twice as much energy as a standard
lithium-ion battery and stays stable after 1,500 charge cycles.
This breakthrough could be a turning point for electric vehicles. One of the
biggest reasons people hesitate to switch from petrol cars is the worry of
running out of charge far from a charging point. A battery that charges this
quickly largely removes that concern, and the MIT team expects to be working
with car makers within two years.
── Technical Synopsis ──
MIT researchers have engineered a solid-state battery prototype using a novel
solid-state electrolyte that achieves 80% charge in under five minutes and an
energy density of 400 Wh/kg — approximately 2× that of conventional Li-ion
cells. The prototype sustained performance over 1,500 charge cycles, indicating
strong electrochemical stability. The lead researcher anticipates automotive
partnerships within two years to advance manufacturing scale-up.
── Social Media Caption ──
MIT just built a battery that charges to 80% in under five minutes and holds
twice the energy of a standard EV battery. Electric vehicles are about to get
a lot less frustrating.
All four summaries are factually faithful to the source — the key figures (80%, five minutes, 400 Wh/kg, 1,500 cycles, two years) appear wherever the style warrants it. The only dimension that changes is framing, vocabulary, and length — all controlled entirely through the system prompt.
Bullet-Point and Structured Summaries
Meeting notes, research papers, and technical reports are best summarised into structured formats that separate the most important information into scannable sections. A structured summary prompt asks the model to organise the content into named sections, making the output directly usable as a document or email attachment.
import ollama
def summarise(text, system, temperature=0.3, max_tokens=500):
response = ollama.chat(
model="llama3.2",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": text}
],
options={"temperature": temperature, "num_predict": max_tokens}
)
return response["message"]["content"].strip()
system = """
You are a business analyst. Summarise the meeting transcript into a structured
report with these exact sections:
**Meeting Summary** — two-sentence overview of the meeting purpose and outcome.
**Key Decisions** — bullet list of decisions made (each bullet: one sentence).
**Action Items** — bullet list of tasks, each formatted as:
• [Owner] — Task description — Due: [date or "TBD"]
**Open Questions** — bullet list of unresolved issues requiring follow-up.
Use only information explicitly stated in the transcript.
"""
transcript = """
Project sync — DataPlatform Team — 14 June 2026
Attendees: Sarah (PM), James (Lead Engineer), Priya (Data Engineer),
Tom (QA), Linda (Stakeholder).
Sarah opened by reviewing Q2 goals. The team is behind on the ETL pipeline
refactor — originally due June 30 but now expected to slip to mid-July due
to an unexpected dependency on the legacy API. James confirmed that the new
connector module is 70% complete. Priya raised a concern about data quality
in the staging environment: three tables have null values in fields that
should be non-nullable. Tom said QA cannot begin full regression testing until
the null issue is resolved.
The team decided to prioritise the null-value fix above all other work this
sprint. James will assign it to Priya with a target completion of June 18.
Sarah will notify Linda of the revised ETL deadline and request a two-week
extension. Tom will draft the QA test plan in parallel so it is ready the
moment Priya's fix merges.
Linda asked whether the dashboard refresh, scheduled for July 5, would be
affected by the ETL slip. Sarah said she was not yet certain and would
confirm by end of week. No decision was made on the dashboard date.
The team will reconvene on June 19 for a follow-up check-in.
"""
print(summarise(transcript, system))
Output:
**Meeting Summary**
The DataPlatform team met on 14 June 2026 to review Q2 progress and address
a critical data quality issue blocking QA. The ETL pipeline refactor has been
delayed to mid-July due to a legacy API dependency, and a null-value bug in
the staging environment was identified as the immediate priority.
**Key Decisions**
• The null-value fix in the staging environment will be the team's top sprint priority.
• James will assign the fix to Priya with a target completion of 18 June.
• Sarah will formally request a two-week ETL deadline extension from Linda.
• Tom will develop the QA test plan in parallel while the fix is in progress.
**Action Items**
• [Priya] — Fix null values in staging environment tables — Due: 18 June 2026
• [Sarah] — Notify Linda of revised ETL deadline and request extension — Due: TBD
• [Tom] — Draft QA regression test plan — Due: before Priya's fix merges
• [Sarah] — Confirm impact on July 5 dashboard refresh — Due: end of week
**Open Questions**
• Will the ETL slip to mid-July affect the dashboard refresh scheduled for 5 July?
• No decision made — Sarah to confirm by end of week.
The structured output is immediately actionable: the action items section alone could be pasted directly into a project management tool. The open question about the dashboard date is correctly preserved as unresolved — the model does not hallucinate a decision that was not made.
Multi-Document Summarization
A common real-world requirement is to synthesise information from several related documents into a single coherent summary — for example, combining multiple analyst reports, customer reviews, or research abstracts. We label each document in the prompt and instruct the model to cross-reference them, highlighting agreements, contradictions, and complementary information.
import ollama
def summarise(text, system, temperature=0.3, max_tokens=500):
response = ollama.chat(
model="llama3.2",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": text}
],
options={"temperature": temperature, "num_predict": max_tokens}
)
return response["message"]["content"].strip()
system = """
You are a research analyst. You will receive multiple labelled documents.
Synthesise them into a single coherent summary that:
1. Identifies the main theme shared across all documents.
2. Notes where documents AGREE on key points.
3. Notes where documents DISAGREE or present conflicting data.
4. Lists any unique information found in only one document.
Write in four clearly labelled paragraphs matching the four points above.
"""
documents = {
"Document A — TechCrunch": """
OpenAI reported revenue of $3.4 billion in 2024, a threefold increase from
the previous year. The company credits GPT-4o and its enterprise API tier
for the growth. However, losses also widened significantly, with operating
costs exceeding $8 billion, largely driven by compute infrastructure spend.
""",
"Document B — Bloomberg": """
OpenAI's 2024 annual revenue surpassed $3 billion according to sources
familiar with the matter, with enterprise contracts accounting for the
majority of income. The company is reportedly on track for an IPO as early
as 2026, though no formal filing has been made. Compute costs remain the
single largest expense line item.
""",
"Document C — The Information": """
While OpenAI's revenues have grown substantially, insiders note that
customer churn among mid-market subscribers has risen by 18% year over year.
Microsoft, which holds a significant equity stake, has begun developing
competing in-house models to reduce dependency on OpenAI's API. Revenue
figures cited by different sources vary between $3.2 billion and $3.7 billion.
""",
}
# Build the combined input
combined = "\n\n".join(
f"[{label}]\n{text.strip()}" for label, text in documents.items()
)
print(summarise(combined, system))Output:
**Main Theme**
All three documents address OpenAI's financial performance in 2024, focusing
on its strong revenue growth, the sources of that growth, and the cost pressures
the company faces as it scales.
**Points of Agreement**
All three sources confirm that OpenAI's 2024 revenues exceeded $3 billion and
that enterprise customers and API usage were the primary revenue drivers. Each
document also identifies compute infrastructure costs as the dominant expense,
consistent with the high hardware demands of training and serving large models.
**Points of Disagreement**
The exact revenue figure differs across sources: Document A cites $3.4 billion,
Document C quotes a range of $3.2–$3.7 billion, and Document B gives a less
precise "surpassed $3 billion." Document A reports operating losses exceeding
$8 billion, but neither Document B nor C provides a matching loss figure,
making the profitability picture difficult to reconcile across sources.
**Unique Information**
Document B alone mentions a potential IPO as early as 2026, with no formal
filing confirmed. Document C is the only source to report an 18% rise in
mid-market subscriber churn and to note that Microsoft is developing competing
in-house models to reduce its dependency on OpenAI's API.
The model correctly identifies the revenue figure discrepancy across the three sources and clearly flags it as a contradiction rather than averaging or silently picking one figure. The IPO detail and the churn statistic are correctly attributed as unique to their respective documents.
Chunked Summarization for Long Documents
LLMs have a finite context window. Documents longer than that window — entire books, long legal contracts, or hour-long transcripts — must be split into chunks, each summarised independently, and then the chunk summaries are combined into a final document summary. This is commonly called the map-reduce pattern: map (summarise each chunk) then reduce (combine chunk summaries into one).
import ollama
def summarise(text, system, temperature=0.3, max_tokens=300):
response = ollama.chat(
model="llama3.2",
messages=[
{"role": "system", "content": system},
{"role": "user", "content": text}
],
options={"temperature": temperature, "num_predict": max_tokens}
)
return response["message"]["content"].strip()
def chunk_text(text: str, chunk_size: int = 400) -> list[str]:
"""Split text into chunks of approximately chunk_size words."""
words = text.split()
chunks = []
for i in range(0, len(words), chunk_size):
chunks.append(" ".join(words[i : i + chunk_size]))
return chunks
def map_reduce_summarise(document: str, chunk_size: int = 400) -> str:
"""Summarise a long document using the map-reduce pattern."""
chunk_system = (
"Summarise the following passage in two to three sentences. "
"Preserve all key facts, figures, names, and dates. "
"This is one section of a longer document."
)
combine_system = (
"You are given a series of short summaries, each covering one section "
"of a longer document. Write a single coherent final summary of the "
"entire document in four to six sentences. Do not repeat yourself. "
"Preserve the most important facts, figures, and conclusions."
)
# Step 1 — MAP: summarise each chunk independently
chunks = chunk_text(document, chunk_size)
chunk_summaries = []
print(f"Document split into {len(chunks)} chunk(s). Summarising each...\n")
for i, chunk in enumerate(chunks, start=1):
chunk_summary = summarise(chunk, chunk_system, max_tokens=150)
chunk_summaries.append(f"[Section {i}]\n{chunk_summary}")
print(f"Section {i} summary:\n{chunk_summary}\n")
# Step 2 — REDUCE: combine chunk summaries into a final summary
combined = "\n\n".join(chunk_summaries)
print("─" * 60)
print("Final combined summary:\n")
return summarise(combined, combine_system, max_tokens=400)
# Simulate a long document with three logical sections
long_document = """
Section one: The history of renewable energy.
Renewable energy sources have been used by humans for millennia — wind-powered
sailing ships date back over 5,000 years, and watermills were widespread in
ancient Rome. The modern era of renewable energy began in the 1970s when the
global oil crisis forced governments to search for alternatives to fossil fuels.
Denmark was an early pioneer, investing heavily in wind power during the 1970s
and 1980s and establishing the foundation for what is now a global industry.
Solar photovoltaic technology was developed by Bell Labs in 1954 but remained
prohibitively expensive until economies of scale drove costs down by over 90%
between 2010 and 2023.
Section two: Current state of the industry.
As of 2024, renewables account for approximately 30% of global electricity
generation, with solar and wind the fastest-growing sources. China leads the
world in installed capacity for both solar and wind, followed by the United
States and the European Union. The levelised cost of electricity from utility-
scale solar has fallen to $0.033 per kWh — making it the cheapest source of
electricity in history. Battery storage capacity is growing in parallel,
addressing the intermittency challenge that long limited renewables to a
supplementary role in the energy mix. Global investment in clean energy reached
$1.8 trillion in 2023, surpassing fossil fuel investment for the first time.
Section three: Future outlook and challenges.
The International Energy Agency projects that renewables could supply 60% of
global electricity by 2030 if current investment trends continue. The principal
remaining challenges include grid modernisation, long-duration energy storage,
and the geopolitical concentration of critical mineral supply chains — lithium,
cobalt, and rare earth elements are largely controlled by a small number of
countries. The energy transition also raises equity concerns: developing nations
that have contributed least to climate change often bear the greatest adaptation
costs and face the highest financing barriers to building renewable infrastructure.
Policymakers, multilateral institutions, and private investors are increasingly
focusing on these structural barriers as the next frontier of the clean energy
transition.
"""
final = map_reduce_summarise(long_document, chunk_size=120)
print(final)Output:
Document split into 3 chunk(s). Summarising each...
Section 1 summary:
Renewable energy has ancient roots, with wind and water power used for
millennia, but the modern industry emerged after the 1970s oil crisis. Denmark
pioneered wind power, while solar PV technology, invented in 1954, became
economically viable only after a 90% cost reduction between 2010 and 2023.
Section 2 summary:
Renewables now supply 30% of global electricity, with solar reaching a record-
low cost of $0.033 per kWh. China leads in installed capacity, and global clean
energy investment hit $1.8 trillion in 2023, exceeding fossil fuel investment
for the first time, supported by rapidly growing battery storage.
Section 3 summary:
The IEA projects renewables could provide 60% of global electricity by 2030,
but challenges remain: grid modernisation, long-duration storage, and critical
mineral supply chains concentrated in few countries. Equity concerns persist,
as developing nations face the highest barriers to financing clean energy
infrastructure despite contributing least to climate change.
────────────────────────────────────────────────────────────
Final combined summary:
Renewable energy has evolved from ancient wind and water power to a modern
industry triggered by the 1970s oil crisis, with Denmark and Bell Labs' 1954
solar PV invention laying early foundations. A 90% cost reduction in solar
between 2010 and 2023 drove its rise to become the cheapest electricity source
in history at $0.033 per kWh. Renewables now supply 30% of global electricity,
led by China in installed capacity, and clean energy investment reached $1.8
trillion in 2023 — surpassing fossil fuels for the first time. The IEA projects
a 60% renewable share by 2030, though grid modernisation, long-duration storage,
and concentrated critical mineral supply chains remain key obstacles. Equity
concerns also persist, as developing nations face the steepest financing barriers
despite contributing least to the climate crisis driving the transition.
Each section is independently summarised to a manageable size, then the three
partial summaries are combined into a final synthesis. The
chunk_size
parameter controls how much text each LLM call processes — reduce it for models
with smaller context windows or increase it to reduce the number of API calls on
moderate-length documents.
Choosing the Right Summarization Approach
Selecting the right summarisation approach depends on the document length, the audience, how the summary will be consumed, and whether preserving the original wording matters. The table below maps common scenarios to practical starting configurations.
| Use Case | Approach | Max Tokens | Temperature |
|---|---|---|---|
| News article (general) | Abstractive, prose | 100 – 200 | 0.3 |
| Executive briefing | One sentence / TL;DR | 30 – 60 | 0.2 |
| Meeting transcript | Structured (decisions, actions) | 400 – 600 | 0.2 |
| Research paper | Technical synopsis | 200 – 400 | 0.2 |
| Multiple documents | Multi-doc synthesis | 400 – 600 | 0.3 |
| Legal / compliance doc | Extractive or structured | 300 – 500 | 0.0 |
| Long document (> context window) | Map-reduce chunked | 150 per chunk + 400 final | 0.3 |
| Social media / marketing | Creative, punchy | 40 – 80 | 0.7 |
Keep temperature low (0.0–0.3) for factual and legal summarisation where faithfulness to the source is critical. A higher temperature (0.5–0.7) is appropriate for creative or marketing summaries where originality and engagement matter more than verbatim accuracy. Always include the instruction "do not add information not in the text" in any factual summarisation prompt to minimise the risk of hallucination.
Conclusion
In this post, we briefly learned what text summarization is and how LLMs approach it through abstractive, structured, multi-document, and chunked strategies. We built a basic summarisation helper, demonstrated four audience-specific style presets for the same article, structured a meeting transcript into decisions and action items, synthesised three conflicting analyst reports into a cross-referenced summary, and implemented a map-reduce pipeline for documents that exceed a single context window. Mastering summarisation is one of the highest-leverage LLM skills in applied development — almost every domain generates more text than any human can read, and a well-prompted summariser dramatically extends what a single person or team can process.
No comments:
Post a Comment