Summarization in Chrome with built-in AI

Published: November 11, 2024

Imagine you could offer your users the ability to distill lengthy articles, complex documents, or even lively chat conversations into concise and insightful summaries.

The Summarizer API can be used to generate different types of summaries in varied lengths and formats, such as sentences, paragraphs, bullet point lists, and more. We believe this API is useful in the following scenarios:

  • Summarizing the key points of an article or a chat conversation.
  • Suggesting titles and headings for articles.
  • Creating a concise and informative summary of a lengthy text.
  • Generating a teaser for a book based on a book review.

Availability

  • Join the Summarizer API origin trial, running from Chrome 131 to Chrome 136, to test the API with real users in production. Origin trials enable the feature for all users on your origin on Chrome. Learn how to get started with origin trials.
    • While there may be usage limits, you can integrate these features for live testing and gathering user feedback. The goal is to inform future iterations of this API, as we work towards wider availability.
  • Follow our implementation in Chrome Status.
  • The Summarizer API proposal is part of a suite of writing APIs, and it's open to discussion.
  • Join the early preview program for an early look at new built-in AI APIs and access to discussion on our mailing list.

Limitations during the origin trial

During the origin trial, the Summarizer API only supports the summarization of English texts, as the model quality was only thoroughly tested on English content. We intend to lift this limitation once we've tested additional languages for quality and safety, and the API is widely available.

Use the Summarizer API

First, run feature detection to see if the browser supports the Summarizer API.

if ('ai' in self && 'summarizer' in self.ai) {
  // The Summarizer API is supported.
}

Model download

The Summarizer API uses a powerful AI model trained to generate high-quality summaries. While the API is built into Chrome, the model is downloaded separately the first time a website uses the API.

To determine if the model is ready to use, call the asynchronous ai.summarizer.capabilities() function. It returns an AISummarizerCapabilities object with an available field that can take three possible values:

  • no: The current browser supports the Summarizer API, but it can't be used at the moment. This could be for a number of reasons, such as insufficient available disk space to download the model.
  • readily: The current browser supports the Summarizer API, and it can be used right away.
  • after-download: The current browser supports the Summarizer API, but it needs to download the model first.

To trigger the model download and create the summarizer, call the asynchronous ai.summarizer.create() function. If the response to capabilities() was after-download, it's best practice to listen for download progress. This way, you can inform the user in case the download takes time.

const summarizer = await ai.summarizer.create({
  monitor(m) {
    m.addEventListener('downloadprogress', (e) => {
      console.log(`Downloaded ${e.loaded} of ${e.total} bytes.`);
    });
  }
});

API functions

The create() function lets you configure a new summarizer object to your needs. It takes an optional options object with the following parameters:

  • sharedContext: Additional shared context that can help the summarizer.
  • type: The type of the summarization, with the allowed values key-points (default), tl;dr, teaser, and headline.
  • format: The format of the summarization, with the allowed values markdown (default), and plain-text.
  • length: The length of the summarization, with the allowed values short, medium (default), and long. The meanings of these lengths vary depending on the type requested. For example, in Chrome's implementation, a short key-points summary consists of three bullet points, and a short summary is one sentence; a long key-points summary is seven bullet points, and a long summary is a paragraph.

The following example demonstrates how to initialize the summarizer.

const options = {
  sharedContext: 'This is a scientific article',
  type: 'key-points',
  format: 'markdown',
  length: 'medium',
};

const available = (await self.ai.summarizer.capabilities()).available;
let summarizer;
if (available === 'no') {
  // The Summarizer API isn't usable.
  return;
}
if (available === 'readily') {
  // The Summarizer API can be used immediately .
  summarizer = await self.ai.summarizer.create(options);
} else {
  // The Summarizer API can be used after the model is downloaded.
  summarizer = await self.ai.summarizer.create(options);
  summarizer.addEventListener('downloadprogress', (e) => {
    console.log(e.loaded, e.total);
  });
  await summarizer.ready;
}

Run the summarizer

There are two ways to run the summarizer: streaming and non-streaming.

Non-streaming summarization

With non-streaming summarization, the model processes the input as a whole and then produces the output.

To get a non-streaming summary, call the summarizer's asynchronous summarize() function. The first argument for the function is the text that you want to summarize. The second, optional argument is an object with a context field. This field lets you add background details that might improve the summarization.

const longText = document.querySelector('article').innerHTML;
const summary = await summarizer.summarize(longText, {
  context: 'This article is intended for a tech-savvy audience.',
});

Streaming summarization

Streaming summarization offers results in real-time. The output updates continuously as the input is added and adjusted.

To get a streaming summary, call the summarizer's summarizeStreaming() function. Then iterate over the available segments of text in the stream.

let result = '';
let previousChunk = '';
for await (const chunk of stream) {
  const newChunk = chunk.startsWith(previousChunk)
      ? chunk.slice(previousChunk.length) : chunk;
  console.log(newChunk);
  result += newChunk;
  previousChunk = chunk;
}
console.log(result);

summarizeStreaming() returns a ReadableStream, in which the response segments build successively on each other. This means each response contains the entire summary generated up to that point, not just the next segment, which is not the intended behavior.

We intend to align with other streaming APIs on the platform, where the segments are successive pieces of a single long stream. For now, to achieve the intended behavior, you can implement the following:

let result = '';
let previousLength = 0;
for await (const segment of stream) {
  const newContent = segment.slice(previousLength);
  console.log(newContent);
  previousLength = segment.length;  
  result += newContent;
}
console.log(result);

Demo

You can try the Summarizer API in the Summarizer API Playground.

Standardization effort

We're working to standardize the Summarizer API, to ensure cross-browser compatibility.

Our API proposal received community support and has moved to the W3C Web Incubator Community Group for further discussion. The Chrome team requested feedback from the W3C Technical Architecture Group, and asked Mozilla and WebKit for their standards positions.

Participate and share feedback

Start testing the Summarizer API now by joining the origin trial and share your feedback. Your input can directly impact how we build and implement future versions of this API, and all built-in AI APIs.